Printable Manual

From Knot Atlas
Revision as of 14:48, 2 September 2005 by 24.112.3.40 (talk)
Jump to navigationJump to search


This manual describes the Mathematica package KnotTheory`, the main tool used to produce The Knot Atlas.

Return to the wiki manual.

Acknowledgement

This Atlas is partially (and indirectly) supported by NSERC grant RGPIN 262178. As a Wiki project, it doesn't make sense anymore to acknowledge individual contributors. Yet for historical purposes, here's our acknowledgement as of the conversion to Wiki formnat on August 2005:

Setup

Start by downloading the file KnotTheory.zip (around 15MB), and unpack it. This will create a subdirectory KnotTheory/ in your current working directory. This done, no installation is required (though you may wish to check out Further Data Files and/or Setting the Path below). Start Mathematica and you're ready to go:

In[2]:= << KnotTheory`

Loading KnotTheory` version of March 22, 2011, 21:10:4.67737. Read more at http://katlas.org/wiki/KnotTheory.

Notice the little "prime" at the end of KnotTheory above. It is a backquote (find it on the upper left side of most keyboards) and not a quote, and it really has to be there for things to work.

Let us check that everything is working well:

In[3]:= Alexander[Knot[6, 2]][t]
Out[3]= -2 3 2 -3 - t + - + 3 t - t t
In[4]:= ?KnotTheoryVersion
KnotTheoryVersion[] returns the date of the current version of the package KnotTheory`. KnotTheoryVersion[k] returns the kth field in KnotTheoryVersion[].
In[5]:= ?KnotTheoryVersionString
KnotTheoryVersionString[] returns a string containing the date and time of the current version of the package KnotTheory`. It is generated from KnotTheoryVersion[].
In[6]:= ?KnotTheoryWelcomeMessage
KnotTheoryWelcomeMessage[] returns a string containing the welcome message printed when KnotTheory` is first loaded.

Thus on the day this manual page was last changed, we had:

In[7]:= {KnotTheoryVersion[], KnotTheoryVersionString[]}
Out[7]= {{2011, 3, 22, 21, 10, 4.67737}, March 22, 2011, 21:10:4.67737}
In[8]:= KnotTheoryWelcomeMessage[]
Out[8]= Loading KnotTheory` version of March 22, 2011, 21:10:4.67737. Read more at http://katlas.org/wiki/KnotTheory.
In[9]:= ?KnotTheoryDirectory
KnotTheoryDirectory[] returns the best guess KnotTheory` has for its location on the host computer. It can be reset by the user.
In[10]:= KnotTheoryDirectory[]
Out[10]= C:\Documents and Settings\pc\Documenti\Wolfram\KnotTheory

KnotTheoryDirectory may not work under some operating systems/environments. Please let Dror know if you encounter any difficulties.

Notes

Precomputed Data

KnotTheory` comes with a certain amount of precomputed data which is loaded "on demand" just when it is needed. When a precomputed data file is read by KnotTheory`, a notification message is displayed. To prevent these messages from appearing execute the command Off[KnotTheory::loading].

Further Data Files

To access the Hoste-Thistlethwaite enumeration of knots with 12 to 16 crossings (see Naming and Enumeration), also download either the file DTCodes4Knots12To16.tar.gz or the file DTCodes4Knots12To16.zip (about 9MB each), and unpack either one into the directory KnotTheory/.

Setting the Path

The directions above are written on the assumption that the package KnotTheory` (more precisely, the directory KnotTheory/ containing the files that make this package), is somewhere on your Mathematica search path. Usually this will be the case if KnotTheory/ is a subdirectory of your current working directory. If for some reason Mathematica cannot find KnotTheory`, you may tell it where to look in either of the following three ways. Assume KnotTheory/ is a subdirectory of FullPathToKnotTheory:

  1. If you are using KnotTheory` rarely and you don't want to change system defaults, evaluate AppendTo[$Path,"FullPathToKnotTheory"] within Mathematica before attempting to load KnotTheory`.
  2. If you plan to use KnotTheory` often, you may want to move the directory KnotTheory/ into one of the directories on your path. Evaluate $Path within Mathematica to see what those are.
  3. Alternatively, you may permanently add FullPathToKnotTheory to your $Path. To do that, find your Mathematica base directory by evaluating $UserBaseDirectory (on Dror's laptop, this comes out to be C:\Users\Dror\AppData\Roaming\Mathematica), and then add the line AppendTo[$Path,"FullPathToKnotTheory/"] to the file $BaseDirectory/Kernel/init.m and restart Mathematica.

Naming and Enumeration

KnotTheory` comes loaded with some knot tables; currently, the Rolfsen table of prime knots with up to 10 crossings [Rolfsen], the Hoste-Thistlethwaite tables of prime knots with up to 16 crossings and the Thistlethwaite table of prime links with up to 11 crossings (see Knotscape):

(For In[1] see Setup)

In[2]:= ?Knot
Knot[n, k] denotes the kth knot with n crossings in the Rolfsen table. Knot[n, Alternating, k] (for n between 11 and 16) denotes the kth alternating n-crossing knot in the Hoste-Thistlethwaite table. Knot[n, NonAlternating, k] denotes the kth non alternating n-crossing knot in the Hoste-Thistlethwaite table.
In[3]:= ?Link
Link[n, Alternating, k] denotes the kth alternating n-crossing link in the Thistlethwaite table. Link[n, NonAlternating, k] denotes the kth non alternating n-crossing link in the Thistlethwaite table.
6 1.gif
6_1
9 46.gif
9_46

Thus, for example, let us verify that the knots 6_1 and 9_46 have the same Alexander polynomial:

In[4]:= Alexander[Knot[6, 1]][t]
Out[4]= 2 5 - - - 2 t t
In[5]:= Alexander[Knot[9, 46]][t]
Out[5]= 2 5 - - - 2 t t
L6a4.gif
L6a4

We can also check that the Borromean rings, L6a4 in the Thistlethwaite table, is a 3-component link:

In[6]:= Length[Skeleton[Link[6, Alternating, 4]]]
Out[6]= 3
In[7]:= ?AllKnots
AllKnots[] return a list of all knots with up to 11 crossings. AllKnots[n_] returns a list of all knots with n crossings, up to 16. AllKnots[{n_, m_}] returns a list of all knots with between n and m crossings, and AllKnots[n_, Alternating|NonAlternating] returns all knots with n crossings of the specified type.
In[8]:= ?AllLinks
AllLinks[] return a list of all links with up to 11 crossings. AllLinks[n_] returns a list of all links with n crossings, up to 12.

Thus at the moment there are 1701936 knots and 5700 links known to KnotTheory`:

In[9]:= Length /@ {AllKnots[{0,16}], AllLinks[{2,12}]}
Out[9]= {1701936, 5700}
In[10]:= Show[DrawPD[Knot[13, NonAlternating, 5016], {Gap -> 0.025}]]
Naming and Enumeration Out 10.gif
Out[10]= -Graphics-

(Shumakovitch had noticed that this nice knot has interesting Khovanov homology; see [Shumakovitch]).

T(5,3).jpg
T(5,3)

In addition to the tables, KnotTheory` also knows about torus knots:

In[11]:= ?TorusKnot
TorusKnot[m, n] represents the (m,n) torus knot.
In[12]:= ?TorusKnots
TorusKnots[n_] returns a list of all torus knots with up to n crossings.

For example, the torus knots T(5,3) and T(3,5) have different presentations with different numbers of crossings, but they are in fact isotopic, and hence they have the same invariants (and in particular the same type 3 Vassiliev invariant ):

In[13]:= Crossings /@ {TorusKnot[5, 3], TorusKnot[3, 5]}
Out[13]= {10, 12}
In[14]:= Vassiliev[3] /@ {TorusKnot[5, 3], TorusKnot[3, 5]}
Out[14]= {20, 20}

KnotTheory` knows how to plot torus knots; see Drawing with TubePlot.

You can also use the function Knot to parse certain string representations of named knots:

In[15]:= Knot /@ {"K11a14", "11a_14", "L8a1", "T(3,5)"}
Out[15]= {Knot[11, Alternating, 14], If[11 a <= 10 && 14 <= NumberOfKnots[11 a, Alternating] + NumberOfKnots[11 a, NonAlternating], Knot @@ KnotTheory`Naming`s$3008], Link[8, Alternating, 1], TorusKnot[3, 5]}

In the opposite direction, the function NameString produces the standard name for a knot, used throughout the Knot Atlas.

In[16]:= NameString /@ {Knot[11, Alternating, 14], TorusKnot[3,5]}
Out[16]= {K11a14, T(3,5)}

References

[Rolfsen] ^  D. Rolfsen, Knots and Links, Publish or Perish, Mathematics Lecture Series 7, Wilmington 1976.

[Shumakovitch] ^  A. Shumakovitch, Torsion of the Khovanov Homology, arXiv:math.GT/0405474.

Presentations

KnotTheory` uses several presentations for knots/links.

Planar Diagrams

The PD notation

In the "Planar Diagrams" (PD) presentation we present every knot or link diagram by labeling its edges (with natural numbers, 1,...,n, and with increasing labels as we go around each component) and by a list crossings presented as symbols where , , and are the labels of the edges around that crossing, starting from the incoming lower edge and proceeding counterclockwise. Thus for example, the PD presentation of the knot above is:

(This of course is the Miller Institute knot, the mirror image of the knot 6_2)

(For In[1] see Setup)

In[2]:= ?PD
PD[v1, v2, ...] represents a planar diagram whose vertices are v1, v2, .... PD also acts as a "type caster", so for example, PD[K] where K is a named knot (or link) returns the PD presentation of that knot.
In[3]:= PD::about
The GaussCode to PD conversion was written by Siddarth Sankaran at the University of Toronto in the summer of 2005.
In[4]:= ?X
X[i,j,k,l] represents a crossing between the edges labeled i, j, k and l starting from the incoming lower strand i and going counterclockwise through j, k and l. The (sometimes ambiguous) orientation of the upper strand is determined by the ordering of {j,l}.

Thus, for example, let us compute the determinant of the above knot:

In[5]:= K = PD[ X[1,9,2,8], X[3,10,4,11], X[5,3,6,2], X[7,1,8,12], X[9,4,10,5], X[11,7,12,6] ];
In[6]:= Alexander[K][-1]
Out[6]= -11

Some further details

In[7]:= ?Xp
Xp[i,j,k,l] represents a positive (right handed) crossing between the edges labeled i, j, k and l starting from the incoming lower strand i and going counter clockwise through j, k and l. The upper strand is therefore oriented from l to j regardless of the ordering of {j,l}. Presently Xp is only lightly supported.
In[8]:= ?Xm
Xm[i,j,k,l] represents a negative (left handed) crossing between the edges labeled i, j, k and l starting from the incoming lower strand i and going counter clockwise through j, k and l. The upper strand is therefore oriented from j to l regardless of the ordering of {j,l}. Presently Xm is only lightly supported.
In[9]:= ?P
P[i,j] represents a bivalent vertex whose adjacent edges are i and j (i.e., a "Point" between the segment i and the segment j). Presently P is only lightly supported.

For example, we could add an extra "point" on the Miller Institute knot, splitting edge 12 into two pieces, labeled 12 and 13:

In[10]:= K1 = PD[ X[1,9,2,8], X[3,10,4,11], X[5,3,6,2], X[7,1,8,13], X[9,4,10,5], X[11,7,12,6], P[12,13] ];

At the moment, many of our routines do not know to ignore such "extra points". But some do:

In[11]:= Jones[K][q] == Jones[K1][q]
Out[11]= True
In[12]:= ?Loop
Loop[i] represents a crossingsless loop labeled i.

Hence we can verify that the A2 invariant of the unknot is :

In[13]:= A2Invariant[Loop[1]][q]
Out[13]= -2 2 1 + q + q

Gauss Codes

The Gauss Code of an -crossing knot or link is obtained as follows:

  • Number the crossings of from 1 to in an arbitrary manner.
  • Order the components of is some arbitrary manner.
  • Start "walking" along the first component of , taking note of the numbers of the crossings you've gone through. If in a given crossing you cross on the "over" strand, write down the number of that crossing. If you cross on the "under" strand, write down the negative of the number of that crossing.
  • Do the same for all other components of (if any).

The resulting list of signed integers (in the case of a knot) or list of lists of signed integers (in the case of a link) is called the Gauss Code of . KnotTheory` has some rudimentary support for Gauss codes:

(For In[1] see Setup)

In[2]:= ?GaussCode
GaussCode[i1, i2, ...] represents a knot via its Gauss Code following the conventions used by the knotilus website, http://srankin.math.uwo.ca/cgi-bin/retrieve.cgi/html/start.html. Likewise GaussCode[l1, l2, ...] represents a link, where each of l1, l2,... is a list describing the code read along one component of the link. GaussCode also acts as a "type caster", so for example, GaussCode[K] where K is is a named knot (or link) returns the Gauss code of that knot.

Thus for example, the Gauss codes for the trefoil knot and the Borromean link are:

In[3]:= GaussCode /@ {Knot[3, 1], Link[6, Alternating, 4]}
Out[3]= {GaussCode[-1, 3, -2, 1, -3, 2], GaussCode[{1, -6, 5, -3}, {4, -1, 2, -5}, {6, -4, 3, -2}]}
3 1.gif
3_1
L6a4.gif
L6a4

Ralph Furmaniak, working under the guidance of Stuart Rankin and Ortho Flint at the University of Western Ontario, wrote a web-based server called "Knotilus" that takes Gauss codes and outputs pictures of the desired knots and links in several standard image formats.

In[4]:= ?KnotilusURL
KnotilusURL[K_] returns the URL of the knot/link K on the knotilus website, http://srankin.math.uwo.ca/cgi-bin/retrieve.cgi/html/start.html.

Thus,

In[5]:= KnotilusURL /@ {Knot[3, 1], Link[6, Alternating, 4]}
Out[5]= {http://srankin.math.uwo.ca/cgi-bin/retrieve.cgi/-1,3,-2,1,-3,2/goTop.h\ tml, http://srankin.math.uwo.ca/cgi-bin/retrieve.cgi/1,-6,5,-3:4,-1,\ 2,-5:6,-4,3,-2/goTop.html}

DT (Dowker-Thistlethwaite) Codes

Knots

The "DT Code" ("DT" after Clifford Hugh Dowker and Morwen Thistlethwaite) of a knot is obtained as follows:

  • Start "walking" along and count every crossing you pass through. If has crossings and given that every crossing is visited twice, the count ends at . Label each crossing with the values of the counter when it is visited, though when labeling by an even number, take it with a minus sign if you are walking "over" the crossing.
  • Every crossing is now labeled with two integers whose absolute values run from to . It is easy to see that each crossing is labeled with one odd integer and one even integer. The DT code of is the list of even integers paired with the odd integers 1, 3, 5, ..., taken in this order. Thus for example the pairing for the knot in the figure below is , and hence its DT code is (and as DT codes are insensitive to overall mirrors, this is equivalent to ).
The DT notation

KnotTheory` has some rudimentary support for DT codes:

