Added io support for module, linear_combination, mod_map and grading.

Added intersection and sum for free_submodule.  Modified mpimain to
dump cohomology, sq1 and sq2 as objects (instead of poincare series).
This commit is contained in:
Cotton Seed 2012-05-03 15:27:05 -04:00
parent b44d6f3699
commit 417fe1ea4d
9 changed files with 475 additions and 49 deletions

View File

@ -15,6 +15,7 @@ class Z2
Z2 (bool v_) : v(v_) { }
Z2 (const Z2 &x) : v(x.v) { }
Z2 (copy, const Z2 &x) : v(x.v) { }
Z2 (reader &r) { v = r.read_bool (); }
~Z2 () { }
Z2 &operator = (const Z2 &x) { v = x.v; return *this; }
@ -64,6 +65,7 @@ class Z2
}
static void show_ring () { printf ("Z2"); }
void write_self (writer &w) const { w.write_bool (v); }
void show_self () const { printf ("%d", (int)v); }
void display_self () const { printf ("%d\n", (int)v); }
};

View File

@ -8,6 +8,12 @@ class grading
grading () : h(0), q(0) { }
grading (int h_, int q_) : h(h_), q(q_) { }
grading (const grading &gr) : h(gr.h), q(gr.q) { }
grading (reader &r)
{
h = r.read_int ();
q = r.read_int ();
}
~grading () { }
grading &operator = (const grading &gr) { h = gr.h; q = gr.q; return *this; }
@ -45,7 +51,13 @@ class grading
}
grading mirror_grading (unsigned nplus, unsigned nminus, bool torsion) const;
void write_self (writer &w) const
{
w.write_int (h);
w.write_int (q);
}
void show_self () const;
void display_self () const;
};

View File

@ -39,6 +39,13 @@ class linear_combination
for (typename map<unsigned, R>::const_iter i = lc.v; i; i ++)
v.push (i.key (), R (COPY, i.val ()));
}
linear_combination (reader &r)
{
m = r.read_mod<R> ();
v = map<unsigned, R> (r);
}
~linear_combination () { }
linear_combination &operator = (const linear_combination &lc)
@ -164,6 +171,12 @@ class linear_combination
assert (!m->is_zero (i.val (), i.key ()));
}
#endif
void write_self (writer &w) const
{
write (w, *m);
write (w, v);
}
void show_self () const;
void display_self () const { show_self (); newline (); }
@ -337,6 +350,12 @@ class linear_combination<Z2>
linear_combination (ptr<const Z2mod> m_) : m(m_) { }
linear_combination (const linear_combination &lc) : m(lc.m), v(lc.v) { }
linear_combination (copy, const linear_combination &lc) : m(lc.m), v(COPY, lc.v) { }
linear_combination (reader &r)
{
m = r.read_mod<Z2> ();
v = set<unsigned> (r);
}
~linear_combination () { }
linear_combination &operator = (const linear_combination &lc)
@ -446,6 +465,12 @@ class linear_combination<Z2>
void check () const;
#endif
void write_self (writer &w) const
{
write (w, *m);
write (w, v);
}
void show_self () const;
void display_self () const { show_self (); newline (); }
};

View File

