Added compute_forgetful_signs to main. Set up mpimain to compute

forgetful spectral sequence over Z/97 for all links with 14 or fewer
crossings.
This commit is contained in:
Cotton Seed 2012-10-13 12:45:43 -04:00
parent 177b37bb57
commit f2375a2d9e
7 changed files with 466 additions and 43 deletions

View File

@ -364,6 +364,13 @@ cube<R>::compute_dinv (unsigned c)
{ {
if (!unsigned_bittest (i, c)) if (!unsigned_bittest (i, c))
continue; continue;
int sign = 1;
for (unsigned j = 1; j < c; j ++)
{
if (unsigned_bittest (i, j))
sign *= -1;
}
smoothing from_s (kd, smallbitset (n_crossings, i)); smoothing from_s (kd, smallbitset (n_crossings, i));
@ -398,12 +405,12 @@ cube<R>::compute_dinv (unsigned c)
j2 = unsigned_bitset (j2, x); j2 = unsigned_bitset (j2, x);
j2 = unsigned_bitclear (j2, y); j2 = unsigned_bitclear (j2, y);
p[generator (i, j)].muladd (1, generator (i2, j2)); p[generator (i, j)].muladd (sign, generator (i2, j2));
j2 = unsigned_bitclear (j2, x); j2 = unsigned_bitclear (j2, x);
j2 = unsigned_bitset (j2, y); j2 = unsigned_bitset (j2, y);
p[generator (i, j)].muladd (1, generator (i2, j2)); p[generator (i, j)].muladd (sign, generator (i2, j2));
} }
else else
{ {
@ -411,7 +418,7 @@ cube<R>::compute_dinv (unsigned c)
j2 = unsigned_bitclear (j2, x); j2 = unsigned_bitclear (j2, x);
j2 = unsigned_bitclear (j2, y); j2 = unsigned_bitclear (j2, y);
p[generator (i, j)].muladd (1, generator (i2, j2)); p[generator (i, j)].muladd (sign, generator (i2, j2));
} }
} }
else else
@ -425,7 +432,7 @@ cube<R>::compute_dinv (unsigned c)
// 1 -> 1 // 1 -> 1
j2 = unsigned_bitset (j2, x); j2 = unsigned_bitset (j2, x);
p[generator (i, j)].muladd (1, generator (i2, j2)); p[generator (i, j)].muladd (sign, generator (i2, j2));
} }
else if ((unsigned_bittest (j, a) else if ((unsigned_bittest (j, a)
&& !unsigned_bittest (j, b)) && !unsigned_bittest (j, b))
@ -435,7 +442,7 @@ cube<R>::compute_dinv (unsigned c)
// a, b -> x // a, b -> x
j2 = unsigned_bitclear (j2, x); j2 = unsigned_bitclear (j2, x);
p[generator (i, j)].muladd (1, generator (i2, j2)); p[generator (i, j)].muladd (sign, generator (i2, j2));
} }
} }
} }

View File

@ -22,7 +22,7 @@ knot_diagram::knot_diagram (const planar_diagram &pd)
crossings[c] = basedvector<unsigned, 1> (4); crossings[c] = basedvector<unsigned, 1> (4);
} }
smallbitset done (num_edges ()); set<unsigned> done;
for (unsigned c0 = 1; c0 <= n_crossings; c0 ++) for (unsigned c0 = 1; c0 <= n_crossings; c0 ++)
{ {
for (unsigned i0 = 1; i0 <= 2; i0 ++) for (unsigned i0 = 1; i0 <= 2; i0 ++)
@ -521,6 +521,63 @@ knot_diagram::rotate_crossing (unsigned c)
} }
} }
unsigned
knot_diagram::total_linking_number () const
{
unionfind<1> u (num_edges ());
for (unsigned i = 1; i <= n_crossings; i ++)
{
u.join (ept_edge (crossings[i][1]),
ept_edge (crossings[i][3]));
u.join (ept_edge (crossings[i][2]),
ept_edge (crossings[i][4]));
}
unsigned n = u.num_sets ();
map<unsigned, unsigned> root_comp;
unsigned t = 0;
for (unsigned i = 1; i <= num_edges (); i ++)
{
if (u.find (i) == i)
{
++ t;
root_comp.push (i, t);
}
}
assert (t == n);
unsigned total_lk = 0;
for (unsigned i = 1; i <= n; i ++)
for (unsigned j = i + 1; j <= n; j ++)
{
if (i == j)
continue;
int lk = 0;
for (unsigned x = 1; x <= n_crossings; x ++)
{
unsigned r1 = root_comp(u.find (ept_edge (crossings[x][1]))),
r2 = root_comp(u.find (ept_edge (crossings[x][2])));
if (((r1 == i) && (r2 == j))
|| ((r2 == i) && (r1 == j)))
{
if (is_to_ept (crossings[x][1]) == is_to_ept (crossings[x][4]))
lk ++;
else
lk --;
}
}
assert (is_even (lk));
lk /= 2;
total_lk += std::abs (lk);
}
return total_lk;
}
knot_diagram::knot_diagram (connect_sum, knot_diagram::knot_diagram (connect_sum,
const knot_diagram &d1, const knot_diagram &d1,
const knot_diagram &d2) const knot_diagram &d2)

