Contact
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
| Download
Project: SageDays78
Views: 431
Kernel: SageMath (Development)

The presentation is aimed at introducing various constructs used in Knot Theory module in Sage. The main aim is to introduce the following :

  • Input a Knot/Link Structure

  • Differentiate between various Knot/Link structures using various invariants.


Definitions :

To begin with we define Knot and Link

Knot:

A knot is defined as embedding of the circle S1\mathbb{S}^1 in the 3-dimensional sphere S3\mathbb{S}^3, considered up to ambient isotopy. They represent the physical idea of a knotted rope, but with the particularity that the rope is closed. That is, the ends of the rope are joined.

Link:

A link is an embedding of one or more copies of S1\mathbb{S}^1 in S3\mathbb{S}^3, considered up to ambient isotopy. That is, a link represents the idea of one or more tied ropes. Every knot is a link, but not every link is a knot.


Various representations in Sage

There are different ways to represent a Link. The main representations which Sage understands are the following :

  • Braid representation of the Link

  • Oriented Gauss Code

  • Planar Diagram Code or PD Code

These are internally recognized by Sage, all the user needs to do is input in one of the above representations.

-----

Let us start by looking at Braid Group (Braidword representation) of the Link.

Braid group to Braidword representation

Consider a 1 x 1 x 1 cube. On the planes z = 0 and z = 1, at x = 1/2 consider n points varying y. Join the n points on both the planes, with the rules being :

  • There is a bijective map between the points, implying every point has to be mapped to unique point on the other plane.

  • The points are joined by non intersecting arcs lying completely inside the cube.

For example, see sage-worksheet

With reference to the above example, there are 3 points on the both the planes and we join them using arcs.


# `BraidGroup` is being called with the number of strings
B = BraidGroup(3)
B1 = B([1,2])

To define a Braid Group, consider the set BB, of all braid diagrams as above. Define the composition of the diagrams as stacking them together vertically.

  • Closure is defined as the stacking of diagrams and this diagram is again in the set BB

  • Consider three different diagrams, say labelled by 1,2,31, 2, 3, stacking 11 with 22 and then with 33 is same as stacking 22 with 33 and stacking the resultant with 11.

  • The identity from the set is the following, label the points on z = 0 plane by a,b,c....a, b, c .... and z = 1 plane by a′,b′,c′....a', b', c' .... connect ii to corresponding i′i'. The diagram obtained is the identity of the group.

  • For every given braid diagram bb, we can always find a diagram b′b' in BB such that b∘b′b \circ b' to obtain the identity as mentioned above.

Therefore, the set BB forms a group.

Generators of group BB

Now we look at the generators σi\sigma_{i} of group BB which help in understanding the braidword construction. As above consider the points on the plane z = 0 and z = 1, let us label the points on the plane z = 0 as Pi0P_{i}^{0} and on z = 1 as Pi1P_{i}^{1}, where i∈{1,2,3,....,n}i \in \{1, 2, 3, ...., n\}. The generators σi\sigma_{i} of group BB, are the following braid diagrams :

Join Pi0P_{i}^{0} to Pi+11P_{i+1}^{1} and Pi+10P_{i+1}^{0} to Pi1P_{i}^{1} and Pj0P_{j}^{0} goes to Pj1P_{j}^{1}, ∀j≠i\forall j \neq i. If we stare at the generators there are two ways in which we can join, i.e., either the arc joining Pi0P_{i}^{0} to Pi0P_{i}^{0} to Pi+11P_{i+1}^{1} is above Pi+10P_{i+1}^{0} to Pi1P_{i}^{1}, say σi\sigma_{i} or the other way round σi−1\sigma_{i}^{-1}. It is very easy to generate all the diagrams from these generators. Projecting these 3d curves into a 2d planes, gives an insight into overcrossing and undercrossing, for example sage-worksheet. For example, the underlying braidword is 1,21, 2 for the above diagram indicating that we join 11 to 2′2' with an over curve and 22 to 3′3' again with an over curve.