@ -14,10 +14,15 @@ template<class R>
class module : public refcounted
{
private:
friend class reader;
friend class writer;
unsigned id;
static unsigned id_counter;
static basedvector<ptr<const module<R> >, 1> id_module;
static map<basedvector<unsigned, 1>,
ptr<const direct_sum<R> > > direct_sum_idx;
static map<basedvector<unsigned, 1>,
@ -28,8 +33,11 @@ class module : public refcounted
public:
module ()
{
id = id_counter;
id_counter ++;
id = id_counter;
id_module.append (this);
assert (id_module.size () == id_counter);
}
module (const module &) = delete;
virtual ~module () { }
@ -49,6 +57,8 @@ class module : public refcounted
// r < i <= n
virtual R generator_ann (unsigned i) const = 0;
set<grading> gradings () const;
bool is_free () const { return dim () == free_rank (); }
bool is_zero (R c, unsigned i) const
@ -143,11 +153,16 @@ class module : public refcounted
factors.append (this);
}
ptr<const free_submodule<R> > graded_piece (grading hq) const;
void write_self (writer &w) const { w.write_mod<R> (this); }
void show_self () const;
void display_self () const;
};
template<class R> unsigned module<R>::id_counter = 1;
template<class R> unsigned module<R>::id_counter = 0;
template<class R> basedvector<ptr<const module<R> >, 1> module<R>::id_module;
template<class R> map<basedvector<unsigned, 1>,
ptr<const direct_sum<R> > > module<R>::direct_sum_idx;
@ -542,6 +557,9 @@ class free_submodule : public module<R>
linear_combination<R> restrict (linear_combination<R> v0) const;
ptr<const free_submodule<R> > restrict_submodule (ptr<const free_submodule<R> > m) const;
ptr<const free_submodule<R> > intersection (ptr<const free_submodule<R> > m) const;
ptr<const free_submodule<R> > plus (ptr<const free_submodule<R> > m) const;
};
template<class R>
@ -854,6 +872,15 @@ class mod_map
mod_map (const map_builder<R> &b)
: impl(new explicit_map_impl<R> (b.from, b.to, b.columns))
{ }
mod_map (reader &r)
{
ptr<const module<R> > from = r.read_mod<R> ();
ptr<const module<R> > to = r.read_mod<R> ();
basedvector<linear_combination<R>, 1> columns (r);
impl = new explicit_map_impl<R> (from, to, columns);
}
~mod_map () { }
mod_map &operator = (const mod_map &m) { impl = m.impl; return *this; }
@ -945,6 +972,14 @@ class mod_map
// ???
basedvector<linear_combination<R>, 1> explicit_columns () const;
void write_self (writer &w) const
{
// write explicitly
write (w, *impl->from);
write (w, *impl->to);
write (w, explicit_columns ());
}
void show_self () const;
void display_self () const;
};
@ -1445,6 +1480,35 @@ module<R>::free_delta_poincare_polynomial () const
return r;
}
template<class R> set<grading>
module<R>::gradings () const
{
set<grading> gs;
for (unsigned i = 1; i <= dim (); i ++)
gs += generator_grading (i);
return gs;
}
template<class R> ptr<const free_submodule<R> >
module<R>::graded_piece (grading hq) const
{
basedvector<linear_combination<R>, 1> s;
for (unsigned i = 1; i <= dim (); i ++)
{
grading ihq = generator_grading (i);
if (ihq.h == hq.h
&& ihq.q == hq.q)
{
linear_combination<R> v (this);
v.muladd (1, i);
s.append (v);
}
}
mod_span<R> span (this, s);
return submodule (span);
}
template<class R> void
module<R>::show_self () const
{
@ -1536,7 +1600,7 @@ mod_map<R>::restrict_from (ptr<const free_submodule<R> > new_from) const
basedvector<linear_combination<R>, 1> v (new_from->dim ());
for (unsigned i = 1; i <= new_from->dim (); i ++)
v[i] = map (new_from->inject_generator (i));
return new explicit_map_impl<R> (new_from, impl->to, v);
return mod_map (IMPL, new explicit_map_impl<R> (new_from, impl->to, v));
}
template<class R> mod_map<R>
@ -1560,7 +1624,7 @@ mod_map<R>::restrict (ptr<const free_submodule<R> > new_from,
basedvector<linear_combination<R>, 1> v (new_from->dim ());
for (unsigned i = 1; i <= new_from->dim (); i ++)
v[i] = new_to->restrict (map (new_from->inject_generator (i)));
return new explicit_map_impl<R> (new_from, new_to, v);
return mod_map (IMPL, new explicit_map_impl<R> (new_from, new_to, v));
}
template<class R> linear_combination<R>
@ -1606,6 +1670,93 @@ free_submodule<R>::restrict_submodule (ptr<const free_submodule<R> > m) const
return this->submodule (span2);
}
template<class R> ptr<const free_submodule<R> >
free_submodule<R>::intersection (ptr<const free_submodule<R> > m) const
{
assert (parent == m->parent);
unsigned md = m->dim (),
d = dim ();
basedvector<linear_combination<R>, 1> intr;
basedvector<linear_combination<R>, 1> hperp,
hproj;
basedvector<unsigned, 1> hpivots;
for (unsigned i = 1; i <= md; i ++)
{
linear_combination<R> perp (COPY, m->gens[i]),
proj (parent);
for (unsigned j = 1; j <= d; j ++)
{
unsigned k = pivots[j];
if (perp % k)
{
const linear_combination<R> &g = gens[j];
R c = g(k);
R d = perp(k);
assert (c | d);
R q = d.div (c);
perp.mulsub (q, g);
proj.mulsub (q, g);
assert (! (perp % k));
}
}
for (unsigned j = 1; j <= hpivots.size (); j ++)
{
unsigned k = hpivots[j];
if (perp % k)
{
const linear_combination<R> &h = hperp[j];
R c = h(k);
R d = perp(k);
assert (c | d);
R q = d.div (c);
perp.mulsub (q, h);
proj.mulsub (q, hproj[j]);
assert (! (perp % k));
}
}
if (perp == 0)
intr.append (proj);
else
{
hperp.append (perp);
hproj.append (proj);
hpivots.append (perp.head ().first);
}
}
mod_span<R> span (parent, intr);
return parent->submodule (span);
}
template<class R> ptr<const free_submodule<R> >
free_submodule<R>::plus (ptr<const free_submodule<R> > m) const
{
assert (parent == m->parent);
basedvector<linear_combination<R>, 1> s;
for (unsigned i = 1; i <= dim (); i ++)
s.append (gens[i]);
for (unsigned i = 1; i <= m->dim (); i ++)
s.append (m->gens[i]);
mod_span<R> span (parent, s);
return parent->submodule (span);
}
template<class R> bool
mod_map<R>::homogeneous () const
{
@ -1655,7 +1806,7 @@ mod_map<R>::kernel () const
to = impl->to;
basedvector<linear_combination<R>, 1> from_xs (from->dim ());
for (unsigned i = 1; i <= to->dim (); i ++)
for (unsigned i = 1; i <= from->dim (); i ++)
{
linear_combination<R> x (from);
x.muladd (1, i);
@ -1835,3 +1986,59 @@ mod_map<R>::display_self () const
newline ();
}
}
// ??? io
template<class R> void
writer::write_mod (ptr<const module<R> > m)
{
pair<unsigned &, bool> p = aw->id_io_id.find (m->id_counter);
if (p.second)
{
write_int ((int)p.first);
}
else
{
++ aw->io_id_counter;
unsigned io_id = aw->io_id_counter;
p.first = io_id;
write_int (- (int)io_id);
unsigned n = m->dim (),
r = m->free_rank ();
write_unsigned (n);
write_unsigned (r);
for (unsigned i = 1; i <= n; i ++)
write (*this, m->generator_grading (i));
for (unsigned i = r + 1; i <= n; i ++)
write (*this, m->generator_ann (i));
}
}
template<class R> ptr<const module<R> >
reader::read_mod ()
{
int io_id = read_int ();
if (io_id < 0)
{
unsigned n = read_unsigned ();
unsigned r = read_unsigned ();
basedvector<grading, 1> gr (n);
for (unsigned i = 1; i <= n; i ++)
gr[i] = grading (*this);
basedvector<R, 1> ann (n - r);
for (unsigned i = r + 1; i <= n; i ++)
ann[i - r] = R (*this);
ptr<const module<R> > m = new explicit_module<R> (r, ann, gr);
ar->io_id_id.push ((unsigned)(-io_id), m->id);
return m;
}
else
{
unsigned id = ar->io_id_id(io_id);
return module<R>::id_module[id];
}
}

