![Wojciech Politarczyk](/assets/img/avatar_default.png)
Verification of Przytycki's congruence works fine, however there are some small modifications that could be made. The, naive, approach to the verification of periodicity congruence for the Khovanov polynomial didn't work. There are just too many cases to check. Generation of all of them can exhaust the memory.
159 lines
4.5 KiB
C++
159 lines
4.5 KiB
C++
#include <periodicity.h>
|
|
#include <simplify_chain_complex.h>
|
|
|
|
void 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<Z2> c (kd, 0);
|
|
ptr<const module<Z2> > C = c.khC;
|
|
|
|
mod_map<Z2> 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::cout << "Computing Khovanov homology" << std::endl;
|
|
{
|
|
chain_complex_simplifier<Z2> s (C, d, maybe<int>(1), maybe<int>(0));
|
|
C = s.new_C;
|
|
d = s.new_d;
|
|
khp = C->free_poincare_polynomial();
|
|
if(verbose)
|
|
std::cout << "KhP = " << khp << "\n";
|
|
}
|
|
|
|
// computing Lee homolgy
|
|
if(verbose)
|
|
std::cout << "Computing Lee homology" << std::endl;
|
|
{
|
|
chain_complex_simplifier<Z2> s(C, d, maybe<int>(1), maybe<int>(2));
|
|
C = s.new_C;
|
|
d = s.new_d;
|
|
leep = C->free_poincare_polynomial();
|
|
if(d != 0) {
|
|
std::cout << "For now, you can only use this criterion on Kh-thin knots." << std::endl;
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
if(verbose) {
|
|
std::cout << "LeeP = " << leep << "\n";
|
|
}
|
|
}
|
|
}
|
|
|
|
void Kh_periodicity_checker::compute_quot() {
|
|
polynomial diff = khp - leep;
|
|
while(diff != 0) {
|
|
pair<monomial, Z> m = diff.head();
|
|
if(m.first.m[1] == 1) {
|
|
pair<monomial, Z> m1 = diff.tail();
|
|
while(m1.first.m.card() == 1 && m1.first.m[2]) {
|
|
quot += polynomial(m1.second, m1.first);
|
|
polynomial p = polynomial(m1.second, m1.first) * mul;
|
|
diff -= p;
|
|
m1 = diff.tail();
|
|
}
|
|
}
|
|
quot += polynomial(m.second, m.first);
|
|
polynomial p = polynomial(m.second, m.first) * mul;
|
|
diff -= p;
|
|
}
|
|
}
|
|
|
|
std::pair<multivariate_laurentpoly<Z>, multivariate_laurentpoly<Z>>
|
|
Kh_periodicity_checker::compute_quotient_and_remainder(const polynomial& quot,
|
|
int period) const {
|
|
polynomial quotient, remainder;
|
|
for(map<monomial, Z>::const_iter i = quot.coeffs; i; i++) {
|
|
std::tuple<Z,Z> div = i.val().divide_with_remainder(period - 1);
|
|
quotient += polynomial(std::get<0>(div), i.key());
|
|
remainder += polynomial(std::get<1>(div), i.key());
|
|
}
|
|
if(verbose) {
|
|
std::cout << "Decomposition of Khp = " << std::endl
|
|
<< leep << " + ("
|
|
<< mul << ") * ("
|
|
<< remainder;
|
|
if(quotient != 0) {
|
|
std::cout << " + " << (period - 1)
|
|
<< " * (" << quotient
|
|
<< ")";
|
|
}
|
|
std::cout << ")" << std::endl;
|
|
|
|
}
|
|
return std::make_pair(quotient, remainder);
|
|
}
|
|
|
|
std::list<multivariate_laurentpoly<Z>>
|
|
Kh_periodicity_checker::generate_candidates(const polynomial &q) const {
|
|
std::list<polynomial> result;
|
|
Z size = 0;
|
|
map<monomial, Z>::const_iter i = q.coeffs;
|
|
|
|
for(int j = 0; Z(j) <= i.val(); j++) {
|
|
result.push_back(polynomial(Z(j), i.key()));
|
|
size += 1;
|
|
}
|
|
|
|
i++;
|
|
|
|
for( ; i; i++) {
|
|
for(int j = 1; Z(j) <= i.val(); j++) {
|
|
std::list<polynomial> temp_list;
|
|
for_each(result.begin(), result.end(),
|
|
[&result, &temp_list, j, i](const polynomial& p){
|
|
temp_list.push_back(p + polynomial(Z(j), i.key()));
|
|
});
|
|
result.splice(result.end(), temp_list);
|
|
size += 1;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
bool Kh_periodicity_checker::check(const polynomial& q,
|
|
const polynomial& r,
|
|
int period) const {
|
|
periodic_congruence_checker<Z> pcc(period);
|
|
polynomial t = leep + mul * r;
|
|
if(q == 0) {
|
|
return pcc(t.evaluate(-1,1));
|
|
}
|
|
else {
|
|
// generate all polynomials
|
|
if(verbose) {
|
|
std::cout << "Generating all candidates..." << std::endl;
|
|
}
|
|
std::list<polynomial> candidates = generate_candidates(q);
|
|
// Z i = 0;
|
|
// for(auto& l : candidates) {
|
|
// i += 1;
|
|
// std::cout << i << ": " << l << std::endl;
|
|
// }
|
|
// and check each one of them
|
|
if(verbose)
|
|
std::cout << "Checking congruences..." << std::endl;
|
|
polynomial m = mul;
|
|
return any_of(candidates.begin(), candidates.end(),
|
|
[&pcc, &t, &m, &period](const polynomial& p){
|
|
return pcc((t + Z(period - 1) * m * p).evaluate(-1,1));
|
|
});
|
|
}
|
|
}
|
|
|
|
std::string Kh_periodicity_checker::operator () (int period) const {
|
|
std::ostringstream out;
|
|
std::pair<polynomial, polynomial> q_r = compute_quotient_and_remainder(quot, period);
|
|
bool res = check(std::get<0>(q_r), std::get<1>(q_r), period);
|
|
out << knot << ": period = " << period << ": "
|
|
<< (res ? "Maybe" : "No");
|
|
return out.str();
|
|
}
|