2016-11-19 21:01:10 +01:00
|
|
|
#ifndef _KNOTKIT_PERIODICITY_H
|
|
|
|
#define _KNOTKIT_PERIODICITY_H
|
|
|
|
|
|
|
|
#include <knotkit.h>
|
|
|
|
#include <sstream>
|
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
2017-01-13 11:51:49 +01:00
|
|
|
#include <utility>
|
2017-01-26 11:33:27 +01:00
|
|
|
#include <tuple>
|
2016-11-19 21:01:10 +01:00
|
|
|
|
|
|
|
extern bool verbose;
|
|
|
|
|
2017-02-08 12:05:23 +01:00
|
|
|
constexpr std::array<int, 6> primes_list = {5, 7, 11, 13, 17, 19};
|
2016-11-19 21:01:10 +01:00
|
|
|
|
2017-02-08 12:05:23 +01:00
|
|
|
constexpr unsigned eval_index = 1;
|
|
|
|
constexpr unsigned invert_index = 2;
|
2016-11-19 21:01:10 +01:00
|
|
|
|
|
|
|
template<class T>
|
|
|
|
class periodic_congruence_checker {
|
2016-11-28 09:26:41 +01:00
|
|
|
protected:
|
2016-11-19 21:01:10 +01:00
|
|
|
using polynomial = multivariate_laurentpoly<T>;
|
|
|
|
using monomial = multivariate_laurent_monomial;
|
|
|
|
|
|
|
|
int prime;
|
|
|
|
unsigned index;
|
|
|
|
|
|
|
|
polynomial prepare_polynomial(const polynomial& pol) const {
|
2016-11-28 09:26:41 +01:00
|
|
|
polynomial inv = invert_variable(pol, index);
|
|
|
|
return pol - inv;
|
2016-11-19 21:01:10 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
2017-02-08 12:05:23 +01:00
|
|
|
periodic_congruence_checker(int p = 5,
|
2016-11-28 09:26:41 +01:00
|
|
|
unsigned ind = invert_index) :
|
2017-02-08 12:05:23 +01:00
|
|
|
prime(p),
|
2016-11-19 21:01:10 +01:00
|
|
|
index(ind)
|
|
|
|
{}
|
|
|
|
|
2016-11-28 09:26:41 +01:00
|
|
|
virtual ~periodic_congruence_checker() {};
|
2016-11-19 21:01:10 +01:00
|
|
|
|
2017-01-13 11:51:49 +01:00
|
|
|
const polynomial reduce(const polynomial& pol) const;
|
|
|
|
|
2016-11-19 21:01:10 +01:00
|
|
|
bool operator() (const polynomial& pol) const {
|
2017-01-13 11:51:49 +01:00
|
|
|
return reduce(prepare_polynomial(pol)) == 0;
|
2016-11-19 21:01:10 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
template<class T>
|
2017-01-13 11:51:49 +01:00
|
|
|
const multivariate_laurentpoly<T>
|
|
|
|
periodic_congruence_checker<T>::reduce(const multivariate_laurentpoly<T>& pol) const {
|
2016-11-19 21:01:10 +01:00
|
|
|
polynomial res;
|
|
|
|
for(typename map<monomial, T>::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);
|
|
|
|
}
|
2017-01-13 11:51:49 +01:00
|
|
|
return res;
|
2016-11-19 21:01:10 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
class Przytycki_periodicity_checker {
|
2016-11-28 09:26:41 +01:00
|
|
|
using polynomial = multivariate_laurentpoly<Z>;
|
2016-11-19 21:01:10 +01:00
|
|
|
using monomial = multivariate_laurent_monomial;
|
|
|
|
|
2016-11-28 09:26:41 +01:00
|
|
|
polynomial jones_pol;
|
2017-02-08 12:05:23 +01:00
|
|
|
std::string knot_name;
|
2016-11-28 09:26:41 +01:00
|
|
|
|
2016-11-19 21:01:10 +01:00
|
|
|
public:
|
2017-02-08 12:05:23 +01:00
|
|
|
Przytycki_periodicity_checker(polynomial j, std::string knot_n) :
|
|
|
|
jones_pol(j), knot_name(knot_n) {}
|
2016-11-19 21:01:10 +01:00
|
|
|
|
|
|
|
~Przytycki_periodicity_checker() {}
|
2016-11-28 09:26:41 +01:00
|
|
|
|
2017-01-13 11:51:49 +01:00
|
|
|
bool check(int period) const;
|
2016-11-28 09:26:41 +01:00
|
|
|
|
2017-01-13 11:51:49 +01:00
|
|
|
std::string operator() (int period) const;
|
2016-11-19 21:01:10 +01:00
|
|
|
};
|
|
|
|
|
2017-01-26 11:33:27 +01:00
|
|
|
class Kh_bounds_iterator {
|
|
|
|
using polynomial = multivariate_laurentpoly<Z>;
|
|
|
|
using monomial = multivariate_laurent_monomial;
|
|
|
|
using polynomial_tuple = std::vector<std::tuple<polynomial, polynomial, polynomial>>;
|
|
|
|
using bounds_vector = std::map<multivariate_laurentpoly<Z>, std::pair<Z, Z>>;
|
|
|
|
|
|
|
|
bounds_vector bv;
|
|
|
|
int period;
|
|
|
|
std::map<polynomial, Z> current_state;
|
|
|
|
std::map<polynomial, std::pair<Z,Z>>::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;
|
|
|
|
};
|
|
|
|
|
2016-11-19 21:01:10 +01:00
|
|
|
class Kh_periodicity_checker {
|
|
|
|
using polynomial = multivariate_laurentpoly<Z>;
|
|
|
|
using monomial = multivariate_laurent_monomial;
|
2017-01-26 11:33:27 +01:00
|
|
|
using polynomial_tuple = std::vector<std::tuple<polynomial, polynomial, polynomial>>;
|
|
|
|
using bounds_vector = std::map<multivariate_laurentpoly<Z>, std::pair<Z, Z>>;
|
2016-11-19 21:01:10 +01:00
|
|
|
|
|
|
|
unsigned ev_index;
|
|
|
|
unsigned index;
|
|
|
|
|
2017-02-08 12:05:23 +01:00
|
|
|
enum class Test_Result { MAYBE, NO, NO_NONTRIVIAL_DECOMP };
|
|
|
|
|
2017-01-26 11:33:27 +01:00
|
|
|
polynomial khp, leep;
|
|
|
|
std::vector<polynomial> quot, mul, quotients, remainders;
|
2016-11-19 21:01:10 +01:00
|
|
|
|
2017-01-13 11:51:49 +01:00
|
|
|
std::string knot_name;
|
2017-02-08 12:05:23 +01:00
|
|
|
std::string field;
|
2017-01-13 11:51:49 +01:00
|
|
|
|
2017-02-08 12:05:23 +01:00
|
|
|
template<typename R>
|
2017-01-26 11:33:27 +01:00
|
|
|
std::vector<polynomial> compute_knot_polynomials(knot_diagram& kd);
|
|
|
|
void compute_quot(const std::vector<polynomial>& lee_ss_polynomials);
|
|
|
|
polynomial_tuple
|
|
|
|
compute_quotient_and_remainder(const std::vector<polynomial>& 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;
|
2016-11-19 21:01:10 +01:00
|
|
|
|
|
|
|
public:
|
2017-02-08 12:05:23 +01:00
|
|
|
Kh_periodicity_checker(knot_diagram& kd, std::string knot_n, std::string f);
|
2016-11-19 21:01:10 +01:00
|
|
|
|
|
|
|
~Kh_periodicity_checker() {}
|
|
|
|
|
|
|
|
std::string operator () (int period) const;
|
2016-11-28 09:26:41 +01:00
|
|
|
|
|
|
|
polynomial get_KhP() const {
|
|
|
|
return khp;
|
|
|
|
}
|
|
|
|
|
|
|
|
polynomial get_LeeP() const {
|
|
|
|
return leep;
|
|
|
|
}
|
2016-11-19 21:01:10 +01:00
|
|
|
};
|
|
|
|
|
2017-02-08 12:05:23 +01:00
|
|
|
void check_periodicity(knot_diagram& kd, const std::string knot_name,
|
|
|
|
int period = 5, const std::string field = "Z2");
|
|
|
|
|
2016-11-19 21:01:10 +01:00
|
|
|
#endif // _KNOTKIT_PERIODICITY_H
|