The way a LinkLink can be constructed from the braidword is by joining the points in the planes z = 0 and z = 1 by a curve which lies outside the cube. Therefore, we can construct a Link by closure of the braidword, and so one of the inputs for the Link construct which Sage understands is a braidword.

B = BraidGroup(3)
# creating a Link out of the braid L = Link(B([1,1,-2,1]))
L
Link with 1 component represented by 4 crossings
L.is_knot()
True
L._braid.plot()
Image in a Jupyter notebook
L.plot()
Image in a Jupyter notebook

Oriented Gauss Code, Planar Diagram Code

Though braidword representation looks as a simple technique to study Links, given a Link it is not straight forward to see it as a braid closure and deduce the braidword representation of the Link. We look at two different representations that is the oriented gauss code and planar diagram code.

Oriented Gauss Code :

In order to deduce the oriented gauss code, we will number the crossings along with a sign, that is if it is a undercrossing we would add a " - " in the front of the crossing as we move along the Link until we return to the starting point, as well assign a +1 or -1 to each of the crossing. Crossings are labelled as +1 and -1 using the following notation : For example consider the trefoil which looks as follows : Using the above rules, the sign at each of the crossing would be -1. The oriented gauss code would be [[[1, -2, 3, -1, 2, -3]],[-1, -1, -1]]

# there are two lists one for the crossings which is a list of lists, the other for the sign of the crossings. L1 = Link([[[1, -2, 3, -1, 2, -3]],[-1, -1, -1]])
L1
Link with 1 component represented by 3 crossings

Sage also allows intercoversion between different input formats. We can intercovert between braidword, oriented gauss code, planar diagram code. As we have still not defined the planar diagram code let us convert this input to braidword.

L1.braid()
s^-3
L1.braid().Tietze()
(-1, -1, -1)
L1.plot()
Image in a Jupyter notebook

Lets reverse engineer, let us see if we end up with the same results, starting with the braid and obtaining the oriented gauss code and therefore the same diagram

b1 = L1.braid()
L1_reconstruct = Link(b1)
L1_reconstruct
Link with 1 component represented by 3 crossings
L1_reconstruct.oriented_gauss_code()
[[[-1, 2, -3, 1, -2, 3]], [-1, -1, -1]]
L1_reconstruct.plot()
Image in a Jupyter notebook
Planar Diagram Code

Finally we introduce the least complicated notation, that is the planar diagram code (pd code). This is constructed in the following way, start with a point on the Link identify this part of the link with a number and keep moving along the Link, once we encounter a crossing just increment the number to the part following the crossing. Once all the parts on the Link are covered, each crossing has 4 numbers associated to it. Each crossing is identified by starting with the undercrossing component and moving in the clockwise direction. For example consider the above trefoil The planar diagram code looks as [[4, 2, 5, 1], [2, 6, 3, 5], [6, 4, 1, 3]]

L1_pd = Link([[4, 2, 5, 1], [2, 6, 3, 5], [6, 4, 1, 3]])
L1_pd.oriented_gauss_code()
[[[1, -2, 3, -1, 2, -3]], [-1, -1, -1]]
L1_pd.braid()
s^-3
L1_pd.braid().Tietze()
(-1, -1, -1)
L1_pd.plot()
Image in a Jupyter notebook

We also look at Seifert circles and Regions as these are used in various alogrithms like interconversion between planar diagram code to braidword construction, in construction of jones polynomial.

L1_pd.seifert_circles()
[[1, 5, 3], [2, 6, 4]]
L1_pd.regions()
[[1, -4], [2, 6, 4], [3, -6], [5, -2], [-5, -1, -3]]

Therefore for the trefoil, as expected we get the same braidword representation [-1, -1, -1] whether we start with oriented gauss code or planar diagram code. This leads us to an interesting question, given two Links how can we say whether they are the same or not, it is not always possible to stare at the diagram and conclude whether the links are identical. So we look at other invariants which help in distinguishing various Links/Knots. Before we do that let us examine the above notations for a more general Link.


Some more examples

Consider the following link diagrams : ,

