Strengthened b'_lk to use Khovanov homology. Set up to compute sp
bounds in paralllel.
This commit is contained in:
parent
e19a274c8e
commit
f3d7e22f51
@ -454,6 +454,60 @@ knot_diagram::knot_diagram (sublink,
|
||||
calculate_nminus_nplus ();
|
||||
}
|
||||
|
||||
knot_diagram::knot_diagram (disjoint_union,
|
||||
const knot_diagram &kd1,
|
||||
const knot_diagram &kd2)
|
||||
: name(kd1.name + "+" + kd2.name),
|
||||
n_crossings(kd1.n_crossings + kd2.n_crossings),
|
||||
marked_edge(0),
|
||||
crossings(n_crossings),
|
||||
nminus(kd1.nminus + kd2.nminus),
|
||||
nplus(kd1.nplus + kd2.nplus)
|
||||
{
|
||||
assert (kd1.marked_edge == 0);
|
||||
assert (kd2.marked_edge == 0);
|
||||
|
||||
for (unsigned i = 1; i <= n_crossings; i ++)
|
||||
crossings[i] = basedvector<unsigned, 1> (4);
|
||||
|
||||
for (unsigned i = 1; i <= kd1.n_crossings; i ++)
|
||||
for (unsigned j = 1; j <= 4; j ++)
|
||||
crossings[i][j] = kd1.crossings[i][j];
|
||||
|
||||
for (unsigned e = 1; e <= kd1.num_edges (); e ++)
|
||||
{
|
||||
if (kd1.edge_smoothing_oriented % e)
|
||||
edge_smoothing_oriented.push (e);
|
||||
}
|
||||
|
||||
for (unsigned i = 1; i <= kd2.n_crossings; i ++)
|
||||
for (unsigned j = 1; j <= 4; j ++)
|
||||
crossings[kd1.n_crossings + i][j] = kd1.num_epts () + kd2.crossings[i][j];
|
||||
|
||||
for (unsigned e = 1; e <= kd2.num_edges (); e ++)
|
||||
{
|
||||
if (kd2.edge_smoothing_oriented % e)
|
||||
edge_smoothing_oriented.push (kd1.num_edges () + e);
|
||||
}
|
||||
|
||||
// ?? break this out into aux function
|
||||
ept_crossing = basedvector<unsigned, 1> (num_epts ());
|
||||
ept_index = basedvector<unsigned, 1> (num_epts ());
|
||||
for (unsigned i = 1; i <= n_crossings; i ++)
|
||||
{
|
||||
for (unsigned j = 1; j <= 4; j ++)
|
||||
{
|
||||
unsigned p = crossings[i][j];
|
||||
ept_crossing[p] = i;
|
||||
ept_index[p] = j;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
check_crossings ();
|
||||
#endif
|
||||
}
|
||||
|
||||
knot_diagram::knot_diagram (mirror, const knot_diagram &kd)
|
||||
: name("mirror(" + kd.name + ")"),
|
||||
n_crossings(kd.n_crossings),
|
||||
|
@ -11,6 +11,7 @@ add_base1_mod4 (unsigned x, unsigned y)
|
||||
enum mirror { MIRROR };
|
||||
enum connect_sum { CONNECT_SUM };
|
||||
enum sublink { SUBLINK };
|
||||
enum disjoint_union { DISJOINT_UNION };
|
||||
|
||||
class knot_diagram
|
||||
{
|
||||
@ -122,6 +123,9 @@ class knot_diagram
|
||||
knot_diagram (sublink,
|
||||
smallbitset c,
|
||||
const knot_diagram &kd);
|
||||
knot_diagram (disjoint_union,
|
||||
const knot_diagram &kd1,
|
||||
const knot_diagram &kd2);
|
||||
|
||||
knot_diagram (const std::string &name_, unsigned n_crossings_, unsigned crossings_ar[][4]);
|
||||
knot_diagram (const std::string &name_, const basedvector<basedvector<unsigned, 1>, 1> &crossings_);
|
||||
|
126
main.cpp
126
main.cpp
@ -2262,6 +2262,106 @@ permutations (unsigned n)
|
||||
return permutations (v);
|
||||
}
|
||||
|
||||
template<class R> multivariate_laurentpoly<Z>
|
||||
Kh_poincare_polynomial (knot_diagram &kd)
|
||||
{
|
||||
cube<R> c (kd);
|
||||
mod_map<R> d = c.compute_d (1, 0, 0, 0, 0);
|
||||
chain_complex_simplifier<R> s (c.khC, d, 0);
|
||||
assert (s.new_d == 0);
|
||||
return s.new_C->free_poincare_polynomial ();
|
||||
}
|
||||
|
||||
unsigned
|
||||
compute_b_lk_weak (knot_diagram &kd)
|
||||
{
|
||||
unsigned m = kd.num_components ();
|
||||
assert (m > 1);
|
||||
|
||||
if (m == 2)
|
||||
{
|
||||
unsigned total_lk = kd.total_linking_number ();
|
||||
return total_lk == 0 ? 2 : total_lk;
|
||||
}
|
||||
|
||||
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]));
|
||||
}
|
||||
assert (m == u.num_sets ());
|
||||
|
||||
map<unsigned, unsigned> 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 == m);
|
||||
|
||||
unsigned b_lk_weak = 0;
|
||||
|
||||
for (unsigned i = 1; i <= m; i ++)
|
||||
for (unsigned j = i + 1; j <= m; j ++)
|
||||
{
|
||||
assert (i < j);
|
||||
|
||||
int lk = 0;
|
||||
for (unsigned x = 1; x <= kd.n_crossings; x ++)
|
||||
{
|
||||
unsigned r1 = root_comp(u.find (kd.ept_edge (kd.crossings[x][1]))),
|
||||
r2 = root_comp(u.find (kd.ept_edge (kd.crossings[x][2])));
|
||||
if (((r1 == i) && (r2 == j))
|
||||
|| ((r2 == i) && (r1 == j)))
|
||||
{
|
||||
if (kd.is_to_ept (kd.crossings[x][1]) == kd.is_to_ept (kd.crossings[x][4]))
|
||||
lk ++;
|
||||
else
|
||||
lk --;
|
||||
}
|
||||
}
|
||||
assert (is_even (lk));
|
||||
lk /= 2;
|
||||
|
||||
if (lk == 0)
|
||||
{
|
||||
smallbitset ci (m);
|
||||
ci.push (i);
|
||||
|
||||
smallbitset cj (m);
|
||||
cj.push (j);
|
||||
|
||||
smallbitset c (m);
|
||||
c.push (i);
|
||||
c.push (j);
|
||||
knot_diagram Lij (SUBLINK, c, kd);
|
||||
|
||||
multivariate_laurentpoly<Z> P_Lij = Kh_poincare_polynomial<Z2> (Lij);
|
||||
|
||||
knot_diagram Li_join_Lj (DISJOINT_UNION,
|
||||
knot_diagram (SUBLINK, ci, kd),
|
||||
knot_diagram (SUBLINK, cj, kd));
|
||||
|
||||
multivariate_laurentpoly<Z> P_Li_join_Lj = Kh_poincare_polynomial<Z2> (Li_join_Lj);
|
||||
|
||||
if (P_Lij != P_Li_join_Lj)
|
||||
lk = 2; // non-split
|
||||
}
|
||||
|
||||
b_lk_weak += abs (lk);
|
||||
}
|
||||
|
||||
return b_lk_weak == 0 ? 2 : b_lk_weak;
|
||||
}
|
||||
|
||||
void
|
||||
compute_splitting_bounds ()
|
||||
{
|
||||
@ -2319,25 +2419,18 @@ compute_splitting_bounds ()
|
||||
printf (" b = %d\n", b);
|
||||
|
||||
unsigned total_lk = kd.total_linking_number ();
|
||||
unsigned b_lk_weak = total_lk == 0 ? 2 : total_lk;
|
||||
|
||||
unsigned b_lk_weak = compute_b_lk_weak (kd);
|
||||
unsigned b_lk_weaker = total_lk == 0 ? 2 : total_lk;
|
||||
|
||||
printf (" b_lk_weaker = %d\n", b_lk_weaker);
|
||||
printf (" b_lk_weak = %d\n", b_lk_weak);
|
||||
|
||||
basedvector<basedvector<unsigned, 1>, 1> ps = permutations (m);
|
||||
#if 0
|
||||
printf ("ps, |ps| = %d, m = %d:\n", ps.size (), m);
|
||||
for (unsigned i = 1; i <= ps.size (); i ++)
|
||||
{
|
||||
basedvector<unsigned, 1> p = ps[i];
|
||||
assert (p.size () == m);
|
||||
|
||||
printf (" % 3d: ", i);
|
||||
for (unsigned j = 1; j <= m; j ++)
|
||||
printf (" %d", p[j]);
|
||||
newline ();
|
||||
}
|
||||
#endif
|
||||
assert (b_lk_weaker <= b_lk_weak);
|
||||
if (b_lk_weaker < b_lk_weak)
|
||||
printf (" > STRICTLY WEAKER\n");
|
||||
|
||||
basedvector<basedvector<unsigned, 1>, 1> ps = permutations (m);
|
||||
unsigned r = kd.n_crossings;
|
||||
for (unsigned i = 1; i <= ps.size (); i ++)
|
||||
{
|
||||
@ -2362,6 +2455,7 @@ compute_splitting_bounds ()
|
||||
}
|
||||
printf (" r = %d\n", r);
|
||||
|
||||
assert (b_lk_weak <= r);
|
||||
assert (b <= r);
|
||||
|
||||
// non-trivial link, sp at least 1.
|
||||
@ -2383,12 +2477,10 @@ compute_splitting_bounds ()
|
||||
printf (" > sp = %d (b + b_lk_weak)\n", b);
|
||||
else
|
||||
printf (" > %d <= sp <= %d (b + b_lk_weak)\n", b, r);
|
||||
|
||||
}
|
||||
else if (b_lk_weak == r)
|
||||
{
|
||||
assert (b < b_lk_weak);
|
||||
|
||||
printf (" > sp = %d (b_lk_weak)\n", b_lk_weak);
|
||||
}
|
||||
}
|
||||
|
227
mpimain.cpp
227
mpimain.cpp
@ -14,10 +14,10 @@ master ()
|
||||
{
|
||||
basedvector<knot_desc, 1> work;
|
||||
|
||||
for (unsigned i = 1; i <= 14; i ++)
|
||||
for (unsigned j = 1; j <= mt_links (i, 0); j ++)
|
||||
for (unsigned i = 1; i <= 10; i ++)
|
||||
for (unsigned j = 1; j <= mt_links (i); j ++)
|
||||
{
|
||||
knot_diagram kd (mt_links (i, 0, j));
|
||||
knot_diagram kd (mt_links (i, j));
|
||||
unsigned n = kd.num_components ();
|
||||
if (n < 2)
|
||||
continue;
|
||||
@ -116,6 +116,7 @@ file_exists (const char *file)
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
void
|
||||
compute_forgetful (int rank, knot_desc desc, const char *buf)
|
||||
{
|
||||
@ -291,6 +292,215 @@ compute_forgetful (int rank, knot_desc desc, const char *buf)
|
||||
write (w, desc);
|
||||
write (w, pages);
|
||||
}
|
||||
#endif
|
||||
|
||||
unsigned
|
||||
compute_b_lk_weak (knot_diagram &kd)
|
||||
{
|
||||
unsigned m = kd.num_components ();
|
||||
assert (m > 1);
|
||||
|
||||
if (m == 2)
|
||||
{
|
||||
unsigned total_lk = kd.total_linking_number ();
|
||||
return total_lk == 0 ? 2 : total_lk;
|
||||
}
|
||||
|
||||
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]));
|
||||
}
|
||||
assert (m == u.num_sets ());
|
||||
|
||||
map<unsigned, unsigned> 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 == m);
|
||||
|
||||
unsigned b_lk_weak = 0;
|
||||
|
||||
for (unsigned i = 1; i <= m; i ++)
|
||||
for (unsigned j = i + 1; j <= m; j ++)
|
||||
{
|
||||
assert (i < j);
|
||||
|
||||
int lk = 0;
|
||||
for (unsigned x = 1; x <= kd.n_crossings; x ++)
|
||||
{
|
||||
unsigned r1 = root_comp(u.find (kd.ept_edge (kd.crossings[x][1]))),
|
||||
r2 = root_comp(u.find (kd.ept_edge (kd.crossings[x][2])));
|
||||
if (((r1 == i) && (r2 == j))
|
||||
|| ((r2 == i) && (r1 == j)))
|
||||
{
|
||||
if (kd.is_to_ept (kd.crossings[x][1]) == kd.is_to_ept (kd.crossings[x][4]))
|
||||
lk ++;
|
||||
else
|
||||
lk --;
|
||||
}
|
||||
}
|
||||
assert (is_even (lk));
|
||||
lk /= 2;
|
||||
|
||||
if (lk == 0)
|
||||
{
|
||||
smallbitset ci (m);
|
||||
ci.push (i);
|
||||
|
||||
smallbitset cj (m);
|
||||
cj.push (j);
|
||||
|
||||
smallbitset c (m);
|
||||
c.push (i);
|
||||
c.push (j);
|
||||
knot_diagram Lij (SUBLINK, c, kd);
|
||||
|
||||
multivariate_laurentpoly<Z> P_Lij = Kh_poincare_polynomial<Z2> (Lij);
|
||||
|
||||
knot_diagram Li_join_Lj (DISJOINT_UNION,
|
||||
knot_diagram (SUBLINK, ci, kd),
|
||||
knot_diagram (SUBLINK, cj, kd));
|
||||
|
||||
multivariate_laurentpoly<Z> P_Li_join_Lj = Kh_poincare_polynomial<Z2> (Li_join_Lj);
|
||||
|
||||
if (P_Lij != P_Li_join_Lj)
|
||||
lk = 2; // non-split
|
||||
}
|
||||
|
||||
b_lk_weak += abs (lk);
|
||||
}
|
||||
|
||||
return b_lk_weak == 0 ? 2 : b_lk_weak;
|
||||
}
|
||||
|
||||
void
|
||||
compute_splitting_bounds (knot_diagram &kd)
|
||||
{
|
||||
int rank = self_rank ();
|
||||
|
||||
typedef fraction_field<polynomial<Z2> > Z2x;
|
||||
|
||||
unsigned m = kd.num_components ();
|
||||
assert (m > 1);
|
||||
|
||||
printf ("[% 2d] ", rank); show (kd); newline ();
|
||||
printf ("[% 2d] m = %d\n", rank, m);
|
||||
|
||||
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]));
|
||||
}
|
||||
assert (u.num_sets () == m);
|
||||
|
||||
map<unsigned, unsigned> 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 == m);
|
||||
|
||||
basedvector<Q, 1> comp_weightQ (m);
|
||||
for (unsigned i = 1; i <= m; i ++)
|
||||
comp_weightQ[i] = Q (i);
|
||||
unsigned bQ = splitting_bound<Q> (kd, comp_weightQ);
|
||||
|
||||
basedvector<Z2x, 1> comp_weightZ2x (m);
|
||||
for (unsigned i = 1; i <= m; i ++)
|
||||
comp_weightZ2x[i] = Z2x (polynomial<Z2> (Z2 (1), i));
|
||||
unsigned bZ2x = splitting_bound<Z2x> (kd, comp_weightZ2x);
|
||||
|
||||
// lower bound
|
||||
unsigned b = std::max (bQ, bZ2x);
|
||||
|
||||
printf ("[% 2d] bQ = %d\n", rank, bQ);
|
||||
printf ("[% 2d] bZ2x = %d\n", rank, bZ2x);
|
||||
printf ("[% 2d] b = %d\n", rank, b);
|
||||
|
||||
|
||||
unsigned total_lk = kd.total_linking_number ();
|
||||
unsigned b_lk_weaker = total_lk == 0 ? 2 : total_lk;
|
||||
|
||||
unsigned b_lk_weak = compute_b_lk_weak (kd);
|
||||
assert (b_lk_weaker <= b_lk_weak);
|
||||
|
||||
printf ("[% 2d] b_lk_weaker = %d\n", rank, b_lk_weaker);
|
||||
printf ("[% 2d] b_lk_weak = %d\n", rank, b_lk_weak);
|
||||
|
||||
if (b_lk_weaker < b_lk_weak)
|
||||
printf ("[% 2d] > STRICTLY WEAKER\n", rank);
|
||||
|
||||
basedvector<basedvector<unsigned, 1>, 1> ps = permutations (m);
|
||||
unsigned r = kd.n_crossings;
|
||||
for (unsigned i = 1; i <= ps.size (); i ++)
|
||||
{
|
||||
basedvector<unsigned, 1> p = ps[i];
|
||||
|
||||
unsigned ri = 0;
|
||||
for (unsigned j = 1; j <= kd.n_crossings; j ++)
|
||||
{
|
||||
unsigned upper_e = kd.ept_edge (kd.crossings[j][2]),
|
||||
lower_e = kd.ept_edge (kd.crossings[j][1]);
|
||||
|
||||
unsigned upper_c = root_comp(u.find (upper_e)),
|
||||
lower_c = root_comp(u.find (lower_e));
|
||||
|
||||
if (upper_c != lower_c
|
||||
&& p[upper_c] < p[lower_c])
|
||||
ri ++;
|
||||
}
|
||||
|
||||
if (ri < r)
|
||||
r = ri;
|
||||
}
|
||||
printf ("[% 2d] r = %d\n", rank, r);
|
||||
|
||||
assert (b_lk_weak <= r);
|
||||
assert (b <= r);
|
||||
|
||||
// non-trivial link, sp at least 1.
|
||||
unsigned best = std::max (b, b_lk_weak);
|
||||
|
||||
if (best == r)
|
||||
printf ("[% 2d] > sp = %d", rank, r);
|
||||
else
|
||||
printf ("[% 2d] > %d <= sp <= %d", rank, best, r);
|
||||
|
||||
printf (" ");
|
||||
|
||||
if (b == best
|
||||
&& b_lk_weak == best)
|
||||
printf ("(b + b_lk_weak)");
|
||||
else if (b == best)
|
||||
printf ("(b)");
|
||||
else
|
||||
{
|
||||
assert (b_lk_weak == best);
|
||||
printf ("(b_lk_weak)");
|
||||
}
|
||||
|
||||
fflush (stdout);
|
||||
}
|
||||
|
||||
void
|
||||
slave ()
|
||||
@ -311,15 +521,8 @@ slave ()
|
||||
|
||||
printf ("[% 2d] CMD_DO %s\n", rank, desc.name ().c_str ());
|
||||
|
||||
assert (desc.t == knot_desc::MT);
|
||||
char buf[1000];
|
||||
sprintf (buf, "/scratch/network/cseed/forgetful/L%d_%d.dat.gz",
|
||||
desc.i, desc.j);
|
||||
|
||||
if (! file_exits ())
|
||||
compute_forgetful (rank, desc, buf);
|
||||
else
|
||||
printf ("skip %s: exists.\n", buf);
|
||||
knot_diagram kd = desc.diagram ();
|
||||
compute_splitting_bounds (kd);
|
||||
|
||||
send_int (0, 0);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user