View File

@ -157,6 +157,8 @@ class knot_diagram
int writhe () const { return (int)nplus - (int)nminus; } int writhe () const { return (int)nplus - (int)nminus; }
unsigned total_linking_number () const;
basedvector<basedvector<int, 1>, 1> planar_diagram_crossings () const; basedvector<basedvector<int, 1>, 1> planar_diagram_crossings () const;
hash_t hash_self () const; hash_t hash_self () const;

View File

@ -1,7 +1,7 @@
#include <knotkit.h> #include <knotkit.h>
#define HOME "/u/cseed/src/knotkit/" #define HOME "/Users/cotton/src/knotkit/"
bool verbose = 0; bool verbose = 0;

180
main.cpp
View File

@ -849,6 +849,183 @@ test_forgetful_ss ()
} }
} }
void
test_forgetful_signs ()
{
typedef Zp<97> R;
#if 0
for (unsigned i = 1; i <= 14; i ++)
for (unsigned j = 1; j <= mt_links (i, 0); j ++)
{
knot_diagram kd (mt_link (i, 0, j));
}
#endif
#if 1
for (unsigned i = 2; i <= 16; i ++)
for (unsigned j = i; j <= 16; j ++)
{
knot_diagram kd (torus_knot (i, j));
assert (kd.n_crossings == (i - 1) * j
&& kd.n_crossings <= i * (j - 1));
if (kd.n_crossings > 13)
continue;
#endif
unsigned n = kd.num_components ();
if (n < 2)
continue;
assert (n < 97);
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]));
}
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 == n);
basedvector<R, 1> comp_weight (n);
for (unsigned i = 1; i <= n; i ++)
comp_weight[i] = R ((int)i);
map<unsigned, R> crossing_over_sign;
// crossings
set<unsigned> pending;
set<unsigned> finished;
crossing_over_sign.push (1, R (1));
pending.push (1);
while (pending.card () > 0)
{
unsigned x = pending.pop ();
finished.push (x);
R s = crossing_over_sign(x);
for (unsigned j = 1; j <= 4; j ++)
{
unsigned p = kd.crossings[x][j];
R t = kd.is_over_ept (p) ? s : -s; // sign of (x, p)
unsigned q = kd.edge_other_ept (p);
unsigned x2 = kd.ept_crossing[q];
R u = kd.is_over_ept (q) ? -t : t;
if (crossing_over_sign % x2)
assert (crossing_over_sign(x2) == u);
else
crossing_over_sign.push (x2, u);
if (! (finished % x2))
pending += x2;
}
}
assert (finished.card () == kd.n_crossings);
#if 0
printf ("crossing_over_sign:\n");
for (unsigned i = 1; i <= kd.n_crossings; i ++)
{
printf (" % 2d: ", i);
display (crossing_over_sign(i));
}
#endif
cube<R> 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<R> untwisted_d = c.compute_d (1, 0, 0, 0, 0);
assert (untwisted_d.compose (untwisted_d) == 0);
mod_map<R> d = untwisted_d;
for (unsigned x = 1; x <= kd.n_crossings; x ++)
{
unsigned p1 = kd.crossings[x][1],
p2 = kd.crossings[x][2];
assert (kd.is_over_ept (p2));
unsigned r1 = u.find (kd.ept_edge (p1)),
r2 = u.find (kd.ept_edge (p2));
unsigned c1 = root_comp(r1),
c2 = root_comp(r2);
if (c1 != c2)
{
R s = crossing_over_sign(x);
R w_under = comp_weight[c1];
R w_over = comp_weight[c2];
d = d + c.compute_dinv (x)*(s*(w_over - w_under))
;
}
}
// display ("d:\n", d);
// mod_map<Z> h = d.compose (d);
// display ("h:\n", h);
assert (d.compose (d) == 0);
ptr<const module<R> > Ek = c.khC;
mod_map<R> dk = d;
unsigned kinf;
for (int dq = 0;; dq -= 2)
{
chain_complex_simplifier<R> s (Ek, dk, dq);
Ek = s.new_C;
dk = s.new_d;
printf ("|E%d| = %d\n", ((- dq) / 2) + 1, Ek->dim ());
if (dk == 0)
{
kinf = ((- dq) / 2);
break;
}
}
unsigned total_lk = kd.total_linking_number ();
unsigned trivial_bound = total_lk == 0 ? 2 : total_lk;
printf ("kinf = %d, trivial bound = %d (total_lk = %d)\n",
kinf, trivial_bound, total_lk);
if (trivial_bound < kinf)
printf (" > BETTER\n");
}
}
/* Kh homotopy type: /* Kh homotopy type:
- check for CP^2, - check for CP^2,
- mutation invariance - mutation invariance
@ -1578,6 +1755,9 @@ convert_15 ()
int int
main () main ()
{ {
test_forgetful_signs ();
return 0;
find_width4_in_h0 (); find_width4_in_h0 ();
// convert_15 (); // convert_15 ();
// test_knot_sq (); // test_knot_sq ();

View File

@ -14,11 +14,24 @@ master ()
{ {
basedvector<knot_desc, 1> work; basedvector<knot_desc, 1> work;
basedvector<basedvector<unsigned, 1>, 1> groups = mutant_knot_groups (15); for (unsigned i = 1; i <= 14; i ++)
for (unsigned j = 1; j <= mt_links (i, 0); j ++)
{
knot_diagram kd (mt_links (i, 0, j));
unsigned n = kd.num_components ();
if (n < 2)
continue;
work.append (knot_desc (knot_desc::MT, i, j));
}
#if 0
basedvector<basedvector<unsigned, 1>, 1> groups = mutant_knot_groups (15);
for (unsigned i = 1; i <= groups.size (); i ++) for (unsigned i = 1; i <= groups.size (); i ++)
for (unsigned j = 1; j <= groups[i].size (); j ++) for (unsigned j = 1; j <= groups[i].size (); j ++)
work.append (knot_desc (knot_desc::HTW, 15, groups[i][j])); work.append (knot_desc (knot_desc::HTW, 15, groups[i][j]));
#endif
#if 0 #if 0
for (unsigned i = 14; i >= 1; i --) for (unsigned i = 14; i >= 1; i --)
@ -87,6 +100,198 @@ master ()
} }
} }
bool
file_exists (const char *file)
{
struct stat stat_buf;
if (stat (file, &stat_buf) != 0)
{
if (errno == ENOENT)
return 0;
stderror ("stat: %s", file);
exit (EXIT_FAILURE);
}
return 1;
}
void
compute_forgetful (int rank, knot_desc desc, const char *buf)
{
knot_diagram kd = desc.diagram ();
typedef Zp<97> R;
unsigned n = kd.num_components ();
assert (n >= 2);
assert (n < 97);
printf ("[% 2d] ", rank);
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]));
}
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 == n);
basedvector<R, 1> comp_weight (n);
for (unsigned i = 1; i <= n; i ++)
comp_weight[i] = R ((int)i);
map<unsigned, R> crossing_over_sign;
// crossings
set<unsigned> pending;
set<unsigned> finished;
crossing_over_sign.push (1, R (1));
pending.push (1);
while (pending.card () > 0)
{
unsigned x = pending.pop ();
finished.push (x);
R s = crossing_over_sign(x);
for (unsigned j = 1; j <= 4; j ++)
{
unsigned p = kd.crossings[x][j];
R t = kd.is_over_ept (p) ? s : -s; // sign of (x, p)
unsigned q = kd.edge_other_ept (p);
unsigned x2 = kd.ept_crossing[q];
R u = kd.is_over_ept (q) ? -t : t;
if (crossing_over_sign % x2)
assert (crossing_over_sign(x2) == u);
else
crossing_over_sign.push (x2, u);
if (! (finished % x2))
pending += x2;
}
}
assert (finished.card () == kd.n_crossings);
#if 0
printf ("crossing_over_sign:\n");
for (unsigned i = 1; i <= kd.n_crossings; i ++)
{
printf (" % 2d: ", i);
display (crossing_over_sign(i));
}
#endif
cube<R> 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<R> untwisted_d = c.compute_d (1, 0, 0, 0, 0);
assert (untwisted_d.compose (untwisted_d) == 0);
mod_map<R> d = untwisted_d;
for (unsigned x = 1; x <= kd.n_crossings; x ++)
{
unsigned p1 = kd.crossings[x][1],
p2 = kd.crossings[x][2];
assert (kd.is_over_ept (p2));
unsigned r1 = u.find (kd.ept_edge (p1)),
r2 = u.find (kd.ept_edge (p2));
unsigned c1 = root_comp(r1),
c2 = root_comp(r2);
if (c1 != c2)
{
R s = crossing_over_sign(x);
R w_under = comp_weight[c1];
R w_over = comp_weight[c2];
d = d + c.compute_dinv (x)*(s*(w_over - w_under))
;
}
}
// display ("d:\n", d);
// mod_map<Z> h = d.compose (d);
// display ("h:\n", h);
assert (d.compose (d) == 0);
ptr<const module<R> > Ek = c.khC;
mod_map<R> dk = d;
basedvector<multivariate_laurentpoly<Z>, 1> pages;
unsigned kinf;
for (int dq = 0;; dq -= 2)
{
chain_complex_simplifier<R> s (Ek, dk, dq);
Ek = s.new_C;
dk = s.new_d;
pages.append (Ek->free_poincare_polynomial ());
printf ("[% 2d] ", rank);
printf ("|E%d| = %d\n", ((- dq) / 2) + 1, Ek->dim ());
if (dk == 0)
{
kinf = ((- dq) / 2);
break;
}
}
unsigned total_lk = kd.total_linking_number ();
unsigned trivial_bound = total_lk == 0 ? 2 : total_lk;
printf ("[% 2d] ", rank);
printf ("kinf = %d, trivial bound = %d (total_lk = %d)\n",
kinf, trivial_bound, total_lk);
if (trivial_bound < kinf)
{
printf ("[% 2d] ", rank);
printf (" > BETTER\n");
}
fflush (stdout);
assert (desc.t == knot_desc::MT);
gzfile_writer w (buf);
write (w, desc);
write (w, pages);
}
void void
slave () slave ()
{ {
@ -106,40 +311,13 @@ slave ()
printf ("[% 2d] CMD_DO %s\n", rank, desc.name ().c_str ()); printf ("[% 2d] CMD_DO %s\n", rank, desc.name ().c_str ());
assert (desc.t == knot_desc::MT);
char buf[1000]; char buf[1000];
sprintf (buf, "/scratch/network/cseed/incoming/K%d_%d.dat.gz", sprintf (buf, "/scratch/network/cseed/forgetful/L%d_%d.dat.gz",
desc.i, desc.j); desc.i, desc.j);
struct stat stat_buf; if (! file_exits ())
if (stat (buf, &stat_buf) != 0) compute_forgetful (rank, desc, buf);
{
if (errno == ENOENT)
{
knot_diagram kd = desc.diagram ();
cube<Z2> c (kd);
mod_map<Z2> d = c.compute_d (1, 0, 0, 0, 0);
chain_complex_simplifier<Z2> s (c.khC, d, 1);
assert (s.new_d == 0);
steenrod_square sq (c, d, s);
mod_map<Z2> sq1 = sq.sq1 ();
mod_map<Z2> sq2 = sq.sq2 ();
assert (sq1.compose (sq1) == 0);
assert (sq2.compose (sq2) + sq1.compose (sq2).compose (sq1) == 0);
gzfile_writer w (buf);
write (w, sq1);
write (w, sq2);
}
else
{
stderror ("stat: %s", buf);
exit (EXIT_FAILURE);
}
}
else else
printf ("skip %s: exists.\n", buf); printf ("skip %s: exists.\n", buf);

View File

@ -63,7 +63,7 @@ class chain_complex_simplifier
public: public:
chain_complex_simplifier (ptr<const module<R> > C_, chain_complex_simplifier (ptr<const module<R> > C_,
const mod_map<R> &d_, const mod_map<R> &d_,
int dh); int dq);
}; };
@ -145,7 +145,7 @@ chain_complex_simplifier<R>::cancel (unsigned i, R b, unsigned j)
template<class R> template<class R>
chain_complex_simplifier<R>::chain_complex_simplifier (ptr<const module<R> > C_, chain_complex_simplifier<R>::chain_complex_simplifier (ptr<const module<R> > C_,
const mod_map<R> &d_, const mod_map<R> &d_,
int dh) int dq)
: C(C_), n(C_->dim ()), d(d_), : C(C_), n(C_->dim ()), d(d_),
new_d_columns(n), new_d_columns(n),
preim(n), preim(n),
@ -172,9 +172,8 @@ chain_complex_simplifier<R>::chain_complex_simplifier (ptr<const module<R> > C_,
for (linear_combination_const_iter<R> j = new_d_columns[i]; j; j ++) for (linear_combination_const_iter<R> j = new_d_columns[i]; j; j ++)
{ {
grading jgr = C->generator_grading (j.key ()); grading jgr = C->generator_grading (j.key ());
// assert (jgr.h >= igr.h);
if (j.val ().is_unit () if (j.val ().is_unit ()
// && jgr.h - igr.h == dh && jgr.q - igr.q == dq
) )
{ {
cancel (i, j.val (), j.key ()); cancel (i, j.val (), j.key ());