diff --git a/algebra/module.h b/algebra/module.h index 0a5904b..b86b7e6 100644 --- a/algebra/module.h +++ b/algebra/module.h @@ -942,6 +942,7 @@ class mod_map // ?? add and other map operations should not be explicit mod_map operator + (const mod_map &m) const; + mod_map operator * (const R &c) const; bool homogeneous () const; void check_grading (grading delta) const; @@ -1787,6 +1788,14 @@ mod_map::check_grading (grading delta) const } } +template mod_map +mod_map::operator * (const R &c) const +{ + basedvector, 1> v (impl->from->dim ()); + for (unsigned i = 1; i <= impl->from->dim (); i ++) + v[i] = c*column (i); + return mod_map (IMPL, new explicit_map_impl (impl->from, impl->to, v)); +} template mod_map mod_map::operator + (const mod_map &m) const diff --git a/cube.h b/cube.h index 2583cab..248995e 100644 --- a/cube.h +++ b/cube.h @@ -47,6 +47,7 @@ public: bool reverse_orientation, unsigned to_reverse) const; + mod_map compute_dinv (unsigned c); mod_map H_i (unsigned c); mod_map compute_nu () const; diff --git a/cube_impl.h b/cube_impl.h index 02521eb..fe181ee 100644 --- a/cube_impl.h +++ b/cube_impl.h @@ -356,6 +356,96 @@ cube::H_i (unsigned c) return H_c; } +template mod_map +cube::compute_dinv (unsigned c) +{ + map_builder p (khC); + for (unsigned i = 0; i < n_resolutions; i ++) + { + if (!unsigned_bittest (i, c)) + continue; + + smoothing from_s (kd, smallbitset (n_crossings, i)); + + unsigned i2 = unsigned_bitclear (i, c); + smoothing to_s (kd, smallbitset (n_crossings, i2)); + + basedvector from_circle_edge_rep (from_s.n_circles); + for (unsigned j = 1; j <= kd.num_edges (); j ++) + from_circle_edge_rep[from_s.edge_circle[j]] = j; + + unsigned a = from_s.crossing_from_circle (kd, c), + b = from_s.crossing_to_circle (kd, c); + unsigned x = to_s.crossing_from_circle (kd, c), + y = to_s.crossing_to_circle (kd, c); + for (unsigned j = 0; j < from_s.num_monomials (); j ++) + { + unsigned j2 = 0; + for (unsigned_const_iter k = j; k; k ++) + { + unsigned s = k.val (); + j2 = unsigned_bitset (j2, to_s.edge_circle[from_circle_edge_rep[s]]); + } + + if (a == b) + { + // split + assert (x != y); + + if (unsigned_bittest (j, a)) + { + // 1 -> x + y + j2 = unsigned_bitset (j2, x); + j2 = unsigned_bitclear (j2, y); + + p[generator (i, j)].muladd (1, generator (i2, j2)); + + j2 = unsigned_bitclear (j2, x); + j2 = unsigned_bitset (j2, y); + + p[generator (i, j)].muladd (1, generator (i2, j2)); + } + else + { + // a -> xy + j2 = unsigned_bitclear (j2, x); + j2 = unsigned_bitclear (j2, y); + + p[generator (i, j)].muladd (1, generator (i2, j2)); + } + } + else + { + // join + assert (x == y); + + if (unsigned_bittest (j, a) + && unsigned_bittest (j, b)) + { + // 1 -> 1 + j2 = unsigned_bitset (j2, x); + + p[generator (i, j)].muladd (1, generator (i2, j2)); + } + else if ((unsigned_bittest (j, a) + && !unsigned_bittest (j, b)) + || (!unsigned_bittest (j, a) + && unsigned_bittest (j, b))) + { + // a, b -> x + j2 = unsigned_bitclear (j2, x); + + p[generator (i, j)].muladd (1, generator (i2, j2)); + } + } + } + } + + mod_map dinv (p); + dinv.check_grading (grading (-1, -2)); + return dinv; +} + template void cube::check_reverse_crossings () { diff --git a/main.cpp b/main.cpp index e35381e..827e919 100644 --- a/main.cpp +++ b/main.cpp @@ -777,9 +777,143 @@ compute_twistedU () } } + +void +test_forgetful_ss () +{ + typedef fraction_field > R; + + for (unsigned i = 1; i <= 11; i ++) + for (unsigned j = 1; j <= mt_links (i, 0); j ++) + { + knot_diagram kd (mt_link (i, 0, j)); + unsigned n = kd.num_components (); + if (n < 2) + continue; + + show (kd); newline (); + + unionfind<1> u (kd.num_edges ()); + for (unsigned i = 1; i <= kd.n_crossings; i ++) + { + u.join (kd.ept_edge (kd.crossings[i][1]), + kd.ept_edge (kd.crossings[i][3])); + u.join (kd.ept_edge (kd.crossings[i][2]), + kd.ept_edge (kd.crossings[i][4])); + } + + printf ("%d components:\n", n); + + map root_comp; + unsigned t = 0; + for (unsigned i = 1; i <= kd.num_edges (); i ++) + { + if (u.find (i) == i) + { + ++ t; + root_comp.push (i, t); + } + } + assert (t == n); + + unsigned disj_rank = 1; + for (unsigned k = 1; k <= n; k ++) + { + knot_diagram comp (SUBLINK, smallbitset (n, unsigned_2pow (k - 1)), kd); + + cube c (comp); + mod_map d = c.compute_d (1, 0, 0, 0, 0); + + chain_complex_simplifier s (c.khC, d, 1); + assert (s.new_d == 0); + + printf (" % 2d: rank %d\n", k, s.new_C->dim ()); + + disj_rank *= s.new_C->dim (); + } + + { + knot_diagram comp (SUBLINK, smallbitset (n, unsigned_bitclear (unsigned_fill (n), 1)), kd); + + cube c (comp); + mod_map d = c.compute_d (1, 0, 0, 0, 0); + + chain_complex_simplifier s (c.khC, d, 1); + assert (s.new_d == 0); + + printf (" 11...10: rank %d\n", s.new_C->dim ()); + } + + cube c (kd); + +#if 0 + for (unsigned i = 0; i < c.n_resolutions; i ++) + { + smallbitset state (kd.n_crossings, i); + smoothing s (kd, state); + s.show_self (kd, state); + newline (); + } +#endif + + mod_map untwisted_d = c.compute_d (1, 0, 0, 0, 0); + assert (untwisted_d.compose (untwisted_d) == 0); + + chain_complex_simplifier s1 (c.khC, untwisted_d, 1); + assert (s1.new_d == 0); + + printf ("untwisted rank = %d\n", s1.new_C->dim ()); + + mod_map d = untwisted_d; + for (unsigned x = 1; x <= kd.n_crossings; x ++) + { + unsigned r1 = u.find (kd.ept_edge (kd.crossings[x][1])), + r2 = u.find (kd.ept_edge (kd.crossings[x][2])); + + d = d + c.compute_dinv (x)*(R (polynomial (1, root_comp(r1))) + 1); + d = d + c.compute_dinv (x)*(R (polynomial (1, root_comp(r2))) + 1); + +#if 0 + R hbar (polynomial (1, 1)); + R hbarp1 = hbar + 1; + + // if (u.find (kd.ept_edge (kd.crossings[x][1])) != u.find (kd.ept_edge (kd.crossings[x][2]))) + + if (u.find (kd.ept_edge (kd.crossings[x][1])) != comp1_root) + d = d + c.compute_dinv (x)*hbarp1; + + if (u.find (kd.ept_edge (kd.crossings[x][2])) != comp1_root) + d = d + c.compute_dinv (x)*hbarp1; +#endif + } + +#if 0 + mod_map h = d.compose (d); + display ("h:\n", h); +#endif + + assert (d.compose (d) == 0); + + // display ("d:\n", d); + + chain_complex_simplifier s2 (c.khC, d, -1); + assert (s2.new_d == 0); + + printf ("twisted rank = %d\n", s2.new_C->dim ()); + + if (disj_rank == s2.new_C->dim ()) + printf (" %d == %d: YES!\n", disj_rank, s2.new_C->dim ()); + else + printf (" %d == %d: NO :-(\n", disj_rank, s2.new_C->dim ()); + } +} + int main () { + test_forgetful_ss (); + return 0; + compute_twistedU (); #if 1 diff --git a/simplify_chain_complex.h b/simplify_chain_complex.h index ec330e3..3cdecfa 100644 --- a/simplify_chain_complex.h +++ b/simplify_chain_complex.h @@ -172,9 +172,10 @@ chain_complex_simplifier::chain_complex_simplifier (ptr > C_, for (linear_combination_const_iter j = new_d_columns[i]; j; j ++) { grading jgr = C->generator_grading (j.key ()); - assert (jgr.h >= igr.h); + // assert (jgr.h >= igr.h); if (j.val ().is_unit () - && jgr.h - igr.h == dh) + // && jgr.h - igr.h == dh + ) { cancel (i, j.val (), j.key ()); break;