# planar diagram input L2_pd = Link([[1, 8, 2, 7], [5, 3, 6, 2], [3, 9, 4, 10],[8, 4, 9, 5],[10, 1, 7, 6]])
# oriented gauss code input L2_ogc = Link([[[-1, 2, -3, 4, -2, 5],[1, -4, 3, -5]],[-1, -1, 1, 1, -1]])
# both are different representations of the same link L2_pd == L2_ogc
True
# is_knot checks if the link is a knot L2_pd.is_knot()
False
# the number of distinct components in a link L2_pd.number_of_components()
2
# valid only for knots, looks at the sign associated with the knot L2_ogc.is_alternating()
False
# planar diagram to braidword representation L2_pd.braid().Tietze()
(1, -2, -2, 1, -2)
# planar diagram to oriented gauss code conversion representation L2_pd.oriented_gauss_code()
[[[1, -4, 3, -5], [-1, 2, -3, 4, -2, 5]], [-1, -1, 1, 1, -1]]
# oriented gauss code to braidword representation L2_ogc.braid().Tietze()
(1, -2, -2, 1, -2)
# oriented gauss code to planar diagram representation L2_ogc.pd_code()
[[1, 8, 2, 7], [5, 3, 6, 2], [3, 9, 4, 10], [8, 4, 9, 5], [10, 1, 7, 6]]
# plotting the planar diagram code L2_pd.plot()
Image in a Jupyter notebook
# plotting the oriented gauss code L2_ogc.plot()
Image in a Jupyter notebook
L2_pd.seifert_circles()
[[1, 8, 5, 3, 10], [2, 6, 7], [4, 9]]
L2_pd.regions()
[[1, 8, -4, 10], [2, -5, -8], [3, -9, 5], [4, 9], [6, -10, -3], [7, -1], [-2, -7, -6]]

We return to the question of how we distinguish various Links given the Link configurations (Planar Diagram Code, Oriented Gauss Code, Braidword representation). Link module allows the computation of the following invariants :

  • Alexander polynomial

  • Jones polynomial

  • Khovanov Homology

  • HOMFLY polynomial (external library interfacing)

Consider the following versions of trefoils, basically the difference is changing the orientation of the crossings from -1 at every crossing to +1.

L_left = Link([[[1, -2, 3, -1, 2, -3]],[-1, -1, -1]]) L_left
Link with 1 component represented by 3 crossings
L_right = Link([[[1, -2, 3, -1, 2, -3]],[1, 1, 1]]) L_right
Link with 1 component represented by 3 crossings
L_left.braid().Tietze()
(-1, -1, -1)
L_right.braid().Tietze()
(1, 1, 1)
L_left.seifert_circles()
[[1, 5, 3], [2, 6, 4]]
L_right.seifert_circles()
[[1, 5, 3], [2, 6, 4]]
L_left.regions()
[[1, -4], [2, 6, 4], [3, -6], [5, -2], [-5, -1, -3]]
L_right.regions()
[[1, 5, 3], [2, -5], [4, -1], [6, -3], [-2, -4, -6]]
L_left.seifert_matrix()
[ 1 -1] [ 0 1]
L_right.seifert_matrix()
[-1 0] [ 1 -1]
L_left.determinant(), L_right.determinant()
(3, 3)
L_left.writhe(), L_right.writhe()
(-3, 3)
L_left.alexander_polynomial(), L_right.alexander_polynomial()
(t^-1 - 1 + t, t^-1 - 1 + t)
L_left.jones_polynomial(), L_right.jones_polynomial()
(1/t + 1/t^3 - 1/t^4, -t^4 + t^3 + t)

Consider the following knots K1 and K2given by the following figure: with reference to the following : http://math.stackexchange.com/questions/1303743/is-there-a-one-to-one-correspondence-between-jones-polynomials-and-knots/1303960