View File

@ -1,5 +1,6 @@
#include <lib/lib.h>
// #include <lib/lib.h>
#include <algebra/algebra.h>
void
writer::write_int (int x)

View File

@ -1,12 +1,18 @@
template<class R> class module;
class algebra_writer;
class algebra_reader;
class writer
{
// don't use leb128 enconding. for backward compatibility.
public:
bool raw;
algebra_writer *aw;
public:
writer (const writer &) = delete;
writer (bool raw_ = false) : raw(raw_) { }
writer (bool raw_ = false) : raw(raw_), aw(0) { }
virtual ~writer () = default;
writer &operator = (const writer &) = delete;
@ -19,16 +25,18 @@ class writer
void write_int (int x);
void write_unsigned (unsigned x);
void write_uint64 (uint64 x);
virtual void write_mpz (const mpz_t x);
template<class R> void write_mod (ptr<const module<R> > m);
};
class reader
{
bool raw;
algebra_reader *ar;
public:
reader (const reader &) = delete;
reader (bool raw_) : raw(raw_) { }
reader (bool raw_) : raw(raw_), ar(0) { }
virtual ~reader () = default;
reader &operator = (const reader &) = delete;
@ -60,6 +68,8 @@ class reader
unsigned read_unsigned ();
uint64 read_uint64 ();
virtual void read_mpz (mpz_t x);
template<class R> ptr<const module<R> > read_mod ();
};
extern FILE *open_file (const std::string &file, const char *mode);

View File

