Merge branch 'periodicity'

This commit is contained in:
Wojciech Politarczyk 2017-02-25 18:48:59 +01:00
commit c3d01fd161
3 changed files with 232 additions and 309 deletions

345
kk.cpp
View File

@ -2,14 +2,10 @@
#include <periodicity.h> #include <periodicity.h>
#include <fstream> #include <fstream>
#include <sstream> #include <sstream>
#include <thread>
#include <future>
#include <vector> #include <vector>
#include <utility> #include <utility>
#include <cctype> #include <cctype>
const unsigned max_threads = 4;
const char *program_name; const char *program_name;
void void
@ -91,11 +87,11 @@ void tex_footer ()
const char *knot = 0; const char *knot = 0;
const char *invariant = 0; const char *invariant = 0;
const char *field = "Z2"; const char *field = "Z2";
std::string periodicity_test = "Przytycki";
int period = 5;
knot_diagram kd; knot_diagram kd;
bool reduced = 0; bool reduced = 0;
std::string in_file_name = "/home/wojtek/ownCloud/Lokalny/khovanov-homology-computation/both.txt";
extern int period;
extern std::string periodicity_test;
class hg_grading_mapper class hg_grading_mapper
{ {
@ -334,170 +330,6 @@ int compute_s_inv(knot_diagram& kd) {
return qmin + 1; return qmin + 1;
} }
std::pair<std::string, int> parse_data_from_file(const std::string& data) {
auto knot_name_stop = data.find(" ");
auto p2 = data.find("=") + 2;
std::string knot_name = data.substr(0, knot_name_stop);
int period = std::stoi(data.substr(knot_name_stop + 3));
return make_pair(knot_name, period);
}
std::string perform_computations(const std::string& knot_name,
knot_diagram kd,
std::vector<int> periods) {
std::ostringstream res;
Kh_periodicity_checker Kh_pc(kd, knot_name);
for(auto p: periods) {
res << "Kh criterion: " << Kh_pc(p) << std::endl;
}
return res.str();
}
void check_periodicity(std::string out_file) {
if(periodicity_test == "all") {
Kh_periodicity_checker Kh_pc(kd, std::string(knot));
for(auto& p : primes_list) {
std::cout << "Kh criterion: "
<< Kh_pc(p) << std::endl;
}
}
else if(periodicity_test == "Kh_from_file") {
std::ifstream in_file(in_file_name);
if(!in_file) {
std::cerr << "Cannot open file " << in_file_name << "\n";
exit(EXIT_FAILURE);
}
unsigned num_threads = std::min(max_threads, std::thread::hardware_concurrency());
unsigned i = 0;
std::string line, previous_knot;
knot_diagram kd_temp;
std::vector<std::future<std::string>> v_future(num_threads);
std::vector<int> periods;
while(std::getline(in_file, line)) {
if(line == "") continue;
std::string knot_name;
int period;
tie(knot_name, period) = parse_data_from_file(line);
if(knot_name == previous_knot) {
auto p = find(primes_list.begin(), primes_list.end(), period);
if(p != primes_list.end()) {
periods.push_back(period);
}
else {
std::cerr << "Period " << period << " cannot be checked..." << "\n";
}
}
else {
if(i == num_threads) {
for(auto& v_f : v_future)
std::cout << v_f.get();
i = 0;
}
if(previous_knot.size() > 0) {
std::cerr << "Checking " << previous_knot << "\n";
v_future[i] = std::async(perform_computations, previous_knot, kd_temp, periods);
++i;
periods.clear();
}
kd_temp = parse_knot(knot_name.c_str());
kd_temp.marked_edge = 1;
periods.push_back(period);
previous_knot = knot_name;
}
}
for(auto& v_f : v_future) {
if(v_f.valid())
std::cout << v_f.get();
}
}
else if(periodicity_test == "all_seq") {
std::string k(knot);
// first check whether the number of crossings is bigger or lower than 10
if(isdigit(k[1])) {
// at least 10 crossings
if(k[1] == '0') {
// ten crossings
int num_cr = 10;
int knot_index = stoi(k.substr(3));
for(unsigned i = knot_index; i < rolfsen_crossing_knots(num_cr); i++) {
std::string knot_name = std::to_string(num_cr) + "_" + std::to_string(i);
knot_diagram kd_temp = parse_knot(knot_name.c_str());
kd.marked_edge = 1;
Kh_periodicity_checker Kh_pc(kd_temp, knot_name);
for(auto& p : primes_list) {
std::cout << "Kh criterion: "
<< Kh_pc(p) << std::endl;
}
}
}
else {
int num_cr = stoi(k.substr(0,2));
int knot_index = stoi(k.substr(3));
char alt = k[2];
bool alternating = (alt == 'a' ? true : false);
for(unsigned i = knot_index; i <= htw_knots(num_cr, alternating); i++) {
std::string knot_name = std::to_string(num_cr) + alt + std::to_string(i);
knot_diagram kd_temp = parse_knot(knot_name.c_str());
kd.marked_edge = 1;
Kh_periodicity_checker Kh_pc(kd_temp, knot_name);
for(auto& p : primes_list) {
std::cout << "Kh criterion: "
<< Kh_pc(p) << std::endl;
}
}
}
}
else {
// at most nine crossings
int num_cr = stoi(k.substr(0, 1));
int knot_index = stoi(k.substr(2));
for(unsigned i = knot_index; i <= rolfsen_crossing_knots(num_cr); i++) {
std::string knot_name = std::to_string(num_cr) + "_" + std::to_string(i);
knot_diagram kd_temp = parse_knot(knot_name.c_str());
kd.marked_edge = 1;
Kh_periodicity_checker Kh_pc(kd_temp, knot_name);
for(auto& p : primes_list) {
std::cout << "Kh criterion: "
<< Kh_pc(p) << std::endl;
}
}
}
}
else {
if(period == 2 || period == 3) {
std::cout << "Sorry, the criterion doesn't work for period "
<< period << "...\n";
exit(EXIT_FAILURE);
}
auto result = std::find(primes_list.begin(), primes_list.end(), period);
if(result == primes_list.end()) {
std::cout << "For now you can only check periodicity for primes up to 19..." << "\n";
exit(EXIT_FAILURE);
}
std::ofstream out(out_file, std::ios_base::app);
if(periodicity_test == "Przytycki") {
Przytycki_periodicity_checker P_pc(compute_jones(kd));
if(out_file.size() != 0)
out << P_pc(period) << std::endl;
else
std::cout << P_pc(period) << std::endl;
}
else if(periodicity_test == "Kh") {
Kh_periodicity_checker Kh_pc(kd, std::string(knot));
if(out_file.size() != 0)
out << Kh_pc(period) << std::endl;
else
std::cout << Kh_pc(period) << std::endl;
}
else {
std::cout << "Sorry, I don't recognize this option..." << "\n";
exit(EXIT_FAILURE);
}
}
}
template<class R> void template<class R> void
compute_invariant () compute_invariant ()
{ {
@ -579,58 +411,56 @@ compute_invariant ()
ss.texshow (outfp, mapper); ss.texshow (outfp, mapper);
tex_footer (); tex_footer ();
} }
else if (!strcmp (invariant, "leess")) else if (!strcmp (invariant, "leess")) {
{ cube<R> c (kd, reduced);
cube<R> c (kd, reduced); ptr<const module<R> > C = c.khC;
ptr<const module<R> > C = c.khC;
mod_map<R> d = c.compute_d (1, 0, 0, 0, 0); mod_map<R> d = c.compute_d (1, 0, 0, 0, 0);
for (unsigned i = 1; i <= kd.n_crossings; i ++)
d = d + c.H_i (i);
assert (d.compose (d) == 0);
unsigned m = kd.num_components (); for (unsigned i = 1; i <= kd.n_crossings; i ++)
hg_grading_mapper mapper (m); d = d + c.H_i (i);
assert (d.compose (d) == 0);
sseq_bounds b (C, mapper); unsigned m = kd.num_components ();
basedvector<sseq_page, 1> pages; hg_grading_mapper mapper (m);
int k = 0; sseq_bounds b (C, mapper);
for (;;) basedvector<sseq_page, 1> pages;
{
chain_complex_simplifier<R> s (C, d,
maybe<int> (1), maybe<int> (2*k));
C = s.new_C;
d = s.new_d;
k ++;
grading dk_gr (1, 2*k); int k = 0;
pages.append (sseq_page (b, k, dk_gr, d.graded_piece (dk_gr), mapper)); for (;;) {
if (d == 0) chain_complex_simplifier<R> s (C, d,
break; maybe<int> (1), maybe<int> (2*k));
} C = s.new_C;
d = s.new_d;
k ++;
sseq ss (b, pages); grading dk_gr (1, 2*k);
pages.append (sseq_page (b, k, dk_gr, d.graded_piece (dk_gr), mapper));
tex_header (); if (d == 0)
fprintf (outfp, "$E_k = %s^{BN}_k(\\verb~%s~; \\verb~%s~)$:\\\\\n", break;
(reduced
? "\\widetilde{E}"
: "E"),
knot, field);
ss.texshow (outfp, mapper);
tex_footer ();
} }
sseq ss (b, pages);
tex_header ();
fprintf (outfp, "$E_k = %s^{BN}_k(\\verb~%s~; \\verb~%s~)$:\\\\\n",
(reduced
? "\\widetilde{E}"
: "E"),
knot, field);
ss.texshow (outfp, mapper);
tex_footer ();
}
else if (!strcmp (invariant, "s")) else if (!strcmp (invariant, "s"))
{ {
int s = compute_s_inv<R>(kd); int s = compute_s_inv<R>(kd);
fprintf (outfp, "s(%s; %s) = %d\n", knot, field, s); fprintf (outfp, "s(%s; %s) = %d\n", knot, field, s);
} }
else else {
{ fprintf (stderr, "error: unknown invariant %s\n", invariant);
fprintf (stderr, "error: unknown invariant %s\n", invariant); exit (EXIT_FAILURE);
exit (EXIT_FAILURE); }
}
} }
void void
@ -834,14 +664,6 @@ main (int argc, char **argv)
} }
periodicity_test = argv[i]; periodicity_test = argv[i];
} }
else if(!strcmp(argv[i], "-i")) {
i++;
if(i == argc) {
fprintf (stderr, "error: missing argument to option `-t'\n");
exit (EXIT_FAILURE);
}
in_file_name = argv[i];
}
else { else {
fprintf (stderr, "error: unknown argument `%s'\n", argv[1]); fprintf (stderr, "error: unknown argument `%s'\n", argv[1]);
fprintf (stderr, " use -h for usage\n"); fprintf (stderr, " use -h for usage\n");
@ -883,48 +705,41 @@ main (int argc, char **argv)
kd = parse_knot (knot); kd = parse_knot (knot);
kd.marked_edge = 1; kd.marked_edge = 1;
if (!strcmp (invariant, "gauss")) if (!strcmp (invariant, "gauss")) {
{
basedvector<basedvector<int, 1>, 1> gc = kd.as_gauss_code (); basedvector<basedvector<int, 1>, 1> gc = kd.as_gauss_code ();
for (unsigned i = 1; i <= gc.size (); i ++) for (unsigned i = 1; i <= gc.size (); i ++) {
{ if (i > 1)
if (i > 1) printf (":");
printf (":"); for (unsigned j = 1; j <= gc[i].size (); j ++) {
for (unsigned j = 1; j <= gc[i].size (); j ++) if (j > 1)
{ printf (",");
if (j > 1) printf ("%d", gc[i][j]);
printf (","); }
printf ("%d", gc[i][j]);
}
}
newline ();
}
if (!strcmp (invariant, "sq2"))
{
if (strcmp (field, "Z2"))
{
fprintf (stderr, "warning: sq2 only defined over Z2, ignoring -f %s\n", field);
field = "Z2";
}
compute_sq2 ();
} }
else if (!strcmp (invariant, "gss")) newline ();
{ }
if (strcmp (field, "Z2"))
{
fprintf (stderr, "warning: gss only defined over Z2, ignoring -f %s\n", field);
field = "Z2";
}
compute_gss (); if (!strcmp (invariant, "sq2")) {
if (strcmp (field, "Z2")) {
fprintf (stderr, "warning: sq2 only defined over Z2, ignoring -f %s\n", field);
field = "Z2";
} }
compute_sq2 ();
}
else if (!strcmp (invariant, "gss")) {
if (strcmp (field, "Z2")) {
fprintf (stderr, "warning: gss only defined over Z2, ignoring -f %s\n", field);
field = "Z2";
}
compute_gss ();
}
else if(!strcmp(invariant, "jones")) { else if(!strcmp(invariant, "jones")) {
std::cout << "Jones polynomial of " << knot << " = " << compute_jones(kd, reduced) << "\n"; std::cout << "Jones polynomial of " << knot << " = " << compute_jones(kd, reduced) << "\n";
} }
else if(!strcmp(invariant, "periodicity")) { else if(!strcmp(invariant, "periodicity")) {
check_periodicity((file ? std::string(file) : std::string())); check_periodicity(kd, std::string(knot), period, std::string(field));
} }
else if(!strcmp(invariant, "khp")) { else if(!strcmp(invariant, "khp")) {
multivariate_laurentpoly<Z> khp; multivariate_laurentpoly<Z> khp;
@ -947,20 +762,18 @@ main (int argc, char **argv)
<< ") of " << knot << " = " << std::endl << ") of " << knot << " = " << std::endl
<< khp << std::endl; << khp << std::endl;
} }
else else {
{ if (!strcmp (field, "Z2"))
if (!strcmp (field, "Z2")) compute_invariant<Z2> ();
compute_invariant<Z2> (); else if (!strcmp (field, "Z3"))
else if (!strcmp (field, "Z3")) compute_invariant<Zp<3>> ();
compute_invariant<Zp<3> > (); else if (!strcmp (field, "Q"))
else if (!strcmp (field, "Q")) compute_invariant<Q> ();
compute_invariant<Q> (); else {
else fprintf (stderr, "error: unknown field %s\n", field);
{ exit (EXIT_FAILURE);
fprintf (stderr, "error: unknown field %s\n", field);
exit (EXIT_FAILURE);
}
} }
}
if (file) if (file)
fclose (outfp); fclose (outfp);

View File

@ -2,6 +2,12 @@
#include <simplify_chain_complex.h> #include <simplify_chain_complex.h>
#include <algorithm> #include <algorithm>
#include <utility> #include <utility>
#include <fstream>
std::string periodicity_test = "Przytycki";
int period = 5;
extern multivariate_laurentpoly<Z> compute_jones(const knot_diagram& k, bool reduced = false);
using polynomial_tuple = std::vector<std::tuple<multivariate_laurentpoly<Z>, multivariate_laurentpoly<Z>, multivariate_laurentpoly<Z>>>; using polynomial_tuple = std::vector<std::tuple<multivariate_laurentpoly<Z>, multivariate_laurentpoly<Z>, multivariate_laurentpoly<Z>>>;
@ -39,7 +45,7 @@ bool Przytycki_periodicity_checker::check(int period) const {
std::string Przytycki_periodicity_checker::operator () (int period) const { std::string Przytycki_periodicity_checker::operator () (int period) const {
std::ostringstream res; std::ostringstream res;
res << knot << ": period = " << period << ": " res << knot_name << ": period = " << period << ": "
<< (check(period) ? "Maybe" : "No"); << (check(period) ? "Maybe" : "No");
return res.str(); return res.str();
} }
@ -82,8 +88,9 @@ multivariate_laurentpoly<Z> Kh_bounds_iterator::get_polynomial() const {
return p; return p;
} }
template<>
std::vector<multivariate_laurentpoly<Z>> std::vector<multivariate_laurentpoly<Z>>
Kh_periodicity_checker::compute_knot_polynomials(knot_diagram& kd) { Kh_periodicity_checker::compute_knot_polynomials<Z2>(knot_diagram& kd) {
unsigned m = kd.num_components (); unsigned m = kd.num_components ();
if (m != 1) { if (m != 1) {
std::cerr << "warning: this implementation of the criterion works for knots only..."; std::cerr << "warning: this implementation of the criterion works for knots only...";
@ -122,21 +129,86 @@ Kh_periodicity_checker::compute_knot_polynomials(knot_diagram& kd) {
std::cerr << "KhP = " << khp << "\n"; std::cerr << "KhP = " << khp << "\n";
std::cerr << "LeeP = " << leep << "\n"; std::cerr << "LeeP = " << leep << "\n";
} }
// for(unsigned i = 0; i < lee_ss_polynomials.size(); ++i) {
// std::cerr << "lee_ss_polynomials[" << i << "]= "
// << lee_ss_polynomials[i] << "\n";
// std::cerr << "mul[" << i << "] = " << mul[i] << "\n";
// }
return lee_ss_polynomials; return lee_ss_polynomials;
} }
template<typename R>
std::vector<multivariate_laurentpoly<Z>>
Kh_periodicity_checker::compute_knot_polynomials(knot_diagram& kd) {
unsigned m = kd.num_components ();
if (m != 1) {
std::cerr << "warning: this implementation of the criterion works for knots only...";
exit (EXIT_FAILURE);
}
cube<R> c (kd, 0);
ptr<const module<R> > C = c.khC;
mod_map<R> d = c.compute_d (1, 0, 0, 0, 0);
for (unsigned i = 1; i <= kd.n_crossings; i ++)
d = d + c.H_i (i);
assert (d.compose (d) == 0);
// computing Khovanov homology
if(verbose)
std::cerr << "Computing Khovanov homology" << std::endl;
std::vector<polynomial> lee_ss_polynomials;
int k = 0;
for(;;) {
chain_complex_simplifier<R> s(C, d, maybe<int>(1), maybe<int>(2*k));
C = s.new_C;
d = s.new_d;
if(k % 2 == 0) {
lee_ss_polynomials.push_back(C->free_poincare_polynomial());
if(k != 0)
mul.push_back(polynomial(Z(1)) + polynomial(Z(1), VARIABLE, 1, 1) * polynomial(Z(1), VARIABLE, 2, 2 * k));
}
if(d == 0)
break;
k++;
}
khp = *lee_ss_polynomials.begin();
leep = *lee_ss_polynomials.rbegin();
if(verbose) {
std::cerr << "KhP = " << khp << "\n";
std::cerr << "LeeP = " << leep << "\n";
}
return lee_ss_polynomials;
}
Kh_periodicity_checker::Kh_periodicity_checker(knot_diagram& kd,
std::string knot_n,
std::string f = "Z2") :
knot_name(knot_n), field(f) {
ev_index = 1;
index = 2;
quot = std::vector<polynomial>();
mul = std::vector<polynomial>();
if(field == "Z2")
compute_quot(compute_knot_polynomials<Z2>(kd));
else if(field == "Z3")
compute_quot(compute_knot_polynomials<Zp<3>>(kd));
else if(field == "Z5")
compute_quot(compute_knot_polynomials<Zp<3>>(kd));
else if(field == "Z7")
compute_quot(compute_knot_polynomials<Zp<7>>(kd));
else if(field == "Z11")
compute_quot(compute_knot_polynomials<Zp<11>>(kd));
else if(field == "Q")
compute_quot(compute_knot_polynomials<Q>(kd));
else {
std::cerr << "Sorry, I don't recognize field " << f << ". Exiting..." << "\n";
exit(EXIT_FAILURE);
}
}
void Kh_periodicity_checker::compute_quot(const std::vector<polynomial>& lee_ss_polynomials) { void Kh_periodicity_checker::compute_quot(const std::vector<polynomial>& lee_ss_polynomials) {
// quot.push_back(polynomial(Z(0)));
for(unsigned i = 1; i < lee_ss_polynomials.size(); ++i) { for(unsigned i = 1; i < lee_ss_polynomials.size(); ++i) {
polynomial diff = lee_ss_polynomials[i-1] - lee_ss_polynomials[i]; polynomial diff = lee_ss_polynomials[i-1] - lee_ss_polynomials[i];
polynomial q = 0; polynomial q = 0;
// std::cerr << "diff = " << diff << "\n";
// std::cerr << "mul = " << mul[i-1] << "\n";
while(diff != 0) { while(diff != 0) {
pair<monomial, Z> m = diff.head(); pair<monomial, Z> m = diff.head();
if(m.first.m[1] == 1) { if(m.first.m[1] == 1) {
@ -160,9 +232,6 @@ void Kh_periodicity_checker::compute_quot(const std::vector<polynomial>& lee_ss_
} }
quot.push_back(q); quot.push_back(q);
} }
// for(unsigned i = 0; i < quot.size(); ++i) {
// std::cerr << "quot[" << i << "] = " << quot[i] << "\n";
// }
} }
polynomial_tuple polynomial_tuple
@ -222,13 +291,9 @@ Kh_periodicity_checker::compute_bounds(const polynomial_tuple& p_tuple, int peri
mon *= monomial(VARIABLE, j.key(), v); mon *= monomial(VARIABLE, j.key(), v);
} }
} }
// std::cerr << polynomial(i.val() * pow(-1,exp), mon) << "\n";
Z v_temp = i.val() * pow(-1, exp); Z v_temp = i.val() * pow(-1, exp);
polynomial p_temp = (polynomial(1, mon) * mul).evaluate(-1, ev_index); polynomial p_temp = (polynomial(1, mon) * mul).evaluate(-1, ev_index);
p_temp = pcc.reduce(p_temp - invert_variable(p_temp, index)); p_temp = pcc.reduce(p_temp - invert_variable(p_temp, index));
// std::cerr << "p_temp = " << p_temp << "\n";
// std::cerr << "v_temp = " << v_temp << "\n";
// std::cerr << "min_exp = " << min_exp << "\n";
if(bounds_v.count(p_temp)) { if(bounds_v.count(p_temp)) {
if(v_temp >= 0) if(v_temp >= 0)
bounds_v[p_temp].second += (v_temp * period); bounds_v[p_temp].second += (v_temp * period);
@ -259,7 +324,8 @@ Kh_periodicity_checker::compute_bounds(const polynomial_tuple& p_tuple, int peri
return bounds_v; return bounds_v;
} }
Test_Result Kh_periodicity_checker::check(const polynomial_tuple& polynomials, Kh_periodicity_checker::Test_Result
Kh_periodicity_checker::check(const polynomial_tuple& polynomials,
int period) const { int period) const {
periodic_congruence_checker<Z> pcc(period); periodic_congruence_checker<Z> pcc(period);
polynomial t = polynomial(COPY, leep); polynomial t = polynomial(COPY, leep);
@ -299,8 +365,23 @@ Test_Result Kh_periodicity_checker::check(const polynomial_tuple& polynomials,
std::string Kh_periodicity_checker::operator () (int period) const { std::string Kh_periodicity_checker::operator () (int period) const {
std::ostringstream out; std::ostringstream out;
if(field == "Z5" && Zp<5>(period) == Zp<5>(0))
return "Period (" + std::to_string(period)
+ ") has to be relatively prime to "
+ "the characteristic of the field ("
+ field + ")...";
else if(field == "Z7" && Zp<7>(period) == Zp<7>(0))
return "Period (" + std::to_string(period)
+ ") has to be relatively prime to "
+ "the characteristic of the field ("
+ field + ")...";
else if(field == "Z11" && Zp<11>(period) == Zp<11>(0))
return "Period (" + std::to_string(period)
+ ") has to be relatively prime to "
+ "the characteristic of the field ("
+ field + ")...";
// first check Przytycki's criterion // first check Przytycki's criterion
Przytycki_periodicity_checker P_pc(evaluate_with_copy<Z>(khp, -1, ev_index)); Przytycki_periodicity_checker P_pc(evaluate_with_copy<Z>(khp, -1, ev_index), knot_name);
if(!P_pc.check(period)) { if(!P_pc.check(period)) {
out << knot_name << ": period = " << period << ": No (Przytycki's criterion)."; out << knot_name << ": period = " << period << ": No (Przytycki's criterion).";
} }
@ -309,7 +390,42 @@ std::string Kh_periodicity_checker::operator () (int period) const {
Test_Result res = check(q_r, period); Test_Result res = check(q_r, period);
out << knot_name << ": period = " << period << ": " out << knot_name << ": period = " << period << ": "
<< (res == Test_Result::MAYBE ? "Maybe" : << (res == Test_Result::MAYBE ? "Maybe" :
(res == Test_Result::NO ? "No" : "No (Nontrivial decomposition).")); (res == Test_Result::NO ? "No" : "No (Nontrivial decomposition) ("
+ field + ")"));
} }
return out.str(); return out.str();
} }
void check_periodicity(knot_diagram& kd, const std::string knot_name, int period, std::string field) {
if(periodicity_test == "all") {
Kh_periodicity_checker Kh_pc(kd, knot_name, field);
for(auto& p : primes_list) {
std::cout << "Kh criterion: "
<< Kh_pc(p) << std::endl;
}
}
else {
if(period == 2 || period == 3) {
std::cout << "Sorry, the criterion doesn't work for period "
<< period << "...\n";
exit(EXIT_FAILURE);
}
auto result = std::find(primes_list.begin(), primes_list.end(), period);
if(result == primes_list.end()) {
std::cout << "For now you can only check periodicity for primes up to 19..." << "\n";
exit(EXIT_FAILURE);
}
if(periodicity_test == "Przytycki") {
Przytycki_periodicity_checker P_pc(compute_jones(kd), knot_name);
std::cout << P_pc(period) << std::endl;
}
else if(periodicity_test == "Kh") {
Kh_periodicity_checker Kh_pc(kd, std::string(knot_name), field);
std::cout << Kh_pc(period) << std::endl;
}
else {
std::cout << "Sorry, I don't recognize this option..." << "\n";
exit(EXIT_FAILURE);
}
}
}

View File

@ -9,16 +9,11 @@
#include <tuple> #include <tuple>
extern bool verbose; extern bool verbose;
extern const char* knot;
extern std::string periodicity_test; constexpr std::array<int, 6> primes_list = {5, 7, 11, 13, 17, 19};
const std::vector<int> primes_list = {5, 7, 11, 13, 17, 19}; constexpr unsigned eval_index = 1;
constexpr unsigned invert_index = 2;
enum class Test_Result { MAYBE, NO, NO_NONTRIVIAL_DECOMP };
const unsigned eval_index = 1;
const unsigned invert_index = 2;
template<class T> template<class T>
class periodic_congruence_checker { class periodic_congruence_checker {
@ -35,9 +30,9 @@ protected:
} }
public: public:
periodic_congruence_checker(int pprime = 5, periodic_congruence_checker(int p = 5,
unsigned ind = invert_index) : unsigned ind = invert_index) :
prime(pprime), prime(p),
index(ind) index(ind)
{} {}
@ -47,7 +42,6 @@ public:
bool operator() (const polynomial& pol) const { bool operator() (const polynomial& pol) const {
return reduce(prepare_polynomial(pol)) == 0; return reduce(prepare_polynomial(pol)) == 0;
// return reduce(prepare_polynomial(pol)) == 0;
} }
}; };
@ -62,8 +56,6 @@ periodic_congruence_checker<T>::reduce(const multivariate_laurentpoly<T>& pol) c
monomial mon = monomial(VARIABLE, index, c); monomial mon = monomial(VARIABLE, index, c);
res += polynomial(i.val(), mon); res += polynomial(i.val(), mon);
} }
// if(verbose)
// std::cout << "res = " << res << "\n";
return res; return res;
} }
@ -72,9 +64,11 @@ class Przytycki_periodicity_checker {
using monomial = multivariate_laurent_monomial; using monomial = multivariate_laurent_monomial;
polynomial jones_pol; polynomial jones_pol;
std::string knot_name;
public: public:
Przytycki_periodicity_checker(polynomial j) : jones_pol(j) {} Przytycki_periodicity_checker(polynomial j, std::string knot_n) :
jones_pol(j), knot_name(knot_n) {}
~Przytycki_periodicity_checker() {} ~Przytycki_periodicity_checker() {}
@ -117,11 +111,15 @@ class Kh_periodicity_checker {
unsigned ev_index; unsigned ev_index;
unsigned index; unsigned index;
enum class Test_Result { MAYBE, NO, NO_NONTRIVIAL_DECOMP };
polynomial khp, leep; polynomial khp, leep;
std::vector<polynomial> quot, mul, quotients, remainders; std::vector<polynomial> quot, mul, quotients, remainders;
std::string knot_name; std::string knot_name;
std::string field;
template<typename R>
std::vector<polynomial> compute_knot_polynomials(knot_diagram& kd); std::vector<polynomial> compute_knot_polynomials(knot_diagram& kd);
void compute_quot(const std::vector<polynomial>& lee_ss_polynomials); void compute_quot(const std::vector<polynomial>& lee_ss_polynomials);
polynomial_tuple polynomial_tuple
@ -131,14 +129,7 @@ class Kh_periodicity_checker {
Test_Result check(const polynomial_tuple& polynomials, int period) const; Test_Result check(const polynomial_tuple& polynomials, int period) const;
public: public:
Kh_periodicity_checker(knot_diagram& kd, std::string knot_n) : Kh_periodicity_checker(knot_diagram& kd, std::string knot_n, std::string f);
knot_name(knot_n) {
ev_index = 1;
index = 2;
quot = std::vector<polynomial>();
mul = std::vector<polynomial>();
compute_quot(compute_knot_polynomials(kd));
}
~Kh_periodicity_checker() {} ~Kh_periodicity_checker() {}
@ -153,4 +144,7 @@ class Kh_periodicity_checker {
} }
}; };
void check_periodicity(knot_diagram& kd, const std::string knot_name,
int period = 5, const std::string field = "Z2");
#endif // _KNOTKIT_PERIODICITY_H #endif // _KNOTKIT_PERIODICITY_H