(For In[1] see Setup)

In[2]:= ?DTCode
DTCode[i1, i2, ...] represents a knot via its DT (Dowker-Thistlethwaite) code, while DTCode[{i11,...}, {i21...}, ...] likewise represents a link. DTCode also acts as a "type caster", so for example, DTCode[K] where K is is a named knot or link returns the DT code of K.

Thus for example, the DT codes for the last 9 crossing alternating knot 9_41 and the first 9 crossing non alternating knot 9_42 are:

In[3]:= dts = DTCode /@ {Knot[9, 41], Knot[9, 42]}
Out[3]= {DTCode[6, 10, 14, 12, 16, 2, 18, 4, 8], DTCode[4, 8, 10, -14, 2, -16, -18, -6, -12]}

(The DT code of an alternating knot is always a sequence of positive numbers but the DT code of a non alternating knot contains both signs.)

9 41.gif
9_41
9 42.gif
9_42

DT codes and Gauss codes carry the same information and are easily convertible:

In[4]:= gcs = GaussCode /@ dts
Out[4]= {GaussCode[1, -6, 2, -8, 3, -1, 4, -9, 5, -2, 6, -4, 7, -3, 8, -5, 9, -7], GaussCode[1, -5, 2, -1, 3, 8, -4, -2, 5, -3, -6, 9, -7, 4, -8, 6, -9, 7]}
In[5]:= DTCode /@ gcs
Out[5]= {DTCode[6, 10, 14, 12, 16, 2, 18, 4, 8], DTCode[4, 8, 10, -14, 2, -16, -18, -6, -12]}

Conversion between DT codes and/or Gauss codes and PD codes is more complicated; the harder side, going from DT/Gauss to PD, was written by Siddarth Sankaran at the University of Toronto:

In[6]:= PD[DTCode[4, 6, 2]]
Out[6]= PD[X[4, 2, 5, 1], X[6, 4, 1, 3], X[2, 6, 3, 5]]

Links

A DT notation example, for the link L7n2

DT Codes for links are defined in a similar way (see [DollHoste]). Follow the same numbering process as for knots, except when you finish traversing one component, jump straight to the next. It is not difficult to see that there is always a choice of starting points along the components for which the resulting pairing is a pairing between odd and even numbers. (On the figure above one possible choice is indicated). Again, it is enough to only list the even numbers corresponding to ; call the resulting list . (Above, ). Notice that the odd indices are naturally subdivided into sublists according to the component of the link on which they lie, and this induces a subdivision of into sublists. Thus with the choices made in the figure above, the DT code for the link L7n2 is .

KnotTheory` knows about DT codes for links:

In[7]:= DTCode[Link[7, NonAlternating, 2]]
Out[7]= DTCode[{6, -8}, {-10, 12, -14, 2, -4}]
In[8]:= MultivariableAlexander[DTCode[{6, -8}, {-10, 12, -14, 2, -4}]][t]
Out[8]= (-1 + t[1]) (-1 + t[2]) ----------------------- Sqrt[t[1]] Sqrt[t[2]]

[DollHoste] ^  H. Doll and J. Hoste, A tabulation of oriented links, Mathematics of Computation 57-196 (1991) 747-761.

Braid Representatives

Every knot and every link is the closure of a braid. KnotTheory` can also represent knots and links as braid closures:

(For In[1] see Setup)

In[2]:= ?BR
BR stands for Braid Representative. BR[k, l] represents a braid on k strands with crossings l={i1, i2, ...}, where a positive index i within the list l indicates a right-handed crossing between strand number i and strand number i+1 and a negative i indicates a left handed crossing between strands numbers |i| and |i|+1. Each ij can also be a list of non-adjacent (i.e., commuting) indices. BR also acts as a "type caster": BR[K] will return a braid whose closure is K if K is given in any format that KnotTheory` understands. BR[K] where K is is a named knot with up to 10 crossings returns a minimum braid representative for that knot.
In[3]:= BR::about
The minimum braids representing the knots with up to 10 crossings were provided by Thomas Gittings. See his article on the subject at arXiv:math.GT/0401051. Vogel's algorithm was implemented by Dan Carney in the summer of 2005 at the University of Toronto.
In[4]:= ?Mirror
Mirror[br] return the mirror braid of br.

Thus for example,

In[5]:= br1 = BR[2, {-1, -1, -1}];


In[6]:= PD[br1]
Out[6]= PD[X[6, 3, 1, 4], X[4, 1, 5, 2], X[2, 5, 3, 6]]
In[7]:= Jones[br1][q]
Out[7]= -4 -3 1 -q + q + - q
In[8]:= Mirror[br1]
Out[8]= BR[2, {1, 1, 1}]
T(5,4).jpg
T(5,4)
K11a362.gif
K11a362

KnotTheory` has the braid representatives of some knots and links pre-loaded, and for all other knots and links it will find a braid representative using Vogel's algorithm. Thus for example,

In[9]:= BR[TorusKnot[5, 4]]
Out[9]= BR[4, {1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3}]
In[10]:= BR[Knot[11, Alternating, 362]]
Out[10]= BR[10, {1, 2, -3, -4, 5, 6, 5, 4, 3, -2, -1, -4, 3, -2, -4, 3, 5, 4, -6, 7, -6, 5, 8, 7, 6, 5, -4, -3, 2, 5, -6, 9, -8, 7, -6, 5, 4, -3, 5, 6, 5, 4, 5, -7, 8, -7, 6, 5, -9, -8, -7}]