@ -158,11 +158,6 @@ void stderror (const char *fmt, ...);
int alpha_to_int (char c);
#include <lib/io.h>
#include <lib/show.h>
#include <lib/refcount.h>
using std::tuple;
using std::get;
using std::make_tuple;
@ -170,6 +165,11 @@ using std::tie;
using std::ignore;
using std::initializer_list;
#include <lib/show.h>
#include <lib/refcount.h>
#include <lib/io.h>
#include <lib/pair.h>
#include <lib/maybe.h>
@ -194,7 +194,6 @@ inline int random_int (int from, int to)
#include <lib/bitset.h>
#include <lib/ullmanset.h>
#include <lib/setcommon.h>
#include <lib/map_wrapper.h>
#include <lib/map.h>
@ -212,3 +211,23 @@ struct hasher : public std::unary_function<K, hash_t>
#include <lib/unionfind.h>
#include <lib/priority_queue.h>
#include <lib/directed_multigraph.h>
// ??? io
class algebra_writer
{
public:
// modules
unsigned io_id_counter;
map<unsigned, unsigned> id_io_id;
algebra_writer () : io_id_counter(0) { }
~algebra_writer () { }
};
class algebra_reader
{
public:
map<unsigned, unsigned> io_id_id;
};

160
main.cpp
View File

@ -277,6 +277,164 @@ load (map<knot_desc,
int
main ()
{
#if 0
knot_diagram kd (rolfsen_knot (8, 19));
show (kd); newline ();
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);
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);
display ("sq1:\n", sq1);
display ("sq2:\n", sq2);
writer w ("sqtest.dat");
write (w, sq1);
write (w, sq2);
#endif
#if 1
#if 0
reader r ("sqtest.dat");
knot_desc kd (knot_desc::ROLFSEN, 8, 19);
mod_map<Z2> sq1 (r);
mod_map<Z2> sq2 (r);
ptr<const module<Z2> > H = sq1.domain ();
display ("sq1:\n", sq1);
display ("sq2:\n", sq2);
#endif
for (unsigned i = 1; i <= 10; i ++)
for (unsigned j = 1; j <= rolfsen_crossing_knots (i); j ++)
{
#if 0
// (Knot Atlas) L10n18
int xings[10][4] = {
{ 6, 1, 7, 2 },
{ 18, 7, 19, 8 },
{ 4,19,1,20 },
{ 5,12,6,13 },
{ 8,4,9,3 },
{ 13,17,14,16 },
{ 9,15,10,14 },
{ 15,11,16,10 },
{ 11,20,12,5 },
{ 2,18,3,17 },
};
knot_diagram kd (planar_diagram ("L10n18", 10, xings));
#endif
// (Knot Atlas) L10n102
int xings[10][4] = {
{ 6,1,7,2 }, { 10,3,11,4 }, { 14,7,15,8 }, { 8,13,5,14 }, { 11,18,12,19 }, { 15,20,16,17 }, { 19,16,20,9 }, { 17,12,18,13 }, { 2,5,3,6 }, { 4,9,1,10 },
};
knot_diagram kd (planar_diagram ("L10n102", 10, xings));
// knot_diagram kd (rolfsen_knot (i, j));
// knot_diagram kd (mt_link (10, 0, 18));
// show (kd); newline ();
printf ("%s ", kd.name.c_str ());
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);
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);
ptr<const module<Z2> > H = sq1.domain ();
bool first = 1;
// ???
set<grading> gs = H->gradings ();
for (set_const_iter<grading> i = gs; i; i ++)
{
grading hq = i.val (),
h1q (hq.h + 1, hq.q),
h2q (hq.h + 2, hq.q);
// printf ("(%d, %d):\n", hq.h, hq.q);
ptr<const free_submodule<Z2> > H_hq = H->graded_piece (hq),
H_h1q = H->graded_piece (h1q),
H_h2q = H->graded_piece (h2q);
mod_map<Z2> whole = sq2.restrict (H_hq, H_h2q),
tail = sq1.restrict (H_hq, H_h1q),
head = sq1.restrict (H_h1q, H_h2q);
ptr<const free_submodule<Z2> > whole_im = whole.image (),
tail_ker = tail.kernel (),
head_im = head.image ();
ptr<const free_submodule<Z2> > inter = whole_im->intersection (head_im);
mod_map<Z2> whole_res = whole.restrict_from (tail_ker);
ptr<const free_submodule<Z2> > whole_res_im = whole_res.image ();
ptr<const free_submodule<Z2> > res_inter = whole_res_im->intersection (head_im);
int r1 = whole_im->dim ();
int r2 = whole_res_im->dim ();
int r3 = inter->dim ();
int r4 = res_inter->dim ();
if (r1 == 0
&& r2 == 0
&& r3 == 0
&& r4 == 0)
continue;
// printf (" r = (%d, %d, %d, %d)\n", r1, r2, r3, r4);
int s1 = r2 - r4,
s2 = r1 - r2 - r3 + r4,
s3 = r4,
s4 = r3 - r4;
if (first)
{
#if 0
show (kd);
printf (": ");
#endif
first = 0;
}
else
printf (", ");
printf ("(%d, %d) -> (%d, %d, %d, %d)",
hq.h, hq.q,
s1, s2, s3, s4);
}
// if (!first)
newline ();
}
#endif
#if 0
// knot_diagram kd (htw_knot (12, 0, 48));
knot_diagram kd (htw_knot (10, 1, 23));
show (kd); newline ();
#endif
#if 0
for (int a = 1; a >= 0; a --)
for (unsigned i = 1; i <= 9; i ++)
@ -350,7 +508,7 @@ main ()
}
#endif
#if 1
#if 0
compute_show_kh_sq (knot_desc (knot_desc::ROLFSEN, 8, 19));
map<knot_desc,

