Merge branch 'periodicity'
This commit is contained in:
commit
c3d01fd161
345
kk.cpp
345
kk.cpp
@ -2,14 +2,10 @@
|
||||
#include <periodicity.h>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <thread>
|
||||
#include <future>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include <cctype>
|
||||
|
||||
const unsigned max_threads = 4;
|
||||
|
||||
const char *program_name;
|
||||
|
||||
void
|
||||
@ -91,11 +87,11 @@ void tex_footer ()
|
||||
const char *knot = 0;
|
||||
const char *invariant = 0;
|
||||
const char *field = "Z2";
|
||||
std::string periodicity_test = "Przytycki";
|
||||
int period = 5;
|
||||
knot_diagram kd;
|
||||
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
|
||||
{
|
||||
@ -334,170 +330,6 @@ int compute_s_inv(knot_diagram& kd) {
|
||||
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
|
||||
compute_invariant ()
|
||||
{
|
||||
@ -579,58 +411,56 @@ compute_invariant ()
|
||||
ss.texshow (outfp, mapper);
|
||||
tex_footer ();
|
||||
}
|
||||
else if (!strcmp (invariant, "leess"))
|
||||
{
|
||||
cube<R> c (kd, reduced);
|
||||
ptr<const module<R> > C = c.khC;
|
||||
else if (!strcmp (invariant, "leess")) {
|
||||
cube<R> c (kd, reduced);
|
||||
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);
|
||||
mod_map<R> d = c.compute_d (1, 0, 0, 0, 0);
|
||||
|
||||
unsigned m = kd.num_components ();
|
||||
hg_grading_mapper mapper (m);
|
||||
for (unsigned i = 1; i <= kd.n_crossings; i ++)
|
||||
d = d + c.H_i (i);
|
||||
assert (d.compose (d) == 0);
|
||||
|
||||
sseq_bounds b (C, mapper);
|
||||
basedvector<sseq_page, 1> pages;
|
||||
unsigned m = kd.num_components ();
|
||||
hg_grading_mapper mapper (m);
|
||||
|
||||
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;
|
||||
k ++;
|
||||
sseq_bounds b (C, mapper);
|
||||
basedvector<sseq_page, 1> pages;
|
||||
|
||||
grading dk_gr (1, 2*k);
|
||||
pages.append (sseq_page (b, k, dk_gr, d.graded_piece (dk_gr), mapper));
|
||||
if (d == 0)
|
||||
break;
|
||||
}
|
||||
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;
|
||||
k ++;
|
||||
|
||||
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 ();
|
||||
grading dk_gr (1, 2*k);
|
||||
pages.append (sseq_page (b, k, dk_gr, d.graded_piece (dk_gr), mapper));
|
||||
if (d == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
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"))
|
||||
{
|
||||
int s = compute_s_inv<R>(kd);
|
||||
fprintf (outfp, "s(%s; %s) = %d\n", knot, field, s);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf (stderr, "error: unknown invariant %s\n", invariant);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
else {
|
||||
fprintf (stderr, "error: unknown invariant %s\n", invariant);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -834,14 +664,6 @@ main (int argc, char **argv)
|
||||
}
|
||||
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 {
|
||||
fprintf (stderr, "error: unknown argument `%s'\n", argv[1]);
|
||||
fprintf (stderr, " use -h for usage\n");
|
||||
@ -883,48 +705,41 @@ main (int argc, char **argv)
|
||||
kd = parse_knot (knot);
|
||||
kd.marked_edge = 1;
|
||||
|
||||
if (!strcmp (invariant, "gauss"))
|
||||
{
|
||||
if (!strcmp (invariant, "gauss")) {
|
||||
basedvector<basedvector<int, 1>, 1> gc = kd.as_gauss_code ();
|
||||
for (unsigned i = 1; i <= gc.size (); i ++)
|
||||
{
|
||||
if (i > 1)
|
||||
printf (":");
|
||||
for (unsigned j = 1; j <= gc[i].size (); j ++)
|
||||
{
|
||||
if (j > 1)
|
||||
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 ();
|
||||
for (unsigned i = 1; i <= gc.size (); i ++) {
|
||||
if (i > 1)
|
||||
printf (":");
|
||||
for (unsigned j = 1; j <= gc[i].size (); j ++) {
|
||||
if (j > 1)
|
||||
printf (",");
|
||||
printf ("%d", gc[i][j]);
|
||||
}
|
||||
}
|
||||
else if (!strcmp (invariant, "gss"))
|
||||
{
|
||||
if (strcmp (field, "Z2"))
|
||||
{
|
||||
fprintf (stderr, "warning: gss only defined over Z2, ignoring -f %s\n", field);
|
||||
field = "Z2";
|
||||
}
|
||||
newline ();
|
||||
}
|
||||
|
||||
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")) {
|
||||
std::cout << "Jones polynomial of " << knot << " = " << compute_jones(kd, reduced) << "\n";
|
||||
}
|
||||
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")) {
|
||||
multivariate_laurentpoly<Z> khp;
|
||||
@ -947,20 +762,18 @@ main (int argc, char **argv)
|
||||
<< ") of " << knot << " = " << std::endl
|
||||
<< khp << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!strcmp (field, "Z2"))
|
||||
compute_invariant<Z2> ();
|
||||
else if (!strcmp (field, "Z3"))
|
||||
compute_invariant<Zp<3> > ();
|
||||
else if (!strcmp (field, "Q"))
|
||||
compute_invariant<Q> ();
|
||||
else
|
||||
{
|
||||
fprintf (stderr, "error: unknown field %s\n", field);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
else {
|
||||
if (!strcmp (field, "Z2"))
|
||||
compute_invariant<Z2> ();
|
||||
else if (!strcmp (field, "Z3"))
|
||||
compute_invariant<Zp<3>> ();
|
||||
else if (!strcmp (field, "Q"))
|
||||
compute_invariant<Q> ();
|
||||
else {
|
||||
fprintf (stderr, "error: unknown field %s\n", field);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
if (file)
|
||||
fclose (outfp);
|
||||
|
156
periodicity.cpp
156
periodicity.cpp
@ -2,6 +2,12 @@
|
||||
#include <simplify_chain_complex.h>
|
||||
#include <algorithm>
|
||||
#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>>>;
|
||||
|
||||
@ -39,7 +45,7 @@ bool Przytycki_periodicity_checker::check(int period) const {
|
||||
|
||||
std::string Przytycki_periodicity_checker::operator () (int period) const {
|
||||
std::ostringstream res;
|
||||
res << knot << ": period = " << period << ": "
|
||||
res << knot_name << ": period = " << period << ": "
|
||||
<< (check(period) ? "Maybe" : "No");
|
||||
return res.str();
|
||||
}
|
||||
@ -82,8 +88,9 @@ multivariate_laurentpoly<Z> Kh_bounds_iterator::get_polynomial() const {
|
||||
return p;
|
||||
}
|
||||
|
||||
template<>
|
||||
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 ();
|
||||
if (m != 1) {
|
||||
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 << "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;
|
||||
}
|
||||
|
||||
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) {
|
||||
// quot.push_back(polynomial(Z(0)));
|
||||
for(unsigned i = 1; i < lee_ss_polynomials.size(); ++i) {
|
||||
polynomial diff = lee_ss_polynomials[i-1] - lee_ss_polynomials[i];
|
||||
polynomial q = 0;
|
||||
// std::cerr << "diff = " << diff << "\n";
|
||||
// std::cerr << "mul = " << mul[i-1] << "\n";
|
||||
while(diff != 0) {
|
||||
pair<monomial, Z> m = diff.head();
|
||||
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);
|
||||
}
|
||||
// for(unsigned i = 0; i < quot.size(); ++i) {
|
||||
// std::cerr << "quot[" << i << "] = " << quot[i] << "\n";
|
||||
// }
|
||||
}
|
||||
|
||||
polynomial_tuple
|
||||
@ -222,13 +291,9 @@ Kh_periodicity_checker::compute_bounds(const polynomial_tuple& p_tuple, int peri
|
||||
mon *= monomial(VARIABLE, j.key(), v);
|
||||
}
|
||||
}
|
||||
// std::cerr << polynomial(i.val() * pow(-1,exp), mon) << "\n";
|
||||
Z v_temp = i.val() * pow(-1, exp);
|
||||
polynomial p_temp = (polynomial(1, mon) * mul).evaluate(-1, ev_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(v_temp >= 0)
|
||||
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;
|
||||
}
|
||||
|
||||
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 {
|
||||
periodic_congruence_checker<Z> pcc(period);
|
||||
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::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
|
||||
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)) {
|
||||
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);
|
||||
out << knot_name << ": period = " << period << ": "
|
||||
<< (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();
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,16 +9,11 @@
|
||||
#include <tuple>
|
||||
|
||||
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};
|
||||
|
||||
enum class Test_Result { MAYBE, NO, NO_NONTRIVIAL_DECOMP };
|
||||
|
||||
const unsigned eval_index = 1;
|
||||
const unsigned invert_index = 2;
|
||||
constexpr unsigned eval_index = 1;
|
||||
constexpr unsigned invert_index = 2;
|
||||
|
||||
template<class T>
|
||||
class periodic_congruence_checker {
|
||||
@ -35,9 +30,9 @@ protected:
|
||||
}
|
||||
|
||||
public:
|
||||
periodic_congruence_checker(int pprime = 5,
|
||||
periodic_congruence_checker(int p = 5,
|
||||
unsigned ind = invert_index) :
|
||||
prime(pprime),
|
||||
prime(p),
|
||||
index(ind)
|
||||
{}
|
||||
|
||||
@ -47,7 +42,6 @@ public:
|
||||
|
||||
bool operator() (const polynomial& pol) const {
|
||||
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);
|
||||
res += polynomial(i.val(), mon);
|
||||
}
|
||||
// if(verbose)
|
||||
// std::cout << "res = " << res << "\n";
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -72,9 +64,11 @@ class Przytycki_periodicity_checker {
|
||||
using monomial = multivariate_laurent_monomial;
|
||||
|
||||
polynomial jones_pol;
|
||||
std::string knot_name;
|
||||
|
||||
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() {}
|
||||
|
||||
@ -117,11 +111,15 @@ class Kh_periodicity_checker {
|
||||
unsigned ev_index;
|
||||
unsigned index;
|
||||
|
||||
enum class Test_Result { MAYBE, NO, NO_NONTRIVIAL_DECOMP };
|
||||
|
||||
polynomial khp, leep;
|
||||
std::vector<polynomial> quot, mul, quotients, remainders;
|
||||
|
||||
std::string knot_name;
|
||||
std::string field;
|
||||
|
||||
template<typename R>
|
||||
std::vector<polynomial> compute_knot_polynomials(knot_diagram& kd);
|
||||
void compute_quot(const std::vector<polynomial>& lee_ss_polynomials);
|
||||
polynomial_tuple
|
||||
@ -131,14 +129,7 @@ class Kh_periodicity_checker {
|
||||
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<polynomial>();
|
||||
mul = std::vector<polynomial>();
|
||||
compute_quot(compute_knot_polynomials(kd));
|
||||
}
|
||||
Kh_periodicity_checker(knot_diagram& kd, std::string knot_n, std::string f);
|
||||
|
||||
~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
|
||||
|
Loading…
Reference in New Issue
Block a user