K1 = Knot([[[1, -2, 3, -4, 2, -1, -5, 6, -7, 8, -6, 5, -8, 7, 4, -3]],[1, 1, -1, -1, -1, -1, 1, 1]]) K1
Knot represented by 8 crossings
K2 = Knot([[[1, -2, 3, -4, 5, -6, 7, -8, 4, -1, 2, -3, 8, -5, 6, -7]],[-1, -1, -1, -1, 1, 1, 1, 1]]) K2
Knot represented by 8 crossings
K1 == K2
False
K1.alexander_polynomial()
t^-2 - 6*t^-1 + 11 - 6*t + t^2
K1.jones_polynomial()
t^4 - 2*t^3 + 3*t^2 - 4*t - 4/t + 3/t^2 - 2/t^3 + 1/t^4 + 5
K2.alexander_polynomial()
-t^-3 + 3*t^-2 - 5*t^-1 + 7 - 5*t + 3*t^2 - t^3
K2.jones_polynomial()
t^4 - 2*t^3 + 3*t^2 - 4*t - 4/t + 3/t^2 - 2/t^3 + 1/t^4 + 5
x = var('x') eqn = (x^-1 - 3 + x)^2 eqn.expand()
x^2 - 6*x - 6/x + 1/x^2 + 11
eqn_j = (x^-2 - x^-1 + 1 - x + x^2)^2 eqn_j.expand()
x^4 - 2*x^3 + 3*x^2 - 4*x - 4/x + 3/x^2 - 2/x^3 + 1/x^4 + 5
K1.arf_invariant()
0
K2.arf_invariant()
0
K1.khovanov_homology()
{-9: {-4: Z}, -7: {-4: 0, -3: Z x C2, -2: 0}, -5: {-4: 0, -3: Z, -2: Z x Z x C2, -1: 0, 0: 0}, -3: {-4: 0, -3: 0, -2: Z, -1: Z x Z x C2 x C2, 0: 0, 1: 0, 2: 0}, -1: {-4: 0, -3: 0, -2: 0, -1: Z x Z, 0: Z x Z x Z x C2 x C2, 1: 0, 2: 0, 3: 0, 4: 0}, 1: {-4: 0, -3: 0, -2: 0, -1: 0, 0: Z x Z x Z, 1: Z x Z x C2 x C2, 2: 0, 3: 0, 4: 0}, 3: {-2: 0, -1: 0, 0: 0, 1: Z x Z, 2: Z x C2 x C2, 3: 0, 4: 0}, 5: {0: 0, 1: 0, 2: Z x Z, 3: Z x C2, 4: 0}, 7: {2: 0, 3: Z, 4: C2}, 9: {4: Z}}
K2.khovanov_homology()
{-9: {-4: Z}, -7: {-4: 0, -3: Z x C2, -2: 0, -1: 0}, -5: {-4: 0, -3: Z, -2: Z x Z x C2, -1: 0, 0: 0, 1: 0}, -3: {-4: 0, -3: 0, -2: Z, -1: Z x Z x C2 x C2, 0: 0, 1: 0, 2: 0}, -1: {-4: 0, -3: 0, -2: 0, -1: Z x Z, 0: Z x Z x Z x C2 x C2, 1: 0, 2: 0, 3: 0, 4: 0}, 1: {-4: 0, -3: 0, -2: 0, -1: 0, 0: Z x Z x Z, 1: Z x Z x C2 x C2, 2: 0, 3: 0, 4: 0}, 3: {-2: 0, -1: 0, 0: 0, 1: Z x Z, 2: Z x C2 x C2, 3: 0, 4: 0}, 5: {-1: 0, 0: 0, 1: 0, 2: Z x Z, 3: Z x C2, 4: 0}, 7: {1: 0, 2: 0, 3: Z, 4: C2}, 9: {4: Z}}
K1.homfly_polynomial()
--------------------------------------------------------------------------- ImportError Traceback (most recent call last) <ipython-input-65-5d58394afbe7> in <module>() ----> 1 K1.homfly_polynomial() /projects/sage/sage-dev/local/lib/python2.7/site-packages/sage/knots/link.pyc in homfly_polynomial(self, var1, var2, normalization) 2330 for i, cr in enumerate(ogc[1]): 2331 s += ' {} {}'.format(i, cr) -> 2332 from sage.libs.homfly import homfly_polynomial_dict 2333 dic = homfly_polynomial_dict(s) 2334 if normalization == 'lm': ImportError: No module named homfly