#ifndef _KNOTKIT_PERIODICITY_H #define _KNOTKIT_PERIODICITY_H #include #include #include #include #include #include extern bool verbose; extern const char* knot; extern std::string periodicity_test; const std::vector primes_list = {5, 7, 11, 13, 17, 19}; enum class Test_Result { MAYBE, NO, NO_NONTRIVIAL_DECOMP }; const unsigned eval_index = 1; const unsigned invert_index = 2; template class periodic_congruence_checker { protected: using polynomial = multivariate_laurentpoly; using monomial = multivariate_laurent_monomial; int prime; unsigned index; polynomial prepare_polynomial(const polynomial& pol) const { polynomial inv = invert_variable(pol, index); return pol - inv; } public: periodic_congruence_checker(int pprime = 5, unsigned ind = invert_index) : prime(pprime), index(ind) {} virtual ~periodic_congruence_checker() {}; const polynomial reduce(const polynomial& pol) const; bool operator() (const polynomial& pol) const { return reduce(prepare_polynomial(pol)) == 0; // return reduce(prepare_polynomial(pol)) == 0; } }; template const multivariate_laurentpoly periodic_congruence_checker::reduce(const multivariate_laurentpoly& pol) const { polynomial res; for(typename map::const_iter i = pol.coeffs; i; i++) { int c = i.key().m[index] % (2 * prime); if(c < 0) c += (2 * prime); monomial mon = monomial(VARIABLE, index, c); res += polynomial(i.val(), mon); } // if(verbose) // std::cout << "res = " << res << "\n"; return res; } class Przytycki_periodicity_checker { using polynomial = multivariate_laurentpoly; using monomial = multivariate_laurent_monomial; polynomial jones_pol; public: Przytycki_periodicity_checker(polynomial j) : jones_pol(j) {} ~Przytycki_periodicity_checker() {} bool check(int period) const; std::string operator() (int period) const; }; class Kh_bounds_iterator { using polynomial = multivariate_laurentpoly; using monomial = multivariate_laurent_monomial; using polynomial_tuple = std::vector>; using bounds_vector = std::map, std::pair>; bounds_vector bv; int period; std::map current_state; std::map>::iterator level; public: Kh_bounds_iterator(bounds_vector v, int p) : bv(v), period(p) { for(auto& v: bv) { current_state[v.first] = v.second.first; } level = bv.begin(); } ~Kh_bounds_iterator() {} bool advance(); polynomial get_polynomial() const; }; class Kh_periodicity_checker { using polynomial = multivariate_laurentpoly; using monomial = multivariate_laurent_monomial; using polynomial_tuple = std::vector>; using bounds_vector = std::map, std::pair>; unsigned ev_index; unsigned index; polynomial khp, leep; std::vector quot, mul, quotients, remainders; std::string knot_name; std::vector compute_knot_polynomials(knot_diagram& kd); void compute_quot(const std::vector& lee_ss_polynomials); polynomial_tuple compute_quotient_and_remainder(const std::vector& p, int period) const; bounds_vector compute_bounds(const polynomial_tuple& p, int period) const; Test_Result check(const polynomial_tuple& polynomials, int period) const; public: Kh_periodicity_checker(knot_diagram& kd, std::string knot_n) : knot_name(knot_n) { ev_index = 1; index = 2; quot = std::vector(); mul = std::vector(); compute_quot(compute_knot_polynomials(kd)); } ~Kh_periodicity_checker() {} std::string operator () (int period) const; polynomial get_KhP() const { return khp; } polynomial get_LeeP() const { return leep; } }; #endif // _KNOTKIT_PERIODICITY_H