(As we see, Vogel's algorithm sometimes produces scary results. A 51-crossings braid representative for an 11-crossing knot, in the case of K11a362).

10 1.gif
10_1
5 2.gif
5_2

The minimum braid representative of a given knot is a braid representative for that knot which has a minimal number of braid crossings and within those braid representatives with a minimal number of braid crossings, it has a minimal number of strands (full details are in [Gittings]). Thomas Gittings kindly provided us the minimum braid representatives for all knots with up to 10 crossings. Thus for example, the minimum braid representative for the knot 10_1 has length (number of crossings) 13 and width 6 (number of strands, also see Invariants from Braid Theory):

In[11]:= br2 = BR[Knot[10, 1]]
Out[11]= BR[6, {-1, -1, -2, 1, -2, -3, 2, -3, -4, 3, 5, -4, 5}]
In[12]:= Show[BraidPlot[CollapseBraid[br2]]]
Braid Representatives Out 12.gif
Out[12]= -Graphics-

Already for the knot 5_2 the minimum braid is shorter than the braid produced by Vogel's algorithm. Indeed, the minimum braid is

In[13]:= Show[BraidPlot[CollapseBraid[BR[Knot[5, 2]]]]]
Braid Representatives Out 13.gif
Out[13]= -Graphics-

To force KnotTheory` to run Vogel's algorithm on 5_2, we first convert it to its PD form,

In[14]:= pd = PD[Knot[5, 2]]
Out[14]= PD[X[1, 4, 2, 5], X[3, 8, 4, 9], X[5, 10, 6, 1], X[9, 6, 10, 7], X[7, 2, 8, 3]]

and only then run BR:

In[15]:= Show[BraidPlot[CollapseBraid[BR[pd]]]]
Braid Representatives Out 15.gif
Out[15]= -Graphics-

(Check Drawing Braids for information about the command BraidPlot and the related command CollapseBraid.)

[Gittings] ^  T. A. Gittings, Minimum braids: a complete invariant of knots and links, arXiv:math.GT/0401051.

MorseLink Presentations

The MorseLink presentation describes an oriented knot or link diagram as a sequence of 'events'. To begin, we fix an axis in the plane, so that each event in the MorseLink description occurs in successive intervals along this axis. The 'events' that comprise a knot or link are 'cups' (creations), 'caps' (annihilations), and crossings, where cups and caps are the minima and maxima (respectively) relative to the chosen axis. The conventions used by MorseLink are as follows:

  • Cup[m,n] represents a creation, where the new strands are in position m and n, with m and n differing by 1, and is directed from m to n.
  • Cap[m,n] represents an annihilation of the strands m and n, again with m and n differing by 1, and is directed from m to n.
  • X[n, d, a, b] is a crossing of the n-th and the (n+1)-th strands. 'd' signifies whether the n-th strand goes 'Over' or 'Under' the (n+1)-th strand. 'a' indicates whether the n-th strand is moving 'Up' or 'Down' through the crossing, relative to the chosen axis; 'b' does the same for the (n+1)-th strand.

For concreteness, let us find a MorseLink presentation of the knot 4_1, based on the following diagram:

A diagram of the knot 4_1

We fix the chosen axis to be the positive axis, and we number the strands at each interval from bottom to top. Clearly the first event to take place is a cup, creating strands 1 and 2, and directed from 1 to 2. The next event is also a cup; this time, the strands 3 and 4 are created, from 3 to 4. So the first two elements of our MorseLink presentation are {Cup[1,2], Cup[3,4], ...}.

A crossing event

The next event to take place is a crossing. This crossing has strand 2 going under strand 3; following the orientations, strand 2 moves to the right through the crossing, while strand 3 comes from the left. Since the chosen axis is pointing to the right, this event is described as X[2, Under, Up, Down]. We may proceed in a similar way for the rest of the crossings.


Two cap events

After three more crossings, we encounter two cap events. The first annihilates strands 2 and 3, and is directed from 2 to 3. The second annihilates strands 1 and 2, but is directed from 2 to 1. So the MorseLink presentation for the knot 4_1 is given by: MorseLink[Cup[1,2], Cup[3,4], X[2 , Under, Up, Down], X[2, Under, Down, Up], X[1, Over, Down, Up], X[1, Over, Up, Down], Cap[2,3], Cap[2,1]].

Further notes

KnotTheory` knows about Morse link presentations: (For In[1] see Setup)

In[2]:= ?MorseLink
MorseLink[K] returns a presentation of the oriented link K, composed, in successive order, of the following 'events': Cup[m,n] is a directed creation, starting at strand position n, towards position m, where m and n differ by 1. X[n,a = {Over/Under}, b = {Up/Down}, c={Up/Down}] is a crossing with lower-left edge at strand n, a determines whether the strand running bottom-left to top-right is over/under the crossing, b and c give the directions of the bottom-left and bottom-right strands respectively through the crossing. Cap[m,n] is a directed cap, from strand m to strand n.
In[3]:= MorseLink::about
MorseLink was added to KnotTheory` by Siddarth Sankaran at the University of Toronto in the summer of 2005.
  • Obviously, there is no unique Morse link presentation for a knot. One presentation may be considered 'better' than another if it generally has fewer strands. Unfortunately, this program makes only a half-hearted attempt in coming up with such presentations; it does a creation only when it can no longer do any caps or crossings, but exhibits a lack of foresight into which edges to create.

Graphical Output

KnotTheory` can draw knots and links in several ways.

Drawing Planar Diagrams

My summer student Emily Redelmeier is in the process of writing a program that uses circle packing to draw an arbitrary object given as a PD as in Planar Diagrams. At the moment her program is still slow, limited and sometimes buggy, but it is already quite useful, as the following lines show:

(For In[1] see Setup)

In[2]:= ?DrawPD
DrawPD[pd] takes the planar diagram description pd and creates a graphics object containing a picture of the knot. DrawPD[pd,options], where options is a list of rules, allows the user to control some of the parameters. OuterFace->n sets the face at infinity to the face numbered n. OuterFace->{e_1,e_2,...,e_n} sets the face at infinity to a face which has edges e_1, e_2, ..., e_n in the planar diagram description. Gap->g sets the size of the gap around a crossing to length g.
In[3]:= DrawPD::about
DrawPD was written by Emily Redelmeier at the University of Toronto in the summers of 2003 and 2004.

Thus, for example, here's the torus knot T(4,3):

In[4]:= Show[DrawPD[TorusKnot[4, 3]]]
Drawing Planar Diagrams Out 4.gif
Out[4]= -Graphics-

One problem we currently have is that crossings come out at non-uniform sizes, hence in the picture below you may need magnifying glasses to decide who's over and who's under:

In[5]:= MillettUnknot = PD[ X[1,10,2,11], X[9,2,10,3], X[3,7,4,6], X[15,5,16,4], X[5,17,6,16],X[7,14,8,15], X[8,18,9,17], X[11,18,12,19], X[19,12,20,13], X[13,20,14,1] ];
In[6]:= Show[DrawPD[MillettUnknot]]
Drawing Planar Diagrams Out 6.gif
Out[6]= -Graphics-

In such a situation, the option Gap is sometimes handy:

In[7]:= Show[DrawPD[MillettUnknot, {Gap -> 0.03}]]
Drawing Planar Diagrams Out 7.gif
Out[7]= -Graphics-

How does it work?

Circles.gif
CirclesAndKnot.gif

DrawPD uses Andreev's theorem [Andreev1], [Andreev2], which states that every planar graph can be realized, nearly uniquely, as the graph of tangencies of circles drawn within the unit disk. That is, to every vertex of one may associate a disk within the unit disk, so that the interiors of these disks are disjoint and they are tangent iff the corresponding vertices are connected by an edge. The Andreev "circle packing" corresponding to the knot 4_1 is the first picture on the right (circle 13 is the unit disk itself).

But now every ingredient of the original knot (every arc, crossing and face) has a disk in the plane in which it can be cleanly drawn and clashes are guaranteed not to occur. Furthermore, knowing the precise coordinates of all the tangency points allows us to represent each ingredient by some nice smooth arcs that meet smoothly. The result is the second picture on the right. Removing all the circles, what remains is the desired clean planar picture of 4_1.

[Andreev1] ^  A. Andreev, On convex polyhedra in Lobacevskii spaces (in Russian), Math. Sbornik USSR, Nov. Ser. 81 (1970) 445-478.

[Andreev2] ^  A. Andreev, On convex polyhedra of finite volume in Lobacevskii spaces (in Russian), Math. Sbornik USSR, Nov. Ser. 83 (1970) 256-260.

Drawing MorseLink Presentations

KnotTheory` can also draw knots and links via their Morse link presentations:

(For In[1] see Setup)

In[1]:= ?DrawMorseLink
DrawMorseLink[L] returns a drawing of the knot or link L as a "Morse Link". For diagrams with a large number of crossings, it may be helpful to use one or both of the options as in DrawMorseLink[L, Gap -> g, ArrowSize -> as ], with 0 < as, g < 1, where g controls the amount of white space at each crossing, and as controls the size of the orientation arrows.
In[2]:= DrawMorseLink::about
DrawMorseLink was written by Siddarth Sankaran at the University of Toronto in the summer of 2005.

For example, here is the 11-crossing alternating link L11a548:

In[4]:= Show[DrawMorseLink[Link[11, Alternating, 548]]]
Drawing MorseLink Presentations Out 3.gif
Out[4]= -Graphics-

There are two options available for this program. Adding the option Gap -> g, where g is between 0 and 1, changes the amount of white space in each crossing; increasing g increases the white space, making large diagrams more visible. The option ArrowSize -> as (where as is between 0 and 1) alters the size of the orientation arrows. Here is the same drawing as above, but this time the orientation arrows are gone and the crossings are more clear:

In[6]:= Show[DrawMorseLink[ Link[11, Alternating, 548], ArrowSize -> 0, Gap -> 0.65 ]]
Drawing MorseLink Presentations Out 5.gif
Out[6]= -Graphics-

Drawing Braids

(For In[1] see Setup)

In[2]:= ?BraidPlot
BraidPlot[br, opts] produces a plot of the braid br. Possible options are Mode, HTMLOpts, WikiOpts and Images.

Thus for example,

In[3]:= br = BR[5, {{1,3}, {-2,-4}, {1, 3}}];
In[4]:= Show[BraidPlot[br]]
Drawing Braids Out 4.gif
Out[4]= -Graphics-

BraidPlot takes several options:

In[5]:= Options[BraidPlot]
Out[5]= {Mode -> Graphics, Images -> {0.gif, 1.gif, 2.gif, 3.gif, 4.gif}, HTMLOpts -> , WikiOpts -> }

The Mode option to BraidPlot defaults to "Graphics", which produces output as above. An alternative is setting Mode -> "HTML", which produces an HTML <table> that can be readily inserted into HTML documents:

In[6]:= BraidPlot[br, Mode -> "HTML"]
Out[6]= <table cellspacing=0 cellpadding=0 border=0> <tr><td><img src=1.gif><img src=0.gif><img src=1.gif></td></tr> <tr><td><img src=2.gif><img src=3.gif><img src=2.gif></td></tr> <tr><td><img src=1.gif><img src=4.gif><img src=1.gif></td></tr> <tr><td><img src=2.gif><img src=3.gif><img src=2.gif></td></tr> <tr><td><img src=0.gif><img src=4.gif><img src=0.gif></td></tr> </table>

The table produced contains an array of image inclusions that together draws the braid using 5 fundamental building blocks: a horizontal "unbraided" line (0.gif above), the upper and lower halves of an overcrossing (1.gif and 2.gif above) and the upper and lower halves of an underfcrossing (3.gif and 4.gif above).

Assuming 0.gif through 4.gif are BraidPart0.gif, BraidPart1.gif, BraidPart2.gif, BraidPart3.gif and BraidPart4.gif, the above table is rendered as follows:

BraidPart1.gifBraidPart0.gifBraidPart1.gif
BraidPart2.gifBraidPart3.gifBraidPart2.gif
BraidPart1.gifBraidPart4.gifBraidPart1.gif
BraidPart2.gifBraidPart3.gifBraidPart2.gif
BraidPart0.gifBraidPart4.gifBraidPart0.gif

The meaning of the Images option to BraidPlot should be clear from reading its default definition:

In[7]:= Images /. Options[BraidPlot]
Out[7]= {0.gif, 1.gif, 2.gif, 3.gif, 4.gif}

The HTMLOpts option to BraidPlot allows to insert options within the HTML <img> tags. Thus

In[8]:= BraidPlot[BR[2, {1, 1}], Mode -> "HTML", HTMLOpts -> "border=1"]
Out[8]= <table cellspacing=0 cellpadding=0 border=0> <tr><td><img border=1 src=1.gif><img border=1 src=1.gif></td></tr> <tr><td><img border=1 src=2.gif><img border=1 src=2.gif></td></tr> </table>

The above table is rendered as follows:

BraidPlotHTMLExample2.gif


In[9]:= ?CollapseBraid
CollapseBraid[br] groups together commuting generators in the braid br. Useful in conjunction with BraidPlot to produce compact braid plots.

Thus compare the plots of br1 and br2 below:

In[10]:= br1 = BR[TorusKnot[5, 4]]
Out[10]= BR[4, {1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3}]
In[11]:= Show[BraidPlot[br1]]
Drawing Braids Out 11.gif
Out[11]= -Graphics-
In[12]:= br2 = CollapseBraid[BR[TorusKnot[5, 4]]]
Out[12]= BR[4, {{1}, {2}, {3, 1}, {2}, {3, 1}, {2}, {3, 1}, {2}, {3, 1}, {2}, {3}}]
In[13]:= Show[BraidPlot[br2]]
Drawing Braids Out 13.gif
Out[13]= -Graphics-

Structure and Operations

(For In[1] see Setup)

In[2]:= ?Crossings
Crossings[L] returns the number of crossings of a knot/link L (in its given presentation).
In[3]:= ?PositiveCrossings
PositiveCrossings[L] returns the number of positive (right handed) crossings in a knot/link L (in its given presentation).
In[4]:= ?NegativeCrossings
NegativeCrossings[L] returns the number of negative (left handed) crossings in a knot/link L (in its given presentation).

Thus here's one tautology and one easy example:

In[5]:= Crossings /@ {Knot[0, 1], TorusKnot[11,10]}
Out[5]= {0, 99}

And another easy example:

In[6]:= K=Knot[6, 2]; {PositiveCrossings[K], NegativeCrossings[K]}
Out[6]= {2, 4}
In[7]:= ?PositiveQ
PositiveQ[xing] returns True if xing is a positive (right handed) crossing and False if it is negative (left handed).
In[8]:= ?NegativeQ
NegativeQ[xing] returns True if xing is a negative (left handed) crossing and False if it is positive (right handed).

For example,

In[9]:= PositiveQ /@ {X[1,3,2,4], X[1,4,2,3], Xp[1,3,2,4], Xp[1,4,2,3]}
Out[9]= {False, True, True, True}
In[10]:= ?ConnectedSum
ConnectedSum[K1, K2] represents the connected sum of the knots K1 and K2 (ConnectedSum may not work with links).

The connected sum of the knot 4_1 with itself has 8 crossings (unsurprisingly):

In[11]:= K = ConnectedSum[Knot[4,1], Knot[4,1]]
Out[11]= ConnectedSum[Knot[4, 1], Knot[4, 1]]
In[12]:= Crossings[K]
Out[12]= 8

It is also nice to know that, as expected, the Jones polynomial of is the square of the Jones polynomial of 4_1:

In[13]:= Jones[K][q] == Expand[Jones[Knot[4,1]][q]^2]
Out[13]= True
4 1.gif
4_1
8 9.gif
8_9

It is less nice to know that the Jones polynomial cannot tell apart from the knot 8_9:

In[14]:= Jones[K][q] == Jones[Knot[8,9]][q]
Out[14]= True

But isn't equivalent to 8_9; indeed, their Alexander polynomials are different:

In[15]:= {Alexander[K][t], Alexander[Knot[8,9]][t]}
Out[15]= -2 6 2 -3 3 5 2 3 {11 + t - - - 6 t + t , 7 - t + -- - - - 5 t + 3 t - t } t 2 t t

Invariants

Invariants from Braid Theory

The braid length of a knot or a link is the smallest number of crossings in a braid whose closure is . KnotTheory` has some braid lengths preloaded:

(For In[1] see Setup)

In[2]:= ?BraidLength
BraidLength[K] returns the braid length of the knot K, if known to KnotTheory`.

Note that the braid length of is simply the length of the minimum braid representing (see Braid Representatives):

In[3]:= K = Knot[9, 49]; {BraidLength[K], Crossings[BR[K]]}
Out[3]= {11, 11}
9 49.gif
9_49
10 136.gif
10_136

The braid index of a knot or a link is the smallest number of strands in a braid whose closure is . KnotTheory` has some braid indices preloaded:

In[4]:= ?BraidIndex
BraidIndex[K] returns the braid index of the knot K, if known to KnotTheory`.
In[5]:= BraidIndex::about
The braid index data known to KnotTheory` is taken from Charles Livingston's "Table of Knot Invariants", http://www.indiana.edu/~knotinfo/.

Of the 250 knots with up to 10 crossings, only 10_136 has braid index smaller than the width of its minimum braid:

In[6]:= K = Knot[10, 136]; {BraidIndex[K], First@BR[K]}
Out[6]= {4, 5}
In[7]:= Show[BraidPlot[BR[K]]]
Invariants from Braid Theory Out 7.gif
Out[7]= -Graphics-

Three Dimensional Invariants

(For In[1] see Setup)

Symmetry Type

In[2]:= ?SymmetryType
SymmetryType[K] returns the symmetry type of the knot K, if known to KnotTheory`. The possible types are: Reversible, FullyAmphicheiral, NegativeAmphicheiral and Chiral.
In[3]:= SymmetryType::about
The symmetry type data known to KnotTheory` is taken from Charles Livingston's "Table of Knot Invariants", http://www.indiana.edu/~knotinfo/.

The inverse of a knot is the knot obtained from it by reversing its parametrization. The mirror of A knot is obtained from by reversing the orientation of the ambient space, or, alternatively, by flipping all the crossings of .

A knot is called "fully amphicheiral" if it is equal to its inverse and also to its mirror. The first knot with this property is

In[4]:= Select[AllKnots[], (SymmetryType[#] == FullyAmphicheiral) &, 1]
Out[4]= {Knot[4, 1]}

A knot is called "reversible" if it is equal to its inverse yet it different from its mirror (and hence also from the inverse of its mirror). Many knots have this property; indeed, the first one is:

In[5]:= Select[AllKnots[], (SymmetryType[#] == Reversible) &, 1]
Out[5]= {Knot[3, 1]}

A knot is called "positive amphicheiral" if it is different from its inverse but equal to its mirror. There are no such knots with up to 11 crossings.

A knot is called "negative amphicheiral" if it is different from its inverse and its mirror, yet it is equal to the inverse of its mirror. The first knot with this property is

In[6]:= Select[AllKnots[], (SymmetryType[#] == NegativeAmphicheiral) &, 1]
Out[6]= {Knot[8, 17]}

Finally, if a knot is different from its inverse, its mirror and from the inverse of its mirror, it is "chiral". The first such knot is

In[7]:= Select[AllKnots[], (SymmetryType[#] == Chiral) &, 1]
Out[7]= {Knot[9, 32]}

It is a amusing to take "symmetry type" statistics on all the prime knots with up to 11 crossings:

In[8]:= Plus @@ (SymmetryType /@ Rest[AllKnots[]])
Out[8]= 216 Chiral + 13 FullyAmphicheiral + 7 NegativeAmphicheiral + 565 Reversible
4 1.gif
4_1
3 1.gif
3_1
8 17.gif
8_17
9 32.gif
9_32

Unknotting Number

The unknotting number of a knot is the minimal number of crossing changes needed in order to unknot .

In[9]:= ?UnknottingNumber
UnknottingNumber[K] returns the unknotting number of the knot K, if known to KnotTheory`. If only a range of possible values is known, a list of the form {min, max} is returned.
In[10]:= UnknottingNumber::about
The unknotting numbers of torus knots are due to ???. All other unknotting numbers known to KnotTheory` are taken from Charles Livingston's "Table of Knot Invariants", http://www.indiana.edu/~knotinfo/.


Of the 512 knots whose unknotting number is known to KnotTheory`, 197 have unknotting number 1, 247 have unknotting number 2, 54 have unknotting number 3, 12 have unknotting number 4 and 1 has unknotting number 5:

In[11]:= Plus @@ u /@ Cases[UnknottingNumber /@ AllKnots[], _Integer]
Out[11]= u[0] + 197 u[1] + 247 u[2] + 54 u[3] + 12 u[4] + u[5]

There are 4 knots with up to 9 crossings whose unknotting number is unknown:

In[12]:= Select[AllKnots[], Crossings[#] <= 9 && Head[UnknottingNumber[#]] === List & ]
Out[12]= {Knot[9, 10], Knot[9, 13], Knot[9, 35], Knot[9, 38]}
9 10.gif
9_10
9 13.gif
9_13
9 35.gif
9_35
9 38.gif
9_38

3-Genus

A Seifert surface for a knot is a compact oriented surface with boundary . Seifert surfaces exist, but are not unique. The SeifertView programme is a visual implementation of the algorithm of Seifert (1934) for the construction of a Seifert surface from a knot projection. The 3-genus of a knot is the minimal genus of a Seifert surface for that knot.


In[13]:= ?ThreeGenus
ThreeGenus[K] returns the 3-genus of the knot K or a list of the form {lower bound, upper bound}.
In[14]:= ThreeGenus::about
The 3-genus program was written by Jake Rasmussen of Princeton University. The program tries to compute the highest nonvanishing group in the knot Floer homology, using Ozsvath and Szabo's version of the Kauffman state model.

The highest 3-genus of the knots known to KnotTheory` is , and there is only one knot with up to 11 crossings whose 3-genus is 5:

In[15]:= Max[ThreeGenus /@ AllKnots[]]
Out[15]= 5
In[16]:= Select[AllKnots[], ThreeGenus[#] == 5 &]
Out[16]= {Knot[11, Alternating, 367]}
K11a367.gif
K11a367
T(11,2).jpg
T(11,2)

(K11a367 is, of couse, also known as the torus knot T(11,2)).

The Conway knot K11n34 is the closure of the braid BR[4, {1, 1, 2, -3, 2, 1, -3, -2, -2, -3, -3}]. Let us compute its 3-genus and compare it with the 3-genus of its mutant companion, the Kinoshita-Terasaka knot K11n42:

In[17]:= ThreeGenus[BR[4, {1, 1, 2, -3, 2, 1, -3, -2, -2, -3, -3}]]
Out[17]= 3
In[18]:= ThreeGenus[Knot[11, NonAlternating, 42]]
Out[18]= 2
K11n34.gif
K11n34
K11n42.gif
K11n42

Bridge Index

The bridge index' of a knot is the minimal number of local maxima (or local minima) in a generic smooth embedding of in .

In[19]:= ?BridgeIndex
BridgeIndex[K] returns the bridge index of the knot K, if known to KnotTheory`.
In[20]:= BridgeIndex::about
The bridge index data known to KnotTheory` is taken from Charles Livingston's "Table of Knot Invariants", http://www.indiana.edu/~knotinfo/.

An often studied class of knots is the class of 2-bridge knots, knots whose bridge index is 2. Of the 49 prime 9-crossings knots, 24 are 2-bridge:

In[21]:= Select[AllKnots[], Crossings[#] == 9 && BridgeIndex[#] == 2 &]
Out[21]= {Knot[9, 1], Knot[9, 2], Knot[9, 3], Knot[9, 4], Knot[9, 5], Knot[9, 6], Knot[9, 7], Knot[9, 8], Knot[9, 9], Knot[9, 10], Knot[9, 11], Knot[9, 12], Knot[9, 13], Knot[9, 14], Knot[9, 15], Knot[9, 17], Knot[9, 18], Knot[9, 19], Knot[9, 20], Knot[9, 21], Knot[9, 23], Knot[9, 26], Knot[9, 27], Knot[9, 31]}

Super Bridge Index

The super bridge index of a knot is the minimal number, in a generic smooth embedding of in , of the maximal number of local maxima (or local minima) in a rigid rotation of that projection.

In[22]:= ?SuperBridgeIndex
SuperBridgeIndex[K] returns the super bridge index of the knot K, if known to KnotTheory`. If only a range of possible values is known, a list of the form {min, max} is returned.
In[23]:= SuperBridgeIndex::about
The super bridge index data known to KnotTheory` is taken from Charles Livingston's "Table of Knot Invariants", http://www.indiana.edu/~knotinfo/.

Nakanishi Index

In[24]:= ?NakanishiIndex
NakanishiIndex[K] returns the Nakanishi index of the knot K, if known to KnotTheory`.
In[25]:= NakanishiIndex::about
The Nakanishi index data known to KnotTheory` is taken from Charles Livingston's "Table of Knot Invariants", http://www.indiana.edu/~knotinfo/.

Synthesis

In[26]:= Profile[K_] := Profile[ SymmetryType[K], UnknottingNumber[K], ThreeGenus[K], BridgeIndex[K], SuperBridgeIndex[K], NakanishiIndex[K] ]
In[27]:= Profile[Knot[9,24]]
Out[27]= Profile[Reversible, 1, 3, 3, {4, 6}, 1]
In[28]:= Ks = Select[AllKnots[], (Crossings[#] == 9 && Profile[#]==Profile[Knot[9,24]])&]
Out[28]= {Knot[9, 24], Knot[9, 28], Knot[9, 30], Knot[9, 34]}
9 24.gif
9_24
9 28.gif
9_28
9 30.gif
9_30
9 34.gif
9_34
In[29]:= Alexander[#][t]& /@ Ks
Out[29]= -3 5 10 2 3 {13 - t + -- - -- - 10 t + 5 t - t , 2 t t -3 5 12 2 3 -15 + t - -- + -- + 12 t - 5 t + t , 2 t t -3 5 12 2 3 17 - t + -- - -- - 12 t + 5 t - t , 2 t t -3 6 16 2 3 23 - t + -- - -- - 16 t + 6 t - t } 2 t t

The Alexander-Conway Polynomial

(For In[1] see Setup)

In[2]:= ?Alexander
Alexander[K][t] computes the Alexander polynomial of a knot K as a function of the variable t. Alexander[K, r][t] computes a basis of the r'th Alexander ideal of K in Z[t].
In[3]:= Alexander::about
The program Alexander[K, r] to compute Alexander ideals was written by Jana Archibald at the University of Toronto in the summer of 2005.
In[4]:= ?Conway
Conway[K][z] computes the Conway polynomial of a knot K as a function of the variable z.
8 18.gif
8_18

The Alexander polynomial and the Conway polynomial of a knot always satisfy . Let us verify this relation for the knot 8_18:

In[5]:= alex = Alexander[Knot[8, 18]][t]
Out[5]= -3 5 10 2 3 13 - t + -- - -- - 10 t + 5 t - t 2 t t
In[6]:= Expand[Conway[Knot[8, 18]][Sqrt[t] - 1/Sqrt[t]]]
Out[6]= -3 5 10 2 3 13 - t + -- - -- - 10 t + 5 t - t 2 t t

The determinant of a knot is . Hence for 8_18 it is

In[7]:= Abs[alex /. t -> -1]
Out[7]= 45

Alternatively (see The Determinant and the Signature):

In[8]:= KnotDet[Knot[8, 18]]
Out[8]= 45

, the (standardly normalized) type 2 Vassiliev invariant of a knot is the coefficient of in its Conway polynomial:

In[9]:= Coefficient[Conway[Knot[8, 18]][z], z^2]
Out[9]= 1

Alternatively (see Finite Type (Vassiliev) Invariants),

In[10]:= Vassiliev[2][Knot[8, 18]]
Out[10]= 1
K11a99.gif
K11a99
K11a277.gif
K11a277

Sometimes two knots have the same Alexander polynomial but different Alexander ideals. An example is the pair K11a99 and K11a277. They have the same Alexander polynomial, but the second Alexander ideal of the first knot is the whole ring while the second Alexander ideal of the second knot is the smaller ideal generated by and by :

In[11]:= {K1, K2} = {Knot[11, Alternating, 99], Knot[11, Alternating, 277]};
In[12]:= Alexander[K1] == Alexander[K2]
Out[12]= True
In[13]:= Alexander[K1, 2][t]
Out[13]= {1}
In[14]:= Alexander[K2, 2][t]
Out[14]= {3, 1 + t}

Finally, the Alexander polynomial attains 551 values on the 802 knots known to KnotTheory`:

In[15]:= Length /@ {Union[Alexander[#]& /@ AllKnots[]], AllKnots[]}
Out[15]= {551, 802}

The Determinant and the Signature

(For In[1] see Setup)

In[2]:= ?KnotDet
KnotDet[K] returns the determinant of a knot K.
In[3]:= ?KnotSignature
KnotSignature[K] returns the signature of a knot K.

Thus, for example, the knots 5_1 and 10_132 have the same determinant (and even the same Alexander and Jones polynomials), but different signatures:

5 1.gif
5_1
10 132.gif
10_132
In[4]:= KnotDet /@ {Knot[5, 1], Knot[10, 132]}
Out[4]= {5, 5}
In[5]:= { Equal @@ (Jones[#][q]& /@ {Knot[5, 1], Knot[10, 132]}), Equal @@ (Alexander[#][t]& /@ {Knot[5, 1], Knot[10, 132]}) }
Out[5]= {True, True}
In[6]:= KnotSignature /@ {Knot[5, 1], Knot[10, 132]}
Out[6]= {-4, 0}

In August 2005 somebody emailed Dror a question about knot colouring, which amounted to "find the first knot (other than the unknot) whose determinant is ". So on September 2nd Dror typed

In[7]:= Select[AllKnots[], Abs[KnotDet[#]] == 1 &]
Out[7]= {Knot[0, 1], Knot[10, 124], Knot[10, 153], Knot[11, NonAlternating, 34], Knot[11, NonAlternating, 42], Knot[11, NonAlternating, 49], Knot[11, NonAlternating, 116]}

Hence the first few knots that are not -colourable for any are 10_124, 10_153, K11n34, K11n42, K11n49 and K11n116.

K11n116.gif
K11n116

The Jones Polynomial

(For In[1] see Setup)

In[2]:= ?Jones
Jones[L][q] computes the Jones polynomial of a knot or link L as a function of the variable q.

In Naming and Enumeration we checked that the knots 6_1 and 9_46 have the same Alexander polynomial. Their Jones polynomials are different, though:

In[3]:= Jones[Knot[6, 1]][q]
Out[3]= -4 -3 -2 2 2 2 + q - q + q - - - q + q q
In[4]:= Jones[Knot[9, 46]][q]
Out[4]= -6 -5 -4 2 -2 1 2 + q - q + q - -- + q - - 3 q q
L8a6.gif
L8a6

On links with an even number of components the Jones polynomial is a function of , and hence it is often more convenient to view it as a function of , where :

In[5]:= Jones[Link[8, Alternating, 6]][q]
Out[5]= -(9/2) -(7/2) 3 3 4 3/2 -q + q - ---- + ---- - ------- + 3 Sqrt[q] - 2 q + 5/2 3/2 Sqrt[q] q q 5/2 7/2 2 q - q
In[6]:= PowerExpand[Jones[Link[8, Alternating, 6]][t^2]]
Out[6]= -9 -7 3 3 4 3 5 7 -t + t - -- + -- - - + 3 t - 2 t + 2 t - t 5 3 t t t

The Jones polynomial attains 2110 values on the 2226 knots and links known to KnotTheory`:

In[7]:= all = Join[AllKnots[], AllLinks[]];
In[8]:= Length /@ {Union[Jones[#][q]& /@ all], all}
Out[8]= {2110, 2226}

How is the Jones polynomial computed?

(See also: The Kauffman Bracket using Haskell)

The Jones polynomial is so simple to compute using Mathematica that it's worthwhile pause and see how this is done, even for readers with limited prior programming experience. First, recall (say from [Kauffman]) the definition of the Jones polynomial using the Kauffman bracket :

[KBDef]
Failed to parse (SVG (MathML can be enabled via browser plugin): Invalid response ("Math extension cannot connect to Restbase.") from server "https://wikimedia.org/api/rest_v1/":): {\displaystyle \langle\emptyset\rangle=1; \qquad \langle\bigcirc L\rangle = (-A^2-B^2)\langle L\rangle; \qquad \langle\slashoverback\rangle = A\langle\hsmoothing\rangle + B\langle\smoothing\rangle; }

here is a commutative variable, , and is the writhe of , the difference where and count the positive Failed to parse (unknown function "\overcrossing"): {\displaystyle (\overcrossing)} and negative Failed to parse (SVG (MathML can be enabled via browser plugin): Invalid response ("Math extension cannot connect to Restbase.") from server "https://wikimedia.org/api/rest_v1/":): {\displaystyle (\undercrossing)} crossings of respectively.

PD[X[1,4,2,5], X[3,6,4,1], X[5,2,6,3]] and P[1,4] P[1,5] P[2,4] P[2,6] P[3,5] P[3,6]

Just for concreteness, let us start by fixing to be the trefoil knot shown above:

In[9]:= L = PD[Knot[3, 1]]
Out[9]= PD[X[1, 4, 2, 5], X[3, 6, 4, 1], X[5, 2, 6, 3]]

Our first task is to perform the replacement Failed to parse (unknown function "\slashoverback"): {\displaystyle \langle\slashoverback\rangle\to A\langle\hsmoothing\rangle + B\langle\smoothing\rangle} on all crossings of . By our conventions (see Planar Diagrams) the edges around a crossing are labeled , , and : Failed to parse (unknown function "\slashoverback"): {\displaystyle {}^c_d\slashoverback{}_a^b} . Labeling the smoothings Failed to parse (unknown function "\hsmoothing"): {\displaystyle (\hsmoothing, \ \smoothing)} in the same way, Failed to parse (unknown function "\hsmoothing"): {\displaystyle {}^c_d\hsmoothing{}_a^b} and Failed to parse (SVG (MathML can be enabled via browser plugin): Invalid response ("Math extension cannot connect to Restbase.") from server "https://wikimedia.org/api/rest_v1/":): {\displaystyle {}^c_d\smoothing{}_a^b} , we are lead to the symbolic replacement rule . Let us apply this rule to , switch to a multiplicative notation and expand:

In[10]:= t1 = L /. X[a_,b_,c_,d_] :> A P[a,d] P[b,c] + B P[a,b] P[c,d]
Out[10]= PD[A P[1, 5] P[2, 4] + B P[1, 4] P[2, 5], B P[1, 4] P[3, 6] + A P[1, 3] P[4, 6], A P[2, 6] P[3, 5] + B P[2, 5] P[3, 6]]
In[11]:= t2 = Expand[Times @@ t1]
Out[11]= 2 A B P[1, 4] P[1, 5] P[2, 4] P[2, 6] P[3, 5] P[3, 6] + 2 2 A B P[1, 4] P[2, 5] P[2, 6] P[3, 5] P[3, 6] + 2 2 A B P[1, 4] P[1, 5] P[2, 4] P[2, 5] P[3, 6] + 3 2 2 2 B P[1, 4] P[2, 5] P[3, 6] + 3 A P[1, 3] P[1, 5] P[2, 4] P[2, 6] P[3, 5] P[4, 6] + 2 A B P[1, 3] P[1, 4] P[2, 5] P[2, 6] P[3, 5] P[4, 6] + 2 A B P[1, 3] P[1, 5] P[2, 4] P[2, 5] P[3, 6] P[4, 6] + 2 2 A B P[1, 3] P[1, 4] P[2, 5] P[3, 6] P[4, 6]

In the above expression the product P[1,4] P[1,5] P[2,4] P[2,6] P[3,5] P[3,6] represents a path in which 1 is connected to 4, 1 is connected to 5, 2 is connected to 4, etc. (see the right half of the figure above). We simplify such paths by repeatedly applying the rules and :

In[12]:= t3 = t2 //. {P[a_,b_]P[b_,c_] :> P[a,c], P[a_,b_]^2 :> P[a,a]}
Out[12]= 3 2 B P[1, 1] P[2, 2] P[3, 3] + A B P[2, 2] P[4, 4] + 3 2 2 A P[3, 3] P[4, 4] + A B P[3, 3] P[4, 4] + 3 A B P[5, 5] + 2 A B P[1, 1] P[5, 5]

To complete the computation of the Kauffman bracket, all that remains is to replace closed cycles (paths of the form by , to replace by , and to simplify:

In[13]:= t4 = Expand[t3 /. P[a_,a_] -> -A^2-B^2 /. B -> 1/A]
Out[13]= -9 1 3 7 -A + - + A + A A

We could have, of course, combined the above four lines to a single very short program, that compues the Kauffman bracket from the beginning to the end:

In[14]:= KB0[pd_] := Expand[ Expand[Times @@ pd /. X[a_,b_,c_,d_] :> A P[a,d] P[b,c] + 1/A P[a,b] P[c,d]] //. {P[a_,b_]P[b_,c_] :> P[a,c], P[a_,b_]^2 :> P[a,a], P[a_,a_] -> -A^2-1/A^2}]
In[15]:= t4 = KB0[PD[Knot[3, 1]]]
Out[15]= -9 1 3 7 -A + - + A + A A

We will skip the uninteresting code for the computation of the writhe here; it is a linear time computation, and if that's all we ever wanted to compute, we wouldn't have bothered to purchase a computer. For our the result is , and hence the Jones polynomial of is given by

In[16]:= (-A^3)^(-3) * t4 / (-A^2-1/A^2) /. A -> q^(1/4) // Simplify // Expand
Out[16]= -4 -3 1 -q + q + - q
L11a548.gif
L11a548

At merely 3 lines of code, our program is surely nice and elegant. But it is very slow:

In[17]:= time0 = Timing[KB0[PD[Link[11, Alternating, 548]]]]
Out[17]= -23 5 10 -3 5 13 17 21 25 {1., A + --- + -- + A + 6 A + 6 A + 5 A - 5 A + 4 A - A } 15 7 A A

Here's the much faster alternative employed by KnotTheory`:

In[18]:= KB1[pd_PD] := KB1[pd, {}, 1]; KB1[pd_PD, inside_, web_] := Module[ {pos = First[Ordering[Length[Complement[List @@ #, inside]]& /@ pd]]}, pd[[pos]] /. X[a_,b_,c_,d_] :> KB1[ Delete[pd, pos], Union[inside, {a,b,c,d}], Expand[web*(A P[a,d] P[b,c]+1/A P[a,b] P[c,d])] //. { P[e_,f_]P[f_,g_] :> P[e,g], P[e_,_]^2 :> P[e,e], P[e_,e_] -> -A^2-1/A^2 } ] ]; KB1[PD[],_,web_] := Expand[web]
In[19]:= time1 = Timing[KB1[PD[Link[11, Alternating, 548]]]]
Out[19]= -23 5 10 -3 5 13 17 21 {0.015, A + --- + -- + A + 6 A + 6 A + 5 A - 5 A + 4 A - 15 7 A A 25 A }

(So on L11a548 KB1 is -23 5 10 -3 5 13 17 21 25 {1., A + --- + -- + A + 6 A + 6 A + 5 A - 5 A + 4 A - A }1,1

            15    7
           A     A/         -23    5    10    -3            5      13      17      21    25

{0.015, A + --- + -- + A + 6 A + 6 A + 5 A - 5 A + 4 A - A }1,1

               15    7
              A     A ~              -23    5    10    -3            5      13      17      21    25
      {1., A    + --- + -- + A   + 6 A + 6 A  + 5 A   - 5 A   + 4 A   - A  }1,1
                   15    7
                  A     A

Round[--------------------------------------------------------------------------------]

              -23    5    10    -3            5      13      17      21    25
     {0.015, A    + --- + -- + A   + 6 A + 6 A  + 5 A   - 5 A   + 4 A   - A  }1,1
                     15    7
                    A     A times faster than KB0.)

The idea here is to maintain a "computation front", a planar domain which starts empty and gradualy increases until the whole link diagram is enclosed. Within the front, the rules defining the Kauffman bracket, Equation [KBDef], are applied and the result is expanded as much as possible. Outside of the front the link diagram remains untouched. At every step we choose a crossing outside the front with the most legs inside and "conquer" it -- apply the rules of [KBDef] and expand again. As our new outpost is maximally connected to our old territory, the length of the boundary is increased in a minimal way, and hence the size of the "web" within our front remains as small as possible and thus quick to manipulate.

In further detail, the routine KB1[pd, inside, web] computes the Kauffman bracket assuming the labels of the edges inside the front are in the variable inside, the already-computed inside of the front is in the variable web and the part of the link diagram yet untouched is pd. The single argument KB1[pd] simply calls KB1[pd, inside, web] with an empty inside and with web set to 1. The three argument KB1[pd, inside, web] finds the position of the crossing maximmally connected to the front using the somewhat cryptic assignment

pos = First[Ordering[Length[Complement[List @@ #, inside]]& /@ pd]]}

KB1[pd, inside, web] then recursively calls itself with that crossing removed from pd}, with its legs added to the inside, and with web updated in accordance with [KBDef]. Finally, when pd is empty, the output is simply the value of web.

[Kauffman] ^  L. H. Kauffman, On knots, Princeton Univ. Press, Princeton, 1987.

The Coloured Jones Polynomials

KnotTheory` can compute the coloured Jones polynomial of knots and links, using the formulas in [Garoufalidis Le]:

(For In[1] see Setup)

In[2]:= ?ColouredJones
ColouredJones[K, n][q] returns the coloured Jones polynomial of a knot in colour n (i.e., in the (n+1)-dimensional representation) in the indeterminate q. Some of these polynomials have been precomputed in KnotTheory`. To force computation, use ColouredJones[K,n, Program -> "prog"][q], with "prog" replaced by one of the two available programs, "REngine" or "Braid" (including the quotes). "REngine" (default) computes the invariant for closed knots (as well as links where all components are coloured by the same integer) directly from the MorseLink presentation of the knot, while "Braid" computes the invariant via a presentation of the knot as a braid closure. "REngine" will usually be faster, but it might be better to use "Braid" when (roughly): 1) a "good" braid representative is available for the knot, and 2) the length of this braid is less than the maximum width of the MorseLink presentation of the knot.
In[3]:= ColouredJones::about
The "REngine" algorithm was written by Siddarth Sankaran in the summer of 2005, while the "Braid" algorithm was written jointly by Dror Bar-Natan and Stavros Garoufalidis. Both are based on formulas by Thang Le and Stavros Garoufalidis; see [Garoufalidis, S. and Le, T. "The coloured Jones function is q-holonomic." Geom. Top., v9, 2005 (1253-1293)].

Thus, for example, here's the coloured Jones polynomial of the knot 4_1 in the 4-dimensional representation of :

In[4]:= ColouredJones[Knot[4, 1], 3][q]
Out[4]= -12 -11 -10 2 2 3 3 2 4 6 3 + q - q - q + -- - -- + -- - -- - 3 q + 3 q - 2 q + 8 6 4 2 q q q q 8 10 11 12 2 q - q - q + q

And here's the coloured Jones polynomial of the same knot in the two dimensional representation of ; this better be equal to the ordinary Jones polynomial of 4_1!

In[5]:= ColouredJones[Knot[4, 1], 1][q]
Out[5]= -2 1 2 1 + q - - - q + q q
In[6]:= Jones[Knot[4, 1]][q]
Out[6]= -2 1 2 1 + q - - - q + q q
4 1.gif
4_1
3 1.gif
3_1
In[7]:= ?CJ`Summand
CJ`Summand[br, n] returned a pair {s, vars} where s is the summand in the the big sum that makes up ColouredJones[br, n][q] and where vars is the list of variables that need to be summed over (from 0 to n) to get ColouredJones[br, n][q]. CJ`Summand[K, n] is the same for knots for which a braid representative is known to this program.

The coloured Jones polynomial of 3_1 is computed via a single summation. Indeed,

In[8]:= s = CJ`Summand[Mirror[Knot[3, 1]], n]
Out[8]= (3 n)/2 + n CJ`k[1] + (-n + 2 CJ`k[1])/2 1 {CJ`q qBinomial[0, 0, ----] CJ`q 1 1 qBinomial[CJ`k[1], 0, ----] qBinomial[CJ`k[1], CJ`k[1], ----] CJ`q CJ`q n 1 n 1 qPochhammer[CJ`q , ----, 0] qPochhammer[CJ`q , ----, CJ`k[1]] CJ`q CJ`q n - CJ`k[1] 1 qPochhammer[CJ`q , ----, 0], {CJ`k[1]}} CJ`q

The symbols in the above formula require a definition:

In[9]:= ?qPochhammer
qPochhammer[a, q, k] represents the q-shifted factorial of a in base q with index k. See Eric Weisstein's http://mathworld.wolfram.com/q-PochhammerSymbol.html and Axel Riese's www.risc.uni-linz.ac.at/research/combinat/risc/software/qMultiSum/
In[10]:= ?qBinomial
qBinomial[n, k, q] represents the q-binomial coefficient of n and k in base q. For k<0 it is 0; otherwise it is qPochhammer[q^(n-k+1), q, k] / qPochhammer[q, q, k].

More precisely, qPochhammer[a, q, k] is

and qBinomial[n, k, q] is

The function qExpand replaces every occurence of a qPochhammer[a, q, k] symbol or a qBinomial[n, k, q] symbol by its definition:

In[11]:= ?qExpand
qExpand[expr_] replaces all occurences of qPochhammer and qBinomial in expr by their definitions as products. See the documentation for qPochhammer and for qBinomial for details.

Hence,

In[12]:= qPochhammer[a, q, 6] // qExpand
Out[12]= 2 3 4 5 (-1 + a) (-1 + a q) (-1 + a q ) (-1 + a q ) (-1 + a q ) (-1 + a q )
In[13]:= First[s] /. {n -> 3, CJ`k[1] -> 2} // qExpand
Out[13]= 11 2 3 CJ`q (-1 + CJ`q ) (-1 + CJ`q )

Finally,


In[14]:= ?ColoredJones
Type ColoredJones and see for yourself.

[Garoufalidis Le] ^  S. Garoufalidis and T. Q. T. Le, The Colored Jones Function is -Holonomic, Georgia Institute of Technology preprint, September 2003, arXiv:math.GT/0309214.

The A2 Invariant

We compute the (or quantum ) invariant using the normalization and formulas of [Khovanov], which in itself follows [Kuperberg]:

(For In[1] see Setup)

In[2]:= ?A2Invariant
A2Invariant[L][q] computes the A2 (sl(3)) invariant of a knot or link L as a function of the variable q.

As an example, let us check that the knots 10_22 and 10_35 have the same Jones polynomial but different invariants:

In[3]:= Jones[Knot[10, 22]][q] == Jones[Knot[10, 35]][q]
Out[3]= True
In[4]:= A2Invariant[Knot[10, 22]][q]
Out[4]= -12 -8 -6 -4 2 4 6 8 10 12 14 -1 + q + q + q - q + -- - q - 2 q + q - q + q + q + 2 q 18 q
In[5]:= A2Invariant[Knot[10, 35]][q]
Out[5]= -14 -12 -10 -8 2 2 2 6 8 10 14 16 q + q - q + q - -- + -- + q - q + q - 2 q + q - q + 4 2 q q 18 20 q + q

The invariant attains 2163 values on the 2226 knots and links known to KnotTheory:

In[6]:= all = Join[AllKnots[], AllLinks[]];
In[7]:= Length /@ {Union[A2Invariant[#][q]& /@ all], all}
Out[7]= {2163, 2226}

[Khovanov] ^  M. Khovanov, link homology I, arXiv:math.QA/0304375.

[Kuperberg] ^  G. Kuperberg, Spiders for rank 2 Lie algebras, Comm. Math. Phys. 180 (1996) 109-151, arXiv:q-alg/9712003.

The HOMFLY-PT Polynomial

The HOMFLY-PT polynomial (see [HOMFLY] and [PT]) of a knot or link is defined by the skein relation

Failed to parse (unknown function "\overcrossing"): {\displaystyle aH\left(\overcrossing\right)-a^{-1}H\left(\undercrossing\right)=zH\left(\smoothing\right) }

and by the initial condition =1.

KnotTheory` knows about the HOMFLY-PT polynomial:

(For In[1] see Setup)

In[2]:= ?HOMFLYPT
HOMFLYPT[K][a, z] computes the HOMFLY-PT (Hoste, Ocneanu, Millett, Freyd, Lickorish, Yetter, Przytycki and Traczyk) polynomial of a knot/link K, in the variables a and z.
In[3]:= HOMFLYPT::about
The HOMFLYPT program was written by Scott Morrison.

Thus, for example, here's the HOMFLY-PT polynomial of the knot 8_1:

In[4]:= K = Knot[8, 1];
In[5]:= HOMFLYPT[Knot[8, 1]][a, z]
Out[5]= -2 4 6 2 2 2 4 2 a - a + a - z - a z - a z

It is well known that HOMFLY-PT polynomial specializes to the Jones polynomial at and and to the Conway polynomial at . Indeed,

In[6]:= Expand[HOMFLYPT[K][1/q, Sqrt[q]-1/Sqrt[q]]]
Out[6]= -6 -5 -4 2 2 2 2 2 + q - q + q - -- + -- - - - q + q 3 2 q q q
In[7]:= Jones[K][q]
Out[7]= -6 -5 -4 2 2 2 2 2 + q - q + q - -- + -- - - - q + q 3 2 q q q
In[8]:= {HOMFLYPT[K][1, z], Conway[K][z]}
Out[8]= 2 2 {1 - 3 z , 1 - 3 z }
8 1.gif
8_1
L5a1.gif
L5a1

In our parametrization of the link invariant, it satisfies

,

where is some knot or link and where is the number of components of . Let us verify this fact for the Whitehead link, L5a1:

In[9]:= L = Link[5, Alternating, 1];
In[10]:= Simplify[{ (-1)^(Length[Skeleton[L]]-1)(q^2+1+1/q^2)HOMFLYPT[L][1/q^3, q-1/q], A2Invariant[L][q] }]
Out[10]= -12 -8 -6 2 -2 2 4 6 {2 - q + q + q + -- + q + q + q + q , 4 q -12 -8 -6 2 -2 2 4 6 2 - q + q + q + -- + q + q + q + q } 4 q

Other Software to Compute the HOMFLY-PT Polynomial

A C-based program running under windows by M. Ochiai can compute the HOMFLY-PT polynomial of certain knots and links with up to hundreds of crossings using "base tangle decompositions". His program, bTd, is available at [1].

References

[HOMFLY] ^  J. Hoste, A. Ocneanu, K. Millett, P. Freyd, W. B. R. Lickorish and D. Yetter, A new polynomial invariant of knots and links, Bull. Amer. Math. Soc. 12 (1985) 239-246.

[PT] ^  J. Przytycki and P. Traczyk, Conway Algebras and Skein Equivalence of Links, Proc. Amer. Math. Soc. 100 (1987) 744-748.

The Kauffman Polynomial

The Kauffman polynomial (see [Kauffman]) of a knot or link is where is the writhe of (see How is the Jones Polynomial Computed?) and where is the regular isotopy invariant defined by the skein relations

(here is a strand and is the same strand with a kink added) and

Failed to parse (unknown function "\backoverslash"): {\displaystyle L(\backoverslash)+L(\slashoverback) = z\left(L(\smoothing)+L(\hsmoothing)\right)}

and by the initial condition where is the unknot BigCirc symbol.gif.

KnotTheory` knows about the Kauffman polynomial:

(For In[1] see Setup)

In[2]:= ?Kauffman
Kauffman[K][a, z] computes the Kauffman polynomial of a knot or link K, in the variables a and z.
In[3]:= Kauffman::about
The Kauffman polynomial program was written by Scott Morrison.

Thus, for example, here's the Kauffman polynomial of the knot 5_2:

In[4]:= Kauffman[Knot[5, 2]][a, z]
Out[4]= 2 4 6 5 7 2 2 4 2 6 2 3 3 -a + a + a - 2 a z - 2 a z + a z - a z - 2 a z + a z + 5 3 7 3 4 4 6 4 2 a z + a z + a z + a z
5 2.gif
5_2
T(8,3).jpg
T(8,3)

It is well known that the Jones polynomial is related to the Kauffman polynomial via

,

where is some knot or link and where is the number of components of . Let us verify this fact for the torus knot T(8,3):

In[5]:= K = TorusKnot[8, 3];
In[6]:= Simplify[{ (-1)^(Length[Skeleton[K]]-1)Kauffman[K][-q^(-3/4), q^(1/4)+q^(-1/4)], Jones[K][q] }]
Out[6]= 7 9 16 7 9 16 {q + q - q , q + q - q }

[Kauffman] ^  L. H. Kauffman, An invariant of regular isotopy, Trans. Amer. Math. Soc. 312 (1990) 417-471.

Finite Type (Vassiliev) Invariants

(For In[1] see Setup)

In[2]:= ?Vassiliev
Vassiliev[2][K] computes the (standardly normalized) type 2 Vassiliev invariant of the knot K, i.e., the coefficient of z^2 in Conway[K][z]. Vassiliev[3][K] computes the (standardly normalized) type 3 Vassiliev invariant of the knot K, i.e., 3J''(1)-(1/36)J'''(1) where J is the Jones polynomial of K.

Thus, for example, let us reproduce Willerton's "fish" (arXiv:math.GT/0104061), the result of plotting the values of against the values of , where is the (standardly normalized) type 2 invariant of , is the (standardly normalized) type 3 invariant of , and where runs over a set of knots with equal crossing numbers (10, in the example below):

In[3]:= ListPlot[ Join @@ Table[ K = Knot[10, k] ; v2 = Vassiliev[2][K]; v3 = Vassiliev[3][K]; {{v2, v3}, {v2, -v3}}, {k, 165} ], PlotStyle -> PointSize[0.02], PlotRange -> All, AspectRatio -> 1 ]
Finite Type Vassiliev Invariants Out 3.gif
Out[3]= -Graphics-


As another example, let us consider the expansion of the Jones polynomial for a knot as a power series in when we substitute the standard variable with and use the power series expansion of :

Then, for the above coefficients we have that and for all is a Vassiliev invariant of type [BirmanLin]. We can see this result by using the invariant formula:

Failed to parse (SVG (MathML can be enabled via browser plugin): Invalid response ("Math extension cannot connect to Restbase.") from server "https://wikimedia.org/api/rest_v1/":): {\displaystyle V\left(\doublepoint\right)= V\left(\overcrossing\right)-V\left(\undercrossing\right)}

to check the Birman-Lin condition, which tells us that an invariant is of type if it vanishes on knots with more than double points, or self intersections (see [Bar-Natan]). Computing on knots with more than one double point by resolving one self intersection at a time, it is enough to check that vanishes on knots with double points:

Failed to parse (unknown function "\doublepoint"): {\displaystyle V\underbrace{ \left(\doublepoint\cdots\doublepoint\right) }_{m+1}=0}

The following two programs let us determine for any integer and knot :

In[4]:= SetCrossing[K_, l_Integer, s_] := Module[ {pd, n}, pd = PD[K]; If[PositiveQ[pd[[l]]], If[s == "-", pd[[l]] = RotateRight@pd[[l]]], If[s == "+", pd[[l]] = RotateLeft@pd[[l]]]]; pd];
In[5]:= V[K_, n_] := Series[Jones[K][Exp[x]], {x, 0, n}]; V[K_, n_, {i1_, is___}] := V[SetCrossing[K, i1, "+"], n, {is}] - V[SetCrossing[K, i1, "-"], n, {is}]; V[K_, n_, {}] := V[K, n];

The first program, SetCrossing, sets the crossing of a knot to be positive or negative depending on whether we choose to be "" or "". The second program uses the invariant formula to give the series expansion of the Jones polynomial of a knot discussed above, up to order , where a selected list of the crossings of are taken as double points. is then the coefficient of the term containing .

For example, we can check that disappears on the knot 9_47 with its first five crossings taken as double points:

In[6]:= V[Knot[9, 47], 4, {1, 2, 3, 4, 5}]
Out[6]= V[Knot[9, 47], 4, {1, 2, 3, 4, 5}]
The knot 9_47 with its first five crossings taken as double points.

[Bar-Natan] ^ D. Bar-Natan, On the Vassiliev Knot Invariants, Topology 34 (1995) 423-472.

[BirmanLin] ^ J.S. Birman and X.-S. Lin, Knot Polynomials and Vassiliev's Invariants, Invent. Math. 111 (1993) 225-270.

Khovanov Homology

(See also: Tweaking JavaKh)

The Khovanov Homology of a knot or a link , also known as Khovanov's categorification of the Jones polynomial of , was defined by Khovanov in [Khovanov1] (also check [Bar-Natan1]), where the notation is closer to the notation used here). It is a graded homology theory; each homology group is in itself a direct sum of homogeneous components. Over a field one can form the two-variable "Poincaré polynomial" (which deserves the name "the Khovanov polynomial of "),

.

(For In[1] see Setup)

In[2]:= ?Kh
Kh[L][q, t] returns the Poincare polynomial of the Khovanov Homology of a knot/link L (over a field of characteristic 0) in terms of the variables q and t. Kh[L, Program -> prog] uses the program prog to perform the computation. The currently available programs are "FastKh", written in Mathematica by Dror Bar-Natan in the winter of 2005, "JavaKh-v1", written in java (java 1.5 required!) by Jeremy Green in the summer of 2005 and "JavaKh-v2" (default), an update of "JavaKh-v1" (now requiring java 1.6) written by Scott Morrison in 2008. ("JavaKh" is also available, currently an alias for "JavaKh-v2".) The java programs are several thousand times faster than the Mathematica program, though java may not be available on some systems. "JavaKh2" also takes the option "Modulus -> p" which changes the characteristic of the ground field to p. If p==0 JavaKh works over the rational numbers; if p==Null JavaKh works over Z (see ?ZMod for the output format).

Thus for example, here's the Khovanov polynomial of the knot 5_1:

In[3]:= kh = Kh[Knot[5, 1]][q, t]
Out[3]= -5 -3 1 1 1 1 q + q + ------ + ------ + ------ + ----- 15 5 11 4 11 3 7 2 q t q t q t q t

The Euler characteristic of the Khovanov Homology is (up to normalization) the Jones polynomial of . Precisely,

.

Let us verify this in the case of 5_1:

In[4]:= {kh /. t -> -1, Expand[(q+1/q)Jones[Knot[5, 1]][q^2]]}
Out[4]= -15 -7 -5 -3 -15 -7 -5 -3 {-q + q + q + q , -q + q + q + q }
5 1.gif
5_1
10 132.gif
10_132

Khovanov's homology is a strictly stronger invariant than the Jones polynomial. Indeed, though :

In[5]:= { Jones[Knot[5, 1]] === Jones[Knot[10, 132]], Kh[Knot[5, 1]] === Kh[Knot[10, 132]] }
Out[5]= {True, False}

The algorithm presently used by KnotTheory` is an efficient algorithm modeled on the Kauffman bracket algorithm of The Jones Polynomial, as explained in [Bar-Natan3] (which follows [Bar-Natan2]). Currently, two implementations of this algorithm are available:

  • FastKh: My original implementation, written in Mathematica in the winter of 2005. This implementation can be explicitly invoked using the syntax Kh[L, Program -> "FastKh"][q, t] or by changing the default behaviour of Kh by evaluating SetOptions[Kh, Program -> "FastKh"].
  • JavaKh: In the summer of 2005 Jeremy Green re-implemented the algorithm in java (java 1.5 required, can be had from http://java.sun.com/) with much further care to the details, leading to an improvement factor of several thousands for large knots/links. This implementation is the default. It can also be explicitly invoked from within Mathematica using the syntax Kh[L, Program -> "JavaKh"][q, t].
In[6]:= Options[Kh]
Out[6]= {ExpansionOrder -> Automatic, Program -> JavaKh-v2, Modulus -> 0, KnotTheory`FastKh`Universal -> False, JavaOptions -> }

JavaKh takes an additional option, Modulus, which sets the characteristic of the ground field for the homology computations to or to a prime . Thus for example, the following four In lines imply that the Khovanov homology of the torus knot T(6,5) has both 3 torsion and 5 torsion, but no 7 torsion:

In[7]:= T65 = TorusKnot[6, 5]; kh = Kh[T65][q, t];
In[8]:= Kh[T65, Modulus -> 3][q, t] - kh
Out[8]= 43 13 43 14 q t + q t
In[9]:= Kh[T65, Modulus -> 5][q, t] - kh
Out[9]= 35 10 35 11 39 11 39 12 q t + q t + q t + q t
In[10]:= Kh[T65, Modulus -> 7][q, t] - kh
Out[10]= 0
T(6,5).jpg
T(6,5)

The following further example is a bit tougher. It takes my computer nearly an hour and some 256Mb of memory to find that the Khovanov homology of the 48-crossing torus knot T(8,7) has 3, 5 and 7 torsion but no 11 torsion:

In[11]:= ?JavaOptions
JavaOptions is an option to Kh. Kh[L, Program -> "JavaKh2", JavaOptions -> jopts] calls java with options jopts. Thus for example, JavaOptions -> "-Xmx256m" sets the maximum java heap size to 256MB - useful for large computations.
In[12]:= SetOptions[Kh, JavaOptions -> "-Xmx256m"];
In[13]:= T87 = TorusKnot[8, 7]; kh = Kh[T87][q, t];
In[14]:= Factor[Kh[T87, Modulus -> 3][q, t] - kh]
Out[14]= 79 25 q t (1 + t)
In[15]:= Factor[Kh[T87, Modulus -> 5][q, t] - kh]
Out[15]= 61 11 12 10 14 12 18 13 q t (1 + t) (1 + q t + q t + q t )
In[16]:= Factor[Kh[T87, Modulus -> 7][q, t] - kh]
Out[16]= 61 14 8 6 12 7 10 8 14 9 q t (1 + t) (1 + q t + q t + q t + q t )
In[17]:= Factor[Kh[T87, Modulus -> 11][q, t] - kh]
Out[17]= 0

JavaKh also works over the integers:

In[18]:= ?ZMod
ZMod[m] denotes the cyclic group Z/mZ. Thus if m=0 it is the infinite cyclic group Z and if m>0 it is the finite cyclic group with m elements. ZMod[m1, m2, ...] denotes the direct sum of ZMod[m1], ZMod[m2], ... .

For example, the 22nd homology group over of the torus knot T(8,7) at degree 73 is the 280 element torsion group :

In[19]:= Coefficient[Kh[T87, Modulus -> Null][q, t], t^22 * q^73]
Out[19]= ZMod[2, 4, 5, 7]

T(8,7) is currently not on the Knot Atlas. Let us see what it looks like:

In[20]:= Show[TubePlot[TorusKnot[8, 7]]]
Khovanov Homology Out 20.gif
Out[20]= -Graphics3D-

Finally, JavaKh may also be run outside of Mathematica, as the following example demonstrates:

drorbn@coxeter:.../KnotTheory: cd JavaKh
drorbn@coxeter:.../KnotTheory/JavaKh: java JavaKh
PD[X[3, 1, 4, 6], X[1, 5, 2, 4], X[5, 3, 6, 2]]
"+ q^1t^0 + q^3t^0 + q^5t^2 + q^9t^3 "

(Type java JavaKh -help for some further help).

(Warning, as of August 2008, you need to include the .jar files in JavaKh/jars on the classpath. If this causes confusion, ask Scott for a script that manages this automatically, or look at p. 29 of [2] for an example.)

Universal Khovanov homology, and reduced homology

The KnotTheory` package can now compute the universal homology over , the reduced homology over as well as directly computing the s-invariant. Type ?UniversalKh, ?KhReduced or ?sInvariant for more information.

The output of UniversalKh is a -linear combination of symbols KhE and KhC[n] for some positive integer . The coefficients of these symbols are individually knot invariants, capturing all of the information in the spectral sequences (over ) for both unreduced and reduced homology.

The s-invariant can be extracted from the output of UniversalKh: the coefficient of KhE is exactly .

The usual 2-variable Khovanov polynomial Kh[K][q,t] can be recovered from UniversalKh[K][q,t] by using the substitution rules

   {KhE->q+q^-1,KhC[1]->t^-1 q^-3+ q^1,KhC[n_]/;n>=2:>(q+q^-1)(t^-1 q^(-2n)+1)};

and similarly the reduced Khovanov polynomial KhReduced[K][q,t] is actually produced by substituting UniversalKh[K][q,t] using the rules

   {KhE->q^-1,KhC[n_]:>t^-1 q^(-2n-1)+q^-1};

Unfortunately, much of the mathematics behind UniversalKh is not in print. There's some explanation in Scott's slides from Kyoto.

UniversalKh also takes the same JavaOptions option described above for Kh, which may be necessary to allow enough memory for large computations.

References

August 2002, Toronto: Mikhail Khovanov explaining his paper [Khovanov2].

[Bar-Natan1] ^  D. Bar-Natan, On Khovanov's categorification of the Jones polynomial, Algebraic and Geometric Topology 2-16 (2002) 337-370, arXiv:math.GT/0201043.

[Bar-Natan2] ^  D. Bar-Natan, Khovanov's Homology for Tangles and Cobordisms, Geometry and Topology 9-33 (2005) 1443-1499, arXiv:math.GT/0410495.

[Bar-Natan3] ^  D. Bar-Natan, I've Computed Kh(T(9,5)) and I'm Happy, talk given at Knots in Washington XX, George Washington University, February 2005.

[Khovanov1] ^  M. Khovanov, A categorification of the Jones polynomial, arXiv:math.QA/9908171.

[Khovanov2] ^  M. Khovanov, An invariant of tangle cobordisms, arXiv:math.QA/0207264.

See also A Khovanov homology bibliography.

Extras Included with KnotTheory`

The package KnotTheory` contains a few extras that are not directly related to knot theory.

Drawing with TubePlot

(For In[1] see Setup)

In[2]:= ?TubePlot
TubePlot[gamma, {t, t0, t1}, r, opts] plots the space curve gamma with the variable t running from t0 to t1, as a tube of radius r. The available options are TubeSubdivision, TubeFraming and TubePlotPrelude. All other options are passed on to Graphics3D. TubePlot[TorusKnot[m, n], opts] produces a tube plot of the (m,n) torus knot.

Thus here's a thin unknot:

In[3]:= Show[TubePlot[{Cos[t], Sin[t], 0}, {t, 0, 2Pi}, 0.1]]
Drawing with TubePlot Out 3.gif
Out[3]= -Graphics3D-
In[4]:= ?TubeSubdivision
TubeSubdivision is an option for TubePlot. TubePlot[__, TubeSubdivision -> {l, m} draws the tube subdivided to l pieces lengthwise and m pieces around. The default is TubeSubdivision -> {50, 12}.
In[5]:= ?TubeFraming
TubeFraming is an option for TubePlot. TubePlot[gamma, {t, __}, _, TubeFraming -> n] sets the framing of the tube (visible when TubeSubdivision -> {l, m} with small m) to be the vector n, which in itself may be a function of t. Thus TubeFraming -> {0,0,1} is "blackboard framing". TubeFraming -> Normal (default) uses the normal vector of the curve gamma.
In[6]:= ?TubePlotPrelude
TubePlotPrelude is an option for TubePlot. Its value is passed to Graphics3D before the main part of the plot, allowing to set various graphics options. For example, TubePlotPrelude -> EdgeForm[{}] will suppress the drawing of edges between the polygons making up the tube. The default is TubePlotPrelude -> {}.

Here's the same unknot, made thicker and not as smooth:

In[7]:= Show[TubePlot[ {Cos[t], Sin[t], 0}, {t, 0, 2Pi}, 0.3, TubeSubdivision -> {6, 3} ]]
Drawing with TubePlot Out 7.gif
Out[7]= -Graphics3D-

Let's play with the framing now:

In[8]:= Show[TubePlot[ {Cos[t], Sin[t], 0}, {t, 0, 2Pi}, 0.2, TubeSubdivision -> {50, 2}, TubeFraming -> {Cos[2t]Cos[t], Cos[2t]Sin[t], Sin[3t]} ]]
Drawing with TubePlot Out 8.gif
Out[8]= -Graphics3D-

Here's an example that uses a prelude and passes options on to Graphics3D:

In[9]:= Show[TubePlot[ {Cos[2t], Sin[2t], 0} + 0.5{Cos[3t]Cos[2t], Cos[3t]Sin[2t], -Sin[3t]}, {t, 0, 2Pi}, 1/3, TubeSubdivision -> {280, 12}, TubeFraming -> {0,0,1}, TubePlotPrelude -> EdgeForm[{}], Boxed -> False, ViewPoint -> {0,0,1} ]]
Drawing with TubePlot Out 9.gif
Out[9]= -Graphics3D-

The last example serves as the basis for the definition of TubePlot[TorusKnot[m, n]]. Here's a final example:

In[10]:= Show[TubePlot[TorusKnot[3, 5]]]
Drawing with TubePlot Out 10.gif
Out[10]= -Graphics3D-

Standalone TubePlot

There may be some independent interest in the routine TubePlot, and hence it is available also as an independent package. Here it is: TubePlot.m (File:TubePlot.m).

WikiLink - The Mediawiki Interface

WikiLink is actually two separate things; firstly, a java class for interfacing with a mediawiki server, and secondly, a Mathematica package providing a wrapper around this. This page documents the Mathematica package, while the java class, and its addition functionality, will be documented elsewhere.

WikiLink is available as a standalone package, suitable for use with any Mediawiki installation, and is included in the KnotTheory` package.

License

WikiLink.nb, WikiLink.m and wikilink.jar are copyright Scott Morrison, available under your choice of the MIT, Apache or GPL licenses. The other components are copyright by other parties, all available under the Apache license.

Download

If you already have KnotTheory` installed, there's no need to install anything. The functionality of WikiLink is available as soon as you open KnotTheory`.

Otherwise, download WikiLink.zip. Unzip this anywhere you like. This will create a subdirectory called WikiLink, containing (at least) these files:

Filename Description
mathematica/WikiLink.nb The Mathematica notebook containing wrapper function definitions.
mathematica/WikiLink.m The Mathematica package automatically generated from WikiLink.nb.
wikilink.jar The WikiLink java classes and source code.

jars/jdom.jar
jars/commons-httpclient-3.0-rc2.jar
jars/commons-codec-1.3.jar
jars/commons-lang-2.1.jar
jars/commons-logging.jar

Libraries (all available under either GPL or the Apache license) required by wikilink.jar

Importing the package in Mathematica

If you're not using KnotTheory`, first, you'll need to set some paths, so WikiLink` can find the java files it needs. You need to add the "mathematica/" subdirectory of the WikiLink distribution to the Mathematica $Path.

In[1]:= WikiLinkPath = "/path/to/WikiLink/mathematica/";
In[2]:= AppendTo[$Path, WikiLinkPath];
In[3]:= <<WikiLink`

If you've already loaded KnotTheory` (e.g., with the statement <<KnotTheory`), you can simply begin at this point.

We then try to connect to the wiki. Executing this line will prompt you for a username and password.

In[6]:= CreateWikiConnection[ "http://katlas.math.toronto.edu/w/index.php", InputString["Enter Your Username:"], InputString["Enter Your Password:"] ]

The function WikiUserName[] checks that we're logged in

In[4]:= ?WikiUserName
WikiUserName[] returns either the name of the user you are logged in as, your IP address if you're not logged in, or $Failed if something more complicated has happened!
In[5]:= WikiUserName[]
Out[5]= ScottManualRobot

Usage

WikiLink` provides functions for checking your login status, getting and setting pages, as well as transparently extending some of Mathematica's string manipulation functions to wiki pages.

In[6]:= ?WikiUserName
WikiUserName[] returns either the name of the user you are logged in as, your IP address if you're not logged in, or $Failed if something more complicated has happened!
In[7]:= ?WikiGetPageText
WikiGetPageText[pagename] returns the raw text of the specified page.
In[8]:= ?WikiSetPageText
WikiSetPageText[pagename, text] overwrites the contents of the specificied page with the given text. WikiSetPageText[pagename, text, summary] overwrites the contents of the specificied page with the given text and notes summary in the change log.
In[9]:= ?WikiSetPageTexts
WikiSetPageText[{{pagename1, text1},{pagename2,text2},...}] efficiently sets multiple pages, by first checking which texts are already up to date.
In[10]:= ?WikiUploadFile
WikiUploadFile[name, description] uploads the specified file to the wiki.

Thus for example after

In[11]:= WikiSetPageText["Sandbox", "A robotic edit, at 19:39, 31-August-2005."]
Out[11]= True

we get

In[12]:= WikiGetPageText["Sandbox"]
Out[12]= A robotic edit, at 19:39, 31-August-2005.

The function WikiSetPageTexts is most useful for batch uploads, as it does considerably more error checking, and filters out edits which won't change the page text. It takes as argument a list of {"title", "text"} pairs, and returns a list of those pairs which failed.

In[13]:= WikiSetPageTexts[{{"Sandbox", "A robotic edit, by --~~"<>"~~"}, {"Sandbox2", "The determinant of the knot [[3_1]] is 3."}}]
Out[13]= {}
In[14]:= WikiGetPageText["Sandbox2"]
Out[14]= The determinant of the knot [[3_1]] is 3.
String manipulation functions

WikiLink` provides functions WikiPageMatchQ, WikiPageFreeQ, WikiStringReplace and WikiStringCases. Each function works likes its usual Mathematica partner, StringMatchQ, StringFreeQ, StringReplace or StringCases. Instead of providing a string, or list of strings, as the first argument, you should give the name of a page, or a list of names.

You can use these to perform all sorts of editing tricks.

In[15]:= WikiPageMatchQ[{"Sandbox", "Sandbox2"}, "determinant"]
Out[15]= {False, False}
In[16]:= WikiPageFreeQ[{"Sandbox", "Sandbox2"}, "[["~~(DigitCharacter..)~~"_"~~(DigitCharacter..)~~"]]"]
Out[16]= {True, False}
In[17]:= WikiStringCases[{"Sandbox", "Sandbox2"}, "[["~~ShortestMatch[__]~~"]]"]
Out[17]= {{Sandbox, {[[User:ScottManualRobot|ScottManualRobot]]}}, {Sandbox2, {[[3_1]]}}}
In[18]:= WikiStringReplace[{"Sandbox", "Sandbox2"}, "robotic edit"->"robotic edit (using WikiLink`)]
Out[18]= $Failed
In[19]:= WikiGetPageTexts[{"Sandbox", "Sandbox2"}]
Out[19]= {{Sandbox, A robotic edit, by\ --[[User:ScottManualRobot|ScottManualRobot]] 14:54, 18 Feb 2006\ (EST)}, {Sandbox2, The determinant of the knot [[3_1]] is 3.}}

Troubleshooting

The instruction ShowJavaConsole[] will bring up a window in which some debugging information is displayed.

Compatibility

WikiLink (with some modifications made in July 2007) appears to work with mediawiki 1.10.1. Bug reports appreciated!

WikiLink has been tested against mediawiki 1.4.5beta3 and 1.4.7.

WikiLink has known issues on mediawiki 1.5.0. Retrieving multiple pages at once is broken. This appears to be a mediawiki bug, and will not be fixed. The same problem does not occur on mediawiki 1.5.8. --Scott 10:56, 27 Mar 2006 (EST)

I expect WikiGetPage text to continue working in mediawiki 1.5 and beyond, because it uses the stable interface Special:Export. Logging in and setting pages will quite likely break in the next version. If you've tried this, please let me know about your experiences. I'm hoping that soon (1.5?) Special:Import will become available, and I can switch to using this. --Scott 15:57, 31 Aug 2005 (EDT)

Todo

I'd love to create an Ant task which allows uploading a file to a wiki. We could then use this in build scripts for KnotTheory, etc. --Scott 04:07, 17 Sep 2005 (EDT)

See Also

All of the Mathematica notebooks in Category:Knot Atlas Maintenance Software rely on WikiLink, and so are good examples of how to use it.

You may also be interested in the Wikipedia page on mediawiki bots, and in particular the Python Wikipedia Robot Framework.

Lightly Documented Features

(For In[1] see Setup)

In[2]:= ?NumberOfKnots
NumberOfKnots[n] returns the number of knots with n crossings. NumberOfKnots[n, Alternating|NonAlternating] returns the number of knots of the specified type.
In[3]:= NumberOfKnots[16, NonAlternating]
Out[3]= 1008906
In[4]:= ?AlternatingQ
AlternatingQ[D] returns True iff the knot/link diagram D is alternating.

Among the knots with up to 11 crossings, 564 are alternating and 238 are not:

In[5]:= Total[AlternatingQ /@ AllKnots[{0,11}]]
Out[5]= 238 False + 564 True

Further Knot Theory Software

KnotPlot

Many of the images appearing in The Knot Atlas were created using Rob Scharein's program KnotPlot:

A snapshot of KnotPlot

Knotscape

Many of the images appearing in The Knot Atlas were created using Jim Hoste's and Morwen Thistlethwaite's program Knotscape.

A snapshot of Knotscape

Xknots

Xknots, developed by Javier Rodríguez is a program that produces postscript knot images.

Extending/Modifying KnotTheory`

Anybody is welcome, indeed encouraged, to fix, modify or extend the package KnotTheory` to the benefit of everybody else. This note explains how this can be done and outlines some of the conventions used within KnotTheory`.

Seeing the sources

The source files for KnotTheory` are kept in a Subversion repository whose overall directory structure is as follows:

http://katlas.math.toronto.edu/svn/KnotTheory/...

  • trunk/... contains the current "working" version of the package.
    • KnotTheory/... is an unpacked version of the whole package, as seen by users.
    • src/... contains the individual mathematica "modules" that are glued together to make KnotTheory/init.m, the main executable of KnotTheory`.
  • branches/... contains development versions of certain new features that are not yet included in the package.
  • tags/...
    • stable/... contains the last "stable" version of the package. It is a snapshot of the trunk/ directory, at some previous moment in time. "Stable" doesn't necessarily mean any great degree of testing has gone on; it just means that the most recently introduced bugs in the trunk haven't been included. The downloadable package is generated from this directory.

Writing Your Extension

Submitting Your Extension

KnotTheory` is a computer program written in an unrestricted language. Meaning that a vicious programmer could use it to do harmful things to the computer running it. Therefore unlike much of the rest of the Knot Atlas, it can be modified directly only by the administrators of this site. If you aren't one, email your extension/modification to Dror. Dror will read through it quickly to confirm that it's not malicious and doesn't do anything obviously wrong and post it in the Setup section of this manual. Thanks!

Lessons learnt from integrating LinKnot`

In February 2006, Radmila, Dror and Scott spent a few days making LinKnot` and KnotTheory` play nicely together. In the end, we had at least partially achieved two of our goals:

  1. Allowing the concurrent usage of KnotTheory` with LinKnot`, so that users of LinKnot` can access the databases and algorithms available in KnotTheory`, while maintaining familiar notations and function names.
  2. Making the functionality of LinKnot` transparently available to users of KnotTheory` (with function names and data conventions consistent with KnotTheory`).

These two goals seem to be a reasonable model for integrating a pair of complementary Mathematica packages; former users of each expect not much to change, but simply to have extra functionality. It's also a reasonable 'minimal' model, in that only 'compatibility layers' are written, leaving the original packages (mostly) unchanged.

Loading side by side

Our first goal was simply to be able to load KnotTheory` and LinKnot` side by side. Initially, we were prevented by two different problems. Firstly, each package unintentionally introduced symbols into the Global` Mathematica context. Secondly, each package expected that the current working directory always be the home of the package; expectations unsatisfiable simultaneously!

Global` symbols

Fixing leakages from KnotTheory` wasn't too hard; just load KnotTheory` in a fresh Mathematica session, then issue the command Names["Global`*"]. There shouldn't be much there, and it's mostly a matter of tracking down where the stray symbols have been introduced. If you don't understand Mathematica's (utterly ugly) system of contexts, you'll start to get the hang of it while doing this!

Leakages from LinKnot` were much more serious, as several subpackages were loaded directly into the Global` context (the authors of K2K didn't follow the usual Mathematica package conventions).

At this point we discovered the first of several painful problems associated with symbols in contexts which aren't currently on the context path, namely that conversions to and from strings (with ToString and ToExpression) are very dangerous. These happen 'at runtime', so the context path could be quite arbitrary (that is, having been modified by other packages or users since the package was loaded), rather than at the moment the package is loaded. It is often necessary to wrap calls to ToExpression with code which temporarily resets the context path. Seaching for ToExpression in the LinKnot sources should find examples of this.

Current working directory

Unfortunately many parts of the K2K package rely on the current working directory being the LinKnot` installation directory. This causes all sorts of problems; users should be able to change the current working directory arbitrarily. Even worse, there are still some bugs in KnotTheory` where certain things don't work if the current working directory isn't set to the KnotTheory` installation directory!

We used two techniques to get around this. First, the KTtoLinKnot subpackage tries to work out the LinKnot` installation directory, using the mnemonic

LinKnotDirectory[]=
        DirectoryName[
          File/.Flatten[
              FileInformation[ToFileName[#,"LinKnots.m"]]&/@$Path]];

(The main KnotTheory` package does a similar thing in System.mm, using

KnotTheoryDirectory[] = (
  File /. Flatten[FileInformation[ToFileName[#,"KnotTheory"]] & /@ ($Path /. "." -> Directory[])]
)

)

It then tries to wrap all calls into K2K with the expression SwitchDirectories[<<do something>>], which changes the current path, and context path, before executing the wrapped code, and restores it after completion. If you're trying to make more K2K functionality available, by modifyin KTtoLinKnot, you should look carefully at what we've already done for other functions.

Transparently calling LinKnot` from KnotTheory`

Setting up LinKnot` for use with KnotTheory` is pretty simple. If you try using a function that relies on LinKnot`, for example converting conway notations to other notations, and don't have LinKnot` installed, you'll get a message along the lines of

The function "ConwayNotation" requires the LinKnot package, which is not distributed as part of KnotTheory. I couldn't seem to load it; try downloading it from http://www.mi.sanu.ac.yu/vismath/linknot/, and adding the appropriate directory to the $Path.

And this should be all that's necessary!

At present, the compatibility layer for LinKnot` provdes Conway notation conversion programs (both directions, although it seems infeasible to calculate conway notations for knots with more than 12 crossings), knot drawing and 'by-mouse' knot input.

Advanced SVN usage

If you have already made some contributions to the KnotTheory` package, it's possible you have direct commit access to the Subversion server. (Please ask Dror or Scott if you think you need it too.) This part of the manual documents some advanced tasks for those with commit access; probably only Dror for now.

Making a new stable release

You'll need a working copy that includes both the tags/ and trunk/ directories of the SVN project. Update everything! Go to the /tags/stable directory, and do an svn merge. You need to specify the beginning and end revisions; the beginning revision should be the head of the /tags/stable, the end revision should be either the head, or a recent revision of /trunk.

Please let me know if this works or not!

List of Modules in KnotTheory`

List of Modules in KnotTheory`

How to Edit this Manual...

To a large extent, editing this manual is easy --- just as easy as editing a page at Wikipedia, or any other wiki. There's some good help on that available at Wikipedia:How to edit a page. However, because we also use Mathematica code within the manual, and automatically generate the output, there are a few things you need to be aware of. Read on! (or don't -- just go edit!)

The Basic Rules

Knot Atlas manual pages are editable and are edited by both humans and robots (dedicated computer programs). Both sides have to be careful not to step into each other's territory. Under the current treaties, robots are responsible for simulated Mathematica output and for certain numerical values that are computed by KnotTheory`. Their territory always lies between <!--$ and <!--END--> tags. Humans are responsible for everything else, including brief ventures into the robot's territories to tell the robots what to do.

Human Edits

To perform a human edit, simply click on the "edit" link at the top of any manual page (or indeed, at the top of almost any other wiki page) and begin editing, saving your work at the end. Be careful not to modify anything in the robots' territory, delimited by <!--$ and <!--END--> tags.

You may find the Local Clip Art library useful, or this brief description of math mode.

If you're adding a new manual page, start it with "{{Manual TOC Sidebar}}" (this produces the table of contents (TOC) sidebar on the right) and make sure to add your page to the table of contents at Manual Table of Contents and to the Printable Manual list-of-sections.

If you are only interested in an edit confined to a human territory, you don't need to read any further.

What Robots Do

Before a human can tell a robot what to do, (s)he must understand the simple way in which robots work. Robots do just one simple thing, and only when instructed to it. Here's how they work:

  1. They search the text of a manual page for patterns of the form <!--$robot instructions$-->old robotic response<!--END-->.
  2. They study the robot instructions and compute something.
  3. They print the output, i.e. the new robotic response, in place of the old robotic response. Just to be sure that humans don't modify the new robotic response, robots precede it with a short human do not enter phrase. Dror's robot's favourite is Robot Land, no human edits to "END".
  4. Robots never modify their own instructions or venture to human territories.

Human Ventures into Robot Lands

It is not a good idea for a human to modify a robotic response, as these changes will be overwritten the next time a robot roams the page. (On the other hand, it doesn't break anything in the meantime.) Better, humans can control the robots.

  • To create a new robot territory, put the pattern <!--$robot instructions$--><!--END--> in the desired place. Note: You must put in <!--END--> by hand! The next time a robot visits it will follow the instructions and place its response between the $--> and <!--END--> tags.
  • To remove an existing robot territory, simply remove everything from the <!--$ tag to the <!--END-->.
  • To modify an existing robot territory, change the content of the robot instructions, between the <!--$ tag and the $--> tag. The next time a robot visits it will follow the new instructions.

Giving Robots Instructions

Currently robots understand the following kinds of instructions:

<!--$instructions$--> Description Example Formatted Output
<!--$$<< KnotTheory`$$--> Simulate In[1] of a KnotTheory` session. <!--$$<< KnotTheory`$$--> <!--END-->

In[2]:= << KnotTheory`

Loading KnotTheory` version of March 22, 2011, 21:10:4.67737. Read more at http://katlas.org/wiki/KnotTheory.

<!--$$Input line$$--> Simulate a Mathematica "In Out" pair. <!--$$Jones[Knot[3, 1]][q]$$--> <!--END-->
In[3]:= Jones[Knot[3, 1]][q]
Out[3]= -4 -3 1 -q + q + - q
(if output is Null) <!--$$Jones[Knot[4, 1]][q];$$--> <!--END-->
In[4]:= Jones[Knot[4, 1]][q];
(if graphics) <!--$$Show[DrawPD[Knot[5, 1]]]$$--> <!--END-->
In[5]:= Show[DrawPD[Knot[5, 1]]]
How to Edit this Manual... Out 5.gif
Out[5]= -Graphics-
<!--$$?Symbol$$--> Simulate a Mathematica help line. <!--$?Jones$--> <!--END-->
In[6]:= ?Jones
Jones[L][q] computes the Jones polynomial of a knot or link L as a function of the variable q.
(if Symbol::about exists) <!--$$?Kauffman$$--> <!--END-->
In[7]:= ?Kauffman
Kauffman[K][a, z] computes the Kauffman polynomial of a knot or link K, in the variables a and z.
In[8]:= Kauffman::about
The Kauffman polynomial program was written by Scott Morrison.
<!--$inlined command$--> Perform a Mathematica command "in line". There are <!--$NumberOfKnots[10]$--> <!--END--> knots with 10 crossings. There are 165 knots with 10 crossings.

Calling for Robotic Action

Copy Dror's robot ManualSpliceRobot.nb (File:ManualSpliceRobot.nb) to your own computer (it is now yours). The robot is a Mathematica notesbook; simply open it and follow the instructions within. You must have the package KnotTheory` around, Scott's Mathematica WikiLink package and java (which comes bundled with Mathematica 4.2 and up). You will need to specify a few paths and your (or better, your robot's) Username and Password on the Knot Atlas wiki. Good luck!

Teaching Robots New Tricks

At the moment robots do not ignore their instructions even if they don't understand them, so there can be only one robot master teaching robots what to do, or else chaos may ensue. If you want to build a better robot or extend Dror's, do it in your sandbox but don't let it roam on public pages. When the new or extended robot is fully trained, and provided its actions extends Dror's robot, send it to Dror and he will upgrade his robot and make the new robot public.