knotkit/knot_diagram.h
Wojciech Politarczyk 203477c3a8 First shot at periodicity congruences
Verification of Przytycki's congruence works fine, however there are
some small modifications that could be made.

The, naive, approach to the verification of periodicity congruence for
the Khovanov polynomial didn't work. There are just too many cases to
check. Generation of all of them can exhaust the memory.
2016-11-24 15:28:31 +01:00

192 lines
4.8 KiB
C++

#ifndef _KNOTKIT_KNOT_DIAGRAM_H
#define _KNOTKIT_KNOT_DIAGRAM_H
#include <planar_diagram.h>
// for building knot_diagram
inline unsigned edge_from_ept (unsigned e)
{
return e * 2 - 1;
}
inline unsigned edge_to_ept (unsigned e)
{
return e * 2;
}
static inline unsigned
add_base1_mod4 (unsigned x, unsigned y)
{
assert (between (1, x, 4));
assert (between (0, y, 4));
return ((x - 1 + y) % 4) + 1;
}
enum mirror { MIRROR };
enum connect_sum { CONNECT_SUM };
enum sublink { SUBLINK };
enum disjoint_union { DISJOINT_UNION };
class knot_diagram
{
public:
std::string name;
unsigned n_crossings;
unsigned marked_edge;
basedvector<basedvector<unsigned, 1>, 1> crossings;
basedvector<unsigned, 1> ept_crossing;
basedvector<unsigned, 1> ept_index;
/* true if the smoothing orientation for an edge matches the link
orientation */
set<unsigned> edge_smoothing_oriented;
unsigned nminus, nplus;
unsigned num_edges () const { return n_crossings * 2; }
unsigned num_epts () const { return n_crossings * 4; }
unsigned ept_edge (unsigned p) const
{
assert (between (1, p, num_epts ()));
return (p + 1) / 2;
}
unsigned edge_other_ept (unsigned p) const
{
assert (between (1, p, num_epts ()));
if (is_odd (p))
return p + 1;
else
return p - 1;
}
unsigned edge_from_ept (unsigned e) const
{
assert (between (1, e, num_edges ()));
return e * 2 - 1;
}
unsigned edge_to_ept (unsigned e) const
{
assert (between (1, e, num_edges ()));
return e * 2;
}
unsigned is_from_ept (unsigned p) const
{
assert (between (1, p, num_epts ()));
return is_odd (p);
}
unsigned is_to_ept (unsigned p) const { return !is_from_ept (p); }
unsigned is_under_ept (unsigned p) const
{
assert (between (1, p, num_epts ()));
return ept_index[p] == 1 || ept_index[p] == 3;
}
unsigned is_over_ept (unsigned p) const { return !is_under_ept (p); }
bool is_crossing_from_ept (unsigned p) const
{
assert (is_under_ept (p));
return ept_index[p] == 1;
}
bool is_crossing_to_ept (unsigned p) const { return !is_crossing_from_ept (p); }
/* wrt smoothing orientation */
unsigned edge_smoothing_from_ept (unsigned e) const
{
return edge_smoothing_oriented % e
? edge_from_ept (e)
: edge_to_ept (e);
}
unsigned edge_smoothing_to_ept (unsigned e) const
{
return edge_smoothing_oriented % e
? edge_to_ept (e)
: edge_from_ept (e);
}
bool is_smoothing_from_ept (unsigned p) const
{
unsigned e = ept_edge (p);
return p == edge_smoothing_from_ept (e);
}
bool is_smoothing_to_ept (unsigned p) const { return !is_smoothing_from_ept (p); }
unsigned num_components () const;
void orient ();
void calculate_nminus_nplus ();
void calculate_smoothing_orientation ();
void check_crossings ();
void rotate_crossing (unsigned c);
public:
knot_diagram ()
: n_crossings(0),
marked_edge(0),
nminus(0),
nplus(0)
{ }
explicit knot_diagram (const planar_diagram &pd);
explicit knot_diagram (const dt_code &dt);
knot_diagram (mirror, const knot_diagram &kd);
knot_diagram (connect_sum,
const knot_diagram &d1,
const knot_diagram &d2);
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_);
knot_diagram (const knot_diagram &kd)
: name(kd.name),
n_crossings(kd.n_crossings),
marked_edge(kd.marked_edge),
crossings(kd.crossings),
ept_crossing(kd.ept_crossing),
ept_index(kd.ept_index),
edge_smoothing_oriented(kd.edge_smoothing_oriented),
nminus(kd.nminus), nplus(kd.nplus)
{ }
~knot_diagram () { }
knot_diagram &operator = (const knot_diagram &kd)
{
name = kd.name;
n_crossings = kd.n_crossings;
marked_edge = kd.marked_edge;
crossings = kd.crossings;
ept_crossing = kd.ept_crossing;
ept_index = kd.ept_index;
edge_smoothing_oriented = kd.edge_smoothing_oriented;
nminus = kd.nminus;
nplus = kd.nplus;
return *this;
}
directed_multigraph black_graph (basedvector<unsigned, 1> &bg_edge_height) const;
unsigned resolve_next_ept (unsigned p, bool resolution) const;
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> as_gauss_code () const;
hash_t hash_self () const;
void show_ept (unsigned p) const;
void show_self () const;
void display_self () const;
};
#endif // _KNOTKIT_KNOT_DIAGRAM_H