Added Roberts' totally twisted Kh differential to

spanning_tree_complex.  Main set up to compare twisted E3, twisted Kh
and normal Kh.
This commit is contained in:
Cotton Seed 2012-03-18 22:55:56 -04:00
parent 7d80c871ff
commit 50a2438996
5 changed files with 168 additions and 214 deletions

View File

@ -6,8 +6,8 @@ CXX = g++
INCLUDES = -I/opt/local/include -I.
OPTFLAGS = -g
# OPTFLAGS = -O2 -g
# OPTFLAGS = -g
OPTFLAGS = -O2 -g
# OPTFLAGS = -O2 -DNDEBUG
LDFLAGS = -L/opt/local/lib

View File

@ -630,9 +630,9 @@ class map_impl : public refcounted
virtual linear_combination<R> column (unsigned i) const = 0;
linear_combination<R> map (linear_combination<R> &lc) const
linear_combination<R> map (const linear_combination<R> &lc) const
{
linear_combination<R> r;
linear_combination<R> r (this->to);
for (linear_combination_const_iter<R> i = lc; i; i ++)
r.muladd (i.val (), column (i.key ()));
return r;
@ -750,7 +750,7 @@ class tensor_impl : public map_impl<R>
public:
tensor_impl (ptr<const map_impl<R> > f_, ptr<const map_impl<R> > g_)
: map_impl<R>(f_->from->tensor (g_->from),
f_->to->tensor (g_->from)),
f_->to->tensor (g_->to)),
f(f_),
g(g_)
{
@ -1741,7 +1741,7 @@ mod_map<R>::homology () const
template<class R> basedvector<linear_combination<R>, 1>
mod_map<R>::explicit_columns () const
{
basedvector<linear_combination<R>, 1> v;
basedvector<linear_combination<R>, 1> v (impl->from->dim ());
for (unsigned i = 1; i <= impl->from->dim (); i ++)
v[i] = column (i);
return v;

257
main.cpp
View File

@ -108,217 +108,74 @@ test_field ()
}
}
void
check (const dt_code &dt)
bool
rank_lte (multivariate_laurentpoly<Z> p,
multivariate_laurentpoly<Z> q)
{
if (dt.num_components () > 1)
for (map<multivariate_laurent_monomial, Z>::const_iter i = p.coeffs; i; i ++)
{
knot_diagram kd (dt);
kd.marked_edge = 1;
show (kd); newline ();
Z a = i.val ();
Z b = q.coeffs(i.key (), Z (0));
assert (a != 0 && b != 0);
cube<Z2> c (kd, 1);
mod_map<Z2> d = c.compute_d (1, 0, 0, 0, 0);
sseq_builder b (c.khC, d);
sseq ss = b.build_sseq ();
unsigned n_comps = kd.num_components ();
assert (n_comps == dt.num_components ());
unsigned split = 1;
for (unsigned k = 1; k < unsigned_2pow (n_comps) - 1; k ++)
{
knot_diagram kd2 (SUBLINK,
smallbitset (n_comps, k),
kd);
kd2.marked_edge = 1;
unsigned n_comps2 = kd2.num_components ();
assert (n_comps2 == unsigned_bitcount (k));
assert (n_comps2 > 0);
assert (n_comps2 < n_comps);
cube<Z2> c2 (kd2, 1);
mod_map<Z2> d2 = c2.compute_d (1, 0, 0, 0, 0);
sseq_builder b2 (c2.khC, d2);
sseq ss2 = b2.build_sseq ();
printf (" k = %d, %d <=? %d\n",
k,
ss2.pages[1].total_rank (),
ss.pages[1].total_rank ());
if (ss2.pages[1].total_rank () > ss.pages[1].total_rank ())
printf (" !! COUNTEREXAMPLE\n");
if (unsigned_bitcount (k) == 1)
split *= ss2.pages[1].total_rank ();
}
printf (" split %d <=? %d\n",
split,
ss.pages[1].total_rank ());
if (split > ss.pages[1].total_rank ())
printf (" !! COUNTEREXAMPLE\n");
if (a > b)
return 0;
}
return 1;
}
int
main ()
{
ptr<const explicit_module<Q> > A
= new explicit_module<Q> (2, basedvector<Q, 1> (), basedvector<grading, 1> (2));
ptr<const explicit_module<Q> > B
= new explicit_module<Q> (3, basedvector<Q, 1> (), basedvector<grading, 1> (3));
ptr<const explicit_module<Q> > C
= new explicit_module<Q> (3, basedvector<Q, 1> (), basedvector<grading, 1> (3));
ptr<const explicit_module<Q> > D
= new explicit_module<Q> (2, basedvector<Q, 1> (), basedvector<grading, 1> (2));
ptr<const explicit_module<Q> > E
= new explicit_module<Q> (2, basedvector<Q, 1> (), basedvector<grading, 1> (3));
ptr<const explicit_module<Q> > F
= new explicit_module<Q> (2, basedvector<Q, 1> (), basedvector<grading, 1> (2));
map_builder<Q> fb (A, B);
fb[1].muladd (2, 1);
fb[1].muladd (3, 2);
fb[2].muladd (-5, 2);
fb[2].muladd (4, 3);
mod_map<Q> f (fb);
display ("f:\n", f);
map_builder<Q> gb (C, D);
gb[1].muladd (1, 1);
gb[2].muladd (3, 1);
gb[2].muladd (-2, 2);
gb[3].muladd (-6, 2);
mod_map<Q> g (gb);
display ("g:\n", g);
display ("f oplus g:\n", f.add (g));
map_builder<Q> hb (E, F);
hb[1].muladd (3, 2);
hb[2].muladd (-3, 1);
mod_map<Q> h (hb);
display ("h:\n", h);
mod_map<Q> fg = f.tensor (g);
display ("fg:\n", fg);
ptr<const module<Q> > AB_C = (A->tensor (B))->tensor (C),
A_BC = A->tensor (B->tensor (C));
assert (AB_C == A_BC);
assert ((f.tensor (g)).tensor (h) == f.tensor (g.tensor (h)));
ptr<const hom_module<Q> > homAB = A->hom (B);
linear_combination<Q> x = homAB->map_as_element (f);
display ("x:\n", x);
#if 0
for (unsigned i = 1; i <= 14; i ++)
{
for (unsigned j = 1; j <= mt_links (i, 0); j ++)
check (mt_link (i, 0, j));
for (unsigned j = 1; j <= mt_links (i, 1); j ++)
check (mt_link (i, 1, j));
}
#endif
#if 0
knot_diagram kd (rolfsen_knot (8, 19));
cube<Z2> c (kd);
sseq ss = compute_szabo_sseq (c);
multivariate_laurentpoly<Z> ssp = ss.pages[1].poincare_polynomial (ss.bounds);
display ("ssp: ", ssp);
multivariate_laurentpoly<Z> p;
p.muladdeq (5, multivariate_laurent_monomial (VARIABLE, 1, -2));
p.muladdeq (-6, multivariate_laurent_monomial (VARIABLE, 2, 13));
p.muladdeq (14, (multivariate_laurent_monomial (VARIABLE, 1, 5)
* multivariate_laurent_monomial (VARIABLE, 2, -6)));
display ("p: ", p);
display ("p*p: ", p*p);
{
writer w ("dump");
write (w, p*p);
}
{
reader r ("dump");
multivariate_laurentpoly<Z> q (r);
display ("q: ", q);
assert (q == p*p);
}
for (unsigned i = 1; i <= 10; i ++)
for (unsigned j = 1; j <= rolfsen_crossing_knots (i); j ++)
{
knot_diagram kd (rolfsen_knot (i, j));
#endif
for (unsigned i = 1; i <= 12; i ++)
for (unsigned j = 1; j <= htw_knots (i, 0); j ++)
{
knot_diagram kd (htw_knot (i, 0, j));
kd.marked_edge = 1;
show (kd); newline ();
spanning_tree_complex<Z2> c (kd);
#if 0
multivariate_laurentpoly<Z> p = -11;
p.muladdeq (5, VARIABLE, 1);
p.muladdeq (7, VARIABLE, 2);
p.muladdeq (-3, VARIABLE, 3);
mod_map<fraction_field<polynomial<Z2> > > E2_d = c.twisted_d2 ();
assert (E2_d.compose (E2_d) == 0);
// display ("E2_d:\n", E2_d);
chain_complex_simplifier<fraction_field<polynomial<Z2> > > E2_s (c.C, E2_d, 2);
assert (E2_s.new_d == 0);
multivariate_laurentpoly<Z> E3_p = E2_s.new_C->free_delta_poincare_polynomial ();
printf ("E3_p = "); show (E3_p); newline ();
mod_map<fraction_field<polynomial<Z2> > > tt_d = c.totally_twisted_kh_d ();
assert (tt_d.compose (tt_d) == 0);
// display ("tt_d:\n", tt_d);
chain_complex_simplifier<fraction_field<polynomial<Z2> > > tt_s (c.C, tt_d, 2);
assert (tt_s.new_d == 0);
multivariate_laurentpoly<Z> q = p*p + p + 23;
multivariate_laurentpoly<Z> r = q*q - Z (7)*p + 81;
multivariate_laurentpoly<Z> s = r - p*q + 10;
display ("p:", p);
display ("q:", q);
display ("r:", r);
display ("s:", s);
map<multivariate_laurentpoly<Z>, std::string> m;
m.push (p, "p");
m.push (q, "q");
m.push (r, "thisisr");
assert (m % p);
assert (m % q);
assert (m % r);
assert (! (m % s));
assert (m(p) == "p");
assert (m(q) == "q");
assert (m(r) == "thisisr");
std::string str ("This is a test.");
{
writer w ("test.dat");
write (w, m);
}
reader rdr ("test.dat");
map<multivariate_laurentpoly<Z>, std::string> m2 (rdr);
assert (m == m2);
assert (m2(p) == "p");
assert (m2(q) == "q");
assert (m2(r) == "thisisr");
#endif
#if 0
test_ring<Z2> (2);
test_ring<Z> (0);
test_ring<Q> (0);
test_ring<Zp<2> > (2);
test_ring<Zp<3> > (3);
test_ring<Zp<5> > (5);
test_ring<Zp<7> > (7);
test_field<Q> ();
test_field<Zp<7> > ();
test_field<Zp<5> > ();
test_field<Zp<3> > ();
test_field<Z2> ();
test_field<Zp<2> > ();
#endif
multivariate_laurentpoly<Z> tt_p = tt_s.new_C->free_delta_poincare_polynomial ();
printf ("tt_p = "); show (tt_p); newline ();
cube<Z2> kh_c (kd, 1);
mod_map<Z2> kh_d = kh_c.compute_d (1, 0, 0, 0, 0);
sseq_builder builder (kh_c.khC, kh_d);
sseq ss = builder.build_sseq ();
multivariate_laurentpoly<Z> kh_p = ss.pages[1].delta_poincare_polynomial (ss.bounds);
printf ("kh_p = "); show (kh_p); newline ();
if (tt_p != kh_p)
printf (" > tt_p != kh_p!!\n");
if (! rank_lte (E3_p, tt_p))
printf (" > rank E2 > rank tt!!\n");
}
}

View File

@ -22,7 +22,8 @@ class spanning_tree_complex
grading tree_grading (unsigned i) const;
void show_tree (unsigned i) const;
mod_map<R> totally_twisted_kh_d () const;
mod_map<R> twisted_d2 () const;
};
@ -90,8 +91,8 @@ template<class F> mod_map<fraction_field<polynomial<F> > >
spanning_tree_complex<F>::twisted_d2 () const
{
assert (kd.marked_edge);
mod_map<R> d (C);
map_builder<R> b (C);
basedvector<int, 1> edge_weight (kd.num_edges ());
for (unsigned i = 1; i <= kd.num_edges (); i ++)
@ -201,10 +202,107 @@ spanning_tree_complex<F>::twisted_d2 () const
x += R (polynomial<F> (1),
polynomial<F> (1) + polynomial<F> (1, B));
d[i].muladd (x, j);
b[i].muladd (x, j);
}
}
}
return d;
return mod_map<R> (b);
}
template<class F> mod_map<fraction_field<polynomial<F> > >
spanning_tree_complex<F>::totally_twisted_kh_d () const
{
assert (kd.marked_edge);
map_builder<R> b (C);
basedvector<int, 1> edge_weight (kd.num_edges ());
for (unsigned i = 1; i <= kd.num_edges (); i ++)
{
edge_weight[i] = i;
// edge_weight[i] = (1 << i);
// edge_weight[i] = 1;
}
for (unsigned i = 1; i <= trees.size (); i ++)
{
set<unsigned> t = trees[i];
smallbitset r (kd.n_crossings);
for (unsigned k = 1; k <= kd.n_crossings; k ++)
{
if ((edge_height[k] == 1) == (t % k))
r.push (k);
}
smoothing s (kd, r);
for (set_const_iter<unsigned> ee = t; ee; ee ++)
{
unsigned e = ee.val ();
if (edge_height[e] != 0)
continue;
for (unsigned f = 1; f <= bg.num_edges (); f ++)
{
if (edge_height[f] != 1 || (t % f))
continue;
set<unsigned> t2 (COPY, t);
t2.yank (e);
t2.push (f);
unsigned j = tree_idx(t2, 0);
if (j == 0)
continue;
set<unsigned> neither (COPY, t);
neither.yank (e);
smallbitset neither_r (kd.n_crossings);
for (unsigned k = 1; k <= kd.n_crossings; k ++)
{
if ((edge_height[k] == 1) == (neither % k))
neither_r.push (k);
}
smoothing neither_s (kd, neither_r);
set<unsigned> both (COPY, t);
both.push (f);
R A = 0;
for (unsigned k = 1; k <= kd.num_edges (); k ++)
{
if (neither_s.edge_circle[k]
!= neither_s.edge_circle[kd.marked_edge])
A += polynomial<F> (1, edge_weight[k]);
}
smallbitset both_r (kd.n_crossings);
for (unsigned k = 1; k <= kd.n_crossings; k ++)
{
if ((edge_height[k] == 1) == (both % k))
both_r.push (k);
}
smoothing both_s (kd, both_r);
R B = 0;
for (unsigned k = 1; k <= kd.num_edges (); k ++)
{
if (both_s.edge_circle[k]
!= both_s.edge_circle[kd.marked_edge])
B += polynomial<F> (1, edge_weight[k]);
}
R x;
x += R (polynomial<F> (1)) / A;
x += R (polynomial<F> (1)) / B;
b[i].muladd (x, j);
}
}
}
return mod_map<R> (b);
}

5
sseq.h
View File

@ -150,8 +150,7 @@ class chain_complex_simplifier
mod_map<R> pi, iota;
private:
mod_map<R> new_d0;
basedvector<linear_combination, 1> new_d0;
basedvector<set<unsigned>, 1> preim;
bool build_pi_iota;
@ -271,7 +270,7 @@ chain_complex_simplifier<R>::chain_complex_simplifier (ptr<const module<R> > C_,
int dh,
bool build_pi_iota_)
: C(C_), n(C_->dim ()), d(d_),
new_d0(COPY2, d),
new_d0(COPY2, d_.explicit_columns ()),
preim(C_->dim ()),
build_pi_iota(build_pi_iota_)
{