Merge branch 'periodicity'
This commit is contained in:
commit
c3d01fd161
345
kk.cpp
345
kk.cpp
@ -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);
|
||||||
|
156
periodicity.cpp
156
periodicity.cpp
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user