View File

@ -7,6 +7,8 @@
#define CMD_DO 1
#define CMD_DIE 2
static const int block_size = 100;
void
master ()
{
@ -14,26 +16,29 @@ master ()
work.append (knot_desc (TORUS, 0, 0));
for (int a = 1; a >= 0; a --)
for (unsigned i = 1; i <= 10; i ++)
for (unsigned j = 1; j <= rolfsen_crossing_knots (i); j += 4000)
for (unsigned i = 14; i >= 1; i --)
{
if (i <= 10)
{
work.append (knot_desc (ROLFSEN, i, j));
for (unsigned j = 1; j <= rolfsen_crossing_knots (i); j += block_size)
{
work.append (knot_desc (ROLFSEN, i, j));
}
}
for (int a = 1; a >= 0; a --)
for (unsigned i = 1; i <= 14; i ++)
for (unsigned j = 1; j <= htw_knots (i); j += 4000)
for (unsigned j = 1; j <= htw_knots (i); j += block_size)
{
work.append (knot_desc (HTW, i, j));
}
for (int a = 1; a >= 0; a --)
for (unsigned i = 1; i <= 13; i ++)
for (unsigned j = 1; j <= mt_links (i); j += 4000)
if (i <= 13)
{
work.append (knot_desc (MT, i, j));
for (unsigned j = 1; j <= mt_links (i); j += block_size)
{
work.append (knot_desc (MT, i, j));
}
}
}
int ntasks = num_tasks ();
@ -80,9 +85,7 @@ master ()
void
compute_kh_sq (map<knot_desc,
triple<multivariate_laurentpoly<Z>,
multivariate_laurentpoly<Z>,
multivariate_laurentpoly<Z> > > &knot_kh_sq,
triple<ptr<const module<Z2> >, mod_map<Z2>, mod_map<Z2> > > &knot_kh_sq,
knot_desc &desc)
{
knot_diagram kd = desc.diagram ();
@ -96,6 +99,7 @@ compute_kh_sq (map<knot_desc,
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 ();
@ -104,18 +108,8 @@ compute_kh_sq (map<knot_desc,
assert (sq1.compose (sq1) == 0);
assert (sq2.compose (sq2) + sq1.compose (sq2).compose (sq1) == 0);
multivariate_laurentpoly<Z> P = s.new_C->free_poincare_polynomial ();
ptr<const free_submodule<Z2> > sq1_im = sq1.image ();
multivariate_laurentpoly<Z> sq1_P = sq1_im->free_poincare_polynomial ();
ptr<const free_submodule<Z2> > sq2_im = sq2.image ();
multivariate_laurentpoly<Z> sq2_P = sq2_im->free_poincare_polynomial ();
knot_kh_sq.push (desc,
triple<multivariate_laurentpoly<Z>,
multivariate_laurentpoly<Z>,
multivariate_laurentpoly<Z> > (P, sq1_P, sq2_P));
triple<ptr<const module<Z2> >, mod_map<Z2>, mod_map<Z2> > (s.new_C, sq1, sq2));
}
void
@ -136,9 +130,7 @@ slave ()
desc.j = (knot_desc::table)recv_int ();
map<knot_desc,
triple<multivariate_laurentpoly<Z>,
multivariate_laurentpoly<Z>,
multivariate_laurentpoly<Z> > > knot_kh_sq;
triple<ptr<const module<Z2> >, mod_map<Z2>, mod_map<Z2> > > knot_kh_sq;
char buf[1000];
if (desc.t == TORUS)
@ -167,7 +159,7 @@ slave ()
j0);
for (unsigned j = j0;
j <= std::min (j0 + 4000,
j <= std::min (j0 + block_size - 1,
desc.table_crossing_knots ());
j ++)
{