<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://katlas.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Sam.panitch</id>
	<title>Knot Atlas - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://katlas.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Sam.panitch"/>
	<link rel="alternate" type="text/html" href="https://katlas.org/wiki/Special:Contributions/Sam.panitch"/>
	<updated>2026-05-11T10:21:27Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.39.6</generator>
	<entry>
		<id>https://katlas.org/index.php?title=Threading_a_link_by_a_polynomial&amp;diff=1725866</id>
		<title>Threading a link by a polynomial</title>
		<link rel="alternate" type="text/html" href="https://katlas.org/index.php?title=Threading_a_link_by_a_polynomial&amp;diff=1725866"/>
		<updated>2025-08-05T23:05:44Z</updated>

		<summary type="html">&lt;p&gt;Sam.panitch: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;code&amp;gt;CableLink[link,poly,strandList,vars]&amp;lt;/code&amp;gt;, whose code is available [[cableLink.m|here]], computes the Kauffman bracket of link (given as a PD) with components L1,L2,...,Ln, cabled by the polynomial poly in the variables z1,z2,...,zn. strandList is a list of strand labels of length n, where the ith element is the first strand label corresponding to component Li.&lt;br /&gt;
As an example, we can verify some formulas from {{ref|Masbaum}}, after importing KnotTheory` and the CableLink code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--$$hopfLink=PD[X[3,1,4,2],X[2,4,1,3]]; //&lt;br /&gt;
bracket[n_]:=a^n-a^(-n); //&lt;br /&gt;
bracketFact[n_]:=Product[bracket[i],{i,1,n}]; //&lt;br /&gt;
lambda[n_] := A^(2*n + 2) + A^(-2*n - 2); //&lt;br /&gt;
R[z_, n_] := Product[z + lambda[2*i], {i, 0, n - 1}]; //&lt;br /&gt;
cheb[0, z_] = 1; &lt;br /&gt;
cheb[1, z_] = z;&lt;br /&gt;
cheb[n_, z_] := cheb[n, z] = z*cheb[n - 1, z] - cheb[n - 2, z];&lt;br /&gt;
$$--&amp;gt;&lt;br /&gt;
&amp;lt;!--Robot Land, no human edits to &amp;quot;END&amp;quot;--&amp;gt;&lt;br /&gt;
{{In|&lt;br /&gt;
n  = 3 |&lt;br /&gt;
in = &amp;lt;nowiki&amp;gt;hopfLink=PD[X[3,1,4,2],X[2,4,1,3]];&lt;br /&gt;
bracket[n_]:=a^n-a^(-n);&lt;br /&gt;
bracketFact[n_]:=Product[bracket[i],{i,1,n}];&lt;br /&gt;
lambda[n_] := A^(2*n + 2) + A^(-2*n - 2);&lt;br /&gt;
R[z_, n_] := Product[z + lambda[2*i], {i, 0, n - 1}];&lt;br /&gt;
cheb[0, z_] = 1; &lt;br /&gt;
cheb[1, z_] = z;&lt;br /&gt;
cheb[n_, z_] := cheb[n, z] = z*cheb[n - 1, z] - cheb[n - 2, z];&amp;lt;/nowiki&amp;gt; |&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;!--END--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--$$Expand[CableLink[hopfLink, &lt;br /&gt;
   R[Subscript[z, 1], 1]*cheb[2, Subscript[z, 2]], {1, 3}, {Subscript[&lt;br /&gt;
    z, 1], Subscript[z, 2]}] /. {A -&amp;gt; a^(1/2)}] //&lt;br /&gt;
Expand[(-1)^1*bracketFact[3]/bracket[1]]&lt;br /&gt;
$$--&amp;gt;&lt;br /&gt;
&amp;lt;!--Robot Land, no human edits to &amp;quot;END&amp;quot;--&amp;gt;&lt;br /&gt;
{{InOut|&lt;br /&gt;
n  = 4 |&lt;br /&gt;
in = &amp;lt;nowiki&amp;gt;Expand[CableLink[hopfLink, &lt;br /&gt;
   R[Subscript[z, 1], 1]*cheb[2, Subscript[z, 2]], {1, 3}, {Subscript[&lt;br /&gt;
    z, 1], Subscript[z, 2]}] /. {A -&amp;gt; a^(1/2)}]&lt;br /&gt;
Expand[(-1)^1*bracketFact[3]/bracket[1]]&amp;lt;/nowiki&amp;gt; |&lt;br /&gt;
out= &amp;lt;nowiki&amp;gt;-1/a^5 + 1/a + a - a^5 &lt;br /&gt;
-1/a^5 + 1/a + a - a^5&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&amp;lt;!--END--&amp;gt;&lt;br /&gt;
&amp;lt;!--$$Expand[CableLink[hopfLink, &lt;br /&gt;
   R[Subscript[z, 1], 2]*cheb[4, Subscript[z, 2]], {1, 3}, {Subscript[&lt;br /&gt;
    z, 1], Subscript[z, 2]}] /. {A -&amp;gt; a^(1/2)}]&lt;br /&gt;
Expand[(-1)^2*bracketFact[5]/bracket[1]] //&lt;br /&gt;
$$--&amp;gt;&lt;br /&gt;
{{InOut|&lt;br /&gt;
n  = 5 |&lt;br /&gt;
in = &amp;lt;nowiki&amp;gt;Expand[CableLink[hopfLink, &lt;br /&gt;
   R[Subscript[z, 1], 2]*cheb[4, Subscript[z, 2]], {1, 3}, {Subscript[&lt;br /&gt;
    z, 1], Subscript[z, 2]}] /. {A -&amp;gt; a^(1/2)}]&lt;br /&gt;
Expand[(-1)^2*bracketFact[5]/bracket[1]]&amp;lt;/nowiki&amp;gt; |&lt;br /&gt;
out= &amp;lt;nowiki&amp;gt;2 + 1/a^14 - 1/a^10 - 1/a^8 - 1/a^6 + 1/a^2 + a^2 - a^6 - a^8 - a^10 + a^14&lt;br /&gt;
2 + 1/a^14 - 1/a^10 - 1/a^8 - 1/a^6 + 1/a^2 + a^2 - a^6 - a^8 - a^10 + a^14&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&amp;lt;!--END--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{note|Masbaum}} Masbaum, Gregor. &#039;&#039;Skein-theoretical derivations of some formulas of Habiro.&#039;&#039; Alg. and Geo. Topology 3 (2003): 537–556. https://doi.org/10.2140/agt.2003.3.537&lt;/div&gt;</summary>
		<author><name>Sam.panitch</name></author>
	</entry>
	<entry>
		<id>https://katlas.org/index.php?title=Threading_a_link_by_a_polynomial&amp;diff=1725865</id>
		<title>Threading a link by a polynomial</title>
		<link rel="alternate" type="text/html" href="https://katlas.org/index.php?title=Threading_a_link_by_a_polynomial&amp;diff=1725865"/>
		<updated>2025-08-05T23:04:46Z</updated>

		<summary type="html">&lt;p&gt;Sam.panitch: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;code&amp;gt;CableLink[link,poly,strandList,vars]&amp;lt;/code&amp;gt;, whose code is available [[cableLink.m|here]], computes the Kauffman bracket of link (given as a PD) with components L1,L2,...,Ln, cabled by the polynomial poly in the variables z1,z2,...,zn. strandList is a list of strand labels of length n, where the ith element is the first strand label corresponding to component Li.&lt;br /&gt;
As an example, we can verify some formulas from {{ref|Masbaum}}, after importing KnotTheory` and the CableLink code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--$$hopfLink=PD[X[3,1,4,2],X[2,4,1,3]]; //&lt;br /&gt;
bracket[n_]:=a^n-a^(-n); //&lt;br /&gt;
bracketFact[n_]:=Product[bracket[i],{i,1,n}]; //&lt;br /&gt;
lambda[n_] := A^(2*n + 2) + A^(-2*n - 2); //&lt;br /&gt;
R[z_, n_] := Product[z + lambda[2*i], {i, 0, n - 1}]; //&lt;br /&gt;
cheb[0, z_] = 1; &lt;br /&gt;
cheb[1, z_] = z;&lt;br /&gt;
cheb[n_, z_] := cheb[n, z] = z*cheb[n - 1, z] - cheb[n - 2, z];&lt;br /&gt;
$$--&amp;gt;&lt;br /&gt;
&amp;lt;!--Robot Land, no human edits to &amp;quot;END&amp;quot;--&amp;gt;&lt;br /&gt;
{{In|&lt;br /&gt;
n  = 3 |&lt;br /&gt;
in = &amp;lt;nowiki&amp;gt;hopfLink=PD[X[3,1,4,2],X[2,4,1,3]];&lt;br /&gt;
bracket[n_]:=a^n-a^(-n);&lt;br /&gt;
bracketFact[n_]:=Product[bracket[i],{i,1,n}];&lt;br /&gt;
lambda[n_] := A^(2*n + 2) + A^(-2*n - 2);&lt;br /&gt;
R[z_, n_] := Product[z + lambda[2*i], {i, 0, n - 1}];&lt;br /&gt;
cheb[0, z_] = 1; &lt;br /&gt;
cheb[1, z_] = z;&lt;br /&gt;
cheb[n_, z_] := cheb[n, z] = z*cheb[n - 1, z] - cheb[n - 2, z];&amp;lt;/nowiki&amp;gt; |&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;!--END--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--$$Expand[CableLink[hopfLink, &lt;br /&gt;
   R[Subscript[z, 1], 1]*cheb[2, Subscript[z, 2]], {1, 3}, {Subscript[&lt;br /&gt;
    z, 1], Subscript[z, 2]}] /. {A -&amp;gt; a^(1/2)}] //&lt;br /&gt;
Expand[(-1)^1*bracketFact[3]/bracket[1]]&lt;br /&gt;
$$--&amp;gt;&lt;br /&gt;
&amp;lt;!--Robot Land, no human edits to &amp;quot;END&amp;quot;--&amp;gt;&lt;br /&gt;
{{InOut|&lt;br /&gt;
n  = 4 |&lt;br /&gt;
in = &amp;lt;nowiki&amp;gt;Expand[CableLink[hopfLink, &lt;br /&gt;
   R[Subscript[z, 1], 1]*cheb[2, Subscript[z, 2]], {1, 3}, {Subscript[&lt;br /&gt;
    z, 1], Subscript[z, 2]}] /. {A -&amp;gt; a^(1/2)}]&lt;br /&gt;
Expand[(-1)^1*bracketFact[3]/bracket[1]]&amp;lt;/nowiki&amp;gt; |&lt;br /&gt;
out= &amp;lt;nowiki&amp;gt;-1/a^5 + 1/a + a - a^5 &lt;br /&gt;
-1/a^5 + 1/a + a - a^5&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&amp;lt;!--END--&amp;gt;&lt;br /&gt;
&amp;lt;!--$$Expand[CableLink[hopfLink, &lt;br /&gt;
   R[Subscript[z, 1], 2]*cheb[4, Subscript[z, 2]], {1, 3}, {Subscript[&lt;br /&gt;
    z, 1], Subscript[z, 2]}] /. {A -&amp;gt; a^(1/2)}]&lt;br /&gt;
Expand[(-1)^2*bracketFact[5]/bracket[1]] //&lt;br /&gt;
$$--&amp;gt;&lt;br /&gt;
{{InOut|&lt;br /&gt;
n  = 5 |&lt;br /&gt;
in = &amp;lt;nowiki&amp;gt;Expand[CableLink[hopfLink, &lt;br /&gt;
   R[Subscript[z, 1], 2]*cheb[4, Subscript[z, 2]], {1, 3}, {Subscript[&lt;br /&gt;
    z, 1], Subscript[z, 2]}] /. {A -&amp;gt; a^(1/2)}]&lt;br /&gt;
Expand[(-1)^1*bracketFact[3]/bracket[1]]&amp;lt;/nowiki&amp;gt; |&lt;br /&gt;
out= &amp;lt;nowiki&amp;gt;2 + 1/a^14 - 1/a^10 - 1/a^8 - 1/a^6 + 1/a^2 + a^2 - a^6 - a^8 - a^10 + a^14&lt;br /&gt;
2 + 1/a^14 - 1/a^10 - 1/a^8 - 1/a^6 + 1/a^2 + a^2 - a^6 - a^8 - a^10 + a^14&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&amp;lt;!--END--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{note|Masbaum}} Masbaum, Gregor. &#039;&#039;Skein-theoretical derivations of some formulas of Habiro.&#039;&#039; Alg. and Geo. Topology 3 (2003): 537–556. https://doi.org/10.2140/agt.2003.3.537&lt;/div&gt;</summary>
		<author><name>Sam.panitch</name></author>
	</entry>
	<entry>
		<id>https://katlas.org/index.php?title=Threading_a_link_by_a_polynomial&amp;diff=1725864</id>
		<title>Threading a link by a polynomial</title>
		<link rel="alternate" type="text/html" href="https://katlas.org/index.php?title=Threading_a_link_by_a_polynomial&amp;diff=1725864"/>
		<updated>2025-08-05T23:04:34Z</updated>

		<summary type="html">&lt;p&gt;Sam.panitch: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;code&amp;gt;CableLink[link,poly,strandList,vars]&amp;lt;/code&amp;gt;, whose code is available [[cableLink.m|here]], computes the Kauffman bracket of link (given as a PD) with components L1,L2,...,Ln, cabled by the polynomial poly in the variables z1,z2,...,zn. strandList is a list of strand labels of length n, where the ith element is the first strand label corresponding to component Li.&lt;br /&gt;
As an example, we can verify some formulas from {{ref|Masbaum}}, after importing KnotTheory` and the CableLink code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--$$hopfLink=PD[X[3,1,4,2],X[2,4,1,3]]; //&lt;br /&gt;
bracket[n_]:=a^n-a^(-n); //&lt;br /&gt;
bracketFact[n_]:=Product[bracket[i],{i,1,n}]; //&lt;br /&gt;
lambda[n_] := A^(2*n + 2) + A^(-2*n - 2); //&lt;br /&gt;
R[z_, n_] := Product[z + lambda[2*i], {i, 0, n - 1}]; //&lt;br /&gt;
cheb[0, z_] = 1; &lt;br /&gt;
cheb[1, z_] = z;&lt;br /&gt;
cheb[n_, z_] := cheb[n, z] = z*cheb[n - 1, z] - cheb[n - 2, z];&lt;br /&gt;
$$--&amp;gt;&lt;br /&gt;
&amp;lt;!--Robot Land, no human edits to &amp;quot;END&amp;quot;--&amp;gt;&lt;br /&gt;
{{In|&lt;br /&gt;
n  = 3 |&lt;br /&gt;
in = &amp;lt;nowiki&amp;gt;hopfLink=PD[X[3,1,4,2],X[2,4,1,3]];&lt;br /&gt;
bracket[n_]:=a^n-a^(-n);&lt;br /&gt;
bracketFact[n_]:=Product[bracket[i],{i,1,n}];&lt;br /&gt;
R[z_, n_] := Product[z + lambda[2*i], {i, 0, n - 1}];&lt;br /&gt;
cheb[0, z_] = 1; &lt;br /&gt;
cheb[1, z_] = z;&lt;br /&gt;
cheb[n_, z_] := cheb[n, z] = z*cheb[n - 1, z] - cheb[n - 2, z];&amp;lt;/nowiki&amp;gt; |&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;!--END--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--$$Expand[CableLink[hopfLink, &lt;br /&gt;
   R[Subscript[z, 1], 1]*cheb[2, Subscript[z, 2]], {1, 3}, {Subscript[&lt;br /&gt;
    z, 1], Subscript[z, 2]}] /. {A -&amp;gt; a^(1/2)}] //&lt;br /&gt;
Expand[(-1)^1*bracketFact[3]/bracket[1]]&lt;br /&gt;
$$--&amp;gt;&lt;br /&gt;
&amp;lt;!--Robot Land, no human edits to &amp;quot;END&amp;quot;--&amp;gt;&lt;br /&gt;
{{InOut|&lt;br /&gt;
n  = 4 |&lt;br /&gt;
in = &amp;lt;nowiki&amp;gt;Expand[CableLink[hopfLink, &lt;br /&gt;
   R[Subscript[z, 1], 1]*cheb[2, Subscript[z, 2]], {1, 3}, {Subscript[&lt;br /&gt;
    z, 1], Subscript[z, 2]}] /. {A -&amp;gt; a^(1/2)}]&lt;br /&gt;
Expand[(-1)^1*bracketFact[3]/bracket[1]]&amp;lt;/nowiki&amp;gt; |&lt;br /&gt;
out= &amp;lt;nowiki&amp;gt;-1/a^5 + 1/a + a - a^5 &lt;br /&gt;
-1/a^5 + 1/a + a - a^5&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&amp;lt;!--END--&amp;gt;&lt;br /&gt;
&amp;lt;!--$$Expand[CableLink[hopfLink, &lt;br /&gt;
   R[Subscript[z, 1], 2]*cheb[4, Subscript[z, 2]], {1, 3}, {Subscript[&lt;br /&gt;
    z, 1], Subscript[z, 2]}] /. {A -&amp;gt; a^(1/2)}]&lt;br /&gt;
Expand[(-1)^2*bracketFact[5]/bracket[1]] //&lt;br /&gt;
$$--&amp;gt;&lt;br /&gt;
{{InOut|&lt;br /&gt;
n  = 5 |&lt;br /&gt;
in = &amp;lt;nowiki&amp;gt;Expand[CableLink[hopfLink, &lt;br /&gt;
   R[Subscript[z, 1], 2]*cheb[4, Subscript[z, 2]], {1, 3}, {Subscript[&lt;br /&gt;
    z, 1], Subscript[z, 2]}] /. {A -&amp;gt; a^(1/2)}]&lt;br /&gt;
Expand[(-1)^1*bracketFact[3]/bracket[1]]&amp;lt;/nowiki&amp;gt; |&lt;br /&gt;
out= &amp;lt;nowiki&amp;gt;2 + 1/a^14 - 1/a^10 - 1/a^8 - 1/a^6 + 1/a^2 + a^2 - a^6 - a^8 - a^10 + a^14&lt;br /&gt;
2 + 1/a^14 - 1/a^10 - 1/a^8 - 1/a^6 + 1/a^2 + a^2 - a^6 - a^8 - a^10 + a^14&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&amp;lt;!--END--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{note|Masbaum}} Masbaum, Gregor. &#039;&#039;Skein-theoretical derivations of some formulas of Habiro.&#039;&#039; Alg. and Geo. Topology 3 (2003): 537–556. https://doi.org/10.2140/agt.2003.3.537&lt;/div&gt;</summary>
		<author><name>Sam.panitch</name></author>
	</entry>
	<entry>
		<id>https://katlas.org/index.php?title=CableLink.m&amp;diff=1725863</id>
		<title>CableLink.m</title>
		<link rel="alternate" type="text/html" href="https://katlas.org/index.php?title=CableLink.m&amp;diff=1725863"/>
		<updated>2025-08-05T23:03:21Z</updated>

		<summary type="html">&lt;p&gt;Sam.panitch: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;(*&lt;br /&gt;
The program &amp;lt;code&amp;gt;CableLink&amp;lt;/code&amp;gt; is documented on the page [[Threading a link by a polynomial]]. It is not part of the package &amp;lt;code&amp;gt;KnotTheory`&amp;lt;/code&amp;gt; but is designed to work with it. Copy-paste the text below ignoring the &amp;lt;code&amp;gt;*&amp;amp;#41;&amp;lt;/code&amp;gt; on the first line and the &amp;lt;code&amp;gt;&amp;amp;#40;*&amp;lt;/code&amp;gt; on the last.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
*)&lt;br /&gt;
&lt;br /&gt;
(*Kauffman bracket*)&lt;br /&gt;
KB1[pd_PD] := KB1[pd, {}, 1];&lt;br /&gt;
KB1[pd_PD, inside_, web_] := &lt;br /&gt;
  Module[{pos = &lt;br /&gt;
     First[Ordering[Length[Complement[List @@ #, inside]] &amp;amp; /@ pd]]}, &lt;br /&gt;
   pd[[pos]] /.  &lt;br /&gt;
    X[a_, b_, c_, d_] :&amp;gt; &lt;br /&gt;
     KB1[Delete[pd, pos], Union[inside, {a, b, c, d}], &lt;br /&gt;
      Expand[web*(A P[a, d] P[b, c] + 1/A P[a, b] P[c, d])] //. {P[e_,&lt;br /&gt;
            f_] P[f_, g_] :&amp;gt; P[e, g], P[e_, _]^2 :&amp;gt; P[e, e], &lt;br /&gt;
        P[e_, e_] -&amp;gt; -A^2 - 1/A^2}]];&lt;br /&gt;
KB1[PD[], _, web_] := Expand[web]&lt;br /&gt;
(*Position of a strand at a crossing*)&lt;br /&gt;
strandAtCrossing[crossing_, s_] := Module[{pos},&lt;br /&gt;
   pos = Position[crossing, s];&lt;br /&gt;
   If[Length[pos] &amp;gt; 0, pos[[1, 1]], False]&lt;br /&gt;
   ];&lt;br /&gt;
(*Orientation of overstrand. Complicated by components with only two strand labels*)&lt;br /&gt;
orientationOfOverStrand[crossing_, link_] := Module[{otherCrossings},&lt;br /&gt;
   (*find the other crossings containing the strand labels of the \&lt;br /&gt;
overstrand crossing*)&lt;br /&gt;
   otherCrossings = &lt;br /&gt;
    DeleteElements[&lt;br /&gt;
     Select[link, &lt;br /&gt;
      ContainsAny[&lt;br /&gt;
        List[Delete[#, 0]], {crossing[[2]], &lt;br /&gt;
         crossing[[4]]}] &amp;amp;], {crossing}];&lt;br /&gt;
   (*if the length of othercrossings is 1, &lt;br /&gt;
   then the overstrand labels are part of a component with only two \&lt;br /&gt;
strand labels*)&lt;br /&gt;
   If[Length[otherCrossings] == 1,&lt;br /&gt;
    (*first check if a strand label is in the first position of the \&lt;br /&gt;
other crossing.*)&lt;br /&gt;
    Which[otherCrossings[[1, 1]] == crossing[[2]],&lt;br /&gt;
     True,&lt;br /&gt;
     otherCrossings[[1, 1]] == crossing[[4]],&lt;br /&gt;
     False,&lt;br /&gt;
     (*Otherwise, the strands are always overcrossings, &lt;br /&gt;
     in which case we just choose to orient from small to large*)&lt;br /&gt;
     True,&lt;br /&gt;
     crossing[[2]] &amp;gt; crossing[[4]]&lt;br /&gt;
     ],&lt;br /&gt;
    (*otherwise, &lt;br /&gt;
    the overcrossing is oriented from 4 to 2 if pos 2 is 1 more than \&lt;br /&gt;
pos 4, or if pos 4 is more than 1 greater than pos 2.*)&lt;br /&gt;
     crossing[[2]] - crossing[[4]] == 1 || &lt;br /&gt;
     crossing[[4]] - crossing[[2]] &amp;gt; 1&lt;br /&gt;
    ]&lt;br /&gt;
   ];&lt;br /&gt;
(*crossing that a strand enters*)&lt;br /&gt;
findEnteringVertex[link_, s_] := &lt;br /&gt;
  Module[{crossingsContainingS, firstCrossing, pos},&lt;br /&gt;
   (*find crossings containing s*)&lt;br /&gt;
   crossingsContainingS = &lt;br /&gt;
    Select[link, IntegerQ[strandAtCrossing[#, s]] &amp;amp;];&lt;br /&gt;
   firstCrossing = crossingsContainingS[[1]];&lt;br /&gt;
   pos = strandAtCrossing[firstCrossing, s];&lt;br /&gt;
   Which[&lt;br /&gt;
    (*if pos is 1, then it is definitely an incoming strand*)&lt;br /&gt;
    pos == 1,&lt;br /&gt;
    firstCrossing,&lt;br /&gt;
    (pos == 2 &amp;amp;&amp;amp; ! &lt;br /&gt;
        orientationOfOverStrand[firstCrossing, link]) || (pos == 4 &amp;amp;&amp;amp; &lt;br /&gt;
       orientationOfOverStrand[firstCrossing, link]),&lt;br /&gt;
    firstCrossing,&lt;br /&gt;
    (*otherwise it must be the entering strand at the other vertex \&lt;br /&gt;
containing that label*)&lt;br /&gt;
    True,&lt;br /&gt;
    crossingsContainingS[[2]]&lt;br /&gt;
    ]&lt;br /&gt;
   ];&lt;br /&gt;
duplicateVertex[link_, crossing_, strands_] := &lt;br /&gt;
  Module[{pos = strandAtCrossing[crossing, strands[[1]]], &lt;br /&gt;
    newLabel = Length[link]*2 + 2, &lt;br /&gt;
    newLink = DeleteElements[link, {crossing}], p1 = crossing[[1]], &lt;br /&gt;
    p2 = crossing[[2]], p3 = crossing[[3]], p4 = crossing[[4]]},&lt;br /&gt;
   Which[&lt;br /&gt;
    (*pos is 1 and the upper strand is oriented from 4 to 2*)&lt;br /&gt;
    pos == 1  &amp;amp;&amp;amp; orientationOfOverStrand[crossing, link],&lt;br /&gt;
    {Union[&lt;br /&gt;
      increaseStrandLabels[newLink, p4],&lt;br /&gt;
      PD[&lt;br /&gt;
       X[If[p1 &amp;lt; p2, p1, p1 + 1], p4 + 1, If[p3 &amp;lt; p2, p3, p3 + 1], &lt;br /&gt;
        p4]],&lt;br /&gt;
      PD[X[newLabel, If[p2 &amp;gt; p4, p2 + 1, p2], newLabel + 1, p4 + 1]]&lt;br /&gt;
      ],&lt;br /&gt;
     Map[If[# &amp;lt;= p2, #, # + 1] &amp;amp;, Prepend[strands[[2 ;;]], p3]]&lt;br /&gt;
     },&lt;br /&gt;
    (*pos is 1 and the upper strand is oriented from 2 to 4*)&lt;br /&gt;
    pos == 1,&lt;br /&gt;
    {Union[&lt;br /&gt;
      increaseStrandLabels[newLink, p2],&lt;br /&gt;
      PD[&lt;br /&gt;
       X[If[p1 &amp;lt; p2, p1, p1 + 1], p2 + 1, If[p3 &amp;lt; p2, p3, p3 + 1], &lt;br /&gt;
        If[p4 &amp;lt; p2, p4, p4 + 1]]],&lt;br /&gt;
      PD[X[newLabel, p2, newLabel + 1, p2 + 1]]&lt;br /&gt;
      ],&lt;br /&gt;
     Map[If[# &amp;lt;= p2, #, # + 1] &amp;amp;, Prepend[strands[[2 ;;]], p3]]&lt;br /&gt;
     },&lt;br /&gt;
    (*pos is 2*)&lt;br /&gt;
    pos == 2,&lt;br /&gt;
    {Union[&lt;br /&gt;
      increaseStrandLabels[newLink, p1],&lt;br /&gt;
      PD[&lt;br /&gt;
       X[p1, If[p2 &amp;lt; p1, p2, p2 + 1], p1 + 1, &lt;br /&gt;
        If[p4 &amp;lt; p1, p4, p4 + 1]]],&lt;br /&gt;
      PD[X[p1 + 1, newLabel, If[p3 &amp;lt; p1, p3, p3 + 1], newLabel + 1]]&lt;br /&gt;
      ],&lt;br /&gt;
     Map[If[# &amp;lt;= p1, #, # + 1] &amp;amp;, Prepend[strands[[2 ;;]], p4]]&lt;br /&gt;
     },&lt;br /&gt;
    (*pos is 4*)&lt;br /&gt;
    True,&lt;br /&gt;
    {Union[&lt;br /&gt;
      increaseStrandLabels[newLink, p1],&lt;br /&gt;
      PD[&lt;br /&gt;
       X[p1 + 1, If[p2 &amp;lt; p1, p2, p2 + 1], If[p3 &amp;lt; p1, p3, p3 + 1], &lt;br /&gt;
        If[p4 &amp;lt; p1, p4, p4 + 1]]],&lt;br /&gt;
      PD[X[p1, newLabel + 1, p1 + 1, newLabel]]&lt;br /&gt;
      ],&lt;br /&gt;
     Map[If[# &amp;lt;= p1, #, # + 1] &amp;amp;, Prepend[strands[[2 ;;]], p2]]&lt;br /&gt;
     }&lt;br /&gt;
    ]&lt;br /&gt;
   ];&lt;br /&gt;
deleteVertex[link_, crossing_, s_, strandList_] := &lt;br /&gt;
 Module[{newCrossing = crossing, &lt;br /&gt;
   newLink = DeleteElements[link, {crossing}], min, max, &lt;br /&gt;
   pos = strandAtCrossing[crossing, s], outgoingStrandPos, &lt;br /&gt;
   newStrandList = strandList},&lt;br /&gt;
  (*we create an unknot if the two labels of the other strand at the \&lt;br /&gt;
crossing are equal*)&lt;br /&gt;
  Which[(pos == 1 &amp;amp;&amp;amp; crossing[[2]] == crossing[[4]]) , &lt;br /&gt;
   newStrandList = &lt;br /&gt;
    Replace[newStrandList, &lt;br /&gt;
     crossing[[2]] -&amp;gt; 0, {1}], (pos == 2 || pos == 4 ) &amp;amp;&amp;amp; &lt;br /&gt;
    crossing[[1]] == crossing[[3]], &lt;br /&gt;
   newStrandList = Replace[newStrandList, crossing[[1]] -&amp;gt; 0, {1}]];&lt;br /&gt;
  (*&amp;quot;&lt;br /&gt;
	we need to keep track of the outgoing strand label. There&#039;s actually \&lt;br /&gt;
two ways to know we&#039;re done:&lt;br /&gt;
	either the outgoing strand is the same as the incoming strand, or \&lt;br /&gt;
the whole vertex only involves 2 different labels.&lt;br /&gt;
&amp;quot;*)&lt;br /&gt;
  outgoingStrandPos = Which[pos == 1, 3, pos == 2, 4, True, 2];&lt;br /&gt;
  If[crossing[[outgoingStrandPos]] == s || &lt;br /&gt;
    CountDistinct[{Delete[crossing, 0]}] &amp;lt; 3, &lt;br /&gt;
   outgoingStrandPos = -1];&lt;br /&gt;
  (*adjust link after combining pos 1 and pos 3*)&lt;br /&gt;
  If[crossing[[1]] &amp;gt; crossing[[3]],&lt;br /&gt;
   newLink = &lt;br /&gt;
    decreaseStrandLabels[&lt;br /&gt;
     Replace[newLink, crossing[[1]] -&amp;gt; crossing[[3]], {2}], &lt;br /&gt;
     newCrossing[[1]]];&lt;br /&gt;
   newCrossing = &lt;br /&gt;
    decreaseStrandLabels[{Replace[newCrossing, &lt;br /&gt;
        crossing[[1]] -&amp;gt; crossing[[3]], {1}]}, newCrossing[[1]]][[&lt;br /&gt;
     1]];&lt;br /&gt;
   newStrandList = &lt;br /&gt;
    Map[If[# &amp;gt; newCrossing[[1]], # - 1, #] &amp;amp;, &lt;br /&gt;
     Replace[newStrandList, crossing[[1]] -&amp;gt; crossing[[3]], {1}]]&lt;br /&gt;
   ,&lt;br /&gt;
   newLink = decreaseStrandLabels[newLink, newCrossing[[1]]];&lt;br /&gt;
   newCrossing = &lt;br /&gt;
    decreaseStrandLabels[{newCrossing}, newCrossing[[1]]][[1]];&lt;br /&gt;
   newStrandList = &lt;br /&gt;
    Map[If[# &amp;gt; newCrossing[[1]], # - 1, #] &amp;amp;, newStrandList]&lt;br /&gt;
   ];&lt;br /&gt;
  (*adjust link after combining pos 2 and pos 4*)&lt;br /&gt;
  min = Min[newCrossing[[2]], newCrossing[[4]]];&lt;br /&gt;
  max = Max[newCrossing[[2]], newCrossing[[4]]];&lt;br /&gt;
  If[max - min &amp;gt; 1,&lt;br /&gt;
   newLink = &lt;br /&gt;
    decreaseStrandLabels[Replace[newLink, max -&amp;gt; min, {2}], max];&lt;br /&gt;
   newCrossing = &lt;br /&gt;
    decreaseStrandLabels[{Replace[newCrossing, max -&amp;gt; min, {1}]}, &lt;br /&gt;
      max][[1]];&lt;br /&gt;
   newStrandList = &lt;br /&gt;
    Map[If[# &amp;gt; max, # - 1, #] &amp;amp;, &lt;br /&gt;
     Replace[newStrandList, max -&amp;gt; min, {1}]],&lt;br /&gt;
   newLink = decreaseStrandLabels[newLink, min];&lt;br /&gt;
   newCrossing = decreaseStrandLabels[{newCrossing}, min][[1]];&lt;br /&gt;
   newStrandList = Map[If[# &amp;gt; max, # - 1, #] &amp;amp;, newStrandList]&lt;br /&gt;
   ];&lt;br /&gt;
  {newLink, &lt;br /&gt;
   If[outgoingStrandPos &amp;gt; 0, newCrossing[[outgoingStrandPos]], -1], &lt;br /&gt;
   newStrandList}&lt;br /&gt;
  ]&lt;br /&gt;
increaseStrandLabels[link_, s_] := &lt;br /&gt;
  Replace[link, n_?(# &amp;gt; s &amp;amp;) -&amp;gt; n + 1, {2}];&lt;br /&gt;
decreaseStrandLabels[link_, s_] := &lt;br /&gt;
  Replace[link, n_?(# &amp;gt; s &amp;amp;) -&amp;gt; n - 1, {2}];&lt;br /&gt;
cableComponent[link_, s_, strandList_] := &lt;br /&gt;
  Module[{initialStrands, newComponentLabel = 2 Length[link] + 1},&lt;br /&gt;
   initialStrands = Join[{s, s, newComponentLabel}, strandList];&lt;br /&gt;
   recurse[newLink_, strands_] := &lt;br /&gt;
    Module[{currentStrand = strands[[1]], firstStrand = strands[[2]], &lt;br /&gt;
      currentCrossing, updatedLink, &lt;br /&gt;
      updatedStrands},(*copy the current crossing*)&lt;br /&gt;
     currentCrossing = findEnteringVertex[newLink, currentStrand];&lt;br /&gt;
     {updatedLink, updatedStrands} = &lt;br /&gt;
      duplicateVertex[newLink, currentCrossing, strands];&lt;br /&gt;
     (*check if we&#039;ve returned to the first strand*)&lt;br /&gt;
     If[updatedStrands[[1]] == updatedStrands[[2]],&lt;br /&gt;
      (*replace the largest strand label with the first strand label \&lt;br /&gt;
of the new component*)&lt;br /&gt;
      {Replace[updatedLink, &lt;br /&gt;
        n_?(# == 2 Length[updatedLink] + 1 &amp;amp;) -&amp;gt; &lt;br /&gt;
         updatedStrands[[3]], {2}], &lt;br /&gt;
       updatedStrands[[4 ;;]]},(*keep adding crossings*)&lt;br /&gt;
      recurse[updatedLink, updatedStrands]]&lt;br /&gt;
     ];&lt;br /&gt;
   recurse[link, initialStrands]&lt;br /&gt;
   ];&lt;br /&gt;
deleteComponent[link_, s_, strandList_] := &lt;br /&gt;
  Module[{newLink, currentStrand, newStrandList, currentCrossing},&lt;br /&gt;
   If[s &amp;lt;= 0,&lt;br /&gt;
    (*we&#039;re done deleting stuff*)&lt;br /&gt;
    {link, strandList},&lt;br /&gt;
    (*keep deleting*)&lt;br /&gt;
    currentCrossing = findEnteringVertex[link, s];&lt;br /&gt;
    {newLink, currentStrand, newStrandList} = &lt;br /&gt;
     deleteVertex[link, currentCrossing, s, strandList];&lt;br /&gt;
    deleteComponent[newLink, currentStrand, newStrandList]&lt;br /&gt;
    ]&lt;br /&gt;
   ];&lt;br /&gt;
cableLinkMonomial[link_, strandList_, degreeList_] := &lt;br /&gt;
  Module[{newLink = link, newStrandList, newDegreeList, coeff = 1},&lt;br /&gt;
   (*reorder so that we&#039;re deleting components first*)&lt;br /&gt;
   {newDegreeList, newStrandList} = {degreeList, strandList}[[All, &lt;br /&gt;
     Ordering@degreeList]];&lt;br /&gt;
   (*start cabling*)&lt;br /&gt;
   Do[&lt;br /&gt;
    Which[&lt;br /&gt;
     newStrandList[[i]] == 0,&lt;br /&gt;
     (*it&#039;s an unknot*)&lt;br /&gt;
     coeff = coeff*(-A^2 - A^(-2))^newDegreeList[[i]],&lt;br /&gt;
     newDegreeList[[i]] == 0,&lt;br /&gt;
     (*we need to delete it*)&lt;br /&gt;
     {newLink, newStrandList} = &lt;br /&gt;
      deleteComponent[newLink, newStrandList[[i]], newStrandList],&lt;br /&gt;
     True,&lt;br /&gt;
     (*cable the component*)&lt;br /&gt;
     Do[&lt;br /&gt;
      {newLink, newStrandList} = &lt;br /&gt;
       cableComponent[newLink, newStrandList[[i]], newStrandList]&lt;br /&gt;
      , {j, 1, newDegreeList[[i]] - 1}]&lt;br /&gt;
     ]&lt;br /&gt;
    , {i, 1, Length[newStrandList]}&lt;br /&gt;
    ];&lt;br /&gt;
   coeff*KB1[newLink]&lt;br /&gt;
   ];&lt;br /&gt;
CableLink[link_, poly_, strandList_, vars_] := &lt;br /&gt;
 Module[{monomials = CoefficientRules[poly, vars], temp},&lt;br /&gt;
  Total[&lt;br /&gt;
   Map[&lt;br /&gt;
    #[[2]]*cableLinkMonomial[link, strandList, #[[1]]] &amp;amp;&lt;br /&gt;
    , monomials]]&lt;br /&gt;
  ]&lt;br /&gt;
&lt;br /&gt;
(* &amp;lt;/pre&amp;gt; *)&lt;/div&gt;</summary>
		<author><name>Sam.panitch</name></author>
	</entry>
	<entry>
		<id>https://katlas.org/index.php?title=CableLink.m&amp;diff=1725862</id>
		<title>CableLink.m</title>
		<link rel="alternate" type="text/html" href="https://katlas.org/index.php?title=CableLink.m&amp;diff=1725862"/>
		<updated>2025-08-05T22:59:13Z</updated>

		<summary type="html">&lt;p&gt;Sam.panitch: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;(*&lt;br /&gt;
The program &amp;lt;code&amp;gt;CableLink&amp;lt;/code&amp;gt; is documented on the page [[Threading a link by a polynomial]]. It is not part of the package &amp;lt;code&amp;gt;KnotTheory`&amp;lt;/code&amp;gt; but is designed to work with it. Copy-paste the text below ignoring the &amp;lt;code&amp;gt;*&amp;amp;#41;&amp;lt;/code&amp;gt; on the first line and the &amp;lt;code&amp;gt;&amp;amp;#40;*&amp;lt;/code&amp;gt; on the last.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
*)&lt;br /&gt;
&lt;br /&gt;
(*Kauffman bracket*)&lt;br /&gt;
KB1[pd_PD] := KB1[pd, {}, 1];&lt;br /&gt;
KB1[pd_PD, inside_, web_] := &lt;br /&gt;
  Module[{pos = &lt;br /&gt;
     First[Ordering[Length[Complement[List @@ #, inside]] &amp;amp; /@ pd]]}, &lt;br /&gt;
   pd[[pos]] /.  &lt;br /&gt;
    X[a_, b_, c_, d_] :&amp;gt; &lt;br /&gt;
     KB1[Delete[pd, pos], Union[inside, {a, b, c, d}], &lt;br /&gt;
      Expand[web*(A P[a, d] P[b, c] + 1/A P[a, b] P[c, d])] //. {P[e_,&lt;br /&gt;
            f_] P[f_, g_] :&amp;gt; P[e, g], P[e_, _]^2 :&amp;gt; P[e, e], &lt;br /&gt;
        P[e_, e_] -&amp;gt; -A^2 - 1/A^2}]];&lt;br /&gt;
KB1[PD[], _, web_] := Expand[web]&lt;br /&gt;
(*Position of a strand at a crossing*)&lt;br /&gt;
strandAtCrossing[crossing_, s_] := Module[{pos},&lt;br /&gt;
   pos = Position[crossing, s];&lt;br /&gt;
   If[Length[pos] &amp;gt; 0, pos[[1, 1]], False]&lt;br /&gt;
   ];&lt;br /&gt;
(*Orientation of overstrand. Complicated by components with only two strand labels*)&lt;br /&gt;
orientationOfOverStrand[crossing_, link_] := Module[{otherCrossings},&lt;br /&gt;
   (*find the other crossings containing the strand labels of the \&lt;br /&gt;
overstrand crossing*)&lt;br /&gt;
   otherCrossings = &lt;br /&gt;
    DeleteElements[&lt;br /&gt;
     Select[link, &lt;br /&gt;
      ContainsAny[&lt;br /&gt;
        List[Delete[#, 0]], {crossing[[2]], &lt;br /&gt;
         crossing[[4]]}] &amp;amp;], {crossing}];&lt;br /&gt;
   (*if the length of othercrossings is 1, &lt;br /&gt;
   then the overstrand labels are part of a component with only two \&lt;br /&gt;
strand labels*)&lt;br /&gt;
   If[Length[otherCrossings] == 1,&lt;br /&gt;
    (*first check if a strand label is in the first position of the \&lt;br /&gt;
other crossing.*)&lt;br /&gt;
    Which[otherCrossings[[1, 1]] == crossing[[2]],&lt;br /&gt;
     True,&lt;br /&gt;
     otherCrossings[[1, 1]] == crossing[[4]],&lt;br /&gt;
     False,&lt;br /&gt;
     (*Otherwise, the strands are always overcrossings, &lt;br /&gt;
     in which case we just choose to orient from small to large*)&lt;br /&gt;
     True,&lt;br /&gt;
     crossing[[2]] &amp;gt; crossing[[4]]&lt;br /&gt;
     ],&lt;br /&gt;
    (*otherwise, &lt;br /&gt;
    the overcrossing is oriented from 4 to 2 if pos 2 is 1 more than \&lt;br /&gt;
pos 4, or if pos 4 is more than 1 greater than pos 2.*)&lt;br /&gt;
     crossing[[2]] - crossing[[4]] == 1 || &lt;br /&gt;
     crossing[[4]] - crossing[[2]] &amp;gt; 1&lt;br /&gt;
    ]&lt;br /&gt;
   ];&lt;br /&gt;
(*crossing that a strand enters*)&lt;br /&gt;
findEnteringVertex[link_, s_] := &lt;br /&gt;
  Module[{crossingsContainingS, firstCrossing, pos},&lt;br /&gt;
   (*find crossings containing s*)&lt;br /&gt;
   crossingsContainingS = &lt;br /&gt;
    Select[link, IntegerQ[strandAtCrossing[#, s]] &amp;amp;];&lt;br /&gt;
   firstCrossing = crossingsContainingS[[1]];&lt;br /&gt;
   pos = strandAtCrossing[firstCrossing, s];&lt;br /&gt;
   Which[&lt;br /&gt;
    (*if pos is 1, then it is definitely an incoming strand*)&lt;br /&gt;
    pos == 1,&lt;br /&gt;
    firstCrossing,&lt;br /&gt;
    (pos == 2 &amp;amp;&amp;amp; ! &lt;br /&gt;
        orientationOfOverStrand[firstCrossing, link]) || (pos == 4 &amp;amp;&amp;amp; &lt;br /&gt;
       orientationOfOverStrand[firstCrossing, link]),&lt;br /&gt;
    firstCrossing,&lt;br /&gt;
    (*otherwise it must be the entering strand at the other vertex \&lt;br /&gt;
containing that label*)&lt;br /&gt;
    True,&lt;br /&gt;
    crossingsContainingS[[2]]&lt;br /&gt;
    ]&lt;br /&gt;
   ];&lt;br /&gt;
duplicateVertex[link_, crossing_, strands_] := &lt;br /&gt;
  Module[{pos = strandAtCrossing[crossing, strands[[1]]], &lt;br /&gt;
    newLabel = Length[link]*2 + 2, &lt;br /&gt;
    newLink = DeleteElements[link, {crossing}], p1 = crossing[[1]], &lt;br /&gt;
    p2 = crossing[[2]], p3 = crossing[[3]], p4 = crossing[[4]]},&lt;br /&gt;
   Which[&lt;br /&gt;
    (*pos is 1 and the upper strand is oriented from 4 to 2*)&lt;br /&gt;
    pos == 1  &amp;amp;&amp;amp; orientationOfOverStrand[crossing, link],&lt;br /&gt;
    {Union[&lt;br /&gt;
      increaseStrandLabels[newLink, p4],&lt;br /&gt;
      PD[&lt;br /&gt;
       X[If[p1 &amp;lt; p2, p1, p1 + 1], p4 + 1, If[p3 &amp;lt; p2, p3, p3 + 1], &lt;br /&gt;
        p4]],&lt;br /&gt;
      PD[X[newLabel, If[p2 &amp;gt; p4, p2 + 1, p2], newLabel + 1, p4 + 1]]&lt;br /&gt;
      ],&lt;br /&gt;
     Map[If[# &amp;lt;= p2, #, # + 1] &amp;amp;, Prepend[strands[[2 ;;]], p3]]&lt;br /&gt;
     },&lt;br /&gt;
    (*pos is 1 and the upper strand is oriented from 2 to 4*)&lt;br /&gt;
    pos == 1,&lt;br /&gt;
    {Union[&lt;br /&gt;
      increaseStrandLabels[newLink, p2],&lt;br /&gt;
      PD[&lt;br /&gt;
       X[If[p1 &amp;lt; p2, p1, p1 + 1], p2 + 1, If[p3 &amp;lt; p2, p3, p3 + 1], &lt;br /&gt;
        If[p4 &amp;lt; p2, p4, p4 + 1]]],&lt;br /&gt;
      PD[X[newLabel, p2, newLabel + 1, p2 + 1]]&lt;br /&gt;
      ],&lt;br /&gt;
     Map[If[# &amp;lt;= p2, #, # + 1] &amp;amp;, Prepend[strands[[2 ;;]], p3]]&lt;br /&gt;
     },&lt;br /&gt;
    (*pos is 2*)&lt;br /&gt;
    pos == 2,&lt;br /&gt;
    {Union[&lt;br /&gt;
      increaseStrandLabels[newLink, p1],&lt;br /&gt;
      PD[&lt;br /&gt;
       X[p1, If[p2 &amp;lt; p1, p2, p2 + 1], p1 + 1, &lt;br /&gt;
        If[p4 &amp;lt; p1, p4, p4 + 1]]],&lt;br /&gt;
      PD[X[p1 + 1, newLabel, If[p3 &amp;lt; p1, p3, p3 + 1], newLabel + 1]]&lt;br /&gt;
      ],&lt;br /&gt;
     Map[If[# &amp;lt;= p1, #, # + 1] &amp;amp;, Prepend[strands[[2 ;;]], p4]]&lt;br /&gt;
     },&lt;br /&gt;
    (*pos is 4*)&lt;br /&gt;
    True,&lt;br /&gt;
    {Union[&lt;br /&gt;
      increaseStrandLabels[newLink, p1],&lt;br /&gt;
      PD[&lt;br /&gt;
       X[p1 + 1, If[p2 &amp;lt; p1, p2, p2 + 1], If[p3 &amp;lt; p1, p3, p3 + 1], &lt;br /&gt;
        If[p4 &amp;lt; p1, p4, p4 + 1]]],&lt;br /&gt;
      PD[X[p1, newLabel + 1, p1 + 1, newLabel]]&lt;br /&gt;
      ],&lt;br /&gt;
     Map[If[# &amp;lt;= p1, #, # + 1] &amp;amp;, Prepend[strands[[2 ;;]], p2]]&lt;br /&gt;
     }&lt;br /&gt;
    ]&lt;br /&gt;
   ];&lt;br /&gt;
deleteVertex[link_, crossing_, s_, strandList_] := &lt;br /&gt;
 Module[{newCrossing = crossing, &lt;br /&gt;
   newLink = DeleteElements[link, {crossing}], min, max, &lt;br /&gt;
   pos = strandAtCrossing[crossing, s], outgoingStrandPos, &lt;br /&gt;
   newStrandList = strandList},&lt;br /&gt;
  (*we create an unknot if the two labels of the other strand at the \&lt;br /&gt;
crossing are equal*)&lt;br /&gt;
  Which[(pos == 1 &amp;amp;&amp;amp; crossing[[2]] == crossing[[4]]) , &lt;br /&gt;
   newStrandList = &lt;br /&gt;
    Replace[newStrandList, &lt;br /&gt;
     crossing[[2]] -&amp;gt; 0, {1}], (pos == 2 || pos == 4 ) &amp;amp;&amp;amp; &lt;br /&gt;
    crossing[[1]] == crossing[[3]], &lt;br /&gt;
   newStrandList = Replace[newStrandList, crossing[[1]] -&amp;gt; 0, {1}]];&lt;br /&gt;
  (*&amp;quot;&lt;br /&gt;
	we need to keep track of the outgoing strand label. There&#039;s actually \&lt;br /&gt;
two ways to know we&#039;re done:&lt;br /&gt;
	either the outgoing strand is the same as the incoming strand, or \&lt;br /&gt;
the whole vertex only involves 2 different labels.&lt;br /&gt;
&amp;quot;*)&lt;br /&gt;
  outgoingStrandPos = Which[pos == 1, 3, pos == 2, 4, True, 2];&lt;br /&gt;
  If[crossing[[outgoingStrandPos]] == s || &lt;br /&gt;
    CountDistinct[{Delete[crossing, 0]}] &amp;lt; 3, &lt;br /&gt;
   outgoingStrandPos = -1];&lt;br /&gt;
  (*adjust link after combining pos 1 and pos 3*)&lt;br /&gt;
  If[crossing[[1]] &amp;gt; crossing[[3]],&lt;br /&gt;
   newLink = &lt;br /&gt;
    decreaseStrandLabels[&lt;br /&gt;
     Replace[newLink, crossing[[1]] -&amp;gt; crossing[[3]], {2}], &lt;br /&gt;
     newCrossing[[1]]];&lt;br /&gt;
   newCrossing = &lt;br /&gt;
    decreaseStrandLabels[{Replace[newCrossing, &lt;br /&gt;
        crossing[[1]] -&amp;gt; crossing[[3]], {1}]}, newCrossing[[1]]][[&lt;br /&gt;
     1]];&lt;br /&gt;
   newStrandList = &lt;br /&gt;
    Map[If[# &amp;gt; newCrossing[[1]], # - 1, #] &amp;amp;, &lt;br /&gt;
     Replace[newStrandList, crossing[[1]] -&amp;gt; crossing[[3]], {1}]]&lt;br /&gt;
   ,&lt;br /&gt;
   newLink = decreaseStrandLabels[newLink, newCrossing[[1]]];&lt;br /&gt;
   newCrossing = &lt;br /&gt;
    decreaseStrandLabels[{newCrossing}, newCrossing[[1]]][[1]];&lt;br /&gt;
   newStrandList = &lt;br /&gt;
    Map[If[# &amp;gt; newCrossing[[1]], # - 1, #] &amp;amp;, newStrandList]&lt;br /&gt;
   ];&lt;br /&gt;
  (*adjust link after combining pos 2 and pos 4*)&lt;br /&gt;
  min = Min[newCrossing[[2]], newCrossing[[4]]];&lt;br /&gt;
  max = Max[newCrossing[[2]], newCrossing[[4]]];&lt;br /&gt;
  If[max - min &amp;gt; 1,&lt;br /&gt;
   newLink = &lt;br /&gt;
    decreaseStrandLabels[Replace[newLink, max -&amp;gt; min, {2}], max];&lt;br /&gt;
   newCrossing = &lt;br /&gt;
    decreaseStrandLabels[{Replace[newCrossing, max -&amp;gt; min, {1}]}, &lt;br /&gt;
      max][[1]];&lt;br /&gt;
   newStrandList = &lt;br /&gt;
    Map[If[# &amp;gt; max, # - 1, #] &amp;amp;, &lt;br /&gt;
     Replace[newStrandList, max -&amp;gt; min, {1}]],&lt;br /&gt;
   newLink = decreaseStrandLabels[newLink, min];&lt;br /&gt;
   newCrossing = decreaseStrandLabels[{newCrossing}, min][[1]];&lt;br /&gt;
   newStrandList = Map[If[# &amp;gt; max, # - 1, #] &amp;amp;, newStrandList]&lt;br /&gt;
   ];&lt;br /&gt;
  {newLink, &lt;br /&gt;
   If[outgoingStrandPos &amp;gt; 0, newCrossing[[outgoingStrandPos]], -1], &lt;br /&gt;
   newStrandList}&lt;br /&gt;
  ]&lt;br /&gt;
increaseStrandLabels[link_, s_] := &lt;br /&gt;
  Replace[link, n_?(# &amp;gt; s &amp;amp;) -&amp;gt; n + 1, {2}];&lt;br /&gt;
decreaseStrandLabels[link_, s_] := &lt;br /&gt;
  Replace[link, n_?(# &amp;gt; s &amp;amp;) -&amp;gt; n - 1, {2}];&lt;br /&gt;
cableComponent[link_, s_, strandList_] := &lt;br /&gt;
  Module[{initialStrands, newComponentLabel = 2 Length[link] + 1},&lt;br /&gt;
   initialStrands = Join[{s, s, newComponentLabel}, strandList];&lt;br /&gt;
   recurse[newLink_, strands_] := &lt;br /&gt;
    Module[{currentStrand = strands[[1]], firstStrand = strands[[2]], &lt;br /&gt;
      currentCrossing, updatedLink, &lt;br /&gt;
      updatedStrands},(*copy the current crossing*)&lt;br /&gt;
     currentCrossing = findEnteringVertex[newLink, currentStrand];&lt;br /&gt;
     {updatedLink, updatedStrands} = &lt;br /&gt;
      duplicateVertex[newLink, currentCrossing, strands];&lt;br /&gt;
     (*check if we&#039;ve returned to the first strand*)&lt;br /&gt;
     If[updatedStrands[[1]] == updatedStrands[[2]],&lt;br /&gt;
      (*replace the largest strand label with the first strand label \&lt;br /&gt;
of the new component*)&lt;br /&gt;
      {Replace[updatedLink, &lt;br /&gt;
        n_?(# == 2 Length[updatedLink] + 1 &amp;amp;) -&amp;gt; &lt;br /&gt;
         updatedStrands[[3]], {2}], &lt;br /&gt;
       updatedStrands[[4 ;;]]},(*keep adding crossings*)&lt;br /&gt;
      recurse[updatedLink, updatedStrands]]&lt;br /&gt;
     ];&lt;br /&gt;
   recurse[link, initialStrands]&lt;br /&gt;
   ];&lt;br /&gt;
deleteComponent[link_, s_, strandList_] := &lt;br /&gt;
  Module[{newLink, currentStrand, newStrandList, currentCrossing},&lt;br /&gt;
   If[s &amp;lt;= 0,&lt;br /&gt;
    (*we&#039;re done deleting stuff*)&lt;br /&gt;
    {link, strandList},&lt;br /&gt;
    (*keep deleting*)&lt;br /&gt;
    currentCrossing = findEnteringVertex[link, s];&lt;br /&gt;
    {newLink, currentStrand, newStrandList} = &lt;br /&gt;
     deleteVertex[link, currentCrossing, s, strandList];&lt;br /&gt;
    deleteComponent[newLink, currentStrand, newStrandList]&lt;br /&gt;
    ]&lt;br /&gt;
   ];&lt;br /&gt;
cableLinkMonomial[link_, strandList_, degreeList_] := &lt;br /&gt;
  Module[{newLink = link, newStrandList, newDegreeList, coeff = 1},&lt;br /&gt;
   (*reorder so that we&#039;re deleting components first*)&lt;br /&gt;
   {newDegreeList, newStrandList} = {degreeList, strandList}[[All, &lt;br /&gt;
     Ordering@degreeList]];&lt;br /&gt;
   (*start cabling*)&lt;br /&gt;
   Do[&lt;br /&gt;
    Which[&lt;br /&gt;
     newStrandList[[i]] == 0,&lt;br /&gt;
     (*it&#039;s an unknot*)&lt;br /&gt;
     coeff = coeff*(-A^2 - A^(-2))^newDegreeList[[i]],&lt;br /&gt;
     newDegreeList[[i]] == 0,&lt;br /&gt;
     (*we need to delete it*)&lt;br /&gt;
     {newLink, newStrandList} = &lt;br /&gt;
      deleteComponent[newLink, newStrandList[[i]], newStrandList],&lt;br /&gt;
     True,&lt;br /&gt;
     (*cable the component*)&lt;br /&gt;
     Do[&lt;br /&gt;
      {newLink, newStrandList} = &lt;br /&gt;
       cableComponent[newLink, newStrandList[[i]], newStrandList]&lt;br /&gt;
      , {j, 1, newDegreeList[[i]] - 1}]&lt;br /&gt;
     ]&lt;br /&gt;
    , {i, 1, Length[newStrandList]}&lt;br /&gt;
    ];&lt;br /&gt;
   coeff*KB1[newLink]&lt;br /&gt;
   ];&lt;br /&gt;
cableLink[link_, poly_, strandList_, vars_] := &lt;br /&gt;
 Module[{monomials = CoefficientRules[poly, vars], temp},&lt;br /&gt;
  Total[&lt;br /&gt;
   Map[&lt;br /&gt;
    #[[2]]*cableLinkMonomial[link, strandList, #[[1]]] &amp;amp;&lt;br /&gt;
    , monomials]]&lt;br /&gt;
  ]&lt;br /&gt;
&lt;br /&gt;
(* &amp;lt;/pre&amp;gt; *)&lt;/div&gt;</summary>
		<author><name>Sam.panitch</name></author>
	</entry>
	<entry>
		<id>https://katlas.org/index.php?title=CableLink.m&amp;diff=1725861</id>
		<title>CableLink.m</title>
		<link rel="alternate" type="text/html" href="https://katlas.org/index.php?title=CableLink.m&amp;diff=1725861"/>
		<updated>2025-08-05T22:58:27Z</updated>

		<summary type="html">&lt;p&gt;Sam.panitch: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
The program &amp;lt;code&amp;gt;CableLink&amp;lt;/code&amp;gt; is documented on the page [[Threading a link by a polynomial]]. It is not part of the package &amp;lt;code&amp;gt;KnotTheory`&amp;lt;/code&amp;gt; but is designed to work with it. Copy-paste the text below ignoring the &amp;lt;code&amp;gt;*&amp;amp;#41;&amp;lt;/code&amp;gt; on the first line and the &amp;lt;code&amp;gt;&amp;amp;#40;*&amp;lt;/code&amp;gt; on the last.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
*)&lt;br /&gt;
&lt;br /&gt;
(*Kauffman bracket*)&lt;br /&gt;
KB1[pd_PD] := KB1[pd, {}, 1];&lt;br /&gt;
KB1[pd_PD, inside_, web_] := &lt;br /&gt;
  Module[{pos = &lt;br /&gt;
     First[Ordering[Length[Complement[List @@ #, inside]] &amp;amp; /@ pd]]}, &lt;br /&gt;
   pd[[pos]] /.  &lt;br /&gt;
    X[a_, b_, c_, d_] :&amp;gt; &lt;br /&gt;
     KB1[Delete[pd, pos], Union[inside, {a, b, c, d}], &lt;br /&gt;
      Expand[web*(A P[a, d] P[b, c] + 1/A P[a, b] P[c, d])] //. {P[e_,&lt;br /&gt;
            f_] P[f_, g_] :&amp;gt; P[e, g], P[e_, _]^2 :&amp;gt; P[e, e], &lt;br /&gt;
        P[e_, e_] -&amp;gt; -A^2 - 1/A^2}]];&lt;br /&gt;
KB1[PD[], _, web_] := Expand[web]&lt;br /&gt;
(*Position of a strand at a crossing*)&lt;br /&gt;
strandAtCrossing[crossing_, s_] := Module[{pos},&lt;br /&gt;
   pos = Position[crossing, s];&lt;br /&gt;
   If[Length[pos] &amp;gt; 0, pos[[1, 1]], False]&lt;br /&gt;
   ];&lt;br /&gt;
(*Orientation of overstrand. Complicated by components with only two strand labels*)&lt;br /&gt;
orientationOfOverStrand[crossing_, link_] := Module[{otherCrossings},&lt;br /&gt;
   (*find the other crossings containing the strand labels of the \&lt;br /&gt;
overstrand crossing*)&lt;br /&gt;
   otherCrossings = &lt;br /&gt;
    DeleteElements[&lt;br /&gt;
     Select[link, &lt;br /&gt;
      ContainsAny[&lt;br /&gt;
        List[Delete[#, 0]], {crossing[[2]], &lt;br /&gt;
         crossing[[4]]}] &amp;amp;], {crossing}];&lt;br /&gt;
   (*if the length of othercrossings is 1, &lt;br /&gt;
   then the overstrand labels are part of a component with only two \&lt;br /&gt;
strand labels*)&lt;br /&gt;
   If[Length[otherCrossings] == 1,&lt;br /&gt;
    (*first check if a strand label is in the first position of the \&lt;br /&gt;
other crossing.*)&lt;br /&gt;
    Which[otherCrossings[[1, 1]] == crossing[[2]],&lt;br /&gt;
     True,&lt;br /&gt;
     otherCrossings[[1, 1]] == crossing[[4]],&lt;br /&gt;
     False,&lt;br /&gt;
     (*Otherwise, the strands are always overcrossings, &lt;br /&gt;
     in which case we just choose to orient from small to large*)&lt;br /&gt;
     True,&lt;br /&gt;
     crossing[[2]] &amp;gt; crossing[[4]]&lt;br /&gt;
     ],&lt;br /&gt;
    (*otherwise, &lt;br /&gt;
    the overcrossing is oriented from 4 to 2 if pos 2 is 1 more than \&lt;br /&gt;
pos 4, or if pos 4 is more than 1 greater than pos 2.*)&lt;br /&gt;
     crossing[[2]] - crossing[[4]] == 1 || &lt;br /&gt;
     crossing[[4]] - crossing[[2]] &amp;gt; 1&lt;br /&gt;
    ]&lt;br /&gt;
   ];&lt;br /&gt;
(*crossing that a strand enters*)&lt;br /&gt;
findEnteringVertex[link_, s_] := &lt;br /&gt;
  Module[{crossingsContainingS, firstCrossing, pos},&lt;br /&gt;
   (*find crossings containing s*)&lt;br /&gt;
   crossingsContainingS = &lt;br /&gt;
    Select[link, IntegerQ[strandAtCrossing[#, s]] &amp;amp;];&lt;br /&gt;
   firstCrossing = crossingsContainingS[[1]];&lt;br /&gt;
   pos = strandAtCrossing[firstCrossing, s];&lt;br /&gt;
   Which[&lt;br /&gt;
    (*if pos is 1, then it is definitely an incoming strand*)&lt;br /&gt;
    pos == 1,&lt;br /&gt;
    firstCrossing,&lt;br /&gt;
    (pos == 2 &amp;amp;&amp;amp; ! &lt;br /&gt;
        orientationOfOverStrand[firstCrossing, link]) || (pos == 4 &amp;amp;&amp;amp; &lt;br /&gt;
       orientationOfOverStrand[firstCrossing, link]),&lt;br /&gt;
    firstCrossing,&lt;br /&gt;
    (*otherwise it must be the entering strand at the other vertex \&lt;br /&gt;
containing that label*)&lt;br /&gt;
    True,&lt;br /&gt;
    crossingsContainingS[[2]]&lt;br /&gt;
    ]&lt;br /&gt;
   ];&lt;br /&gt;
duplicateVertex[link_, crossing_, strands_] := &lt;br /&gt;
  Module[{pos = strandAtCrossing[crossing, strands[[1]]], &lt;br /&gt;
    newLabel = Length[link]*2 + 2, &lt;br /&gt;
    newLink = DeleteElements[link, {crossing}], p1 = crossing[[1]], &lt;br /&gt;
    p2 = crossing[[2]], p3 = crossing[[3]], p4 = crossing[[4]]},&lt;br /&gt;
   Which[&lt;br /&gt;
    (*pos is 1 and the upper strand is oriented from 4 to 2*)&lt;br /&gt;
    pos == 1  &amp;amp;&amp;amp; orientationOfOverStrand[crossing, link],&lt;br /&gt;
    {Union[&lt;br /&gt;
      increaseStrandLabels[newLink, p4],&lt;br /&gt;
      PD[&lt;br /&gt;
       X[If[p1 &amp;lt; p2, p1, p1 + 1], p4 + 1, If[p3 &amp;lt; p2, p3, p3 + 1], &lt;br /&gt;
        p4]],&lt;br /&gt;
      PD[X[newLabel, If[p2 &amp;gt; p4, p2 + 1, p2], newLabel + 1, p4 + 1]]&lt;br /&gt;
      ],&lt;br /&gt;
     Map[If[# &amp;lt;= p2, #, # + 1] &amp;amp;, Prepend[strands[[2 ;;]], p3]]&lt;br /&gt;
     },&lt;br /&gt;
    (*pos is 1 and the upper strand is oriented from 2 to 4*)&lt;br /&gt;
    pos == 1,&lt;br /&gt;
    {Union[&lt;br /&gt;
      increaseStrandLabels[newLink, p2],&lt;br /&gt;
      PD[&lt;br /&gt;
       X[If[p1 &amp;lt; p2, p1, p1 + 1], p2 + 1, If[p3 &amp;lt; p2, p3, p3 + 1], &lt;br /&gt;
        If[p4 &amp;lt; p2, p4, p4 + 1]]],&lt;br /&gt;
      PD[X[newLabel, p2, newLabel + 1, p2 + 1]]&lt;br /&gt;
      ],&lt;br /&gt;
     Map[If[# &amp;lt;= p2, #, # + 1] &amp;amp;, Prepend[strands[[2 ;;]], p3]]&lt;br /&gt;
     },&lt;br /&gt;
    (*pos is 2*)&lt;br /&gt;
    pos == 2,&lt;br /&gt;
    {Union[&lt;br /&gt;
      increaseStrandLabels[newLink, p1],&lt;br /&gt;
      PD[&lt;br /&gt;
       X[p1, If[p2 &amp;lt; p1, p2, p2 + 1], p1 + 1, &lt;br /&gt;
        If[p4 &amp;lt; p1, p4, p4 + 1]]],&lt;br /&gt;
      PD[X[p1 + 1, newLabel, If[p3 &amp;lt; p1, p3, p3 + 1], newLabel + 1]]&lt;br /&gt;
      ],&lt;br /&gt;
     Map[If[# &amp;lt;= p1, #, # + 1] &amp;amp;, Prepend[strands[[2 ;;]], p4]]&lt;br /&gt;
     },&lt;br /&gt;
    (*pos is 4*)&lt;br /&gt;
    True,&lt;br /&gt;
    {Union[&lt;br /&gt;
      increaseStrandLabels[newLink, p1],&lt;br /&gt;
      PD[&lt;br /&gt;
       X[p1 + 1, If[p2 &amp;lt; p1, p2, p2 + 1], If[p3 &amp;lt; p1, p3, p3 + 1], &lt;br /&gt;
        If[p4 &amp;lt; p1, p4, p4 + 1]]],&lt;br /&gt;
      PD[X[p1, newLabel + 1, p1 + 1, newLabel]]&lt;br /&gt;
      ],&lt;br /&gt;
     Map[If[# &amp;lt;= p1, #, # + 1] &amp;amp;, Prepend[strands[[2 ;;]], p2]]&lt;br /&gt;
     }&lt;br /&gt;
    ]&lt;br /&gt;
   ];&lt;br /&gt;
deleteVertex[link_, crossing_, s_, strandList_] := &lt;br /&gt;
 Module[{newCrossing = crossing, &lt;br /&gt;
   newLink = DeleteElements[link, {crossing}], min, max, &lt;br /&gt;
   pos = strandAtCrossing[crossing, s], outgoingStrandPos, &lt;br /&gt;
   newStrandList = strandList},&lt;br /&gt;
  (*we create an unknot if the two labels of the other strand at the \&lt;br /&gt;
crossing are equal*)&lt;br /&gt;
  Which[(pos == 1 &amp;amp;&amp;amp; crossing[[2]] == crossing[[4]]) , &lt;br /&gt;
   newStrandList = &lt;br /&gt;
    Replace[newStrandList, &lt;br /&gt;
     crossing[[2]] -&amp;gt; 0, {1}], (pos == 2 || pos == 4 ) &amp;amp;&amp;amp; &lt;br /&gt;
    crossing[[1]] == crossing[[3]], &lt;br /&gt;
   newStrandList = Replace[newStrandList, crossing[[1]] -&amp;gt; 0, {1}]];&lt;br /&gt;
  (*&amp;quot;&lt;br /&gt;
	we need to keep track of the outgoing strand label. There&#039;s actually \&lt;br /&gt;
two ways to know we&#039;re done:&lt;br /&gt;
	either the outgoing strand is the same as the incoming strand, or \&lt;br /&gt;
the whole vertex only involves 2 different labels.&lt;br /&gt;
&amp;quot;*)&lt;br /&gt;
  outgoingStrandPos = Which[pos == 1, 3, pos == 2, 4, True, 2];&lt;br /&gt;
  If[crossing[[outgoingStrandPos]] == s || &lt;br /&gt;
    CountDistinct[{Delete[crossing, 0]}] &amp;lt; 3, &lt;br /&gt;
   outgoingStrandPos = -1];&lt;br /&gt;
  (*adjust link after combining pos 1 and pos 3*)&lt;br /&gt;
  If[crossing[[1]] &amp;gt; crossing[[3]],&lt;br /&gt;
   newLink = &lt;br /&gt;
    decreaseStrandLabels[&lt;br /&gt;
     Replace[newLink, crossing[[1]] -&amp;gt; crossing[[3]], {2}], &lt;br /&gt;
     newCrossing[[1]]];&lt;br /&gt;
   newCrossing = &lt;br /&gt;
    decreaseStrandLabels[{Replace[newCrossing, &lt;br /&gt;
        crossing[[1]] -&amp;gt; crossing[[3]], {1}]}, newCrossing[[1]]][[&lt;br /&gt;
     1]];&lt;br /&gt;
   newStrandList = &lt;br /&gt;
    Map[If[# &amp;gt; newCrossing[[1]], # - 1, #] &amp;amp;, &lt;br /&gt;
     Replace[newStrandList, crossing[[1]] -&amp;gt; crossing[[3]], {1}]]&lt;br /&gt;
   ,&lt;br /&gt;
   newLink = decreaseStrandLabels[newLink, newCrossing[[1]]];&lt;br /&gt;
   newCrossing = &lt;br /&gt;
    decreaseStrandLabels[{newCrossing}, newCrossing[[1]]][[1]];&lt;br /&gt;
   newStrandList = &lt;br /&gt;
    Map[If[# &amp;gt; newCrossing[[1]], # - 1, #] &amp;amp;, newStrandList]&lt;br /&gt;
   ];&lt;br /&gt;
  (*adjust link after combining pos 2 and pos 4*)&lt;br /&gt;
  min = Min[newCrossing[[2]], newCrossing[[4]]];&lt;br /&gt;
  max = Max[newCrossing[[2]], newCrossing[[4]]];&lt;br /&gt;
  If[max - min &amp;gt; 1,&lt;br /&gt;
   newLink = &lt;br /&gt;
    decreaseStrandLabels[Replace[newLink, max -&amp;gt; min, {2}], max];&lt;br /&gt;
   newCrossing = &lt;br /&gt;
    decreaseStrandLabels[{Replace[newCrossing, max -&amp;gt; min, {1}]}, &lt;br /&gt;
      max][[1]];&lt;br /&gt;
   newStrandList = &lt;br /&gt;
    Map[If[# &amp;gt; max, # - 1, #] &amp;amp;, &lt;br /&gt;
     Replace[newStrandList, max -&amp;gt; min, {1}]],&lt;br /&gt;
   newLink = decreaseStrandLabels[newLink, min];&lt;br /&gt;
   newCrossing = decreaseStrandLabels[{newCrossing}, min][[1]];&lt;br /&gt;
   newStrandList = Map[If[# &amp;gt; max, # - 1, #] &amp;amp;, newStrandList]&lt;br /&gt;
   ];&lt;br /&gt;
  {newLink, &lt;br /&gt;
   If[outgoingStrandPos &amp;gt; 0, newCrossing[[outgoingStrandPos]], -1], &lt;br /&gt;
   newStrandList}&lt;br /&gt;
  ]&lt;br /&gt;
increaseStrandLabels[link_, s_] := &lt;br /&gt;
  Replace[link, n_?(# &amp;gt; s &amp;amp;) -&amp;gt; n + 1, {2}];&lt;br /&gt;
decreaseStrandLabels[link_, s_] := &lt;br /&gt;
  Replace[link, n_?(# &amp;gt; s &amp;amp;) -&amp;gt; n - 1, {2}];&lt;br /&gt;
cableComponent[link_, s_, strandList_] := &lt;br /&gt;
  Module[{initialStrands, newComponentLabel = 2 Length[link] + 1},&lt;br /&gt;
   initialStrands = Join[{s, s, newComponentLabel}, strandList];&lt;br /&gt;
   recurse[newLink_, strands_] := &lt;br /&gt;
    Module[{currentStrand = strands[[1]], firstStrand = strands[[2]], &lt;br /&gt;
      currentCrossing, updatedLink, &lt;br /&gt;
      updatedStrands},(*copy the current crossing*)&lt;br /&gt;
     currentCrossing = findEnteringVertex[newLink, currentStrand];&lt;br /&gt;
     {updatedLink, updatedStrands} = &lt;br /&gt;
      duplicateVertex[newLink, currentCrossing, strands];&lt;br /&gt;
     (*check if we&#039;ve returned to the first strand*)&lt;br /&gt;
     If[updatedStrands[[1]] == updatedStrands[[2]],&lt;br /&gt;
      (*replace the largest strand label with the first strand label \&lt;br /&gt;
of the new component*)&lt;br /&gt;
      {Replace[updatedLink, &lt;br /&gt;
        n_?(# == 2 Length[updatedLink] + 1 &amp;amp;) -&amp;gt; &lt;br /&gt;
         updatedStrands[[3]], {2}], &lt;br /&gt;
       updatedStrands[[4 ;;]]},(*keep adding crossings*)&lt;br /&gt;
      recurse[updatedLink, updatedStrands]]&lt;br /&gt;
     ];&lt;br /&gt;
   recurse[link, initialStrands]&lt;br /&gt;
   ];&lt;br /&gt;
deleteComponent[link_, s_, strandList_] := &lt;br /&gt;
  Module[{newLink, currentStrand, newStrandList, currentCrossing},&lt;br /&gt;
   If[s &amp;lt;= 0,&lt;br /&gt;
    (*we&#039;re done deleting stuff*)&lt;br /&gt;
    {link, strandList},&lt;br /&gt;
    (*keep deleting*)&lt;br /&gt;
    currentCrossing = findEnteringVertex[link, s];&lt;br /&gt;
    {newLink, currentStrand, newStrandList} = &lt;br /&gt;
     deleteVertex[link, currentCrossing, s, strandList];&lt;br /&gt;
    deleteComponent[newLink, currentStrand, newStrandList]&lt;br /&gt;
    ]&lt;br /&gt;
   ];&lt;br /&gt;
cableLinkMonomial[link_, strandList_, degreeList_] := &lt;br /&gt;
  Module[{newLink = link, newStrandList, newDegreeList, coeff = 1},&lt;br /&gt;
   (*reorder so that we&#039;re deleting components first*)&lt;br /&gt;
   {newDegreeList, newStrandList} = {degreeList, strandList}[[All, &lt;br /&gt;
     Ordering@degreeList]];&lt;br /&gt;
   (*start cabling*)&lt;br /&gt;
   Do[&lt;br /&gt;
    Which[&lt;br /&gt;
     newStrandList[[i]] == 0,&lt;br /&gt;
     (*it&#039;s an unknot*)&lt;br /&gt;
     coeff = coeff*(-A^2 - A^(-2))^newDegreeList[[i]],&lt;br /&gt;
     newDegreeList[[i]] == 0,&lt;br /&gt;
     (*we need to delete it*)&lt;br /&gt;
     {newLink, newStrandList} = &lt;br /&gt;
      deleteComponent[newLink, newStrandList[[i]], newStrandList],&lt;br /&gt;
     True,&lt;br /&gt;
     (*cable the component*)&lt;br /&gt;
     Do[&lt;br /&gt;
      {newLink, newStrandList} = &lt;br /&gt;
       cableComponent[newLink, newStrandList[[i]], newStrandList]&lt;br /&gt;
      , {j, 1, newDegreeList[[i]] - 1}]&lt;br /&gt;
     ]&lt;br /&gt;
    , {i, 1, Length[newStrandList]}&lt;br /&gt;
    ];&lt;br /&gt;
   coeff*KB1[newLink]&lt;br /&gt;
   ];&lt;br /&gt;
cableLink[link_, poly_, strandList_, vars_] := &lt;br /&gt;
 Module[{monomials = CoefficientRules[poly, vars], temp},&lt;br /&gt;
  Total[&lt;br /&gt;
   Map[&lt;br /&gt;
    #[[2]]*cableLinkMonomial[link, strandList, #[[1]]] &amp;amp;&lt;br /&gt;
    , monomials]]&lt;br /&gt;
  ]&lt;br /&gt;
&lt;br /&gt;
(*&lt;/div&gt;</summary>
		<author><name>Sam.panitch</name></author>
	</entry>
	<entry>
		<id>https://katlas.org/index.php?title=CableLink.m&amp;diff=1725860</id>
		<title>CableLink.m</title>
		<link rel="alternate" type="text/html" href="https://katlas.org/index.php?title=CableLink.m&amp;diff=1725860"/>
		<updated>2025-08-05T22:58:12Z</updated>

		<summary type="html">&lt;p&gt;Sam.panitch: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
The program &amp;lt;code&amp;gt;CableLink&amp;lt;/code&amp;gt; is documented on the page [[Threading a link by a polynomial]]. It is not part of the package &amp;lt;code&amp;gt;KnotTheory`&amp;lt;/code&amp;gt; but is designed to work with it. Copy-paste the text below ignoring the &amp;lt;code&amp;gt;*&amp;amp;#41;&amp;lt;/code&amp;gt; on the first line and the &amp;lt;code&amp;gt;&amp;amp;#40;*&amp;lt;/code&amp;gt; on the last.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
*)&lt;br /&gt;
&lt;br /&gt;
(*Kauffman bracket*)&lt;br /&gt;
KB1[pd_PD] := KB1[pd, {}, 1];&lt;br /&gt;
KB1[pd_PD, inside_, web_] := &lt;br /&gt;
  Module[{pos = &lt;br /&gt;
     First[Ordering[Length[Complement[List @@ #, inside]] &amp;amp; /@ pd]]}, &lt;br /&gt;
   pd&amp;lt;code&amp;gt;[[pos]]&amp;lt;code&amp;gt; /.  &lt;br /&gt;
    X[a_, b_, c_, d_] :&amp;gt; &lt;br /&gt;
     KB1[Delete[pd, pos], Union[inside, {a, b, c, d}], &lt;br /&gt;
      Expand[web*(A P[a, d] P[b, c] + 1/A P[a, b] P[c, d])] //. {P[e_,&lt;br /&gt;
            f_] P[f_, g_] :&amp;gt; P[e, g], P[e_, _]^2 :&amp;gt; P[e, e], &lt;br /&gt;
        P[e_, e_] -&amp;gt; -A^2 - 1/A^2}]];&lt;br /&gt;
KB1[PD[], _, web_] := Expand[web]&lt;br /&gt;
(*Position of a strand at a crossing*)&lt;br /&gt;
strandAtCrossing[crossing_, s_] := Module[{pos},&lt;br /&gt;
   pos = Position[crossing, s];&lt;br /&gt;
   If[Length[pos] &amp;gt; 0, pos[[1, 1]], False]&lt;br /&gt;
   ];&lt;br /&gt;
(*Orientation of overstrand. Complicated by components with only two strand labels*)&lt;br /&gt;
orientationOfOverStrand[crossing_, link_] := Module[{otherCrossings},&lt;br /&gt;
   (*find the other crossings containing the strand labels of the \&lt;br /&gt;
overstrand crossing*)&lt;br /&gt;
   otherCrossings = &lt;br /&gt;
    DeleteElements[&lt;br /&gt;
     Select[link, &lt;br /&gt;
      ContainsAny[&lt;br /&gt;
        List[Delete[#, 0]], {crossing[[2]], &lt;br /&gt;
         crossing[[4]]}] &amp;amp;], {crossing}];&lt;br /&gt;
   (*if the length of othercrossings is 1, &lt;br /&gt;
   then the overstrand labels are part of a component with only two \&lt;br /&gt;
strand labels*)&lt;br /&gt;
   If[Length[otherCrossings] == 1,&lt;br /&gt;
    (*first check if a strand label is in the first position of the \&lt;br /&gt;
other crossing.*)&lt;br /&gt;
    Which[otherCrossings[[1, 1]] == crossing[[2]],&lt;br /&gt;
     True,&lt;br /&gt;
     otherCrossings[[1, 1]] == crossing[[4]],&lt;br /&gt;
     False,&lt;br /&gt;
     (*Otherwise, the strands are always overcrossings, &lt;br /&gt;
     in which case we just choose to orient from small to large*)&lt;br /&gt;
     True,&lt;br /&gt;
     crossing[[2]] &amp;gt; crossing[[4]]&lt;br /&gt;
     ],&lt;br /&gt;
    (*otherwise, &lt;br /&gt;
    the overcrossing is oriented from 4 to 2 if pos 2 is 1 more than \&lt;br /&gt;
pos 4, or if pos 4 is more than 1 greater than pos 2.*)&lt;br /&gt;
     crossing[[2]] - crossing[[4]] == 1 || &lt;br /&gt;
     crossing[[4]] - crossing[[2]] &amp;gt; 1&lt;br /&gt;
    ]&lt;br /&gt;
   ];&lt;br /&gt;
(*crossing that a strand enters*)&lt;br /&gt;
findEnteringVertex[link_, s_] := &lt;br /&gt;
  Module[{crossingsContainingS, firstCrossing, pos},&lt;br /&gt;
   (*find crossings containing s*)&lt;br /&gt;
   crossingsContainingS = &lt;br /&gt;
    Select[link, IntegerQ[strandAtCrossing[#, s]] &amp;amp;];&lt;br /&gt;
   firstCrossing = crossingsContainingS[[1]];&lt;br /&gt;
   pos = strandAtCrossing[firstCrossing, s];&lt;br /&gt;
   Which[&lt;br /&gt;
    (*if pos is 1, then it is definitely an incoming strand*)&lt;br /&gt;
    pos == 1,&lt;br /&gt;
    firstCrossing,&lt;br /&gt;
    (pos == 2 &amp;amp;&amp;amp; ! &lt;br /&gt;
        orientationOfOverStrand[firstCrossing, link]) || (pos == 4 &amp;amp;&amp;amp; &lt;br /&gt;
       orientationOfOverStrand[firstCrossing, link]),&lt;br /&gt;
    firstCrossing,&lt;br /&gt;
    (*otherwise it must be the entering strand at the other vertex \&lt;br /&gt;
containing that label*)&lt;br /&gt;
    True,&lt;br /&gt;
    crossingsContainingS[[2]]&lt;br /&gt;
    ]&lt;br /&gt;
   ];&lt;br /&gt;
duplicateVertex[link_, crossing_, strands_] := &lt;br /&gt;
  Module[{pos = strandAtCrossing[crossing, strands[[1]]], &lt;br /&gt;
    newLabel = Length[link]*2 + 2, &lt;br /&gt;
    newLink = DeleteElements[link, {crossing}], p1 = crossing[[1]], &lt;br /&gt;
    p2 = crossing[[2]], p3 = crossing[[3]], p4 = crossing[[4]]},&lt;br /&gt;
   Which[&lt;br /&gt;
    (*pos is 1 and the upper strand is oriented from 4 to 2*)&lt;br /&gt;
    pos == 1  &amp;amp;&amp;amp; orientationOfOverStrand[crossing, link],&lt;br /&gt;
    {Union[&lt;br /&gt;
      increaseStrandLabels[newLink, p4],&lt;br /&gt;
      PD[&lt;br /&gt;
       X[If[p1 &amp;lt; p2, p1, p1 + 1], p4 + 1, If[p3 &amp;lt; p2, p3, p3 + 1], &lt;br /&gt;
        p4]],&lt;br /&gt;
      PD[X[newLabel, If[p2 &amp;gt; p4, p2 + 1, p2], newLabel + 1, p4 + 1]]&lt;br /&gt;
      ],&lt;br /&gt;
     Map[If[# &amp;lt;= p2, #, # + 1] &amp;amp;, Prepend[strands[[2 ;;]], p3]]&lt;br /&gt;
     },&lt;br /&gt;
    (*pos is 1 and the upper strand is oriented from 2 to 4*)&lt;br /&gt;
    pos == 1,&lt;br /&gt;
    {Union[&lt;br /&gt;
      increaseStrandLabels[newLink, p2],&lt;br /&gt;
      PD[&lt;br /&gt;
       X[If[p1 &amp;lt; p2, p1, p1 + 1], p2 + 1, If[p3 &amp;lt; p2, p3, p3 + 1], &lt;br /&gt;
        If[p4 &amp;lt; p2, p4, p4 + 1]]],&lt;br /&gt;
      PD[X[newLabel, p2, newLabel + 1, p2 + 1]]&lt;br /&gt;
      ],&lt;br /&gt;
     Map[If[# &amp;lt;= p2, #, # + 1] &amp;amp;, Prepend[strands[[2 ;;]], p3]]&lt;br /&gt;
     },&lt;br /&gt;
    (*pos is 2*)&lt;br /&gt;
    pos == 2,&lt;br /&gt;
    {Union[&lt;br /&gt;
      increaseStrandLabels[newLink, p1],&lt;br /&gt;
      PD[&lt;br /&gt;
       X[p1, If[p2 &amp;lt; p1, p2, p2 + 1], p1 + 1, &lt;br /&gt;
        If[p4 &amp;lt; p1, p4, p4 + 1]]],&lt;br /&gt;
      PD[X[p1 + 1, newLabel, If[p3 &amp;lt; p1, p3, p3 + 1], newLabel + 1]]&lt;br /&gt;
      ],&lt;br /&gt;
     Map[If[# &amp;lt;= p1, #, # + 1] &amp;amp;, Prepend[strands[[2 ;;]], p4]]&lt;br /&gt;
     },&lt;br /&gt;
    (*pos is 4*)&lt;br /&gt;
    True,&lt;br /&gt;
    {Union[&lt;br /&gt;
      increaseStrandLabels[newLink, p1],&lt;br /&gt;
      PD[&lt;br /&gt;
       X[p1 + 1, If[p2 &amp;lt; p1, p2, p2 + 1], If[p3 &amp;lt; p1, p3, p3 + 1], &lt;br /&gt;
        If[p4 &amp;lt; p1, p4, p4 + 1]]],&lt;br /&gt;
      PD[X[p1, newLabel + 1, p1 + 1, newLabel]]&lt;br /&gt;
      ],&lt;br /&gt;
     Map[If[# &amp;lt;= p1, #, # + 1] &amp;amp;, Prepend[strands[[2 ;;]], p2]]&lt;br /&gt;
     }&lt;br /&gt;
    ]&lt;br /&gt;
   ];&lt;br /&gt;
deleteVertex[link_, crossing_, s_, strandList_] := &lt;br /&gt;
 Module[{newCrossing = crossing, &lt;br /&gt;
   newLink = DeleteElements[link, {crossing}], min, max, &lt;br /&gt;
   pos = strandAtCrossing[crossing, s], outgoingStrandPos, &lt;br /&gt;
   newStrandList = strandList},&lt;br /&gt;
  (*we create an unknot if the two labels of the other strand at the \&lt;br /&gt;
crossing are equal*)&lt;br /&gt;
  Which[(pos == 1 &amp;amp;&amp;amp; crossing[[2]] == crossing[[4]]) , &lt;br /&gt;
   newStrandList = &lt;br /&gt;
    Replace[newStrandList, &lt;br /&gt;
     crossing[[2]] -&amp;gt; 0, {1}], (pos == 2 || pos == 4 ) &amp;amp;&amp;amp; &lt;br /&gt;
    crossing[[1]] == crossing[[3]], &lt;br /&gt;
   newStrandList = Replace[newStrandList, crossing[[1]] -&amp;gt; 0, {1}]];&lt;br /&gt;
  (*&amp;quot;&lt;br /&gt;
	we need to keep track of the outgoing strand label. There&#039;s actually \&lt;br /&gt;
two ways to know we&#039;re done:&lt;br /&gt;
	either the outgoing strand is the same as the incoming strand, or \&lt;br /&gt;
the whole vertex only involves 2 different labels.&lt;br /&gt;
&amp;quot;*)&lt;br /&gt;
  outgoingStrandPos = Which[pos == 1, 3, pos == 2, 4, True, 2];&lt;br /&gt;
  If[crossing[[outgoingStrandPos]] == s || &lt;br /&gt;
    CountDistinct[{Delete[crossing, 0]}] &amp;lt; 3, &lt;br /&gt;
   outgoingStrandPos = -1];&lt;br /&gt;
  (*adjust link after combining pos 1 and pos 3*)&lt;br /&gt;
  If[crossing[[1]] &amp;gt; crossing[[3]],&lt;br /&gt;
   newLink = &lt;br /&gt;
    decreaseStrandLabels[&lt;br /&gt;
     Replace[newLink, crossing[[1]] -&amp;gt; crossing[[3]], {2}], &lt;br /&gt;
     newCrossing[[1]]];&lt;br /&gt;
   newCrossing = &lt;br /&gt;
    decreaseStrandLabels[{Replace[newCrossing, &lt;br /&gt;
        crossing[[1]] -&amp;gt; crossing[[3]], {1}]}, newCrossing[[1]]][[&lt;br /&gt;
     1]];&lt;br /&gt;
   newStrandList = &lt;br /&gt;
    Map[If[# &amp;gt; newCrossing[[1]], # - 1, #] &amp;amp;, &lt;br /&gt;
     Replace[newStrandList, crossing[[1]] -&amp;gt; crossing[[3]], {1}]]&lt;br /&gt;
   ,&lt;br /&gt;
   newLink = decreaseStrandLabels[newLink, newCrossing[[1]]];&lt;br /&gt;
   newCrossing = &lt;br /&gt;
    decreaseStrandLabels[{newCrossing}, newCrossing[[1]]][[1]];&lt;br /&gt;
   newStrandList = &lt;br /&gt;
    Map[If[# &amp;gt; newCrossing[[1]], # - 1, #] &amp;amp;, newStrandList]&lt;br /&gt;
   ];&lt;br /&gt;
  (*adjust link after combining pos 2 and pos 4*)&lt;br /&gt;
  min = Min[newCrossing[[2]], newCrossing[[4]]];&lt;br /&gt;
  max = Max[newCrossing[[2]], newCrossing[[4]]];&lt;br /&gt;
  If[max - min &amp;gt; 1,&lt;br /&gt;
   newLink = &lt;br /&gt;
    decreaseStrandLabels[Replace[newLink, max -&amp;gt; min, {2}], max];&lt;br /&gt;
   newCrossing = &lt;br /&gt;
    decreaseStrandLabels[{Replace[newCrossing, max -&amp;gt; min, {1}]}, &lt;br /&gt;
      max][[1]];&lt;br /&gt;
   newStrandList = &lt;br /&gt;
    Map[If[# &amp;gt; max, # - 1, #] &amp;amp;, &lt;br /&gt;
     Replace[newStrandList, max -&amp;gt; min, {1}]],&lt;br /&gt;
   newLink = decreaseStrandLabels[newLink, min];&lt;br /&gt;
   newCrossing = decreaseStrandLabels[{newCrossing}, min][[1]];&lt;br /&gt;
   newStrandList = Map[If[# &amp;gt; max, # - 1, #] &amp;amp;, newStrandList]&lt;br /&gt;
   ];&lt;br /&gt;
  {newLink, &lt;br /&gt;
   If[outgoingStrandPos &amp;gt; 0, newCrossing[[outgoingStrandPos]], -1], &lt;br /&gt;
   newStrandList}&lt;br /&gt;
  ]&lt;br /&gt;
increaseStrandLabels[link_, s_] := &lt;br /&gt;
  Replace[link, n_?(# &amp;gt; s &amp;amp;) -&amp;gt; n + 1, {2}];&lt;br /&gt;
decreaseStrandLabels[link_, s_] := &lt;br /&gt;
  Replace[link, n_?(# &amp;gt; s &amp;amp;) -&amp;gt; n - 1, {2}];&lt;br /&gt;
cableComponent[link_, s_, strandList_] := &lt;br /&gt;
  Module[{initialStrands, newComponentLabel = 2 Length[link] + 1},&lt;br /&gt;
   initialStrands = Join[{s, s, newComponentLabel}, strandList];&lt;br /&gt;
   recurse[newLink_, strands_] := &lt;br /&gt;
    Module[{currentStrand = strands[[1]], firstStrand = strands[[2]], &lt;br /&gt;
      currentCrossing, updatedLink, &lt;br /&gt;
      updatedStrands},(*copy the current crossing*)&lt;br /&gt;
     currentCrossing = findEnteringVertex[newLink, currentStrand];&lt;br /&gt;
     {updatedLink, updatedStrands} = &lt;br /&gt;
      duplicateVertex[newLink, currentCrossing, strands];&lt;br /&gt;
     (*check if we&#039;ve returned to the first strand*)&lt;br /&gt;
     If[updatedStrands[[1]] == updatedStrands[[2]],&lt;br /&gt;
      (*replace the largest strand label with the first strand label \&lt;br /&gt;
of the new component*)&lt;br /&gt;
      {Replace[updatedLink, &lt;br /&gt;
        n_?(# == 2 Length[updatedLink] + 1 &amp;amp;) -&amp;gt; &lt;br /&gt;
         updatedStrands[[3]], {2}], &lt;br /&gt;
       updatedStrands[[4 ;;]]},(*keep adding crossings*)&lt;br /&gt;
      recurse[updatedLink, updatedStrands]]&lt;br /&gt;
     ];&lt;br /&gt;
   recurse[link, initialStrands]&lt;br /&gt;
   ];&lt;br /&gt;
deleteComponent[link_, s_, strandList_] := &lt;br /&gt;
  Module[{newLink, currentStrand, newStrandList, currentCrossing},&lt;br /&gt;
   If[s &amp;lt;= 0,&lt;br /&gt;
    (*we&#039;re done deleting stuff*)&lt;br /&gt;
    {link, strandList},&lt;br /&gt;
    (*keep deleting*)&lt;br /&gt;
    currentCrossing = findEnteringVertex[link, s];&lt;br /&gt;
    {newLink, currentStrand, newStrandList} = &lt;br /&gt;
     deleteVertex[link, currentCrossing, s, strandList];&lt;br /&gt;
    deleteComponent[newLink, currentStrand, newStrandList]&lt;br /&gt;
    ]&lt;br /&gt;
   ];&lt;br /&gt;
cableLinkMonomial[link_, strandList_, degreeList_] := &lt;br /&gt;
  Module[{newLink = link, newStrandList, newDegreeList, coeff = 1},&lt;br /&gt;
   (*reorder so that we&#039;re deleting components first*)&lt;br /&gt;
   {newDegreeList, newStrandList} = {degreeList, strandList}[[All, &lt;br /&gt;
     Ordering@degreeList]];&lt;br /&gt;
   (*start cabling*)&lt;br /&gt;
   Do[&lt;br /&gt;
    Which[&lt;br /&gt;
     newStrandList[[i]] == 0,&lt;br /&gt;
     (*it&#039;s an unknot*)&lt;br /&gt;
     coeff = coeff*(-A^2 - A^(-2))^newDegreeList[[i]],&lt;br /&gt;
     newDegreeList[[i]] == 0,&lt;br /&gt;
     (*we need to delete it*)&lt;br /&gt;
     {newLink, newStrandList} = &lt;br /&gt;
      deleteComponent[newLink, newStrandList[[i]], newStrandList],&lt;br /&gt;
     True,&lt;br /&gt;
     (*cable the component*)&lt;br /&gt;
     Do[&lt;br /&gt;
      {newLink, newStrandList} = &lt;br /&gt;
       cableComponent[newLink, newStrandList[[i]], newStrandList]&lt;br /&gt;
      , {j, 1, newDegreeList[[i]] - 1}]&lt;br /&gt;
     ]&lt;br /&gt;
    , {i, 1, Length[newStrandList]}&lt;br /&gt;
    ];&lt;br /&gt;
   coeff*KB1[newLink]&lt;br /&gt;
   ];&lt;br /&gt;
cableLink[link_, poly_, strandList_, vars_] := &lt;br /&gt;
 Module[{monomials = CoefficientRules[poly, vars], temp},&lt;br /&gt;
  Total[&lt;br /&gt;
   Map[&lt;br /&gt;
    #[[2]]*cableLinkMonomial[link, strandList, #[[1]]] &amp;amp;&lt;br /&gt;
    , monomials]]&lt;br /&gt;
  ]&lt;br /&gt;
&lt;br /&gt;
(*&lt;/div&gt;</summary>
		<author><name>Sam.panitch</name></author>
	</entry>
	<entry>
		<id>https://katlas.org/index.php?title=CableLink.m&amp;diff=1725859</id>
		<title>CableLink.m</title>
		<link rel="alternate" type="text/html" href="https://katlas.org/index.php?title=CableLink.m&amp;diff=1725859"/>
		<updated>2025-08-05T22:56:57Z</updated>

		<summary type="html">&lt;p&gt;Sam.panitch: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
The program &amp;lt;code&amp;gt;CableLink&amp;lt;/code&amp;gt; is documented on the page [[Threading a link by a polynomial]]. It is not part of the package &amp;lt;code&amp;gt;KnotTheory`&amp;lt;/code&amp;gt; but is designed to work with it. Copy-paste the text below ignoring the &amp;lt;code&amp;gt;*&amp;amp;#41;&amp;lt;/code&amp;gt; on the first line and the &amp;lt;code&amp;gt;&amp;amp;#40;*&amp;lt;/code&amp;gt; on the last.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
*)&lt;br /&gt;
&lt;br /&gt;
(*Kauffman bracket*)&lt;br /&gt;
KB1[pd_PD] := KB1[pd, {}, 1];&lt;br /&gt;
KB1[pd_PD, inside_, web_] := &lt;br /&gt;
  Module[{pos = &lt;br /&gt;
     First[Ordering[Length[Complement[List @@ #, inside]] &amp;amp; /@ pd]]}, &lt;br /&gt;
   pd\[\[pos\]\] /.  &lt;br /&gt;
    X[a_, b_, c_, d_] :&amp;gt; &lt;br /&gt;
     KB1[Delete[pd, pos], Union[inside, {a, b, c, d}], &lt;br /&gt;
      Expand[web*(A P[a, d] P[b, c] + 1/A P[a, b] P[c, d])] //. {P[e_,&lt;br /&gt;
            f_] P[f_, g_] :&amp;gt; P[e, g], P[e_, _]^2 :&amp;gt; P[e, e], &lt;br /&gt;
        P[e_, e_] -&amp;gt; -A^2 - 1/A^2}]];&lt;br /&gt;
KB1[PD[], _, web_] := Expand[web]&lt;br /&gt;
(*Position of a strand at a crossing*)&lt;br /&gt;
strandAtCrossing[crossing_, s_] := Module[{pos},&lt;br /&gt;
   pos = Position[crossing, s];&lt;br /&gt;
   If[Length[pos] &amp;gt; 0, pos[[1, 1]], False]&lt;br /&gt;
   ];&lt;br /&gt;
(*Orientation of overstrand. Complicated by components with only two strand labels*)&lt;br /&gt;
orientationOfOverStrand[crossing_, link_] := Module[{otherCrossings},&lt;br /&gt;
   (*find the other crossings containing the strand labels of the \&lt;br /&gt;
overstrand crossing*)&lt;br /&gt;
   otherCrossings = &lt;br /&gt;
    DeleteElements[&lt;br /&gt;
     Select[link, &lt;br /&gt;
      ContainsAny[&lt;br /&gt;
        List[Delete[#, 0]], {crossing[[2]], &lt;br /&gt;
         crossing[[4]]}] &amp;amp;], {crossing}];&lt;br /&gt;
   (*if the length of othercrossings is 1, &lt;br /&gt;
   then the overstrand labels are part of a component with only two \&lt;br /&gt;
strand labels*)&lt;br /&gt;
   If[Length[otherCrossings] == 1,&lt;br /&gt;
    (*first check if a strand label is in the first position of the \&lt;br /&gt;
other crossing.*)&lt;br /&gt;
    Which[otherCrossings[[1, 1]] == crossing[[2]],&lt;br /&gt;
     True,&lt;br /&gt;
     otherCrossings[[1, 1]] == crossing[[4]],&lt;br /&gt;
     False,&lt;br /&gt;
     (*Otherwise, the strands are always overcrossings, &lt;br /&gt;
     in which case we just choose to orient from small to large*)&lt;br /&gt;
     True,&lt;br /&gt;
     crossing[[2]] &amp;gt; crossing[[4]]&lt;br /&gt;
     ],&lt;br /&gt;
    (*otherwise, &lt;br /&gt;
    the overcrossing is oriented from 4 to 2 if pos 2 is 1 more than \&lt;br /&gt;
pos 4, or if pos 4 is more than 1 greater than pos 2.*)&lt;br /&gt;
     crossing[[2]] - crossing[[4]] == 1 || &lt;br /&gt;
     crossing[[4]] - crossing[[2]] &amp;gt; 1&lt;br /&gt;
    ]&lt;br /&gt;
   ];&lt;br /&gt;
(*crossing that a strand enters*)&lt;br /&gt;
findEnteringVertex[link_, s_] := &lt;br /&gt;
  Module[{crossingsContainingS, firstCrossing, pos},&lt;br /&gt;
   (*find crossings containing s*)&lt;br /&gt;
   crossingsContainingS = &lt;br /&gt;
    Select[link, IntegerQ[strandAtCrossing[#, s]] &amp;amp;];&lt;br /&gt;
   firstCrossing = crossingsContainingS[[1]];&lt;br /&gt;
   pos = strandAtCrossing[firstCrossing, s];&lt;br /&gt;
   Which[&lt;br /&gt;
    (*if pos is 1, then it is definitely an incoming strand*)&lt;br /&gt;
    pos == 1,&lt;br /&gt;
    firstCrossing,&lt;br /&gt;
    (pos == 2 &amp;amp;&amp;amp; ! &lt;br /&gt;
        orientationOfOverStrand[firstCrossing, link]) || (pos == 4 &amp;amp;&amp;amp; &lt;br /&gt;
       orientationOfOverStrand[firstCrossing, link]),&lt;br /&gt;
    firstCrossing,&lt;br /&gt;
    (*otherwise it must be the entering strand at the other vertex \&lt;br /&gt;
containing that label*)&lt;br /&gt;
    True,&lt;br /&gt;
    crossingsContainingS[[2]]&lt;br /&gt;
    ]&lt;br /&gt;
   ];&lt;br /&gt;
duplicateVertex[link_, crossing_, strands_] := &lt;br /&gt;
  Module[{pos = strandAtCrossing[crossing, strands[[1]]], &lt;br /&gt;
    newLabel = Length[link]*2 + 2, &lt;br /&gt;
    newLink = DeleteElements[link, {crossing}], p1 = crossing[[1]], &lt;br /&gt;
    p2 = crossing[[2]], p3 = crossing[[3]], p4 = crossing[[4]]},&lt;br /&gt;
   Which[&lt;br /&gt;
    (*pos is 1 and the upper strand is oriented from 4 to 2*)&lt;br /&gt;
    pos == 1  &amp;amp;&amp;amp; orientationOfOverStrand[crossing, link],&lt;br /&gt;
    {Union[&lt;br /&gt;
      increaseStrandLabels[newLink, p4],&lt;br /&gt;
      PD[&lt;br /&gt;
       X[If[p1 &amp;lt; p2, p1, p1 + 1], p4 + 1, If[p3 &amp;lt; p2, p3, p3 + 1], &lt;br /&gt;
        p4]],&lt;br /&gt;
      PD[X[newLabel, If[p2 &amp;gt; p4, p2 + 1, p2], newLabel + 1, p4 + 1]]&lt;br /&gt;
      ],&lt;br /&gt;
     Map[If[# &amp;lt;= p2, #, # + 1] &amp;amp;, Prepend[strands[[2 ;;]], p3]]&lt;br /&gt;
     },&lt;br /&gt;
    (*pos is 1 and the upper strand is oriented from 2 to 4*)&lt;br /&gt;
    pos == 1,&lt;br /&gt;
    {Union[&lt;br /&gt;
      increaseStrandLabels[newLink, p2],&lt;br /&gt;
      PD[&lt;br /&gt;
       X[If[p1 &amp;lt; p2, p1, p1 + 1], p2 + 1, If[p3 &amp;lt; p2, p3, p3 + 1], &lt;br /&gt;
        If[p4 &amp;lt; p2, p4, p4 + 1]]],&lt;br /&gt;
      PD[X[newLabel, p2, newLabel + 1, p2 + 1]]&lt;br /&gt;
      ],&lt;br /&gt;
     Map[If[# &amp;lt;= p2, #, # + 1] &amp;amp;, Prepend[strands[[2 ;;]], p3]]&lt;br /&gt;
     },&lt;br /&gt;
    (*pos is 2*)&lt;br /&gt;
    pos == 2,&lt;br /&gt;
    {Union[&lt;br /&gt;
      increaseStrandLabels[newLink, p1],&lt;br /&gt;
      PD[&lt;br /&gt;
       X[p1, If[p2 &amp;lt; p1, p2, p2 + 1], p1 + 1, &lt;br /&gt;
        If[p4 &amp;lt; p1, p4, p4 + 1]]],&lt;br /&gt;
      PD[X[p1 + 1, newLabel, If[p3 &amp;lt; p1, p3, p3 + 1], newLabel + 1]]&lt;br /&gt;
      ],&lt;br /&gt;
     Map[If[# &amp;lt;= p1, #, # + 1] &amp;amp;, Prepend[strands[[2 ;;]], p4]]&lt;br /&gt;
     },&lt;br /&gt;
    (*pos is 4*)&lt;br /&gt;
    True,&lt;br /&gt;
    {Union[&lt;br /&gt;
      increaseStrandLabels[newLink, p1],&lt;br /&gt;
      PD[&lt;br /&gt;
       X[p1 + 1, If[p2 &amp;lt; p1, p2, p2 + 1], If[p3 &amp;lt; p1, p3, p3 + 1], &lt;br /&gt;
        If[p4 &amp;lt; p1, p4, p4 + 1]]],&lt;br /&gt;
      PD[X[p1, newLabel + 1, p1 + 1, newLabel]]&lt;br /&gt;
      ],&lt;br /&gt;
     Map[If[# &amp;lt;= p1, #, # + 1] &amp;amp;, Prepend[strands[[2 ;;]], p2]]&lt;br /&gt;
     }&lt;br /&gt;
    ]&lt;br /&gt;
   ];&lt;br /&gt;
deleteVertex[link_, crossing_, s_, strandList_] := &lt;br /&gt;
 Module[{newCrossing = crossing, &lt;br /&gt;
   newLink = DeleteElements[link, {crossing}], min, max, &lt;br /&gt;
   pos = strandAtCrossing[crossing, s], outgoingStrandPos, &lt;br /&gt;
   newStrandList = strandList},&lt;br /&gt;
  (*we create an unknot if the two labels of the other strand at the \&lt;br /&gt;
crossing are equal*)&lt;br /&gt;
  Which[(pos == 1 &amp;amp;&amp;amp; crossing[[2]] == crossing[[4]]) , &lt;br /&gt;
   newStrandList = &lt;br /&gt;
    Replace[newStrandList, &lt;br /&gt;
     crossing[[2]] -&amp;gt; 0, {1}], (pos == 2 || pos == 4 ) &amp;amp;&amp;amp; &lt;br /&gt;
    crossing[[1]] == crossing[[3]], &lt;br /&gt;
   newStrandList = Replace[newStrandList, crossing[[1]] -&amp;gt; 0, {1}]];&lt;br /&gt;
  (*&amp;quot;&lt;br /&gt;
	we need to keep track of the outgoing strand label. There&#039;s actually \&lt;br /&gt;
two ways to know we&#039;re done:&lt;br /&gt;
	either the outgoing strand is the same as the incoming strand, or \&lt;br /&gt;
the whole vertex only involves 2 different labels.&lt;br /&gt;
&amp;quot;*)&lt;br /&gt;
  outgoingStrandPos = Which[pos == 1, 3, pos == 2, 4, True, 2];&lt;br /&gt;
  If[crossing[[outgoingStrandPos]] == s || &lt;br /&gt;
    CountDistinct[{Delete[crossing, 0]}] &amp;lt; 3, &lt;br /&gt;
   outgoingStrandPos = -1];&lt;br /&gt;
  (*adjust link after combining pos 1 and pos 3*)&lt;br /&gt;
  If[crossing[[1]] &amp;gt; crossing[[3]],&lt;br /&gt;
   newLink = &lt;br /&gt;
    decreaseStrandLabels[&lt;br /&gt;
     Replace[newLink, crossing[[1]] -&amp;gt; crossing[[3]], {2}], &lt;br /&gt;
     newCrossing[[1]]];&lt;br /&gt;
   newCrossing = &lt;br /&gt;
    decreaseStrandLabels[{Replace[newCrossing, &lt;br /&gt;
        crossing[[1]] -&amp;gt; crossing[[3]], {1}]}, newCrossing[[1]]][[&lt;br /&gt;
     1]];&lt;br /&gt;
   newStrandList = &lt;br /&gt;
    Map[If[# &amp;gt; newCrossing[[1]], # - 1, #] &amp;amp;, &lt;br /&gt;
     Replace[newStrandList, crossing[[1]] -&amp;gt; crossing[[3]], {1}]]&lt;br /&gt;
   ,&lt;br /&gt;
   newLink = decreaseStrandLabels[newLink, newCrossing[[1]]];&lt;br /&gt;
   newCrossing = &lt;br /&gt;
    decreaseStrandLabels[{newCrossing}, newCrossing[[1]]][[1]];&lt;br /&gt;
   newStrandList = &lt;br /&gt;
    Map[If[# &amp;gt; newCrossing[[1]], # - 1, #] &amp;amp;, newStrandList]&lt;br /&gt;
   ];&lt;br /&gt;
  (*adjust link after combining pos 2 and pos 4*)&lt;br /&gt;
  min = Min[newCrossing[[2]], newCrossing[[4]]];&lt;br /&gt;
  max = Max[newCrossing[[2]], newCrossing[[4]]];&lt;br /&gt;
  If[max - min &amp;gt; 1,&lt;br /&gt;
   newLink = &lt;br /&gt;
    decreaseStrandLabels[Replace[newLink, max -&amp;gt; min, {2}], max];&lt;br /&gt;
   newCrossing = &lt;br /&gt;
    decreaseStrandLabels[{Replace[newCrossing, max -&amp;gt; min, {1}]}, &lt;br /&gt;
      max][[1]];&lt;br /&gt;
   newStrandList = &lt;br /&gt;
    Map[If[# &amp;gt; max, # - 1, #] &amp;amp;, &lt;br /&gt;
     Replace[newStrandList, max -&amp;gt; min, {1}]],&lt;br /&gt;
   newLink = decreaseStrandLabels[newLink, min];&lt;br /&gt;
   newCrossing = decreaseStrandLabels[{newCrossing}, min][[1]];&lt;br /&gt;
   newStrandList = Map[If[# &amp;gt; max, # - 1, #] &amp;amp;, newStrandList]&lt;br /&gt;
   ];&lt;br /&gt;
  {newLink, &lt;br /&gt;
   If[outgoingStrandPos &amp;gt; 0, newCrossing[[outgoingStrandPos]], -1], &lt;br /&gt;
   newStrandList}&lt;br /&gt;
  ]&lt;br /&gt;
increaseStrandLabels[link_, s_] := &lt;br /&gt;
  Replace[link, n_?(# &amp;gt; s &amp;amp;) -&amp;gt; n + 1, {2}];&lt;br /&gt;
decreaseStrandLabels[link_, s_] := &lt;br /&gt;
  Replace[link, n_?(# &amp;gt; s &amp;amp;) -&amp;gt; n - 1, {2}];&lt;br /&gt;
cableComponent[link_, s_, strandList_] := &lt;br /&gt;
  Module[{initialStrands, newComponentLabel = 2 Length[link] + 1},&lt;br /&gt;
   initialStrands = Join[{s, s, newComponentLabel}, strandList];&lt;br /&gt;
   recurse[newLink_, strands_] := &lt;br /&gt;
    Module[{currentStrand = strands[[1]], firstStrand = strands[[2]], &lt;br /&gt;
      currentCrossing, updatedLink, &lt;br /&gt;
      updatedStrands},(*copy the current crossing*)&lt;br /&gt;
     currentCrossing = findEnteringVertex[newLink, currentStrand];&lt;br /&gt;
     {updatedLink, updatedStrands} = &lt;br /&gt;
      duplicateVertex[newLink, currentCrossing, strands];&lt;br /&gt;
     (*check if we&#039;ve returned to the first strand*)&lt;br /&gt;
     If[updatedStrands[[1]] == updatedStrands[[2]],&lt;br /&gt;
      (*replace the largest strand label with the first strand label \&lt;br /&gt;
of the new component*)&lt;br /&gt;
      {Replace[updatedLink, &lt;br /&gt;
        n_?(# == 2 Length[updatedLink] + 1 &amp;amp;) -&amp;gt; &lt;br /&gt;
         updatedStrands[[3]], {2}], &lt;br /&gt;
       updatedStrands[[4 ;;]]},(*keep adding crossings*)&lt;br /&gt;
      recurse[updatedLink, updatedStrands]]&lt;br /&gt;
     ];&lt;br /&gt;
   recurse[link, initialStrands]&lt;br /&gt;
   ];&lt;br /&gt;
deleteComponent[link_, s_, strandList_] := &lt;br /&gt;
  Module[{newLink, currentStrand, newStrandList, currentCrossing},&lt;br /&gt;
   If[s &amp;lt;= 0,&lt;br /&gt;
    (*we&#039;re done deleting stuff*)&lt;br /&gt;
    {link, strandList},&lt;br /&gt;
    (*keep deleting*)&lt;br /&gt;
    currentCrossing = findEnteringVertex[link, s];&lt;br /&gt;
    {newLink, currentStrand, newStrandList} = &lt;br /&gt;
     deleteVertex[link, currentCrossing, s, strandList];&lt;br /&gt;
    deleteComponent[newLink, currentStrand, newStrandList]&lt;br /&gt;
    ]&lt;br /&gt;
   ];&lt;br /&gt;
cableLinkMonomial[link_, strandList_, degreeList_] := &lt;br /&gt;
  Module[{newLink = link, newStrandList, newDegreeList, coeff = 1},&lt;br /&gt;
   (*reorder so that we&#039;re deleting components first*)&lt;br /&gt;
   {newDegreeList, newStrandList} = {degreeList, strandList}[[All, &lt;br /&gt;
     Ordering@degreeList]];&lt;br /&gt;
   (*start cabling*)&lt;br /&gt;
   Do[&lt;br /&gt;
    Which[&lt;br /&gt;
     newStrandList[[i]] == 0,&lt;br /&gt;
     (*it&#039;s an unknot*)&lt;br /&gt;
     coeff = coeff*(-A^2 - A^(-2))^newDegreeList[[i]],&lt;br /&gt;
     newDegreeList[[i]] == 0,&lt;br /&gt;
     (*we need to delete it*)&lt;br /&gt;
     {newLink, newStrandList} = &lt;br /&gt;
      deleteComponent[newLink, newStrandList[[i]], newStrandList],&lt;br /&gt;
     True,&lt;br /&gt;
     (*cable the component*)&lt;br /&gt;
     Do[&lt;br /&gt;
      {newLink, newStrandList} = &lt;br /&gt;
       cableComponent[newLink, newStrandList[[i]], newStrandList]&lt;br /&gt;
      , {j, 1, newDegreeList[[i]] - 1}]&lt;br /&gt;
     ]&lt;br /&gt;
    , {i, 1, Length[newStrandList]}&lt;br /&gt;
    ];&lt;br /&gt;
   coeff*KB1[newLink]&lt;br /&gt;
   ];&lt;br /&gt;
cableLink[link_, poly_, strandList_, vars_] := &lt;br /&gt;
 Module[{monomials = CoefficientRules[poly, vars], temp},&lt;br /&gt;
  Total[&lt;br /&gt;
   Map[&lt;br /&gt;
    #[[2]]*cableLinkMonomial[link, strandList, #[[1]]] &amp;amp;&lt;br /&gt;
    , monomials]]&lt;br /&gt;
  ]&lt;br /&gt;
&lt;br /&gt;
(*&lt;/div&gt;</summary>
		<author><name>Sam.panitch</name></author>
	</entry>
	<entry>
		<id>https://katlas.org/index.php?title=CableLink.m&amp;diff=1725858</id>
		<title>CableLink.m</title>
		<link rel="alternate" type="text/html" href="https://katlas.org/index.php?title=CableLink.m&amp;diff=1725858"/>
		<updated>2025-08-05T22:55:24Z</updated>

		<summary type="html">&lt;p&gt;Sam.panitch: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
The program &amp;lt;code&amp;gt;CableLink&amp;lt;/code&amp;gt; is documented on the page [[Threading a link by a polynomial]]. It is not part of the package &amp;lt;code&amp;gt;KnotTheory`&amp;lt;/code&amp;gt; but is designed to work with it. Copy-paste the text below ignoring the &amp;lt;code&amp;gt;*&amp;amp;#41;&amp;lt;/code&amp;gt; on the first line and the &amp;lt;code&amp;gt;&amp;amp;#40;*&amp;lt;/code&amp;gt; on the last.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
*)&lt;br /&gt;
&lt;br /&gt;
(*Kauffman bracket*)&lt;br /&gt;
KB1[pd_PD] := KB1[pd, {}, 1];&lt;br /&gt;
KB1[pd_PD, inside_, web_] := &lt;br /&gt;
  Module[{pos = &lt;br /&gt;
     First[Ordering[Length[Complement[List @@ #, inside]] &amp;amp; /@ pd]]}, &lt;br /&gt;
   pd[[pos]] /.  &lt;br /&gt;
    X[a_, b_, c_, d_] :&amp;gt; &lt;br /&gt;
     KB1[Delete[pd, pos], Union[inside, {a, b, c, d}], &lt;br /&gt;
      Expand[web*(A P[a, d] P[b, c] + 1/A P[a, b] P[c, d])] //. {P[e_,&lt;br /&gt;
            f_] P[f_, g_] :&amp;gt; P[e, g], P[e_, _]^2 :&amp;gt; P[e, e], &lt;br /&gt;
        P[e_, e_] -&amp;gt; -A^2 - 1/A^2}]];&lt;br /&gt;
KB1[PD[], _, web_] := Expand[web]&lt;br /&gt;
(*Position of a strand at a crossing*)&lt;br /&gt;
strandAtCrossing[crossing_, s_] := Module[{pos},&lt;br /&gt;
   pos = Position[crossing, s];&lt;br /&gt;
   If[Length[pos] &amp;gt; 0, pos[[1, 1]], False]&lt;br /&gt;
   ];&lt;br /&gt;
(*Orientation of overstrand. Complicated by components with only two strand labels*)&lt;br /&gt;
orientationOfOverStrand[crossing_, link_] := Module[{otherCrossings},&lt;br /&gt;
   (*find the other crossings containing the strand labels of the \&lt;br /&gt;
overstrand crossing*)&lt;br /&gt;
   otherCrossings = &lt;br /&gt;
    DeleteElements[&lt;br /&gt;
     Select[link, &lt;br /&gt;
      ContainsAny[&lt;br /&gt;
        List[Delete[#, 0]], {crossing[[2]], &lt;br /&gt;
         crossing[[4]]}] &amp;amp;], {crossing}];&lt;br /&gt;
   (*if the length of othercrossings is 1, &lt;br /&gt;
   then the overstrand labels are part of a component with only two \&lt;br /&gt;
strand labels*)&lt;br /&gt;
   If[Length[otherCrossings] == 1,&lt;br /&gt;
    (*first check if a strand label is in the first position of the \&lt;br /&gt;
other crossing.*)&lt;br /&gt;
    Which[otherCrossings[[1, 1]] == crossing[[2]],&lt;br /&gt;
     True,&lt;br /&gt;
     otherCrossings[[1, 1]] == crossing[[4]],&lt;br /&gt;
     False,&lt;br /&gt;
     (*Otherwise, the strands are always overcrossings, &lt;br /&gt;
     in which case we just choose to orient from small to large*)&lt;br /&gt;
     True,&lt;br /&gt;
     crossing[[2]] &amp;gt; crossing[[4]]&lt;br /&gt;
     ],&lt;br /&gt;
    (*otherwise, &lt;br /&gt;
    the overcrossing is oriented from 4 to 2 if pos 2 is 1 more than \&lt;br /&gt;
pos 4, or if pos 4 is more than 1 greater than pos 2.*)&lt;br /&gt;
     crossing[[2]] - crossing[[4]] == 1 || &lt;br /&gt;
     crossing[[4]] - crossing[[2]] &amp;gt; 1&lt;br /&gt;
    ]&lt;br /&gt;
   ];&lt;br /&gt;
(*crossing that a strand enters*)&lt;br /&gt;
findEnteringVertex[link_, s_] := &lt;br /&gt;
  Module[{crossingsContainingS, firstCrossing, pos},&lt;br /&gt;
   (*find crossings containing s*)&lt;br /&gt;
   crossingsContainingS = &lt;br /&gt;
    Select[link, IntegerQ[strandAtCrossing[#, s]] &amp;amp;];&lt;br /&gt;
   firstCrossing = crossingsContainingS[[1]];&lt;br /&gt;
   pos = strandAtCrossing[firstCrossing, s];&lt;br /&gt;
   Which[&lt;br /&gt;
    (*if pos is 1, then it is definitely an incoming strand*)&lt;br /&gt;
    pos == 1,&lt;br /&gt;
    firstCrossing,&lt;br /&gt;
    (pos == 2 &amp;amp;&amp;amp; ! &lt;br /&gt;
        orientationOfOverStrand[firstCrossing, link]) || (pos == 4 &amp;amp;&amp;amp; &lt;br /&gt;
       orientationOfOverStrand[firstCrossing, link]),&lt;br /&gt;
    firstCrossing,&lt;br /&gt;
    (*otherwise it must be the entering strand at the other vertex \&lt;br /&gt;
containing that label*)&lt;br /&gt;
    True,&lt;br /&gt;
    crossingsContainingS[[2]]&lt;br /&gt;
    ]&lt;br /&gt;
   ];&lt;br /&gt;
duplicateVertex[link_, crossing_, strands_] := &lt;br /&gt;
  Module[{pos = strandAtCrossing[crossing, strands[[1]]], &lt;br /&gt;
    newLabel = Length[link]*2 + 2, &lt;br /&gt;
    newLink = DeleteElements[link, {crossing}], p1 = crossing[[1]], &lt;br /&gt;
    p2 = crossing[[2]], p3 = crossing[[3]], p4 = crossing[[4]]},&lt;br /&gt;
   Which[&lt;br /&gt;
    (*pos is 1 and the upper strand is oriented from 4 to 2*)&lt;br /&gt;
    pos == 1  &amp;amp;&amp;amp; orientationOfOverStrand[crossing, link],&lt;br /&gt;
    {Union[&lt;br /&gt;
      increaseStrandLabels[newLink, p4],&lt;br /&gt;
      PD[&lt;br /&gt;
       X[If[p1 &amp;lt; p2, p1, p1 + 1], p4 + 1, If[p3 &amp;lt; p2, p3, p3 + 1], &lt;br /&gt;
        p4]],&lt;br /&gt;
      PD[X[newLabel, If[p2 &amp;gt; p4, p2 + 1, p2], newLabel + 1, p4 + 1]]&lt;br /&gt;
      ],&lt;br /&gt;
     Map[If[# &amp;lt;= p2, #, # + 1] &amp;amp;, Prepend[strands[[2 ;;]], p3]]&lt;br /&gt;
     },&lt;br /&gt;
    (*pos is 1 and the upper strand is oriented from 2 to 4*)&lt;br /&gt;
    pos == 1,&lt;br /&gt;
    {Union[&lt;br /&gt;
      increaseStrandLabels[newLink, p2],&lt;br /&gt;
      PD[&lt;br /&gt;
       X[If[p1 &amp;lt; p2, p1, p1 + 1], p2 + 1, If[p3 &amp;lt; p2, p3, p3 + 1], &lt;br /&gt;
        If[p4 &amp;lt; p2, p4, p4 + 1]]],&lt;br /&gt;
      PD[X[newLabel, p2, newLabel + 1, p2 + 1]]&lt;br /&gt;
      ],&lt;br /&gt;
     Map[If[# &amp;lt;= p2, #, # + 1] &amp;amp;, Prepend[strands[[2 ;;]], p3]]&lt;br /&gt;
     },&lt;br /&gt;
    (*pos is 2*)&lt;br /&gt;
    pos == 2,&lt;br /&gt;
    {Union[&lt;br /&gt;
      increaseStrandLabels[newLink, p1],&lt;br /&gt;
      PD[&lt;br /&gt;
       X[p1, If[p2 &amp;lt; p1, p2, p2 + 1], p1 + 1, &lt;br /&gt;
        If[p4 &amp;lt; p1, p4, p4 + 1]]],&lt;br /&gt;
      PD[X[p1 + 1, newLabel, If[p3 &amp;lt; p1, p3, p3 + 1], newLabel + 1]]&lt;br /&gt;
      ],&lt;br /&gt;
     Map[If[# &amp;lt;= p1, #, # + 1] &amp;amp;, Prepend[strands[[2 ;;]], p4]]&lt;br /&gt;
     },&lt;br /&gt;
    (*pos is 4*)&lt;br /&gt;
    True,&lt;br /&gt;
    {Union[&lt;br /&gt;
      increaseStrandLabels[newLink, p1],&lt;br /&gt;
      PD[&lt;br /&gt;
       X[p1 + 1, If[p2 &amp;lt; p1, p2, p2 + 1], If[p3 &amp;lt; p1, p3, p3 + 1], &lt;br /&gt;
        If[p4 &amp;lt; p1, p4, p4 + 1]]],&lt;br /&gt;
      PD[X[p1, newLabel + 1, p1 + 1, newLabel]]&lt;br /&gt;
      ],&lt;br /&gt;
     Map[If[# &amp;lt;= p1, #, # + 1] &amp;amp;, Prepend[strands[[2 ;;]], p2]]&lt;br /&gt;
     }&lt;br /&gt;
    ]&lt;br /&gt;
   ];&lt;br /&gt;
deleteVertex[link_, crossing_, s_, strandList_] := &lt;br /&gt;
 Module[{newCrossing = crossing, &lt;br /&gt;
   newLink = DeleteElements[link, {crossing}], min, max, &lt;br /&gt;
   pos = strandAtCrossing[crossing, s], outgoingStrandPos, &lt;br /&gt;
   newStrandList = strandList},&lt;br /&gt;
  (*we create an unknot if the two labels of the other strand at the \&lt;br /&gt;
crossing are equal*)&lt;br /&gt;
  Which[(pos == 1 &amp;amp;&amp;amp; crossing[[2]] == crossing[[4]]) , &lt;br /&gt;
   newStrandList = &lt;br /&gt;
    Replace[newStrandList, &lt;br /&gt;
     crossing[[2]] -&amp;gt; 0, {1}], (pos == 2 || pos == 4 ) &amp;amp;&amp;amp; &lt;br /&gt;
    crossing[[1]] == crossing[[3]], &lt;br /&gt;
   newStrandList = Replace[newStrandList, crossing[[1]] -&amp;gt; 0, {1}]];&lt;br /&gt;
  (*&amp;quot;&lt;br /&gt;
	we need to keep track of the outgoing strand label. There&#039;s actually \&lt;br /&gt;
two ways to know we&#039;re done:&lt;br /&gt;
	either the outgoing strand is the same as the incoming strand, or \&lt;br /&gt;
the whole vertex only involves 2 different labels.&lt;br /&gt;
&amp;quot;*)&lt;br /&gt;
  outgoingStrandPos = Which[pos == 1, 3, pos == 2, 4, True, 2];&lt;br /&gt;
  If[crossing[[outgoingStrandPos]] == s || &lt;br /&gt;
    CountDistinct[{Delete[crossing, 0]}] &amp;lt; 3, &lt;br /&gt;
   outgoingStrandPos = -1];&lt;br /&gt;
  (*adjust link after combining pos 1 and pos 3*)&lt;br /&gt;
  If[crossing[[1]] &amp;gt; crossing[[3]],&lt;br /&gt;
   newLink = &lt;br /&gt;
    decreaseStrandLabels[&lt;br /&gt;
     Replace[newLink, crossing[[1]] -&amp;gt; crossing[[3]], {2}], &lt;br /&gt;
     newCrossing[[1]]];&lt;br /&gt;
   newCrossing = &lt;br /&gt;
    decreaseStrandLabels[{Replace[newCrossing, &lt;br /&gt;
        crossing[[1]] -&amp;gt; crossing[[3]], {1}]}, newCrossing[[1]]][[&lt;br /&gt;
     1]];&lt;br /&gt;
   newStrandList = &lt;br /&gt;
    Map[If[# &amp;gt; newCrossing[[1]], # - 1, #] &amp;amp;, &lt;br /&gt;
     Replace[newStrandList, crossing[[1]] -&amp;gt; crossing[[3]], {1}]]&lt;br /&gt;
   ,&lt;br /&gt;
   newLink = decreaseStrandLabels[newLink, newCrossing[[1]]];&lt;br /&gt;
   newCrossing = &lt;br /&gt;
    decreaseStrandLabels[{newCrossing}, newCrossing[[1]]][[1]];&lt;br /&gt;
   newStrandList = &lt;br /&gt;
    Map[If[# &amp;gt; newCrossing[[1]], # - 1, #] &amp;amp;, newStrandList]&lt;br /&gt;
   ];&lt;br /&gt;
  (*adjust link after combining pos 2 and pos 4*)&lt;br /&gt;
  min = Min[newCrossing[[2]], newCrossing[[4]]];&lt;br /&gt;
  max = Max[newCrossing[[2]], newCrossing[[4]]];&lt;br /&gt;
  If[max - min &amp;gt; 1,&lt;br /&gt;
   newLink = &lt;br /&gt;
    decreaseStrandLabels[Replace[newLink, max -&amp;gt; min, {2}], max];&lt;br /&gt;
   newCrossing = &lt;br /&gt;
    decreaseStrandLabels[{Replace[newCrossing, max -&amp;gt; min, {1}]}, &lt;br /&gt;
      max][[1]];&lt;br /&gt;
   newStrandList = &lt;br /&gt;
    Map[If[# &amp;gt; max, # - 1, #] &amp;amp;, &lt;br /&gt;
     Replace[newStrandList, max -&amp;gt; min, {1}]],&lt;br /&gt;
   newLink = decreaseStrandLabels[newLink, min];&lt;br /&gt;
   newCrossing = decreaseStrandLabels[{newCrossing}, min][[1]];&lt;br /&gt;
   newStrandList = Map[If[# &amp;gt; max, # - 1, #] &amp;amp;, newStrandList]&lt;br /&gt;
   ];&lt;br /&gt;
  {newLink, &lt;br /&gt;
   If[outgoingStrandPos &amp;gt; 0, newCrossing[[outgoingStrandPos]], -1], &lt;br /&gt;
   newStrandList}&lt;br /&gt;
  ]&lt;br /&gt;
increaseStrandLabels[link_, s_] := &lt;br /&gt;
  Replace[link, n_?(# &amp;gt; s &amp;amp;) -&amp;gt; n + 1, {2}];&lt;br /&gt;
decreaseStrandLabels[link_, s_] := &lt;br /&gt;
  Replace[link, n_?(# &amp;gt; s &amp;amp;) -&amp;gt; n - 1, {2}];&lt;br /&gt;
cableComponent[link_, s_, strandList_] := &lt;br /&gt;
  Module[{initialStrands, newComponentLabel = 2 Length[link] + 1},&lt;br /&gt;
   initialStrands = Join[{s, s, newComponentLabel}, strandList];&lt;br /&gt;
   recurse[newLink_, strands_] := &lt;br /&gt;
    Module[{currentStrand = strands[[1]], firstStrand = strands[[2]], &lt;br /&gt;
      currentCrossing, updatedLink, &lt;br /&gt;
      updatedStrands},(*copy the current crossing*)&lt;br /&gt;
     currentCrossing = findEnteringVertex[newLink, currentStrand];&lt;br /&gt;
     {updatedLink, updatedStrands} = &lt;br /&gt;
      duplicateVertex[newLink, currentCrossing, strands];&lt;br /&gt;
     (*check if we&#039;ve returned to the first strand*)&lt;br /&gt;
     If[updatedStrands[[1]] == updatedStrands[[2]],&lt;br /&gt;
      (*replace the largest strand label with the first strand label \&lt;br /&gt;
of the new component*)&lt;br /&gt;
      {Replace[updatedLink, &lt;br /&gt;
        n_?(# == 2 Length[updatedLink] + 1 &amp;amp;) -&amp;gt; &lt;br /&gt;
         updatedStrands[[3]], {2}], &lt;br /&gt;
       updatedStrands[[4 ;;]]},(*keep adding crossings*)&lt;br /&gt;
      recurse[updatedLink, updatedStrands]]&lt;br /&gt;
     ];&lt;br /&gt;
   recurse[link, initialStrands]&lt;br /&gt;
   ];&lt;br /&gt;
deleteComponent[link_, s_, strandList_] := &lt;br /&gt;
  Module[{newLink, currentStrand, newStrandList, currentCrossing},&lt;br /&gt;
   If[s &amp;lt;= 0,&lt;br /&gt;
    (*we&#039;re done deleting stuff*)&lt;br /&gt;
    {link, strandList},&lt;br /&gt;
    (*keep deleting*)&lt;br /&gt;
    currentCrossing = findEnteringVertex[link, s];&lt;br /&gt;
    {newLink, currentStrand, newStrandList} = &lt;br /&gt;
     deleteVertex[link, currentCrossing, s, strandList];&lt;br /&gt;
    deleteComponent[newLink, currentStrand, newStrandList]&lt;br /&gt;
    ]&lt;br /&gt;
   ];&lt;br /&gt;
cableLinkMonomial[link_, strandList_, degreeList_] := &lt;br /&gt;
  Module[{newLink = link, newStrandList, newDegreeList, coeff = 1},&lt;br /&gt;
   (*reorder so that we&#039;re deleting components first*)&lt;br /&gt;
   {newDegreeList, newStrandList} = {degreeList, strandList}[[All, &lt;br /&gt;
     Ordering@degreeList]];&lt;br /&gt;
   (*start cabling*)&lt;br /&gt;
   Do[&lt;br /&gt;
    Which[&lt;br /&gt;
     newStrandList[[i]] == 0,&lt;br /&gt;
     (*it&#039;s an unknot*)&lt;br /&gt;
     coeff = coeff*(-A^2 - A^(-2))^newDegreeList[[i]],&lt;br /&gt;
     newDegreeList[[i]] == 0,&lt;br /&gt;
     (*we need to delete it*)&lt;br /&gt;
     {newLink, newStrandList} = &lt;br /&gt;
      deleteComponent[newLink, newStrandList[[i]], newStrandList],&lt;br /&gt;
     True,&lt;br /&gt;
     (*cable the component*)&lt;br /&gt;
     Do[&lt;br /&gt;
      {newLink, newStrandList} = &lt;br /&gt;
       cableComponent[newLink, newStrandList[[i]], newStrandList]&lt;br /&gt;
      , {j, 1, newDegreeList[[i]] - 1}]&lt;br /&gt;
     ]&lt;br /&gt;
    , {i, 1, Length[newStrandList]}&lt;br /&gt;
    ];&lt;br /&gt;
   coeff*KB1[newLink]&lt;br /&gt;
   ];&lt;br /&gt;
cableLink[link_, poly_, strandList_, vars_] := &lt;br /&gt;
 Module[{monomials = CoefficientRules[poly, vars], temp},&lt;br /&gt;
  Total[&lt;br /&gt;
   Map[&lt;br /&gt;
    #[[2]]*cableLinkMonomial[link, strandList, #[[1]]] &amp;amp;&lt;br /&gt;
    , monomials]]&lt;br /&gt;
  ]&lt;br /&gt;
&lt;br /&gt;
(*&lt;/div&gt;</summary>
		<author><name>Sam.panitch</name></author>
	</entry>
	<entry>
		<id>https://katlas.org/index.php?title=CableLink.m&amp;diff=1725857</id>
		<title>CableLink.m</title>
		<link rel="alternate" type="text/html" href="https://katlas.org/index.php?title=CableLink.m&amp;diff=1725857"/>
		<updated>2025-08-05T22:55:08Z</updated>

		<summary type="html">&lt;p&gt;Sam.panitch: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
The program &amp;lt;code&amp;gt;CableLink&amp;lt;/code&amp;gt; is documented on the page [[Threading a link by a polynomial]]. It is not part of the package &amp;lt;code&amp;gt;KnotTheory`&amp;lt;/code&amp;gt; but is designed to work with it. Copy-paste the text below ignoring the &amp;lt;code&amp;gt;*&amp;amp;#41;&amp;lt;/code&amp;gt; on the first line and the &amp;lt;code&amp;gt;&amp;amp;#40;*&amp;lt;/code&amp;gt; on the last.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
*)&lt;br /&gt;
&lt;br /&gt;
(*Kauffman bracket*)&lt;br /&gt;
KB1[pd_PD] := KB1[pd, {}, 1];&lt;br /&gt;
KB1[pd_PD, inside_, web_] := &lt;br /&gt;
  Module[{pos = &lt;br /&gt;
     First[Ordering[Length[Complement[List @@ #, inside]] &amp;amp; /@ pd]]}, &lt;br /&gt;
   pd[[pos]] /.  &lt;br /&gt;
    X[a_, b_, c_, d_] :&amp;gt; &lt;br /&gt;
     KB1[Delete[pd, pos], Union[inside, {a, b, c, d}], &lt;br /&gt;
      Expand[web*(A P[a, d] P[b, c] + 1/A P[a, b] P[c, d])] //. {P[e_,&lt;br /&gt;
            f_] P[f_, g_] :&amp;gt; P[e, g], P[e_, _]^2 :&amp;gt; P[e, e], &lt;br /&gt;
        P[e_, e_] -&amp;gt; -A^2 - 1/A^2}]];&lt;br /&gt;
KB1[PD[], _, web_] := Expand[web]&lt;br /&gt;
(*Position of a strand at a crossing*)&lt;br /&gt;
strandAtCrossing[crossing_, s_] := Module[{pos},&lt;br /&gt;
   pos = Position[crossing, s];&lt;br /&gt;
   If[Length[pos] &amp;gt; 0, pos[[1, 1]], False]&lt;br /&gt;
   ];&lt;br /&gt;
(*Orientation of overstrand. Complicated by components with only two strand labels*)&lt;br /&gt;
orientationOfOverStrand[crossing_, link_] := Module[{otherCrossings},&lt;br /&gt;
   (*find the other crossings containing the strand labels of the \&lt;br /&gt;
overstrand crossing*)&lt;br /&gt;
   otherCrossings = &lt;br /&gt;
    DeleteElements[&lt;br /&gt;
     Select[link, &lt;br /&gt;
      ContainsAny[&lt;br /&gt;
        List[Delete[#, 0]], {crossing[[2]], &lt;br /&gt;
         crossing[[4]]}] &amp;amp;], {crossing}];&lt;br /&gt;
   (*if the length of othercrossings is 1, &lt;br /&gt;
   then the overstrand labels are part of a component with only two \&lt;br /&gt;
strand labels*)&lt;br /&gt;
   If[Length[otherCrossings] == 1,&lt;br /&gt;
    (*first check if a strand label is in the first position of the \&lt;br /&gt;
other crossing.*)&lt;br /&gt;
    Which[otherCrossings[[1, 1]] == crossing[[2]],&lt;br /&gt;
     True,&lt;br /&gt;
     otherCrossings[[1, 1]] == crossing[[4]],&lt;br /&gt;
     False,&lt;br /&gt;
     (*Otherwise, the strands are always overcrossings, &lt;br /&gt;
     in which case we just choose to orient from small to large*)&lt;br /&gt;
     True,&lt;br /&gt;
     crossing[[2]] &amp;gt; crossing[[4]]&lt;br /&gt;
     ],&lt;br /&gt;
    (*otherwise, &lt;br /&gt;
    the overcrossing is oriented from 4 to 2 if pos 2 is 1 more than \&lt;br /&gt;
pos 4, or if pos 4 is more than 1 greater than pos 2.*)&lt;br /&gt;
     crossing[[2]] - crossing[[4]] == 1 || &lt;br /&gt;
     crossing[[4]] - crossing[[2]] &amp;gt; 1&lt;br /&gt;
    ]&lt;br /&gt;
   ];&lt;br /&gt;
(*crossing that a strand enters*)&lt;br /&gt;
findEnteringVertex[link_, s_] := &lt;br /&gt;
  Module[{crossingsContainingS, firstCrossing, pos},&lt;br /&gt;
   (*find crossings containing s*)&lt;br /&gt;
   crossingsContainingS = &lt;br /&gt;
    Select[link, IntegerQ[strandAtCrossing[#, s]] &amp;amp;];&lt;br /&gt;
   firstCrossing = crossingsContainingS[[1]];&lt;br /&gt;
   pos = strandAtCrossing[firstCrossing, s];&lt;br /&gt;
   Which[&lt;br /&gt;
    (*if pos is 1, then it is definitely an incoming strand*)&lt;br /&gt;
    pos == 1,&lt;br /&gt;
    firstCrossing,&lt;br /&gt;
    (pos == 2 &amp;amp;&amp;amp; ! &lt;br /&gt;
        orientationOfOverStrand[firstCrossing, link]) || (pos == 4 &amp;amp;&amp;amp; &lt;br /&gt;
       orientationOfOverStrand[firstCrossing, link]),&lt;br /&gt;
    firstCrossing,&lt;br /&gt;
    (*otherwise it must be the entering strand at the other vertex \&lt;br /&gt;
containing that label*)&lt;br /&gt;
    True,&lt;br /&gt;
    crossingsContainingS[[2]]&lt;br /&gt;
    ]&lt;br /&gt;
   ];&lt;br /&gt;
duplicateVertex[link_, crossing_, strands_] := &lt;br /&gt;
  Module[{pos = strandAtCrossing[crossing, strands[[1]]], &lt;br /&gt;
    newLabel = Length[link]*2 + 2, &lt;br /&gt;
    newLink = DeleteElements[link, {crossing}], p1 = crossing[[1]], &lt;br /&gt;
    p2 = crossing[[2]], p3 = crossing[[3]], p4 = crossing[[4]]},&lt;br /&gt;
   Which[&lt;br /&gt;
    (*pos is 1 and the upper strand is oriented from 4 to 2*)&lt;br /&gt;
    pos == 1  &amp;amp;&amp;amp; orientationOfOverStrand[crossing, link],&lt;br /&gt;
    {Union[&lt;br /&gt;
      increaseStrandLabels[newLink, p4],&lt;br /&gt;
      PD[&lt;br /&gt;
       X[If[p1 &amp;lt; p2, p1, p1 + 1], p4 + 1, If[p3 &amp;lt; p2, p3, p3 + 1], &lt;br /&gt;
        p4]],&lt;br /&gt;
      PD[X[newLabel, If[p2 &amp;gt; p4, p2 + 1, p2], newLabel + 1, p4 + 1]]&lt;br /&gt;
      ],&lt;br /&gt;
     Map[If[# &amp;lt;= p2, #, # + 1] &amp;amp;, Prepend[strands[[2 ;;]], p3]]&lt;br /&gt;
     },&lt;br /&gt;
    (*pos is 1 and the upper strand is oriented from 2 to 4*)&lt;br /&gt;
    pos == 1,&lt;br /&gt;
    {Union[&lt;br /&gt;
      increaseStrandLabels[newLink, p2],&lt;br /&gt;
      PD[&lt;br /&gt;
       X[If[p1 &amp;lt; p2, p1, p1 + 1], p2 + 1, If[p3 &amp;lt; p2, p3, p3 + 1], &lt;br /&gt;
        If[p4 &amp;lt; p2, p4, p4 + 1]]],&lt;br /&gt;
      PD[X[newLabel, p2, newLabel + 1, p2 + 1]]&lt;br /&gt;
      ],&lt;br /&gt;
     Map[If[# &amp;lt;= p2, #, # + 1] &amp;amp;, Prepend[strands[[2 ;;]], p3]]&lt;br /&gt;
     },&lt;br /&gt;
    (*pos is 2*)&lt;br /&gt;
    pos == 2,&lt;br /&gt;
    {Union[&lt;br /&gt;
      increaseStrandLabels[newLink, p1],&lt;br /&gt;
      PD[&lt;br /&gt;
       X[p1, If[p2 &amp;lt; p1, p2, p2 + 1], p1 + 1, &lt;br /&gt;
        If[p4 &amp;lt; p1, p4, p4 + 1]]],&lt;br /&gt;
      PD[X[p1 + 1, newLabel, If[p3 &amp;lt; p1, p3, p3 + 1], newLabel + 1]]&lt;br /&gt;
      ],&lt;br /&gt;
     Map[If[# &amp;lt;= p1, #, # + 1] &amp;amp;, Prepend[strands[[2 ;;]], p4]]&lt;br /&gt;
     },&lt;br /&gt;
    (*pos is 4*)&lt;br /&gt;
    True,&lt;br /&gt;
    {Union[&lt;br /&gt;
      increaseStrandLabels[newLink, p1],&lt;br /&gt;
      PD[&lt;br /&gt;
       X[p1 + 1, If[p2 &amp;lt; p1, p2, p2 + 1], If[p3 &amp;lt; p1, p3, p3 + 1], &lt;br /&gt;
        If[p4 &amp;lt; p1, p4, p4 + 1]]],&lt;br /&gt;
      PD[X[p1, newLabel + 1, p1 + 1, newLabel]]&lt;br /&gt;
      ],&lt;br /&gt;
     Map[If[# &amp;lt;= p1, #, # + 1] &amp;amp;, Prepend[strands[[2 ;;]], p2]]&lt;br /&gt;
     }&lt;br /&gt;
    ]&lt;br /&gt;
   ];&lt;br /&gt;
deleteVertex[link_, crossing_, s_, strandList_] := &lt;br /&gt;
 Module[{newCrossing = crossing, &lt;br /&gt;
   newLink = DeleteElements[link, {crossing}], min, max, &lt;br /&gt;
   pos = strandAtCrossing[crossing, s], outgoingStrandPos, &lt;br /&gt;
   newStrandList = strandList},&lt;br /&gt;
  (*we create an unknot if the two labels of the other strand at the \&lt;br /&gt;
crossing are equal*)&lt;br /&gt;
  Which[(pos == 1 &amp;amp;&amp;amp; crossing[[2]] == crossing[[4]]) , &lt;br /&gt;
   newStrandList = &lt;br /&gt;
    Replace[newStrandList, &lt;br /&gt;
     crossing[[2]] -&amp;gt; 0, {1}], (pos == 2 || pos == 4 ) &amp;amp;&amp;amp; &lt;br /&gt;
    crossing[[1]] == crossing[[3]], &lt;br /&gt;
   newStrandList = Replace[newStrandList, crossing[[1]] -&amp;gt; 0, {1}]];&lt;br /&gt;
  (*&amp;quot;&lt;br /&gt;
	we need to keep track of the outgoing strand label. There&#039;s actually \&lt;br /&gt;
two ways to know we&#039;re done:&lt;br /&gt;
	either the outgoing strand is the same as the incoming strand, or \&lt;br /&gt;
the whole vertex only involves 2 different labels.&lt;br /&gt;
&amp;quot;*)&lt;br /&gt;
  outgoingStrandPos = Which[pos == 1, 3, pos == 2, 4, True, 2];&lt;br /&gt;
  If[crossing[[outgoingStrandPos]] == s || &lt;br /&gt;
    CountDistinct[{Delete[crossing, 0]}] &amp;lt; 3, &lt;br /&gt;
   outgoingStrandPos = -1];&lt;br /&gt;
  (*adjust link after combining pos 1 and pos 3*)&lt;br /&gt;
  If[crossing[[1]] &amp;gt; crossing[[3]],&lt;br /&gt;
   newLink = &lt;br /&gt;
    decreaseStrandLabels[&lt;br /&gt;
     Replace[newLink, crossing[[1]] -&amp;gt; crossing[[3]], {2}], &lt;br /&gt;
     newCrossing[[1]]];&lt;br /&gt;
   newCrossing = &lt;br /&gt;
    decreaseStrandLabels[{Replace[newCrossing, &lt;br /&gt;
        crossing[[1]] -&amp;gt; crossing[[3]], {1}]}, newCrossing[[1]]][[&lt;br /&gt;
     1]];&lt;br /&gt;
   newStrandList = &lt;br /&gt;
    Map[If[# &amp;gt; newCrossing[[1]], # - 1, #] &amp;amp;, &lt;br /&gt;
     Replace[newStrandList, crossing[[1]] -&amp;gt; crossing[[3]], {1}]]&lt;br /&gt;
   ,&lt;br /&gt;
   newLink = decreaseStrandLabels[newLink, newCrossing[[1]]];&lt;br /&gt;
   newCrossing = &lt;br /&gt;
    decreaseStrandLabels[{newCrossing}, newCrossing[[1]]][[1]];&lt;br /&gt;
   newStrandList = &lt;br /&gt;
    Map[If[# &amp;gt; newCrossing[[1]], # - 1, #] &amp;amp;, newStrandList]&lt;br /&gt;
   ];&lt;br /&gt;
  (*adjust link after combining pos 2 and pos 4*)&lt;br /&gt;
  min = Min[newCrossing[[2]], newCrossing[[4]]];&lt;br /&gt;
  max = Max[newCrossing[[2]], newCrossing[[4]]];&lt;br /&gt;
  If[max - min &amp;gt; 1,&lt;br /&gt;
   newLink = &lt;br /&gt;
    decreaseStrandLabels[Replace[newLink, max -&amp;gt; min, {2}], max];&lt;br /&gt;
   newCrossing = &lt;br /&gt;
    decreaseStrandLabels[{Replace[newCrossing, max -&amp;gt; min, {1}]}, &lt;br /&gt;
      max][[1]];&lt;br /&gt;
   newStrandList = &lt;br /&gt;
    Map[If[# &amp;gt; max, # - 1, #] &amp;amp;, &lt;br /&gt;
     Replace[newStrandList, max -&amp;gt; min, {1}]],&lt;br /&gt;
   newLink = decreaseStrandLabels[newLink, min];&lt;br /&gt;
   newCrossing = decreaseStrandLabels[{newCrossing}, min][[1]];&lt;br /&gt;
   newStrandList = Map[If[# &amp;gt; max, # - 1, #] &amp;amp;, newStrandList]&lt;br /&gt;
   ];&lt;br /&gt;
  {newLink, &lt;br /&gt;
   If[outgoingStrandPos &amp;gt; 0, newCrossing[[outgoingStrandPos]], -1], &lt;br /&gt;
   newStrandList}&lt;br /&gt;
  ]&lt;br /&gt;
increaseStrandLabels[link_, s_] := &lt;br /&gt;
  Replace[link, n_?(# &amp;gt; s &amp;amp;) -&amp;gt; n + 1, {2}];&lt;br /&gt;
decreaseStrandLabels[link_, s_] := &lt;br /&gt;
  Replace[link, n_?(# &amp;gt; s &amp;amp;) -&amp;gt; n - 1, {2}];&lt;br /&gt;
cableComponent[link_, s_, strandList_] := &lt;br /&gt;
  Module[{initialStrands, newComponentLabel = 2 Length[link] + 1},&lt;br /&gt;
   initialStrands = Join[{s, s, newComponentLabel}, strandList];&lt;br /&gt;
   recurse[newLink_, strands_] := &lt;br /&gt;
    Module[{currentStrand = strands[[1]], firstStrand = strands[[2]], &lt;br /&gt;
      currentCrossing, updatedLink, &lt;br /&gt;
      updatedStrands},(*copy the current crossing*)&lt;br /&gt;
     currentCrossing = findEnteringVertex[newLink, currentStrand];&lt;br /&gt;
     {updatedLink, updatedStrands} = &lt;br /&gt;
      duplicateVertex[newLink, currentCrossing, strands];&lt;br /&gt;
     (*check if we&#039;ve returned to the first strand*)&lt;br /&gt;
     If[updatedStrands[[1]] == updatedStrands[[2]],&lt;br /&gt;
      (*replace the largest strand label with the first strand label \&lt;br /&gt;
of the new component*)&lt;br /&gt;
      {Replace[updatedLink, &lt;br /&gt;
        n_?(# == 2 Length[updatedLink] + 1 &amp;amp;) -&amp;gt; &lt;br /&gt;
         updatedStrands[[3]], {2}], &lt;br /&gt;
       updatedStrands[[4 ;;]]},(*keep adding crossings*)&lt;br /&gt;
      recurse[updatedLink, updatedStrands]]&lt;br /&gt;
     ];&lt;br /&gt;
   recurse[link, initialStrands]&lt;br /&gt;
   ];&lt;br /&gt;
deleteComponent[link_, s_, strandList_] := &lt;br /&gt;
  Module[{newLink, currentStrand, newStrandList, currentCrossing},&lt;br /&gt;
   If[s &amp;lt;= 0,&lt;br /&gt;
    (*we&#039;re done deleting stuff*)&lt;br /&gt;
    {link, strandList},&lt;br /&gt;
    (*keep deleting*)&lt;br /&gt;
    currentCrossing = findEnteringVertex[link, s];&lt;br /&gt;
    {newLink, currentStrand, newStrandList} = &lt;br /&gt;
     deleteVertex[link, currentCrossing, s, strandList];&lt;br /&gt;
    deleteComponent[newLink, currentStrand, newStrandList]&lt;br /&gt;
    ]&lt;br /&gt;
   ];&lt;br /&gt;
cableLinkMonomial[link_, strandList_, degreeList_] := &lt;br /&gt;
  Module[{newLink = link, newStrandList, newDegreeList, coeff = 1},&lt;br /&gt;
   (*reorder so that we&#039;re deleting components first*)&lt;br /&gt;
   {newDegreeList, newStrandList} = {degreeList, strandList}[[All, &lt;br /&gt;
     Ordering@degreeList]];&lt;br /&gt;
   (*start cabling*)&lt;br /&gt;
   Do[&lt;br /&gt;
    Which[&lt;br /&gt;
     newStrandList[[i]] == 0,&lt;br /&gt;
     (*it&#039;s an unknot*)&lt;br /&gt;
     coeff = coeff*(-A^2 - A^(-2))^newDegreeList[[i]],&lt;br /&gt;
     newDegreeList[[i]] == 0,&lt;br /&gt;
     (*we need to delete it*)&lt;br /&gt;
     {newLink, newStrandList} = &lt;br /&gt;
      deleteComponent[newLink, newStrandList[[i]], newStrandList],&lt;br /&gt;
     True,&lt;br /&gt;
     (*cable the component*)&lt;br /&gt;
     Do[&lt;br /&gt;
      {newLink, newStrandList} = &lt;br /&gt;
       cableComponent[newLink, newStrandList[[i]], newStrandList]&lt;br /&gt;
      , {j, 1, newDegreeList[[i]] - 1}]&lt;br /&gt;
     ]&lt;br /&gt;
    , {i, 1, Length[newStrandList]}&lt;br /&gt;
    ];&lt;br /&gt;
   coeff*KB1[newLink]&lt;br /&gt;
   ];&lt;br /&gt;
cableLink[link_, poly_, strandList_, vars_] := &lt;br /&gt;
 Module[{monomials = CoefficientRules[poly, vars], temp},&lt;br /&gt;
  Total[&lt;br /&gt;
   Map[&lt;br /&gt;
    #[[2]]*cableLinkMonomial[link, strandList, #[[1]]] &amp;amp;&lt;br /&gt;
    , monomials]]&lt;br /&gt;
  ]&lt;br /&gt;
&lt;br /&gt;
*(&lt;/div&gt;</summary>
		<author><name>Sam.panitch</name></author>
	</entry>
	<entry>
		<id>https://katlas.org/index.php?title=CableLink.m&amp;diff=1725856</id>
		<title>CableLink.m</title>
		<link rel="alternate" type="text/html" href="https://katlas.org/index.php?title=CableLink.m&amp;diff=1725856"/>
		<updated>2025-08-05T22:52:47Z</updated>

		<summary type="html">&lt;p&gt;Sam.panitch: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
The program &amp;lt;code&amp;gt;CableLink&amp;lt;/code&amp;gt; is documented on the page [[Threading a link by a polynomial]]. It is not part of the package &amp;lt;code&amp;gt;KnotTheory`&amp;lt;/code&amp;gt; but is designed to work with it. Copy-paste the text below ignoring the &amp;lt;code&amp;gt;*&amp;amp;#41;&amp;lt;/code&amp;gt; on the first line and the &amp;lt;code&amp;gt;&amp;amp;#40;*&amp;lt;/code&amp;gt; on the last.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
*)&lt;br /&gt;
&lt;br /&gt;
(*Kauffman bracket*)&lt;br /&gt;
KB1[pd_PD] := KB1[pd, {}, 1];&lt;br /&gt;
KB1[pd_PD, inside_, web_] := &lt;br /&gt;
  Module[{pos = &lt;br /&gt;
     First[Ordering[Length[Complement[List @@ #, inside]] &amp;amp; /@ pd]]}, &lt;br /&gt;
   pd[[pos]] /.  &lt;br /&gt;
    X[a_, b_, c_, d_] :&amp;gt; &lt;br /&gt;
     KB1[Delete[pd, pos], Union[inside, {a, b, c, d}], &lt;br /&gt;
      Expand[web*(A P[a, d] P[b, c] + 1/A P[a, b] P[c, d])] //. {P[e_,&lt;br /&gt;
            f_] P[f_, g_] :&amp;gt; P[e, g], P[e_, _]^2 :&amp;gt; P[e, e], &lt;br /&gt;
        P[e_, e_] -&amp;gt; -A^2 - 1/A^2}]];&lt;br /&gt;
KB1[PD[], _, web_] := Expand[web]&lt;br /&gt;
(*Position of a strand at a crossing*)&lt;br /&gt;
strandAtCrossing[crossing_, s_] := Module[{pos},&lt;br /&gt;
   pos = Position[crossing, s];&lt;br /&gt;
   If[Length[pos] &amp;gt; 0, pos[[1, 1]], False]&lt;br /&gt;
   ];&lt;br /&gt;
(*Orientation of overstrand. Complicated by components with only two strand labels*)&lt;br /&gt;
orientationOfOverStrand[crossing_, link_] := Module[{otherCrossings},&lt;br /&gt;
   (*find the other crossings containing the strand labels of the \&lt;br /&gt;
overstrand crossing*)&lt;br /&gt;
   otherCrossings = &lt;br /&gt;
    DeleteElements[&lt;br /&gt;
     Select[link, &lt;br /&gt;
      ContainsAny[&lt;br /&gt;
        List[Delete[#, 0]], {crossing[[2]], &lt;br /&gt;
         crossing[[4]]}] &amp;amp;], {crossing}];&lt;br /&gt;
   (*if the length of othercrossings is 1, &lt;br /&gt;
   then the overstrand labels are part of a component with only two \&lt;br /&gt;
strand labels*)&lt;br /&gt;
   If[Length[otherCrossings] == 1,&lt;br /&gt;
    (*first check if a strand label is in the first position of the \&lt;br /&gt;
other crossing.*)&lt;br /&gt;
    Which[otherCrossings[[1, 1]] == crossing[[2]],&lt;br /&gt;
     True,&lt;br /&gt;
     otherCrossings[[1, 1]] == crossing[[4]],&lt;br /&gt;
     False,&lt;br /&gt;
     (*Otherwise, the strands are always overcrossings, &lt;br /&gt;
     in which case we just choose to orient from small to large*)&lt;br /&gt;
     True,&lt;br /&gt;
     crossing[[2]] &amp;gt; crossing[[4]]&lt;br /&gt;
     ],&lt;br /&gt;
    (*otherwise, &lt;br /&gt;
    the overcrossing is oriented from 4 to 2 if pos 2 is 1 more than \&lt;br /&gt;
pos 4, or if pos 4 is more than 1 greater than pos 2.*)&lt;br /&gt;
     crossing[[2]] - crossing[[4]] == 1 || &lt;br /&gt;
     crossing[[4]] - crossing[[2]] &amp;gt; 1&lt;br /&gt;
    ]&lt;br /&gt;
   ];&lt;br /&gt;
(*crossing that a strand enters*)&lt;br /&gt;
findEnteringVertex[link_, s_] := &lt;br /&gt;
  Module[{crossingsContainingS, firstCrossing, pos},&lt;br /&gt;
   (*find crossings containing s*)&lt;br /&gt;
   crossingsContainingS = &lt;br /&gt;
    Select[link, IntegerQ[strandAtCrossing[#, s]] &amp;amp;];&lt;br /&gt;
   firstCrossing = crossingsContainingS[[1]];&lt;br /&gt;
   pos = strandAtCrossing[firstCrossing, s];&lt;br /&gt;
   Which[&lt;br /&gt;
    (*if pos is 1, then it is definitely an incoming strand*)&lt;br /&gt;
    pos == 1,&lt;br /&gt;
    firstCrossing,&lt;br /&gt;
    (pos == 2 &amp;amp;&amp;amp; ! &lt;br /&gt;
        orientationOfOverStrand[firstCrossing, link]) || (pos == 4 &amp;amp;&amp;amp; &lt;br /&gt;
       orientationOfOverStrand[firstCrossing, link]),&lt;br /&gt;
    firstCrossing,&lt;br /&gt;
    (*otherwise it must be the entering strand at the other vertex \&lt;br /&gt;
containing that label*)&lt;br /&gt;
    True,&lt;br /&gt;
    crossingsContainingS[[2]]&lt;br /&gt;
    ]&lt;br /&gt;
   ];&lt;br /&gt;
duplicateVertex[link_, crossing_, strands_] := &lt;br /&gt;
  Module[{pos = strandAtCrossing[crossing, strands[[1]]], &lt;br /&gt;
    newLabel = Length[link]*2 + 2, &lt;br /&gt;
    newLink = DeleteElements[link, {crossing}], p1 = crossing[[1]], &lt;br /&gt;
    p2 = crossing[[2]], p3 = crossing[[3]], p4 = crossing[[4]]},&lt;br /&gt;
   Which[&lt;br /&gt;
    (*pos is 1 and the upper strand is oriented from 4 to 2*)&lt;br /&gt;
    pos == 1  &amp;amp;&amp;amp; orientationOfOverStrand[crossing, link],&lt;br /&gt;
    {Union[&lt;br /&gt;
      increaseStrandLabels[newLink, p4],&lt;br /&gt;
      PD[&lt;br /&gt;
       X[If[p1 &amp;lt; p2, p1, p1 + 1], p4 + 1, If[p3 &amp;lt; p2, p3, p3 + 1], &lt;br /&gt;
        p4]],&lt;br /&gt;
      PD[X[newLabel, If[p2 &amp;gt; p4, p2 + 1, p2], newLabel + 1, p4 + 1]]&lt;br /&gt;
      ],&lt;br /&gt;
     Map[If[# &amp;lt;= p2, #, # + 1] &amp;amp;, Prepend[strands[[2 ;;]], p3]]&lt;br /&gt;
     },&lt;br /&gt;
    (*pos is 1 and the upper strand is oriented from 2 to 4*)&lt;br /&gt;
    pos == 1,&lt;br /&gt;
    {Union[&lt;br /&gt;
      increaseStrandLabels[newLink, p2],&lt;br /&gt;
      PD[&lt;br /&gt;
       X[If[p1 &amp;lt; p2, p1, p1 + 1], p2 + 1, If[p3 &amp;lt; p2, p3, p3 + 1], &lt;br /&gt;
        If[p4 &amp;lt; p2, p4, p4 + 1]]],&lt;br /&gt;
      PD[X[newLabel, p2, newLabel + 1, p2 + 1]]&lt;br /&gt;
      ],&lt;br /&gt;
     Map[If[# &amp;lt;= p2, #, # + 1] &amp;amp;, Prepend[strands[[2 ;;]], p3]]&lt;br /&gt;
     },&lt;br /&gt;
    (*pos is 2*)&lt;br /&gt;
    pos == 2,&lt;br /&gt;
    {Union[&lt;br /&gt;
      increaseStrandLabels[newLink, p1],&lt;br /&gt;
      PD[&lt;br /&gt;
       X[p1, If[p2 &amp;lt; p1, p2, p2 + 1], p1 + 1, &lt;br /&gt;
        If[p4 &amp;lt; p1, p4, p4 + 1]]],&lt;br /&gt;
      PD[X[p1 + 1, newLabel, If[p3 &amp;lt; p1, p3, p3 + 1], newLabel + 1]]&lt;br /&gt;
      ],&lt;br /&gt;
     Map[If[# &amp;lt;= p1, #, # + 1] &amp;amp;, Prepend[strands[[2 ;;]], p4]]&lt;br /&gt;
     },&lt;br /&gt;
    (*pos is 4*)&lt;br /&gt;
    True,&lt;br /&gt;
    {Union[&lt;br /&gt;
      increaseStrandLabels[newLink, p1],&lt;br /&gt;
      PD[&lt;br /&gt;
       X[p1 + 1, If[p2 &amp;lt; p1, p2, p2 + 1], If[p3 &amp;lt; p1, p3, p3 + 1], &lt;br /&gt;
        If[p4 &amp;lt; p1, p4, p4 + 1]]],&lt;br /&gt;
      PD[X[p1, newLabel + 1, p1 + 1, newLabel]]&lt;br /&gt;
      ],&lt;br /&gt;
     Map[If[# &amp;lt;= p1, #, # + 1] &amp;amp;, Prepend[strands[[2 ;;]], p2]]&lt;br /&gt;
     }&lt;br /&gt;
    ]&lt;br /&gt;
   ];&lt;br /&gt;
deleteVertex[link_, crossing_, s_, strandList_] := &lt;br /&gt;
 Module[{newCrossing = crossing, &lt;br /&gt;
   newLink = DeleteElements[link, {crossing}], min, max, &lt;br /&gt;
   pos = strandAtCrossing[crossing, s], outgoingStrandPos, &lt;br /&gt;
   newStrandList = strandList},&lt;br /&gt;
  (*we create an unknot if the two labels of the other strand at the \&lt;br /&gt;
crossing are equal*)&lt;br /&gt;
  Which[(pos == 1 &amp;amp;&amp;amp; crossing[[2]] == crossing[[4]]) , &lt;br /&gt;
   newStrandList = &lt;br /&gt;
    Replace[newStrandList, &lt;br /&gt;
     crossing[[2]] -&amp;gt; 0, {1}], (pos == 2 || pos == 4 ) &amp;amp;&amp;amp; &lt;br /&gt;
    crossing[[1]] == crossing[[3]], &lt;br /&gt;
   newStrandList = Replace[newStrandList, crossing[[1]] -&amp;gt; 0, {1}]];&lt;br /&gt;
  (*&amp;quot;&lt;br /&gt;
	we need to keep track of the outgoing strand label. There&#039;s actually \&lt;br /&gt;
two ways to know we&#039;re done:&lt;br /&gt;
	either the outgoing strand is the same as the incoming strand, or \&lt;br /&gt;
the whole vertex only involves 2 different labels.&lt;br /&gt;
&amp;quot;*)&lt;br /&gt;
  outgoingStrandPos = Which[pos == 1, 3, pos == 2, 4, True, 2];&lt;br /&gt;
  If[crossing[[outgoingStrandPos]] == s || &lt;br /&gt;
    CountDistinct[{Delete[crossing, 0]}] &amp;lt; 3, &lt;br /&gt;
   outgoingStrandPos = -1];&lt;br /&gt;
  (*adjust link after combining pos 1 and pos 3*)&lt;br /&gt;
  If[crossing[[1]] &amp;gt; crossing[[3]],&lt;br /&gt;
   newLink = &lt;br /&gt;
    decreaseStrandLabels[&lt;br /&gt;
     Replace[newLink, crossing[[1]] -&amp;gt; crossing[[3]], {2}], &lt;br /&gt;
     newCrossing[[1]]];&lt;br /&gt;
   newCrossing = &lt;br /&gt;
    decreaseStrandLabels[{Replace[newCrossing, &lt;br /&gt;
        crossing[[1]] -&amp;gt; crossing[[3]], {1}]}, newCrossing[[1]]][[&lt;br /&gt;
     1]];&lt;br /&gt;
   newStrandList = &lt;br /&gt;
    Map[If[# &amp;gt; newCrossing[[1]], # - 1, #] &amp;amp;, &lt;br /&gt;
     Replace[newStrandList, crossing[[1]] -&amp;gt; crossing[[3]], {1}]]&lt;br /&gt;
   ,&lt;br /&gt;
   newLink = decreaseStrandLabels[newLink, newCrossing[[1]]];&lt;br /&gt;
   newCrossing = &lt;br /&gt;
    decreaseStrandLabels[{newCrossing}, newCrossing[[1]]][[1]];&lt;br /&gt;
   newStrandList = &lt;br /&gt;
    Map[If[# &amp;gt; newCrossing[[1]], # - 1, #] &amp;amp;, newStrandList]&lt;br /&gt;
   ];&lt;br /&gt;
  (*adjust link after combining pos 2 and pos 4*)&lt;br /&gt;
  min = Min[newCrossing[[2]], newCrossing[[4]]];&lt;br /&gt;
  max = Max[newCrossing[[2]], newCrossing[[4]]];&lt;br /&gt;
  If[max - min &amp;gt; 1,&lt;br /&gt;
   newLink = &lt;br /&gt;
    decreaseStrandLabels[Replace[newLink, max -&amp;gt; min, {2}], max];&lt;br /&gt;
   newCrossing = &lt;br /&gt;
    decreaseStrandLabels[{Replace[newCrossing, max -&amp;gt; min, {1}]}, &lt;br /&gt;
      max][[1]];&lt;br /&gt;
   newStrandList = &lt;br /&gt;
    Map[If[# &amp;gt; max, # - 1, #] &amp;amp;, &lt;br /&gt;
     Replace[newStrandList, max -&amp;gt; min, {1}]],&lt;br /&gt;
   newLink = decreaseStrandLabels[newLink, min];&lt;br /&gt;
   newCrossing = decreaseStrandLabels[{newCrossing}, min][[1]];&lt;br /&gt;
   newStrandList = Map[If[# &amp;gt; max, # - 1, #] &amp;amp;, newStrandList]&lt;br /&gt;
   ];&lt;br /&gt;
  {newLink, &lt;br /&gt;
   If[outgoingStrandPos &amp;gt; 0, newCrossing[[outgoingStrandPos]], -1], &lt;br /&gt;
   newStrandList}&lt;br /&gt;
  ]&lt;br /&gt;
increaseStrandLabels[link_, s_] := &lt;br /&gt;
  Replace[link, n_?(# &amp;gt; s &amp;amp;) -&amp;gt; n + 1, {2}];&lt;br /&gt;
decreaseStrandLabels[link_, s_] := &lt;br /&gt;
  Replace[link, n_?(# &amp;gt; s &amp;amp;) -&amp;gt; n - 1, {2}];&lt;br /&gt;
cableComponent[link_, s_, strandList_] := &lt;br /&gt;
  Module[{initialStrands, newComponentLabel = 2 Length[link] + 1},&lt;br /&gt;
   initialStrands = Join[{s, s, newComponentLabel}, strandList];&lt;br /&gt;
   recurse[newLink_, strands_] := &lt;br /&gt;
    Module[{currentStrand = strands[[1]], firstStrand = strands[[2]], &lt;br /&gt;
      currentCrossing, updatedLink, &lt;br /&gt;
      updatedStrands},(*copy the current crossing*)&lt;br /&gt;
     currentCrossing = findEnteringVertex[newLink, currentStrand];&lt;br /&gt;
     {updatedLink, updatedStrands} = &lt;br /&gt;
      duplicateVertex[newLink, currentCrossing, strands];&lt;br /&gt;
     (*check if we&#039;ve returned to the first strand*)&lt;br /&gt;
     If[updatedStrands[[1]] == updatedStrands[[2]],&lt;br /&gt;
      (*replace the largest strand label with the first strand label \&lt;br /&gt;
of the new component*)&lt;br /&gt;
      {Replace[updatedLink, &lt;br /&gt;
        n_?(# == 2 Length[updatedLink] + 1 &amp;amp;) -&amp;gt; &lt;br /&gt;
         updatedStrands[[3]], {2}], &lt;br /&gt;
       updatedStrands[[4 ;;]]},(*keep adding crossings*)&lt;br /&gt;
      recurse[updatedLink, updatedStrands]]&lt;br /&gt;
     ];&lt;br /&gt;
   recurse[link, initialStrands]&lt;br /&gt;
   ];&lt;br /&gt;
deleteComponent[link_, s_, strandList_] := &lt;br /&gt;
  Module[{newLink, currentStrand, newStrandList, currentCrossing},&lt;br /&gt;
   If[s &amp;lt;= 0,&lt;br /&gt;
    (*we&#039;re done deleting stuff*)&lt;br /&gt;
    {link, strandList},&lt;br /&gt;
    (*keep deleting*)&lt;br /&gt;
    currentCrossing = findEnteringVertex[link, s];&lt;br /&gt;
    {newLink, currentStrand, newStrandList} = &lt;br /&gt;
     deleteVertex[link, currentCrossing, s, strandList];&lt;br /&gt;
    deleteComponent[newLink, currentStrand, newStrandList]&lt;br /&gt;
    ]&lt;br /&gt;
   ];&lt;br /&gt;
cableLinkMonomial[link_, strandList_, degreeList_] := &lt;br /&gt;
  Module[{newLink = link, newStrandList, newDegreeList, coeff = 1},&lt;br /&gt;
   (*reorder so that we&#039;re deleting components first*)&lt;br /&gt;
   {newDegreeList, newStrandList} = {degreeList, strandList}[[All, &lt;br /&gt;
     Ordering@degreeList]];&lt;br /&gt;
   (*start cabling*)&lt;br /&gt;
   Do[&lt;br /&gt;
    Which[&lt;br /&gt;
     newStrandList[[i]] == 0,&lt;br /&gt;
     (*it&#039;s an unknot*)&lt;br /&gt;
     coeff = coeff*(-A^2 - A^(-2))^newDegreeList[[i]],&lt;br /&gt;
     newDegreeList[[i]] == 0,&lt;br /&gt;
     (*we need to delete it*)&lt;br /&gt;
     {newLink, newStrandList} = &lt;br /&gt;
      deleteComponent[newLink, newStrandList[[i]], newStrandList],&lt;br /&gt;
     True,&lt;br /&gt;
     (*cable the component*)&lt;br /&gt;
     Do[&lt;br /&gt;
      {newLink, newStrandList} = &lt;br /&gt;
       cableComponent[newLink, newStrandList[[i]], newStrandList]&lt;br /&gt;
      , {j, 1, newDegreeList[[i]] - 1}]&lt;br /&gt;
     ]&lt;br /&gt;
    , {i, 1, Length[newStrandList]}&lt;br /&gt;
    ];&lt;br /&gt;
   coeff*KB1[newLink]&lt;br /&gt;
   ];&lt;br /&gt;
cableLink[link_, poly_, strandList_, vars_] := &lt;br /&gt;
 Module[{monomials = CoefficientRules[poly, vars], temp},&lt;br /&gt;
  Total[&lt;br /&gt;
   Map[&lt;br /&gt;
    #[[2]]*cableLinkMonomial[link, strandList, #[[1]]] &amp;amp;&lt;br /&gt;
    , monomials]]&lt;br /&gt;
  ]&lt;/div&gt;</summary>
		<author><name>Sam.panitch</name></author>
	</entry>
	<entry>
		<id>https://katlas.org/index.php?title=Threading_a_link_by_a_polynomial&amp;diff=1725855</id>
		<title>Threading a link by a polynomial</title>
		<link rel="alternate" type="text/html" href="https://katlas.org/index.php?title=Threading_a_link_by_a_polynomial&amp;diff=1725855"/>
		<updated>2025-08-05T22:46:10Z</updated>

		<summary type="html">&lt;p&gt;Sam.panitch: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;code&amp;gt;CableLink[link,poly,strandList,vars]&amp;lt;/code&amp;gt;, whose code is available [[cableLink.m|here]], computes the Kauffman bracket of link (given as a PD) with components L1,L2,...,Ln, cabled by the polynomial poly in the variables z1,z2,...,zn. strandList is a list of strand labels of length n, where the ith element is the first strand label corresponding to component Li.&lt;br /&gt;
As an example, we can verify some formulas from {{ref|Masbaum}}, after importing KnotTheory` and the CableLink code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--$$hopfLink=PD[X[3,1,4,2],X[2,4,1,3]]; //&lt;br /&gt;
bracket[n_]:=a^n-a^(-n); //&lt;br /&gt;
bracketFact[n_]:=Product[bracket[i],{i,1,n}]; //&lt;br /&gt;
R[z_, n_] := Product[z + lambda[2*i], {i, 0, n - 1}]; //&lt;br /&gt;
cheb[0, z_] = 1; &lt;br /&gt;
cheb[1, z_] = z;&lt;br /&gt;
cheb[n_, z_] := cheb[n, z] = z*cheb[n - 1, z] - cheb[n - 2, z];&lt;br /&gt;
$$--&amp;gt;&lt;br /&gt;
&amp;lt;!--Robot Land, no human edits to &amp;quot;END&amp;quot;--&amp;gt;&lt;br /&gt;
{{In|&lt;br /&gt;
n  = 3 |&lt;br /&gt;
in = &amp;lt;nowiki&amp;gt;hopfLink=PD[X[3,1,4,2],X[2,4,1,3]];&lt;br /&gt;
bracket[n_]:=a^n-a^(-n);&lt;br /&gt;
bracketFact[n_]:=Product[bracket[i],{i,1,n}];&lt;br /&gt;
R[z_, n_] := Product[z + lambda[2*i], {i, 0, n - 1}];&lt;br /&gt;
cheb[0, z_] = 1; &lt;br /&gt;
cheb[1, z_] = z;&lt;br /&gt;
cheb[n_, z_] := cheb[n, z] = z*cheb[n - 1, z] - cheb[n - 2, z];&amp;lt;/nowiki&amp;gt; |&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;!--END--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--$$Expand[CableLink[hopfLink, &lt;br /&gt;
   R[Subscript[z, 1], 1]*cheb[2, Subscript[z, 2]], {1, 3}, {Subscript[&lt;br /&gt;
    z, 1], Subscript[z, 2]}] /. {A -&amp;gt; a^(1/2)}] //&lt;br /&gt;
Expand[(-1)^1*bracketFact[3]/bracket[1]]&lt;br /&gt;
$$--&amp;gt;&lt;br /&gt;
&amp;lt;!--Robot Land, no human edits to &amp;quot;END&amp;quot;--&amp;gt;&lt;br /&gt;
{{InOut|&lt;br /&gt;
n  = 4 |&lt;br /&gt;
in = &amp;lt;nowiki&amp;gt;Expand[CableLink[hopfLink, &lt;br /&gt;
   R[Subscript[z, 1], 1]*cheb[2, Subscript[z, 2]], {1, 3}, {Subscript[&lt;br /&gt;
    z, 1], Subscript[z, 2]}] /. {A -&amp;gt; a^(1/2)}]&lt;br /&gt;
Expand[(-1)^1*bracketFact[3]/bracket[1]]&amp;lt;/nowiki&amp;gt; |&lt;br /&gt;
out= &amp;lt;nowiki&amp;gt;-1/a^5 + 1/a + a - a^5 &lt;br /&gt;
-1/a^5 + 1/a + a - a^5&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&amp;lt;!--END--&amp;gt;&lt;br /&gt;
&amp;lt;!--$$Expand[CableLink[hopfLink, &lt;br /&gt;
   R[Subscript[z, 1], 2]*cheb[4, Subscript[z, 2]], {1, 3}, {Subscript[&lt;br /&gt;
    z, 1], Subscript[z, 2]}] /. {A -&amp;gt; a^(1/2)}]&lt;br /&gt;
Expand[(-1)^2*bracketFact[5]/bracket[1]] //&lt;br /&gt;
$$--&amp;gt;&lt;br /&gt;
{{InOut|&lt;br /&gt;
n  = 5 |&lt;br /&gt;
in = &amp;lt;nowiki&amp;gt;Expand[CableLink[hopfLink, &lt;br /&gt;
   R[Subscript[z, 1], 2]*cheb[4, Subscript[z, 2]], {1, 3}, {Subscript[&lt;br /&gt;
    z, 1], Subscript[z, 2]}] /. {A -&amp;gt; a^(1/2)}]&lt;br /&gt;
Expand[(-1)^1*bracketFact[3]/bracket[1]]&amp;lt;/nowiki&amp;gt; |&lt;br /&gt;
out= &amp;lt;nowiki&amp;gt;2 + 1/a^14 - 1/a^10 - 1/a^8 - 1/a^6 + 1/a^2 + a^2 - a^6 - a^8 - a^10 + a^14&lt;br /&gt;
2 + 1/a^14 - 1/a^10 - 1/a^8 - 1/a^6 + 1/a^2 + a^2 - a^6 - a^8 - a^10 + a^14&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&amp;lt;!--END--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{note|Masbaum}} Masbaum, Gregor. &#039;&#039;Skein-theoretical derivations of some formulas of Habiro.&#039;&#039; Alg. and Geo. Topology 3 (2003): 537–556. https://doi.org/10.2140/agt.2003.3.537&lt;/div&gt;</summary>
		<author><name>Sam.panitch</name></author>
	</entry>
	<entry>
		<id>https://katlas.org/index.php?title=Threading_a_link_by_a_polynomial&amp;diff=1725854</id>
		<title>Threading a link by a polynomial</title>
		<link rel="alternate" type="text/html" href="https://katlas.org/index.php?title=Threading_a_link_by_a_polynomial&amp;diff=1725854"/>
		<updated>2025-08-05T22:43:59Z</updated>

		<summary type="html">&lt;p&gt;Sam.panitch: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;code&amp;gt;CableLink[link,poly,strandList,vars]&amp;lt;/code&amp;gt;, whose code is available [[cableLink.m|here]], computes the Kauffman bracket of link (given as a PD) with components L1,L2,...,Ln, cabled by the polynomial poly in the variables z1,z2,...,zn. strandList is a list of strand labels of length n, where the ith element is the first strand label corresponding to component Li.&lt;br /&gt;
As an example, we can verify some formulas from {{ref|Masbaum}}, after importing KnotTheory` and the CableLink code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--$$hopfLink=PD[X[3,1,4,2],X[2,4,1,3]]; //&lt;br /&gt;
bracket[n_]:=a^n-a^(-n); //&lt;br /&gt;
bracketFact[n_]:=Product[bracket[i],{i,1,n}]; //&lt;br /&gt;
R[z_, n_] := Product[z + lambda[2*i], {i, 0, n - 1}]; //&lt;br /&gt;
cheb[0, z_] = 1; &lt;br /&gt;
cheb[1, z_] = z;&lt;br /&gt;
cheb[n_, z_] := cheb[n, z] = z*cheb[n - 1, z] - cheb[n - 2, z];&lt;br /&gt;
$$--&amp;gt;&lt;br /&gt;
&amp;lt;!--Robot Land, no human edits to &amp;quot;END&amp;quot;--&amp;gt;&lt;br /&gt;
{{In|&lt;br /&gt;
n  = 3 |&lt;br /&gt;
in = &amp;lt;nowiki&amp;gt;hopfLink=PD[X[3,1,4,2],X[2,4,1,3]];&lt;br /&gt;
bracket[n_]:=a^n-a^(-n);&lt;br /&gt;
bracketFact[n_]:=Product[bracket[i],{i,1,n}];&lt;br /&gt;
R[z_, n_] := Product[z + lambda[2*i], {i, 0, n - 1}];&lt;br /&gt;
cheb[0, z_] = 1; &lt;br /&gt;
cheb[1, z_] = z;&lt;br /&gt;
cheb[n_, z_] := cheb[n, z] = z*cheb[n - 1, z] - cheb[n - 2, z];&amp;lt;/nowiki&amp;gt; |&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;!--END--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--$$Expand[CableLink[hopfLink, &lt;br /&gt;
   R[Subscript[z, 1], 1]*cheb[2, Subscript[z, 2]], {1, 3}, {Subscript[&lt;br /&gt;
    z, 1], Subscript[z, 2]}] /. {A -&amp;gt; a^(1/2)}] //&lt;br /&gt;
Expand[(-1)^1*bracketFact[3]/bracket[1]]&lt;br /&gt;
$$--&amp;gt;&lt;br /&gt;
&amp;lt;!--Robot Land, no human edits to &amp;quot;END&amp;quot;--&amp;gt;&lt;br /&gt;
{{InOut|&lt;br /&gt;
n  = 4 |&lt;br /&gt;
in = &amp;lt;nowiki&amp;gt;Expand[CableLink[hopfLink, &lt;br /&gt;
   R[Subscript[z, 1], 1]*cheb[2, Subscript[z, 2]], {1, 3}, {Subscript[&lt;br /&gt;
    z, 1], Subscript[z, 2]}] /. {A -&amp;gt; a^(1/2)}]&lt;br /&gt;
Expand[(-1)^1*bracketFact[3]/bracket[1]]&amp;lt;/nowiki&amp;gt; |&lt;br /&gt;
out= &amp;lt;nowiki&amp;gt;-1/a^5 + 1/a + a - a^5 &lt;br /&gt;
-1/a^5 + 1/a + a - a^5&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&amp;lt;!--END--&amp;gt;&lt;br /&gt;
&amp;lt;!--$$Expand[CableLink[hopfLink, &lt;br /&gt;
   R[Subscript[z, 1], 2]*cheb[4, Subscript[z, 2]], {1, 3}, {Subscript[&lt;br /&gt;
    z, 1], Subscript[z, 2]}] /. {A -&amp;gt; a^(1/2)}]&lt;br /&gt;
Expand[(-1)^2*bracketFact[5]/bracket[1]] //&lt;br /&gt;
$$--&amp;gt;&lt;br /&gt;
{{InOut|&lt;br /&gt;
n  = 5 |&lt;br /&gt;
in = &amp;lt;nowiki&amp;gt;Expand[CableLink[hopfLink, &lt;br /&gt;
   R[Subscript[z, 1], 2]*cheb[4, Subscript[z, 2]], {1, 3}, {Subscript[&lt;br /&gt;
    z, 1], Subscript[z, 2]}] /. {A -&amp;gt; a^(1/2)}]&lt;br /&gt;
Expand[(-1)^1*bracketFact[3]/bracket[1]]&amp;lt;/nowiki&amp;gt; |&lt;br /&gt;
out= &amp;lt;nowiki&amp;gt;2 + 1/a^14 - 1/a^10 - 1/a^8 - 1/a^6 + 1/a^2 + a^2 - a^6 - a^8 - a^10 + a^14&lt;br /&gt;
2 + 1/a^14 - 1/a^10 - 1/a^8 - 1/a^6 + 1/a^2 + a^2 - a^6 - a^8 - a^10 + a^14&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&amp;lt;!--END--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
{{note|Masbaum}} Masbaum, Gregor. &#039;&#039;Skein-theoretical derivations of some formulas of Habiro.&#039;&#039; Alg. and Geo. Topology 3 (2003): 537–556. https://doi.org/10.2140/agt.2003.3.537&lt;/div&gt;</summary>
		<author><name>Sam.panitch</name></author>
	</entry>
	<entry>
		<id>https://katlas.org/index.php?title=Threading_a_link_by_a_polynomial&amp;diff=1725853</id>
		<title>Threading a link by a polynomial</title>
		<link rel="alternate" type="text/html" href="https://katlas.org/index.php?title=Threading_a_link_by_a_polynomial&amp;diff=1725853"/>
		<updated>2025-08-05T22:35:49Z</updated>

		<summary type="html">&lt;p&gt;Sam.panitch: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;code&amp;gt;CableLink[link,poly,strandList,vars]&amp;lt;/code&amp;gt;, whose code is available [[cableLink.m|here]], computes the Kauffman bracket of link (given as a PD) with components L1,L2,...,Ln, cabled by the polynomial poly in the variables z1,z2,...,zn. strandList is a list of strand labels of length n, where the ith element is the first strand label corresponding to component Li.&lt;br /&gt;
As an example, we can verify some formulas from Mausbaum, after importing KnotTheory` and the CableLink code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--$$hopfLink=PD[X[3,1,4,2],X[2,4,1,3]]; //&lt;br /&gt;
bracket[n_]:=a^n-a^(-n); //&lt;br /&gt;
bracketFact[n_]:=Product[bracket[i],{i,1,n}]; //&lt;br /&gt;
R[z_, n_] := Product[z + lambda[2*i], {i, 0, n - 1}]; //&lt;br /&gt;
cheb[0, z_] = 1; &lt;br /&gt;
cheb[1, z_] = z;&lt;br /&gt;
cheb[n_, z_] := cheb[n, z] = z*cheb[n - 1, z] - cheb[n - 2, z];&lt;br /&gt;
$$--&amp;gt;&lt;br /&gt;
&amp;lt;!--Robot Land, no human edits to &amp;quot;END&amp;quot;--&amp;gt;&lt;br /&gt;
{{In|&lt;br /&gt;
n  = 3 |&lt;br /&gt;
in = &amp;lt;nowiki&amp;gt;hopfLink=PD[X[3,1,4,2],X[2,4,1,3]];&lt;br /&gt;
bracket[n_]:=a^n-a^(-n);&lt;br /&gt;
bracketFact[n_]:=Product[bracket[i],{i,1,n}];&lt;br /&gt;
R[z_, n_] := Product[z + lambda[2*i], {i, 0, n - 1}];&lt;br /&gt;
cheb[0, z_] = 1; &lt;br /&gt;
cheb[1, z_] = z;&lt;br /&gt;
cheb[n_, z_] := cheb[n, z] = z*cheb[n - 1, z] - cheb[n - 2, z];&amp;lt;/nowiki&amp;gt; |&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;!--END--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--$$Expand[CableLink[hopfLink, &lt;br /&gt;
   R[Subscript[z, 1], 1]*cheb[2, Subscript[z, 2]], {1, 3}, {Subscript[&lt;br /&gt;
    z, 1], Subscript[z, 2]}] /. {A -&amp;gt; a^(1/2)}] //&lt;br /&gt;
Expand[(-1)^1*bracketFact[3]/bracket[1]]&lt;br /&gt;
$$--&amp;gt;&lt;br /&gt;
&amp;lt;!--Robot Land, no human edits to &amp;quot;END&amp;quot;--&amp;gt;&lt;br /&gt;
{{InOut|&lt;br /&gt;
n  = 4 |&lt;br /&gt;
in = &amp;lt;nowiki&amp;gt;Expand[CableLink[hopfLink, &lt;br /&gt;
   R[Subscript[z, 1], 1]*cheb[2, Subscript[z, 2]], {1, 3}, {Subscript[&lt;br /&gt;
    z, 1], Subscript[z, 2]}] /. {A -&amp;gt; a^(1/2)}]&lt;br /&gt;
Expand[(-1)^1*bracketFact[3]/bracket[1]]&amp;lt;/nowiki&amp;gt; |&lt;br /&gt;
out= &amp;lt;nowiki&amp;gt;-1/a^5 + 1/a + a - a^5 &lt;br /&gt;
-1/a^5 + 1/a + a - a^5&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&amp;lt;!--END--&amp;gt;&lt;br /&gt;
&amp;lt;!--$$Expand[CableLink[hopfLink, &lt;br /&gt;
   R[Subscript[z, 1], 2]*cheb[4, Subscript[z, 2]], {1, 3}, {Subscript[&lt;br /&gt;
    z, 1], Subscript[z, 2]}] /. {A -&amp;gt; a^(1/2)}]&lt;br /&gt;
Expand[(-1)^2*bracketFact[5]/bracket[1]] //&lt;br /&gt;
$$--&amp;gt;&lt;br /&gt;
{{InOut|&lt;br /&gt;
n  = 5 |&lt;br /&gt;
in = &amp;lt;nowiki&amp;gt;Expand[CableLink[hopfLink, &lt;br /&gt;
   R[Subscript[z, 1], 2]*cheb[4, Subscript[z, 2]], {1, 3}, {Subscript[&lt;br /&gt;
    z, 1], Subscript[z, 2]}] /. {A -&amp;gt; a^(1/2)}]&lt;br /&gt;
Expand[(-1)^1*bracketFact[3]/bracket[1]]&amp;lt;/nowiki&amp;gt; |&lt;br /&gt;
out= &amp;lt;nowiki&amp;gt;2 + 1/a^14 - 1/a^10 - 1/a^8 - 1/a^6 + 1/a^2 + a^2 - a^6 - a^8 - a^10 + a^14&lt;br /&gt;
2 + 1/a^14 - 1/a^10 - 1/a^8 - 1/a^6 + 1/a^2 + a^2 - a^6 - a^8 - a^10 + a^14&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&amp;lt;!--END--&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sam.panitch</name></author>
	</entry>
	<entry>
		<id>https://katlas.org/index.php?title=CableLink.m&amp;diff=1725852</id>
		<title>CableLink.m</title>
		<link rel="alternate" type="text/html" href="https://katlas.org/index.php?title=CableLink.m&amp;diff=1725852"/>
		<updated>2025-08-05T22:34:33Z</updated>

		<summary type="html">&lt;p&gt;Sam.panitch: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
The program &amp;lt;code&amp;gt;CableLink&amp;lt;/code&amp;gt; is documented on the page [[Threading a link by a polynomial]]. It is not part of the package &amp;lt;code&amp;gt;KnotTheory`&amp;lt;/code&amp;gt; but is designed to work with it. Copy-paste the text below ignoring the &amp;lt;code&amp;gt;*&amp;amp;#41;&amp;lt;/code&amp;gt; on the first line and the &amp;lt;code&amp;gt;&amp;amp;#40;*&amp;lt;/code&amp;gt; on the last.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
*)&lt;br /&gt;
&lt;br /&gt;
(*Kauffman bracket*)&lt;br /&gt;
KB1[pd_PD] := KB1[pd, {}, 1];&lt;br /&gt;
KB1[pd_PD, inside_, web_] := &lt;br /&gt;
  Module[{pos = &lt;br /&gt;
     First[Ordering[Length[Complement[List @@ #, inside]] &amp;amp; /@ pd]]}, &lt;br /&gt;
   pd[[pos]] /.  &lt;br /&gt;
    X[a_, b_, c_, d_] :&amp;gt; &lt;br /&gt;
     KB1[Delete[pd, pos], Union[inside, {a, b, c, d}], &lt;br /&gt;
      Expand[web*(A P[a, d] P[b, c] + 1/A P[a, b] P[c, d])] //. {P[e_,&lt;br /&gt;
            f_] P[f_, g_] :&amp;gt; P[e, g], P[e_, _]^2 :&amp;gt; P[e, e], &lt;br /&gt;
        P[e_, e_] -&amp;gt; -A^2 - 1/A^2}]];&lt;br /&gt;
KB1[PD[], _, web_] := Expand[web]&lt;br /&gt;
(*determine position of a strand label at a crossing*)&lt;br /&gt;
strandAtCrossing[crossing_, s_] := Module[{pos},&lt;br /&gt;
   pos = Position[crossing, s];&lt;br /&gt;
   If[Length[pos] &amp;gt; 0, pos[[1, 1]], False]&lt;br /&gt;
   ];&lt;br /&gt;
(*determine orientation of overstrand. Complicated by components with only 2 labels*)&lt;br /&gt;
orientationOfOverStrand[crossing_, link_] := Module[{otherCrossings},&lt;br /&gt;
   (*find the other crossings containing the strand labels of the overstrand crossing*)&lt;br /&gt;
   otherCrossings = &lt;br /&gt;
    DeleteElements[&lt;br /&gt;
     Select[link, &lt;br /&gt;
      ContainsAny[&lt;br /&gt;
        List[Delete[#, 0]], {crossing[[2]], &lt;br /&gt;
         crossing[[4]]}] &amp;amp;], {crossing}];&lt;br /&gt;
   (*if the length of othercrossings is 1, &lt;br /&gt;
   then the overstrand labels are part of a component with only two \&lt;br /&gt;
strand labels*)&lt;br /&gt;
   If[Length[otherCrossings] == 1,&lt;br /&gt;
    (*first check if a strand label is in the first position of the \&lt;br /&gt;
other crossing.*)&lt;br /&gt;
    Which[otherCrossings[[1, 1]] == crossing[[2]],&lt;br /&gt;
     True,&lt;br /&gt;
     otherCrossings[[1, 1]] == crossing[[4]],&lt;br /&gt;
     False,&lt;br /&gt;
     (*Otherwise, the strands are always overcrossings, &lt;br /&gt;
     in which case we just choose to orient from small to large*)&lt;br /&gt;
     True,&lt;br /&gt;
     crossing[[2]] &amp;gt; crossing[[4]]&lt;br /&gt;
     ],&lt;br /&gt;
    (*otherwise, &lt;br /&gt;
    the overcrossing is oriented from 4 to 2 if pos 2 is 1 more than \&lt;br /&gt;
pos 4, or if pos 4 is more than 1 greater than pos 2.*)&lt;br /&gt;
     crossing[[2]] - crossing[[4]] == 1 || &lt;br /&gt;
     crossing[[4]] - crossing[[2]] &amp;gt; 1&lt;br /&gt;
    ]&lt;br /&gt;
   ];&lt;br /&gt;
(*find crossing where a strand label enters*)&lt;br /&gt;
findEnteringVertex[link_, s_] := &lt;br /&gt;
  Module[{crossingsContainingS, firstCrossing, pos},&lt;br /&gt;
   (*find crossings containing s*)&lt;br /&gt;
   crossingsContainingS = &lt;br /&gt;
    Select[link, IntegerQ[strandAtCrossing[#, s]] &amp;amp;];&lt;br /&gt;
   firstCrossing = crossingsContainingS[[1]];&lt;br /&gt;
   pos = strandAtCrossing[firstCrossing, s];&lt;br /&gt;
   Which[&lt;br /&gt;
    (*if pos is 1, then it is definitely an incoming strand*)&lt;br /&gt;
    pos == 1,&lt;br /&gt;
    firstCrossing,&lt;br /&gt;
    (pos == 2 &amp;amp;&amp;amp; ! &lt;br /&gt;
        orientationOfOverStrand[firstCrossing, link]) || (pos == 4 &amp;amp;&amp;amp; &lt;br /&gt;
       orientationOfOverStrand[firstCrossing, link]),&lt;br /&gt;
    firstCrossing,&lt;br /&gt;
    (*otherwise it must be the entering strand at the other vertex \&lt;br /&gt;
containing that label*)&lt;br /&gt;
    True,&lt;br /&gt;
    crossingsContainingS[[2]]&lt;br /&gt;
    ]&lt;br /&gt;
   ];&lt;br /&gt;
increaseStrandLabels[link_, s_] := &lt;br /&gt;
  Replace[link, n_?(# &amp;gt; s &amp;amp;) -&amp;gt; n + 1, {2}];&lt;br /&gt;
decreaseStrandLabels[link_, s_] := &lt;br /&gt;
  Replace[link, n_?(# &amp;gt; s &amp;amp;) -&amp;gt; n - 1, {2}];&lt;br /&gt;
(*duplicate a crossing*)&lt;br /&gt;
duplicateVertex[link_, crossing_, strands_] := &lt;br /&gt;
  Module[{pos = strandAtCrossing[crossing, strands[[1]]], &lt;br /&gt;
    newLabel = Length[link]*2 + 2, &lt;br /&gt;
    newLink = DeleteElements[link, {crossing}], p1 = crossing[[1]], &lt;br /&gt;
    p2 = crossing[[2]], p3 = crossing[[3]], p4 = crossing[[4]]},&lt;br /&gt;
   Which[&lt;br /&gt;
    (*pos is 1 and the upper strand is oriented from 4 to 2*)&lt;br /&gt;
    pos == 1  &amp;amp;&amp;amp; orientationOfOverStrand[crossing, link],&lt;br /&gt;
    {Union[&lt;br /&gt;
      increaseStrandLabels[newLink, p4],&lt;br /&gt;
      PD[&lt;br /&gt;
       X[If[p1 &amp;lt; p2, p1, p1 + 1], p4 + 1, If[p3 &amp;lt; p2, p3, p3 + 1], &lt;br /&gt;
        p4]],&lt;br /&gt;
      PD[X[newLabel, If[p2 &amp;gt; p4, p2 + 1, p2], newLabel + 1, p4 + 1]]&lt;br /&gt;
      ],&lt;br /&gt;
     Map[If[# &amp;lt;= p2, #, # + 1] &amp;amp;, Prepend[strands[[2 ;;]], p3]]&lt;br /&gt;
     },&lt;br /&gt;
    (*pos is 1 and the upper strand is oriented from 2 to 4*)&lt;br /&gt;
    pos == 1,&lt;br /&gt;
    {Union[&lt;br /&gt;
      increaseStrandLabels[newLink, p2],&lt;br /&gt;
      PD[&lt;br /&gt;
       X[If[p1 &amp;lt; p2, p1, p1 + 1], p2 + 1, If[p3 &amp;lt; p2, p3, p3 + 1], &lt;br /&gt;
        If[p4 &amp;lt; p2, p4, p4 + 1]]],&lt;br /&gt;
      PD[X[newLabel, p2, newLabel + 1, p2 + 1]]&lt;br /&gt;
      ],&lt;br /&gt;
     Map[If[# &amp;lt;= p2, #, # + 1] &amp;amp;, Prepend[strands[[2 ;;]], p3]]&lt;br /&gt;
     },&lt;br /&gt;
    (*pos is 2*)&lt;br /&gt;
    pos == 2,&lt;br /&gt;
    {Union[&lt;br /&gt;
      increaseStrandLabels[newLink, p1],&lt;br /&gt;
      PD[&lt;br /&gt;
       X[p1, If[p2 &amp;lt; p1, p2, p2 + 1], p1 + 1, &lt;br /&gt;
        If[p4 &amp;lt; p1, p4, p4 + 1]]],&lt;br /&gt;
      PD[X[p1 + 1, newLabel, If[p3 &amp;lt; p1, p3, p3 + 1], newLabel + 1]]&lt;br /&gt;
      ],&lt;br /&gt;
     Map[If[# &amp;lt;= p1, #, # + 1] &amp;amp;, Prepend[strands[[2 ;;]], p4]]&lt;br /&gt;
     },&lt;br /&gt;
    (*pos is 4*)&lt;br /&gt;
    True,&lt;br /&gt;
    {Union[&lt;br /&gt;
      increaseStrandLabels[newLink, p1],&lt;br /&gt;
      PD[&lt;br /&gt;
       X[p1 + 1, If[p2 &amp;lt; p1, p2, p2 + 1], If[p3 &amp;lt; p1, p3, p3 + 1], &lt;br /&gt;
        If[p4 &amp;lt; p1, p4, p4 + 1]]],&lt;br /&gt;
      PD[X[p1, newLabel + 1, p1 + 1, newLabel]]&lt;br /&gt;
      ],&lt;br /&gt;
     Map[If[# &amp;lt;= p1, #, # + 1] &amp;amp;, Prepend[strands[[2 ;;]], p2]]&lt;br /&gt;
     }&lt;br /&gt;
    ]&lt;br /&gt;
   ];&lt;br /&gt;
(*delete a crossing*)&lt;br /&gt;
deleteVertex[link_, crossing_, s_, strandList_] := &lt;br /&gt;
 Module[{newCrossing = crossing, &lt;br /&gt;
   newLink = DeleteElements[link, {crossing}], min, max, &lt;br /&gt;
   pos = strandAtCrossing[crossing, s], outgoingStrandPos, &lt;br /&gt;
   newStrandList = strandList},&lt;br /&gt;
  (*we create an unknot if the two labels of the other strand at the \&lt;br /&gt;
crossing are equal*)&lt;br /&gt;
  Which[(pos == 1 &amp;amp;&amp;amp; crossing[[2]] == crossing[[4]]) , &lt;br /&gt;
   newStrandList = &lt;br /&gt;
    Replace[newStrandList, &lt;br /&gt;
     crossing[[2]] -&amp;gt; 0, {1}], (pos == 2 || pos == 4 ) &amp;amp;&amp;amp; &lt;br /&gt;
    crossing[[1]] == crossing[[3]], &lt;br /&gt;
   newStrandList = Replace[newStrandList, crossing[[1]] -&amp;gt; 0, {1}]];&lt;br /&gt;
  (*&amp;quot;&lt;br /&gt;
	we need to keep track of the outgoing strand label. There&#039;s actually \&lt;br /&gt;
two ways to know we&#039;re done:&lt;br /&gt;
	either the outgoing strand is the same as the incoming strand, or \&lt;br /&gt;
the whole vertex only involves 2 different labels.&lt;br /&gt;
&amp;quot;*)&lt;br /&gt;
  outgoingStrandPos = Which[pos == 1, 3, pos == 2, 4, True, 2];&lt;br /&gt;
  If[crossing[[outgoingStrandPos]] == s || &lt;br /&gt;
    CountDistinct[{Delete[crossing, 0]}] &amp;lt; 3, &lt;br /&gt;
   outgoingStrandPos = -1];&lt;br /&gt;
  (*adjust link after combining pos 1 and pos 3*)&lt;br /&gt;
  If[crossing[[1]] &amp;gt; crossing[[3]],&lt;br /&gt;
   newLink = &lt;br /&gt;
    decreaseStrandLabels[&lt;br /&gt;
     Replace[newLink, crossing[[1]] -&amp;gt; crossing[[3]], {2}], &lt;br /&gt;
     newCrossing[[1]]];&lt;br /&gt;
   newCrossing = &lt;br /&gt;
    decreaseStrandLabels[{Replace[newCrossing, &lt;br /&gt;
        crossing[[1]] -&amp;gt; crossing[[3]], {1}]}, &lt;br /&gt;
      newCrossing[[1]]][[1]];&lt;br /&gt;
   newStrandList = &lt;br /&gt;
    Map[If[# &amp;gt; newCrossing[[1]], # - 1, #] &amp;amp;, &lt;br /&gt;
     Replace[newStrandList, crossing[[1]] -&amp;gt; crossing[[3]], {1}]]&lt;br /&gt;
   ,&lt;br /&gt;
   newLink = decreaseStrandLabels[newLink, newCrossing[[1]]];&lt;br /&gt;
   newCrossing = &lt;br /&gt;
    decreaseStrandLabels[{newCrossing}, newCrossing[[1]]][[1]];&lt;br /&gt;
   newStrandList = &lt;br /&gt;
    Map[If[# &amp;gt; newCrossing[[1]], # - 1, #] &amp;amp;, newStrandList]&lt;br /&gt;
   ];&lt;br /&gt;
  (*adjust link after combining pos 2 and pos 4*)&lt;br /&gt;
  min = Min[newCrossing[[2]], newCrossing[[4]]];&lt;br /&gt;
  max = Max[newCrossing[[2]], newCrossing[[4]]];&lt;br /&gt;
  If[max - min &amp;gt; 1,&lt;br /&gt;
   newLink = &lt;br /&gt;
    decreaseStrandLabels[Replace[newLink, max -&amp;gt; min, {2}], max];&lt;br /&gt;
   newCrossing = &lt;br /&gt;
    decreaseStrandLabels[{Replace[newCrossing, max -&amp;gt; min, {1}]}, &lt;br /&gt;
      max][[1]];&lt;br /&gt;
   newStrandList = &lt;br /&gt;
    Map[If[# &amp;gt; max, # - 1, #] &amp;amp;, &lt;br /&gt;
     Replace[newStrandList, max -&amp;gt; min, {1}]],&lt;br /&gt;
   newLink = decreaseStrandLabels[newLink, min];&lt;br /&gt;
   newCrossing = decreaseStrandLabels[{newCrossing}, min][[1]];&lt;br /&gt;
   newStrandList = Map[If[# &amp;gt; max, # - 1, #] &amp;amp;, newStrandList]&lt;br /&gt;
   ];&lt;br /&gt;
  {newLink, &lt;br /&gt;
   If[outgoingStrandPos &amp;gt; 0, newCrossing[[outgoingStrandPos]], -1], &lt;br /&gt;
   newStrandList}&lt;br /&gt;
  ]&lt;br /&gt;
cableComponent[link_, s_, strandList_] := &lt;br /&gt;
  Module[{initialStrands, newComponentLabel = 2 Length[link] + 1},&lt;br /&gt;
   initialStrands = Join[{s, s, newComponentLabel}, strandList];&lt;br /&gt;
   recurse[newLink_, strands_] := &lt;br /&gt;
    Module[{currentStrand = strands[[1]], firstStrand = strands[[2]], &lt;br /&gt;
      currentCrossing, updatedLink, &lt;br /&gt;
      updatedStrands},(*copy the current crossing*)&lt;br /&gt;
     currentCrossing = findEnteringVertex[newLink, currentStrand];&lt;br /&gt;
     {updatedLink, updatedStrands} = &lt;br /&gt;
      duplicateVertex[newLink, currentCrossing, strands];&lt;br /&gt;
     (*check if we&#039;ve returned to the first strand*)&lt;br /&gt;
     If[updatedStrands[[1]] == updatedStrands[[2]],&lt;br /&gt;
      (*replace the largest strand label with the first strand label \&lt;br /&gt;
of the new component*)&lt;br /&gt;
      {Replace[updatedLink, &lt;br /&gt;
        n_?(# == 2 Length[updatedLink] + 1 &amp;amp;) -&amp;gt; &lt;br /&gt;
         updatedStrands[[3]], {2}], &lt;br /&gt;
       updatedStrands[[4 ;;]]},(*keep adding crossings*)&lt;br /&gt;
      recurse[updatedLink, updatedStrands]]&lt;br /&gt;
     ];&lt;br /&gt;
   recurse[link, initialStrands]&lt;br /&gt;
   ];&lt;br /&gt;
deleteComponent[link_, s_, strandList_] := &lt;br /&gt;
  Module[{newLink, currentStrand, newStrandList, currentCrossing},&lt;br /&gt;
   If[s &amp;lt;= 0,&lt;br /&gt;
    (*we&#039;re done deleting stuff*)&lt;br /&gt;
    {link, strandList},&lt;br /&gt;
    (*keep deleting*)&lt;br /&gt;
    currentCrossing = findEnteringVertex[link, s];&lt;br /&gt;
    {newLink, currentStrand, newStrandList} = &lt;br /&gt;
     deleteVertex[link, currentCrossing, s, strandList];&lt;br /&gt;
    deleteComponent[newLink, currentStrand, newStrandList]&lt;br /&gt;
    ]&lt;br /&gt;
   ];&lt;br /&gt;
cableLinkMonomial[link_, strandList_, degreeList_] := &lt;br /&gt;
  Module[{newLink = link, newStrandList, newDegreeList, coeff = 1},&lt;br /&gt;
   (*reorder so that we&#039;re deleting components first*)&lt;br /&gt;
   {newDegreeList, newStrandList} = {degreeList, strandList}[[All, &lt;br /&gt;
     Ordering@degreeList]];&lt;br /&gt;
   (*start cabling*)&lt;br /&gt;
   Do[&lt;br /&gt;
    Which[&lt;br /&gt;
     newStrandList[[i]] == 0,&lt;br /&gt;
     (*it&#039;s an unknot*)&lt;br /&gt;
     coeff = coeff*(-A^2 - A^(-2))^newDegreeList[[i]],&lt;br /&gt;
     newDegreeList[[i]] == 0,&lt;br /&gt;
     (*we need to delete it*)&lt;br /&gt;
     {newLink, newStrandList} = &lt;br /&gt;
      deleteComponent[newLink, newStrandList[[i]], newStrandList],&lt;br /&gt;
     True,&lt;br /&gt;
     (*cable the component*)&lt;br /&gt;
     Do[&lt;br /&gt;
      {newLink, newStrandList} = &lt;br /&gt;
       cableComponent[newLink, newStrandList[[i]], newStrandList]&lt;br /&gt;
      , {j, 1, newDegreeList[[i]] - 1}]&lt;br /&gt;
     ]&lt;br /&gt;
    , {i, 1, Length[newStrandList]}&lt;br /&gt;
    ];&lt;br /&gt;
   coeff*KB1[newLink]&lt;br /&gt;
   ];&lt;br /&gt;
CableLink[link_, poly_, strandList_, vars_] := &lt;br /&gt;
 Module[{monomials = CoefficientRules[poly, vars], temp},&lt;br /&gt;
  Total[&lt;br /&gt;
   Map[&lt;br /&gt;
    #[[2]]*cableLinkMonomial[link, strandList, #[[1]]] &amp;amp;&lt;br /&gt;
    , monomials]]&lt;br /&gt;
  ]&lt;/div&gt;</summary>
		<author><name>Sam.panitch</name></author>
	</entry>
	<entry>
		<id>https://katlas.org/index.php?title=CableLink.m&amp;diff=1725851</id>
		<title>CableLink.m</title>
		<link rel="alternate" type="text/html" href="https://katlas.org/index.php?title=CableLink.m&amp;diff=1725851"/>
		<updated>2025-08-05T22:34:17Z</updated>

		<summary type="html">&lt;p&gt;Sam.panitch: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;(*&lt;br /&gt;
&lt;br /&gt;
The program &amp;lt;code&amp;gt;CableLink&amp;lt;/code&amp;gt; is documented on the page [[Threading a link by a polynomial]]. It is not part of the package &amp;lt;code&amp;gt;KnotTheory`&amp;lt;/code&amp;gt; but is designed to work with it. Copy-paste the text below ignoring the &amp;lt;code&amp;gt;*&amp;amp;#41;&amp;lt;/code&amp;gt; on the first line and the &amp;lt;code&amp;gt;&amp;amp;#40;*&amp;lt;/code&amp;gt; on the last.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
*)&lt;br /&gt;
*)&lt;br /&gt;
(*Kauffman bracket*)&lt;br /&gt;
KB1[pd_PD] := KB1[pd, {}, 1];&lt;br /&gt;
KB1[pd_PD, inside_, web_] := &lt;br /&gt;
  Module[{pos = &lt;br /&gt;
     First[Ordering[Length[Complement[List @@ #, inside]] &amp;amp; /@ pd]]}, &lt;br /&gt;
   pd[[pos]] /.  &lt;br /&gt;
    X[a_, b_, c_, d_] :&amp;gt; &lt;br /&gt;
     KB1[Delete[pd, pos], Union[inside, {a, b, c, d}], &lt;br /&gt;
      Expand[web*(A P[a, d] P[b, c] + 1/A P[a, b] P[c, d])] //. {P[e_,&lt;br /&gt;
            f_] P[f_, g_] :&amp;gt; P[e, g], P[e_, _]^2 :&amp;gt; P[e, e], &lt;br /&gt;
        P[e_, e_] -&amp;gt; -A^2 - 1/A^2}]];&lt;br /&gt;
KB1[PD[], _, web_] := Expand[web]&lt;br /&gt;
(*determine position of a strand label at a crossing*)&lt;br /&gt;
strandAtCrossing[crossing_, s_] := Module[{pos},&lt;br /&gt;
   pos = Position[crossing, s];&lt;br /&gt;
   If[Length[pos] &amp;gt; 0, pos[[1, 1]], False]&lt;br /&gt;
   ];&lt;br /&gt;
(*determine orientation of overstrand. Complicated by components with only 2 labels*)&lt;br /&gt;
orientationOfOverStrand[crossing_, link_] := Module[{otherCrossings},&lt;br /&gt;
   (*find the other crossings containing the strand labels of the overstrand crossing*)&lt;br /&gt;
   otherCrossings = &lt;br /&gt;
    DeleteElements[&lt;br /&gt;
     Select[link, &lt;br /&gt;
      ContainsAny[&lt;br /&gt;
        List[Delete[#, 0]], {crossing[[2]], &lt;br /&gt;
         crossing[[4]]}] &amp;amp;], {crossing}];&lt;br /&gt;
   (*if the length of othercrossings is 1, &lt;br /&gt;
   then the overstrand labels are part of a component with only two \&lt;br /&gt;
strand labels*)&lt;br /&gt;
   If[Length[otherCrossings] == 1,&lt;br /&gt;
    (*first check if a strand label is in the first position of the \&lt;br /&gt;
other crossing.*)&lt;br /&gt;
    Which[otherCrossings[[1, 1]] == crossing[[2]],&lt;br /&gt;
     True,&lt;br /&gt;
     otherCrossings[[1, 1]] == crossing[[4]],&lt;br /&gt;
     False,&lt;br /&gt;
     (*Otherwise, the strands are always overcrossings, &lt;br /&gt;
     in which case we just choose to orient from small to large*)&lt;br /&gt;
     True,&lt;br /&gt;
     crossing[[2]] &amp;gt; crossing[[4]]&lt;br /&gt;
     ],&lt;br /&gt;
    (*otherwise, &lt;br /&gt;
    the overcrossing is oriented from 4 to 2 if pos 2 is 1 more than \&lt;br /&gt;
pos 4, or if pos 4 is more than 1 greater than pos 2.*)&lt;br /&gt;
     crossing[[2]] - crossing[[4]] == 1 || &lt;br /&gt;
     crossing[[4]] - crossing[[2]] &amp;gt; 1&lt;br /&gt;
    ]&lt;br /&gt;
   ];&lt;br /&gt;
(*find crossing where a strand label enters*)&lt;br /&gt;
findEnteringVertex[link_, s_] := &lt;br /&gt;
  Module[{crossingsContainingS, firstCrossing, pos},&lt;br /&gt;
   (*find crossings containing s*)&lt;br /&gt;
   crossingsContainingS = &lt;br /&gt;
    Select[link, IntegerQ[strandAtCrossing[#, s]] &amp;amp;];&lt;br /&gt;
   firstCrossing = crossingsContainingS[[1]];&lt;br /&gt;
   pos = strandAtCrossing[firstCrossing, s];&lt;br /&gt;
   Which[&lt;br /&gt;
    (*if pos is 1, then it is definitely an incoming strand*)&lt;br /&gt;
    pos == 1,&lt;br /&gt;
    firstCrossing,&lt;br /&gt;
    (pos == 2 &amp;amp;&amp;amp; ! &lt;br /&gt;
        orientationOfOverStrand[firstCrossing, link]) || (pos == 4 &amp;amp;&amp;amp; &lt;br /&gt;
       orientationOfOverStrand[firstCrossing, link]),&lt;br /&gt;
    firstCrossing,&lt;br /&gt;
    (*otherwise it must be the entering strand at the other vertex \&lt;br /&gt;
containing that label*)&lt;br /&gt;
    True,&lt;br /&gt;
    crossingsContainingS[[2]]&lt;br /&gt;
    ]&lt;br /&gt;
   ];&lt;br /&gt;
increaseStrandLabels[link_, s_] := &lt;br /&gt;
  Replace[link, n_?(# &amp;gt; s &amp;amp;) -&amp;gt; n + 1, {2}];&lt;br /&gt;
decreaseStrandLabels[link_, s_] := &lt;br /&gt;
  Replace[link, n_?(# &amp;gt; s &amp;amp;) -&amp;gt; n - 1, {2}];&lt;br /&gt;
(*duplicate a crossing*)&lt;br /&gt;
duplicateVertex[link_, crossing_, strands_] := &lt;br /&gt;
  Module[{pos = strandAtCrossing[crossing, strands[[1]]], &lt;br /&gt;
    newLabel = Length[link]*2 + 2, &lt;br /&gt;
    newLink = DeleteElements[link, {crossing}], p1 = crossing[[1]], &lt;br /&gt;
    p2 = crossing[[2]], p3 = crossing[[3]], p4 = crossing[[4]]},&lt;br /&gt;
   Which[&lt;br /&gt;
    (*pos is 1 and the upper strand is oriented from 4 to 2*)&lt;br /&gt;
    pos == 1  &amp;amp;&amp;amp; orientationOfOverStrand[crossing, link],&lt;br /&gt;
    {Union[&lt;br /&gt;
      increaseStrandLabels[newLink, p4],&lt;br /&gt;
      PD[&lt;br /&gt;
       X[If[p1 &amp;lt; p2, p1, p1 + 1], p4 + 1, If[p3 &amp;lt; p2, p3, p3 + 1], &lt;br /&gt;
        p4]],&lt;br /&gt;
      PD[X[newLabel, If[p2 &amp;gt; p4, p2 + 1, p2], newLabel + 1, p4 + 1]]&lt;br /&gt;
      ],&lt;br /&gt;
     Map[If[# &amp;lt;= p2, #, # + 1] &amp;amp;, Prepend[strands[[2 ;;]], p3]]&lt;br /&gt;
     },&lt;br /&gt;
    (*pos is 1 and the upper strand is oriented from 2 to 4*)&lt;br /&gt;
    pos == 1,&lt;br /&gt;
    {Union[&lt;br /&gt;
      increaseStrandLabels[newLink, p2],&lt;br /&gt;
      PD[&lt;br /&gt;
       X[If[p1 &amp;lt; p2, p1, p1 + 1], p2 + 1, If[p3 &amp;lt; p2, p3, p3 + 1], &lt;br /&gt;
        If[p4 &amp;lt; p2, p4, p4 + 1]]],&lt;br /&gt;
      PD[X[newLabel, p2, newLabel + 1, p2 + 1]]&lt;br /&gt;
      ],&lt;br /&gt;
     Map[If[# &amp;lt;= p2, #, # + 1] &amp;amp;, Prepend[strands[[2 ;;]], p3]]&lt;br /&gt;
     },&lt;br /&gt;
    (*pos is 2*)&lt;br /&gt;
    pos == 2,&lt;br /&gt;
    {Union[&lt;br /&gt;
      increaseStrandLabels[newLink, p1],&lt;br /&gt;
      PD[&lt;br /&gt;
       X[p1, If[p2 &amp;lt; p1, p2, p2 + 1], p1 + 1, &lt;br /&gt;
        If[p4 &amp;lt; p1, p4, p4 + 1]]],&lt;br /&gt;
      PD[X[p1 + 1, newLabel, If[p3 &amp;lt; p1, p3, p3 + 1], newLabel + 1]]&lt;br /&gt;
      ],&lt;br /&gt;
     Map[If[# &amp;lt;= p1, #, # + 1] &amp;amp;, Prepend[strands[[2 ;;]], p4]]&lt;br /&gt;
     },&lt;br /&gt;
    (*pos is 4*)&lt;br /&gt;
    True,&lt;br /&gt;
    {Union[&lt;br /&gt;
      increaseStrandLabels[newLink, p1],&lt;br /&gt;
      PD[&lt;br /&gt;
       X[p1 + 1, If[p2 &amp;lt; p1, p2, p2 + 1], If[p3 &amp;lt; p1, p3, p3 + 1], &lt;br /&gt;
        If[p4 &amp;lt; p1, p4, p4 + 1]]],&lt;br /&gt;
      PD[X[p1, newLabel + 1, p1 + 1, newLabel]]&lt;br /&gt;
      ],&lt;br /&gt;
     Map[If[# &amp;lt;= p1, #, # + 1] &amp;amp;, Prepend[strands[[2 ;;]], p2]]&lt;br /&gt;
     }&lt;br /&gt;
    ]&lt;br /&gt;
   ];&lt;br /&gt;
(*delete a crossing*)&lt;br /&gt;
deleteVertex[link_, crossing_, s_, strandList_] := &lt;br /&gt;
 Module[{newCrossing = crossing, &lt;br /&gt;
   newLink = DeleteElements[link, {crossing}], min, max, &lt;br /&gt;
   pos = strandAtCrossing[crossing, s], outgoingStrandPos, &lt;br /&gt;
   newStrandList = strandList},&lt;br /&gt;
  (*we create an unknot if the two labels of the other strand at the \&lt;br /&gt;
crossing are equal*)&lt;br /&gt;
  Which[(pos == 1 &amp;amp;&amp;amp; crossing[[2]] == crossing[[4]]) , &lt;br /&gt;
   newStrandList = &lt;br /&gt;
    Replace[newStrandList, &lt;br /&gt;
     crossing[[2]] -&amp;gt; 0, {1}], (pos == 2 || pos == 4 ) &amp;amp;&amp;amp; &lt;br /&gt;
    crossing[[1]] == crossing[[3]], &lt;br /&gt;
   newStrandList = Replace[newStrandList, crossing[[1]] -&amp;gt; 0, {1}]];&lt;br /&gt;
  (*&amp;quot;&lt;br /&gt;
	we need to keep track of the outgoing strand label. There&#039;s actually \&lt;br /&gt;
two ways to know we&#039;re done:&lt;br /&gt;
	either the outgoing strand is the same as the incoming strand, or \&lt;br /&gt;
the whole vertex only involves 2 different labels.&lt;br /&gt;
&amp;quot;*)&lt;br /&gt;
  outgoingStrandPos = Which[pos == 1, 3, pos == 2, 4, True, 2];&lt;br /&gt;
  If[crossing[[outgoingStrandPos]] == s || &lt;br /&gt;
    CountDistinct[{Delete[crossing, 0]}] &amp;lt; 3, &lt;br /&gt;
   outgoingStrandPos = -1];&lt;br /&gt;
  (*adjust link after combining pos 1 and pos 3*)&lt;br /&gt;
  If[crossing[[1]] &amp;gt; crossing[[3]],&lt;br /&gt;
   newLink = &lt;br /&gt;
    decreaseStrandLabels[&lt;br /&gt;
     Replace[newLink, crossing[[1]] -&amp;gt; crossing[[3]], {2}], &lt;br /&gt;
     newCrossing[[1]]];&lt;br /&gt;
   newCrossing = &lt;br /&gt;
    decreaseStrandLabels[{Replace[newCrossing, &lt;br /&gt;
        crossing[[1]] -&amp;gt; crossing[[3]], {1}]}, &lt;br /&gt;
      newCrossing[[1]]][[1]];&lt;br /&gt;
   newStrandList = &lt;br /&gt;
    Map[If[# &amp;gt; newCrossing[[1]], # - 1, #] &amp;amp;, &lt;br /&gt;
     Replace[newStrandList, crossing[[1]] -&amp;gt; crossing[[3]], {1}]]&lt;br /&gt;
   ,&lt;br /&gt;
   newLink = decreaseStrandLabels[newLink, newCrossing[[1]]];&lt;br /&gt;
   newCrossing = &lt;br /&gt;
    decreaseStrandLabels[{newCrossing}, newCrossing[[1]]][[1]];&lt;br /&gt;
   newStrandList = &lt;br /&gt;
    Map[If[# &amp;gt; newCrossing[[1]], # - 1, #] &amp;amp;, newStrandList]&lt;br /&gt;
   ];&lt;br /&gt;
  (*adjust link after combining pos 2 and pos 4*)&lt;br /&gt;
  min = Min[newCrossing[[2]], newCrossing[[4]]];&lt;br /&gt;
  max = Max[newCrossing[[2]], newCrossing[[4]]];&lt;br /&gt;
  If[max - min &amp;gt; 1,&lt;br /&gt;
   newLink = &lt;br /&gt;
    decreaseStrandLabels[Replace[newLink, max -&amp;gt; min, {2}], max];&lt;br /&gt;
   newCrossing = &lt;br /&gt;
    decreaseStrandLabels[{Replace[newCrossing, max -&amp;gt; min, {1}]}, &lt;br /&gt;
      max][[1]];&lt;br /&gt;
   newStrandList = &lt;br /&gt;
    Map[If[# &amp;gt; max, # - 1, #] &amp;amp;, &lt;br /&gt;
     Replace[newStrandList, max -&amp;gt; min, {1}]],&lt;br /&gt;
   newLink = decreaseStrandLabels[newLink, min];&lt;br /&gt;
   newCrossing = decreaseStrandLabels[{newCrossing}, min][[1]];&lt;br /&gt;
   newStrandList = Map[If[# &amp;gt; max, # - 1, #] &amp;amp;, newStrandList]&lt;br /&gt;
   ];&lt;br /&gt;
  {newLink, &lt;br /&gt;
   If[outgoingStrandPos &amp;gt; 0, newCrossing[[outgoingStrandPos]], -1], &lt;br /&gt;
   newStrandList}&lt;br /&gt;
  ]&lt;br /&gt;
cableComponent[link_, s_, strandList_] := &lt;br /&gt;
  Module[{initialStrands, newComponentLabel = 2 Length[link] + 1},&lt;br /&gt;
   initialStrands = Join[{s, s, newComponentLabel}, strandList];&lt;br /&gt;
   recurse[newLink_, strands_] := &lt;br /&gt;
    Module[{currentStrand = strands[[1]], firstStrand = strands[[2]], &lt;br /&gt;
      currentCrossing, updatedLink, &lt;br /&gt;
      updatedStrands},(*copy the current crossing*)&lt;br /&gt;
     currentCrossing = findEnteringVertex[newLink, currentStrand];&lt;br /&gt;
     {updatedLink, updatedStrands} = &lt;br /&gt;
      duplicateVertex[newLink, currentCrossing, strands];&lt;br /&gt;
     (*check if we&#039;ve returned to the first strand*)&lt;br /&gt;
     If[updatedStrands[[1]] == updatedStrands[[2]],&lt;br /&gt;
      (*replace the largest strand label with the first strand label \&lt;br /&gt;
of the new component*)&lt;br /&gt;
      {Replace[updatedLink, &lt;br /&gt;
        n_?(# == 2 Length[updatedLink] + 1 &amp;amp;) -&amp;gt; &lt;br /&gt;
         updatedStrands[[3]], {2}], &lt;br /&gt;
       updatedStrands[[4 ;;]]},(*keep adding crossings*)&lt;br /&gt;
      recurse[updatedLink, updatedStrands]]&lt;br /&gt;
     ];&lt;br /&gt;
   recurse[link, initialStrands]&lt;br /&gt;
   ];&lt;br /&gt;
deleteComponent[link_, s_, strandList_] := &lt;br /&gt;
  Module[{newLink, currentStrand, newStrandList, currentCrossing},&lt;br /&gt;
   If[s &amp;lt;= 0,&lt;br /&gt;
    (*we&#039;re done deleting stuff*)&lt;br /&gt;
    {link, strandList},&lt;br /&gt;
    (*keep deleting*)&lt;br /&gt;
    currentCrossing = findEnteringVertex[link, s];&lt;br /&gt;
    {newLink, currentStrand, newStrandList} = &lt;br /&gt;
     deleteVertex[link, currentCrossing, s, strandList];&lt;br /&gt;
    deleteComponent[newLink, currentStrand, newStrandList]&lt;br /&gt;
    ]&lt;br /&gt;
   ];&lt;br /&gt;
cableLinkMonomial[link_, strandList_, degreeList_] := &lt;br /&gt;
  Module[{newLink = link, newStrandList, newDegreeList, coeff = 1},&lt;br /&gt;
   (*reorder so that we&#039;re deleting components first*)&lt;br /&gt;
   {newDegreeList, newStrandList} = {degreeList, strandList}[[All, &lt;br /&gt;
     Ordering@degreeList]];&lt;br /&gt;
   (*start cabling*)&lt;br /&gt;
   Do[&lt;br /&gt;
    Which[&lt;br /&gt;
     newStrandList[[i]] == 0,&lt;br /&gt;
     (*it&#039;s an unknot*)&lt;br /&gt;
     coeff = coeff*(-A^2 - A^(-2))^newDegreeList[[i]],&lt;br /&gt;
     newDegreeList[[i]] == 0,&lt;br /&gt;
     (*we need to delete it*)&lt;br /&gt;
     {newLink, newStrandList} = &lt;br /&gt;
      deleteComponent[newLink, newStrandList[[i]], newStrandList],&lt;br /&gt;
     True,&lt;br /&gt;
     (*cable the component*)&lt;br /&gt;
     Do[&lt;br /&gt;
      {newLink, newStrandList} = &lt;br /&gt;
       cableComponent[newLink, newStrandList[[i]], newStrandList]&lt;br /&gt;
      , {j, 1, newDegreeList[[i]] - 1}]&lt;br /&gt;
     ]&lt;br /&gt;
    , {i, 1, Length[newStrandList]}&lt;br /&gt;
    ];&lt;br /&gt;
   coeff*KB1[newLink]&lt;br /&gt;
   ];&lt;br /&gt;
CableLink[link_, poly_, strandList_, vars_] := &lt;br /&gt;
 Module[{monomials = CoefficientRules[poly, vars], temp},&lt;br /&gt;
  Total[&lt;br /&gt;
   Map[&lt;br /&gt;
    #[[2]]*cableLinkMonomial[link, strandList, #[[1]]] &amp;amp;&lt;br /&gt;
    , monomials]]&lt;br /&gt;
  ]&lt;/div&gt;</summary>
		<author><name>Sam.panitch</name></author>
	</entry>
	<entry>
		<id>https://katlas.org/index.php?title=CableLink.m&amp;diff=1725850</id>
		<title>CableLink.m</title>
		<link rel="alternate" type="text/html" href="https://katlas.org/index.php?title=CableLink.m&amp;diff=1725850"/>
		<updated>2025-08-05T22:33:55Z</updated>

		<summary type="html">&lt;p&gt;Sam.panitch: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;(*&lt;br /&gt;
&lt;br /&gt;
The program &amp;lt;code&amp;gt;CableLink&amp;lt;/code&amp;gt; is documented on the page [[Threading a link by a polynomial]]. It is not part of the package &amp;lt;code&amp;gt;KnotTheory`&amp;lt;/code&amp;gt; but is designed to work with it. Copy-paste the text below ignoring the &amp;lt;code&amp;gt;*&amp;amp;#41;&amp;lt;/code&amp;gt; on the first line and the &amp;lt;code&amp;gt;&amp;amp;#40;*&amp;lt;/code&amp;gt; on the last.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
*)&lt;br /&gt;
(*Kauffman bracket*)&lt;br /&gt;
KB1[pd_PD] := KB1[pd, {}, 1];&lt;br /&gt;
KB1[pd_PD, inside_, web_] := &lt;br /&gt;
  Module[{pos = &lt;br /&gt;
     First[Ordering[Length[Complement[List @@ #, inside]] &amp;amp; /@ pd]]}, &lt;br /&gt;
   pd[[pos]] /.  &lt;br /&gt;
    X[a_, b_, c_, d_] :&amp;gt; &lt;br /&gt;
     KB1[Delete[pd, pos], Union[inside, {a, b, c, d}], &lt;br /&gt;
      Expand[web*(A P[a, d] P[b, c] + 1/A P[a, b] P[c, d])] //. {P[e_,&lt;br /&gt;
            f_] P[f_, g_] :&amp;gt; P[e, g], P[e_, _]^2 :&amp;gt; P[e, e], &lt;br /&gt;
        P[e_, e_] -&amp;gt; -A^2 - 1/A^2}]];&lt;br /&gt;
KB1[PD[], _, web_] := Expand[web]&lt;br /&gt;
(*determine position of a strand label at a crossing*)&lt;br /&gt;
strandAtCrossing[crossing_, s_] := Module[{pos},&lt;br /&gt;
   pos = Position[crossing, s];&lt;br /&gt;
   If[Length[pos] &amp;gt; 0, pos[[1, 1]], False]&lt;br /&gt;
   ];&lt;br /&gt;
(*determine orientation of overstrand. Complicated by components with only 2 labels*)&lt;br /&gt;
orientationOfOverStrand[crossing_, link_] := Module[{otherCrossings},&lt;br /&gt;
   (*find the other crossings containing the strand labels of the overstrand crossing*)&lt;br /&gt;
   otherCrossings = &lt;br /&gt;
    DeleteElements[&lt;br /&gt;
     Select[link, &lt;br /&gt;
      ContainsAny[&lt;br /&gt;
        List[Delete[#, 0]], {crossing[[2]], &lt;br /&gt;
         crossing[[4]]}] &amp;amp;], {crossing}];&lt;br /&gt;
   (*if the length of othercrossings is 1, &lt;br /&gt;
   then the overstrand labels are part of a component with only two \&lt;br /&gt;
strand labels*)&lt;br /&gt;
   If[Length[otherCrossings] == 1,&lt;br /&gt;
    (*first check if a strand label is in the first position of the \&lt;br /&gt;
other crossing.*)&lt;br /&gt;
    Which[otherCrossings[[1, 1]] == crossing[[2]],&lt;br /&gt;
     True,&lt;br /&gt;
     otherCrossings[[1, 1]] == crossing[[4]],&lt;br /&gt;
     False,&lt;br /&gt;
     (*Otherwise, the strands are always overcrossings, &lt;br /&gt;
     in which case we just choose to orient from small to large*)&lt;br /&gt;
     True,&lt;br /&gt;
     crossing[[2]] &amp;gt; crossing[[4]]&lt;br /&gt;
     ],&lt;br /&gt;
    (*otherwise, &lt;br /&gt;
    the overcrossing is oriented from 4 to 2 if pos 2 is 1 more than \&lt;br /&gt;
pos 4, or if pos 4 is more than 1 greater than pos 2.*)&lt;br /&gt;
     crossing[[2]] - crossing[[4]] == 1 || &lt;br /&gt;
     crossing[[4]] - crossing[[2]] &amp;gt; 1&lt;br /&gt;
    ]&lt;br /&gt;
   ];&lt;br /&gt;
(*find crossing where a strand label enters*)&lt;br /&gt;
findEnteringVertex[link_, s_] := &lt;br /&gt;
  Module[{crossingsContainingS, firstCrossing, pos},&lt;br /&gt;
   (*find crossings containing s*)&lt;br /&gt;
   crossingsContainingS = &lt;br /&gt;
    Select[link, IntegerQ[strandAtCrossing[#, s]] &amp;amp;];&lt;br /&gt;
   firstCrossing = crossingsContainingS[[1]];&lt;br /&gt;
   pos = strandAtCrossing[firstCrossing, s];&lt;br /&gt;
   Which[&lt;br /&gt;
    (*if pos is 1, then it is definitely an incoming strand*)&lt;br /&gt;
    pos == 1,&lt;br /&gt;
    firstCrossing,&lt;br /&gt;
    (pos == 2 &amp;amp;&amp;amp; ! &lt;br /&gt;
        orientationOfOverStrand[firstCrossing, link]) || (pos == 4 &amp;amp;&amp;amp; &lt;br /&gt;
       orientationOfOverStrand[firstCrossing, link]),&lt;br /&gt;
    firstCrossing,&lt;br /&gt;
    (*otherwise it must be the entering strand at the other vertex \&lt;br /&gt;
containing that label*)&lt;br /&gt;
    True,&lt;br /&gt;
    crossingsContainingS[[2]]&lt;br /&gt;
    ]&lt;br /&gt;
   ];&lt;br /&gt;
increaseStrandLabels[link_, s_] := &lt;br /&gt;
  Replace[link, n_?(# &amp;gt; s &amp;amp;) -&amp;gt; n + 1, {2}];&lt;br /&gt;
decreaseStrandLabels[link_, s_] := &lt;br /&gt;
  Replace[link, n_?(# &amp;gt; s &amp;amp;) -&amp;gt; n - 1, {2}];&lt;br /&gt;
(*duplicate a crossing*)&lt;br /&gt;
duplicateVertex[link_, crossing_, strands_] := &lt;br /&gt;
  Module[{pos = strandAtCrossing[crossing, strands[[1]]], &lt;br /&gt;
    newLabel = Length[link]*2 + 2, &lt;br /&gt;
    newLink = DeleteElements[link, {crossing}], p1 = crossing[[1]], &lt;br /&gt;
    p2 = crossing[[2]], p3 = crossing[[3]], p4 = crossing[[4]]},&lt;br /&gt;
   Which[&lt;br /&gt;
    (*pos is 1 and the upper strand is oriented from 4 to 2*)&lt;br /&gt;
    pos == 1  &amp;amp;&amp;amp; orientationOfOverStrand[crossing, link],&lt;br /&gt;
    {Union[&lt;br /&gt;
      increaseStrandLabels[newLink, p4],&lt;br /&gt;
      PD[&lt;br /&gt;
       X[If[p1 &amp;lt; p2, p1, p1 + 1], p4 + 1, If[p3 &amp;lt; p2, p3, p3 + 1], &lt;br /&gt;
        p4]],&lt;br /&gt;
      PD[X[newLabel, If[p2 &amp;gt; p4, p2 + 1, p2], newLabel + 1, p4 + 1]]&lt;br /&gt;
      ],&lt;br /&gt;
     Map[If[# &amp;lt;= p2, #, # + 1] &amp;amp;, Prepend[strands[[2 ;;]], p3]]&lt;br /&gt;
     },&lt;br /&gt;
    (*pos is 1 and the upper strand is oriented from 2 to 4*)&lt;br /&gt;
    pos == 1,&lt;br /&gt;
    {Union[&lt;br /&gt;
      increaseStrandLabels[newLink, p2],&lt;br /&gt;
      PD[&lt;br /&gt;
       X[If[p1 &amp;lt; p2, p1, p1 + 1], p2 + 1, If[p3 &amp;lt; p2, p3, p3 + 1], &lt;br /&gt;
        If[p4 &amp;lt; p2, p4, p4 + 1]]],&lt;br /&gt;
      PD[X[newLabel, p2, newLabel + 1, p2 + 1]]&lt;br /&gt;
      ],&lt;br /&gt;
     Map[If[# &amp;lt;= p2, #, # + 1] &amp;amp;, Prepend[strands[[2 ;;]], p3]]&lt;br /&gt;
     },&lt;br /&gt;
    (*pos is 2*)&lt;br /&gt;
    pos == 2,&lt;br /&gt;
    {Union[&lt;br /&gt;
      increaseStrandLabels[newLink, p1],&lt;br /&gt;
      PD[&lt;br /&gt;
       X[p1, If[p2 &amp;lt; p1, p2, p2 + 1], p1 + 1, &lt;br /&gt;
        If[p4 &amp;lt; p1, p4, p4 + 1]]],&lt;br /&gt;
      PD[X[p1 + 1, newLabel, If[p3 &amp;lt; p1, p3, p3 + 1], newLabel + 1]]&lt;br /&gt;
      ],&lt;br /&gt;
     Map[If[# &amp;lt;= p1, #, # + 1] &amp;amp;, Prepend[strands[[2 ;;]], p4]]&lt;br /&gt;
     },&lt;br /&gt;
    (*pos is 4*)&lt;br /&gt;
    True,&lt;br /&gt;
    {Union[&lt;br /&gt;
      increaseStrandLabels[newLink, p1],&lt;br /&gt;
      PD[&lt;br /&gt;
       X[p1 + 1, If[p2 &amp;lt; p1, p2, p2 + 1], If[p3 &amp;lt; p1, p3, p3 + 1], &lt;br /&gt;
        If[p4 &amp;lt; p1, p4, p4 + 1]]],&lt;br /&gt;
      PD[X[p1, newLabel + 1, p1 + 1, newLabel]]&lt;br /&gt;
      ],&lt;br /&gt;
     Map[If[# &amp;lt;= p1, #, # + 1] &amp;amp;, Prepend[strands[[2 ;;]], p2]]&lt;br /&gt;
     }&lt;br /&gt;
    ]&lt;br /&gt;
   ];&lt;br /&gt;
(*delete a crossing*)&lt;br /&gt;
deleteVertex[link_, crossing_, s_, strandList_] := &lt;br /&gt;
 Module[{newCrossing = crossing, &lt;br /&gt;
   newLink = DeleteElements[link, {crossing}], min, max, &lt;br /&gt;
   pos = strandAtCrossing[crossing, s], outgoingStrandPos, &lt;br /&gt;
   newStrandList = strandList},&lt;br /&gt;
  (*we create an unknot if the two labels of the other strand at the \&lt;br /&gt;
crossing are equal*)&lt;br /&gt;
  Which[(pos == 1 &amp;amp;&amp;amp; crossing[[2]] == crossing[[4]]) , &lt;br /&gt;
   newStrandList = &lt;br /&gt;
    Replace[newStrandList, &lt;br /&gt;
     crossing[[2]] -&amp;gt; 0, {1}], (pos == 2 || pos == 4 ) &amp;amp;&amp;amp; &lt;br /&gt;
    crossing[[1]] == crossing[[3]], &lt;br /&gt;
   newStrandList = Replace[newStrandList, crossing[[1]] -&amp;gt; 0, {1}]];&lt;br /&gt;
  (*&amp;quot;&lt;br /&gt;
	we need to keep track of the outgoing strand label. There&#039;s actually \&lt;br /&gt;
two ways to know we&#039;re done:&lt;br /&gt;
	either the outgoing strand is the same as the incoming strand, or \&lt;br /&gt;
the whole vertex only involves 2 different labels.&lt;br /&gt;
&amp;quot;*)&lt;br /&gt;
  outgoingStrandPos = Which[pos == 1, 3, pos == 2, 4, True, 2];&lt;br /&gt;
  If[crossing[[outgoingStrandPos]] == s || &lt;br /&gt;
    CountDistinct[{Delete[crossing, 0]}] &amp;lt; 3, &lt;br /&gt;
   outgoingStrandPos = -1];&lt;br /&gt;
  (*adjust link after combining pos 1 and pos 3*)&lt;br /&gt;
  If[crossing[[1]] &amp;gt; crossing[[3]],&lt;br /&gt;
   newLink = &lt;br /&gt;
    decreaseStrandLabels[&lt;br /&gt;
     Replace[newLink, crossing[[1]] -&amp;gt; crossing[[3]], {2}], &lt;br /&gt;
     newCrossing[[1]]];&lt;br /&gt;
   newCrossing = &lt;br /&gt;
    decreaseStrandLabels[{Replace[newCrossing, &lt;br /&gt;
        crossing[[1]] -&amp;gt; crossing[[3]], {1}]}, &lt;br /&gt;
      newCrossing[[1]]][[1]];&lt;br /&gt;
   newStrandList = &lt;br /&gt;
    Map[If[# &amp;gt; newCrossing[[1]], # - 1, #] &amp;amp;, &lt;br /&gt;
     Replace[newStrandList, crossing[[1]] -&amp;gt; crossing[[3]], {1}]]&lt;br /&gt;
   ,&lt;br /&gt;
   newLink = decreaseStrandLabels[newLink, newCrossing[[1]]];&lt;br /&gt;
   newCrossing = &lt;br /&gt;
    decreaseStrandLabels[{newCrossing}, newCrossing[[1]]][[1]];&lt;br /&gt;
   newStrandList = &lt;br /&gt;
    Map[If[# &amp;gt; newCrossing[[1]], # - 1, #] &amp;amp;, newStrandList]&lt;br /&gt;
   ];&lt;br /&gt;
  (*adjust link after combining pos 2 and pos 4*)&lt;br /&gt;
  min = Min[newCrossing[[2]], newCrossing[[4]]];&lt;br /&gt;
  max = Max[newCrossing[[2]], newCrossing[[4]]];&lt;br /&gt;
  If[max - min &amp;gt; 1,&lt;br /&gt;
   newLink = &lt;br /&gt;
    decreaseStrandLabels[Replace[newLink, max -&amp;gt; min, {2}], max];&lt;br /&gt;
   newCrossing = &lt;br /&gt;
    decreaseStrandLabels[{Replace[newCrossing, max -&amp;gt; min, {1}]}, &lt;br /&gt;
      max][[1]];&lt;br /&gt;
   newStrandList = &lt;br /&gt;
    Map[If[# &amp;gt; max, # - 1, #] &amp;amp;, &lt;br /&gt;
     Replace[newStrandList, max -&amp;gt; min, {1}]],&lt;br /&gt;
   newLink = decreaseStrandLabels[newLink, min];&lt;br /&gt;
   newCrossing = decreaseStrandLabels[{newCrossing}, min][[1]];&lt;br /&gt;
   newStrandList = Map[If[# &amp;gt; max, # - 1, #] &amp;amp;, newStrandList]&lt;br /&gt;
   ];&lt;br /&gt;
  {newLink, &lt;br /&gt;
   If[outgoingStrandPos &amp;gt; 0, newCrossing[[outgoingStrandPos]], -1], &lt;br /&gt;
   newStrandList}&lt;br /&gt;
  ]&lt;br /&gt;
cableComponent[link_, s_, strandList_] := &lt;br /&gt;
  Module[{initialStrands, newComponentLabel = 2 Length[link] + 1},&lt;br /&gt;
   initialStrands = Join[{s, s, newComponentLabel}, strandList];&lt;br /&gt;
   recurse[newLink_, strands_] := &lt;br /&gt;
    Module[{currentStrand = strands[[1]], firstStrand = strands[[2]], &lt;br /&gt;
      currentCrossing, updatedLink, &lt;br /&gt;
      updatedStrands},(*copy the current crossing*)&lt;br /&gt;
     currentCrossing = findEnteringVertex[newLink, currentStrand];&lt;br /&gt;
     {updatedLink, updatedStrands} = &lt;br /&gt;
      duplicateVertex[newLink, currentCrossing, strands];&lt;br /&gt;
     (*check if we&#039;ve returned to the first strand*)&lt;br /&gt;
     If[updatedStrands[[1]] == updatedStrands[[2]],&lt;br /&gt;
      (*replace the largest strand label with the first strand label \&lt;br /&gt;
of the new component*)&lt;br /&gt;
      {Replace[updatedLink, &lt;br /&gt;
        n_?(# == 2 Length[updatedLink] + 1 &amp;amp;) -&amp;gt; &lt;br /&gt;
         updatedStrands[[3]], {2}], &lt;br /&gt;
       updatedStrands[[4 ;;]]},(*keep adding crossings*)&lt;br /&gt;
      recurse[updatedLink, updatedStrands]]&lt;br /&gt;
     ];&lt;br /&gt;
   recurse[link, initialStrands]&lt;br /&gt;
   ];&lt;br /&gt;
deleteComponent[link_, s_, strandList_] := &lt;br /&gt;
  Module[{newLink, currentStrand, newStrandList, currentCrossing},&lt;br /&gt;
   If[s &amp;lt;= 0,&lt;br /&gt;
    (*we&#039;re done deleting stuff*)&lt;br /&gt;
    {link, strandList},&lt;br /&gt;
    (*keep deleting*)&lt;br /&gt;
    currentCrossing = findEnteringVertex[link, s];&lt;br /&gt;
    {newLink, currentStrand, newStrandList} = &lt;br /&gt;
     deleteVertex[link, currentCrossing, s, strandList];&lt;br /&gt;
    deleteComponent[newLink, currentStrand, newStrandList]&lt;br /&gt;
    ]&lt;br /&gt;
   ];&lt;br /&gt;
cableLinkMonomial[link_, strandList_, degreeList_] := &lt;br /&gt;
  Module[{newLink = link, newStrandList, newDegreeList, coeff = 1},&lt;br /&gt;
   (*reorder so that we&#039;re deleting components first*)&lt;br /&gt;
   {newDegreeList, newStrandList} = {degreeList, strandList}[[All, &lt;br /&gt;
     Ordering@degreeList]];&lt;br /&gt;
   (*start cabling*)&lt;br /&gt;
   Do[&lt;br /&gt;
    Which[&lt;br /&gt;
     newStrandList[[i]] == 0,&lt;br /&gt;
     (*it&#039;s an unknot*)&lt;br /&gt;
     coeff = coeff*(-A^2 - A^(-2))^newDegreeList[[i]],&lt;br /&gt;
     newDegreeList[[i]] == 0,&lt;br /&gt;
     (*we need to delete it*)&lt;br /&gt;
     {newLink, newStrandList} = &lt;br /&gt;
      deleteComponent[newLink, newStrandList[[i]], newStrandList],&lt;br /&gt;
     True,&lt;br /&gt;
     (*cable the component*)&lt;br /&gt;
     Do[&lt;br /&gt;
      {newLink, newStrandList} = &lt;br /&gt;
       cableComponent[newLink, newStrandList[[i]], newStrandList]&lt;br /&gt;
      , {j, 1, newDegreeList[[i]] - 1}]&lt;br /&gt;
     ]&lt;br /&gt;
    , {i, 1, Length[newStrandList]}&lt;br /&gt;
    ];&lt;br /&gt;
   coeff*KB1[newLink]&lt;br /&gt;
   ];&lt;br /&gt;
CableLink[link_, poly_, strandList_, vars_] := &lt;br /&gt;
 Module[{monomials = CoefficientRules[poly, vars], temp},&lt;br /&gt;
  Total[&lt;br /&gt;
   Map[&lt;br /&gt;
    #[[2]]*cableLinkMonomial[link, strandList, #[[1]]] &amp;amp;&lt;br /&gt;
    , monomials]]&lt;br /&gt;
  ]&lt;/div&gt;</summary>
		<author><name>Sam.panitch</name></author>
	</entry>
	<entry>
		<id>https://katlas.org/index.php?title=Threading_a_link_by_a_polynomial&amp;diff=1725849</id>
		<title>Threading a link by a polynomial</title>
		<link rel="alternate" type="text/html" href="https://katlas.org/index.php?title=Threading_a_link_by_a_polynomial&amp;diff=1725849"/>
		<updated>2025-08-05T22:27:17Z</updated>

		<summary type="html">&lt;p&gt;Sam.panitch: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;code&amp;gt;CableLink[link,poly,strandList,vars]&amp;lt;/code&amp;gt;, whose code is available [[cableLink.m|here]], computes the Kauffman bracket of link (given as a PD) with components L1,L2,...,Ln, cabled by the polynomial poly in the variables z1,z2,...,zn. strandList is a list of strand labels of length n, where the ith element is the first strand label corresponding to component Li.&lt;br /&gt;
As an example, we can verify some formulas from Mausbaum:&lt;br /&gt;
&lt;br /&gt;
{{Startup Note}}&lt;br /&gt;
&amp;lt;!--$$Import[&amp;quot;http://katlas.org/w/index.php?title=CableLink.m&amp;amp;action=raw&amp;quot;];$$--&amp;gt;&lt;br /&gt;
&amp;lt;!--$$Import[&amp;quot;http://katlas.org/w/index.php?title=CableLink.m&amp;amp;action=raw&amp;quot;];$$--&amp;gt;&lt;br /&gt;
&amp;lt;!--Robot Land, no human edits to &amp;quot;END&amp;quot;--&amp;gt;&lt;br /&gt;
{{In|&lt;br /&gt;
n  = 2 |&lt;br /&gt;
in = &amp;lt;nowiki&amp;gt;Import[&amp;quot;http://katlas.org/w/index.php?title=CableComponent.m&amp;amp;action=raw&amp;quot;];&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&amp;lt;!--END--&amp;gt;&lt;br /&gt;
&amp;lt;!--$$hopfLink=PD[X[3,1,4,2],X[2,4,1,3]]; //&lt;br /&gt;
bracket[n_]:=a^n-a^(-n); //&lt;br /&gt;
bracketFact[n_]:=Product[bracket[i],{i,1,n}]; //&lt;br /&gt;
R[z_, n_] := Product[z + lambda[2*i], {i, 0, n - 1}]; //&lt;br /&gt;
cheb[0, z_] = 1; &lt;br /&gt;
cheb[1, z_] = z;&lt;br /&gt;
cheb[n_, z_] := cheb[n, z] = z*cheb[n - 1, z] - cheb[n - 2, z];&lt;br /&gt;
$$--&amp;gt;&lt;br /&gt;
&amp;lt;!--Robot Land, no human edits to &amp;quot;END&amp;quot;--&amp;gt;&lt;br /&gt;
{{In|&lt;br /&gt;
n  = 3 |&lt;br /&gt;
in = &amp;lt;nowiki&amp;gt;hopfLink=PD[X[3,1,4,2],X[2,4,1,3]];&lt;br /&gt;
bracket[n_]:=a^n-a^(-n);&lt;br /&gt;
bracketFact[n_]:=Product[bracket[i],{i,1,n}];&lt;br /&gt;
R[z_, n_] := Product[z + lambda[2*i], {i, 0, n - 1}];&lt;br /&gt;
cheb[0, z_] = 1; &lt;br /&gt;
cheb[1, z_] = z;&lt;br /&gt;
cheb[n_, z_] := cheb[n, z] = z*cheb[n - 1, z] - cheb[n - 2, z];&amp;lt;/nowiki&amp;gt; |&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;!--END--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--$$Expand[CableLink[hopfLink, &lt;br /&gt;
   R[Subscript[z, 1], 1]*cheb[2, Subscript[z, 2]], {1, 3}, {Subscript[&lt;br /&gt;
    z, 1], Subscript[z, 2]}] /. {A -&amp;gt; a^(1/2)}] //&lt;br /&gt;
Expand[(-1)^1*bracketFact[3]/bracket[1]]&lt;br /&gt;
$$--&amp;gt;&lt;br /&gt;
&amp;lt;!--Robot Land, no human edits to &amp;quot;END&amp;quot;--&amp;gt;&lt;br /&gt;
{{InOut|&lt;br /&gt;
n  = 4 |&lt;br /&gt;
in = &amp;lt;nowiki&amp;gt;Expand[CableLink[hopfLink, &lt;br /&gt;
   R[Subscript[z, 1], 1]*cheb[2, Subscript[z, 2]], {1, 3}, {Subscript[&lt;br /&gt;
    z, 1], Subscript[z, 2]}] /. {A -&amp;gt; a^(1/2)}]&lt;br /&gt;
Expand[(-1)^1*bracketFact[3]/bracket[1]]&amp;lt;/nowiki&amp;gt; |&lt;br /&gt;
out= &amp;lt;nowiki&amp;gt;-1/a^5 + 1/a + a - a^5 &lt;br /&gt;
-1/a^5 + 1/a + a - a^5&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&amp;lt;!--END--&amp;gt;&lt;br /&gt;
&amp;lt;!--$$Expand[CableLink[hopfLink, &lt;br /&gt;
   R[Subscript[z, 1], 2]*cheb[4, Subscript[z, 2]], {1, 3}, {Subscript[&lt;br /&gt;
    z, 1], Subscript[z, 2]}] /. {A -&amp;gt; a^(1/2)}]&lt;br /&gt;
Expand[(-1)^2*bracketFact[5]/bracket[1]] //&lt;br /&gt;
$$--&amp;gt;&lt;br /&gt;
{{InOut|&lt;br /&gt;
n  = 5 |&lt;br /&gt;
in = &amp;lt;nowiki&amp;gt;Expand[CableLink[hopfLink, &lt;br /&gt;
   R[Subscript[z, 1], 2]*cheb[4, Subscript[z, 2]], {1, 3}, {Subscript[&lt;br /&gt;
    z, 1], Subscript[z, 2]}] /. {A -&amp;gt; a^(1/2)}]&lt;br /&gt;
Expand[(-1)^1*bracketFact[3]/bracket[1]]&amp;lt;/nowiki&amp;gt; |&lt;br /&gt;
out= &amp;lt;nowiki&amp;gt;2 + 1/a^14 - 1/a^10 - 1/a^8 - 1/a^6 + 1/a^2 + a^2 - a^6 - a^8 - a^10 + a^14&lt;br /&gt;
2 + 1/a^14 - 1/a^10 - 1/a^8 - 1/a^6 + 1/a^2 + a^2 - a^6 - a^8 - a^10 + a^14&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&amp;lt;!--END--&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sam.panitch</name></author>
	</entry>
	<entry>
		<id>https://katlas.org/index.php?title=Threading_a_link_by_a_polynomial&amp;diff=1725848</id>
		<title>Threading a link by a polynomial</title>
		<link rel="alternate" type="text/html" href="https://katlas.org/index.php?title=Threading_a_link_by_a_polynomial&amp;diff=1725848"/>
		<updated>2025-08-05T22:26:38Z</updated>

		<summary type="html">&lt;p&gt;Sam.panitch: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;code&amp;gt;CableLink[link,poly,strandList,vars]&amp;lt;/code&amp;gt;, whose code is available [[cableLink.m|here]], computes the Kauffman bracket of link (given as a PD) with components L1,L2,...,Ln, cabled by the polynomial poly in the variables z1,z2,...,zn. strandList is a list of strand labels of length n, where the ith element is the first strand label corresponding to component Li.&lt;br /&gt;
As an example, we can verify some formulas from Mausbaum:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--$$Import[&amp;quot;http://katlas.org/w/index.php?title=CableLink.m&amp;amp;action=raw&amp;quot;];$$--&amp;gt;&lt;br /&gt;
&amp;lt;!--$$Import[&amp;quot;http://katlas.org/w/index.php?title=CableLink.m&amp;amp;action=raw&amp;quot;];$$--&amp;gt;&lt;br /&gt;
&amp;lt;!--Robot Land, no human edits to &amp;quot;END&amp;quot;--&amp;gt;&lt;br /&gt;
{{In|&lt;br /&gt;
n  = 1 |&lt;br /&gt;
in = &amp;lt;nowiki&amp;gt;Import[&amp;quot;http://katlas.org/w/index.php?title=CableComponent.m&amp;amp;action=raw&amp;quot;];&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&amp;lt;!--END--&amp;gt;&lt;br /&gt;
&amp;lt;!--$$hopfLink=PD[X[3,1,4,2],X[2,4,1,3]]; //&lt;br /&gt;
bracket[n_]:=a^n-a^(-n); //&lt;br /&gt;
bracketFact[n_]:=Product[bracket[i],{i,1,n}]; //&lt;br /&gt;
R[z_, n_] := Product[z + lambda[2*i], {i, 0, n - 1}]; //&lt;br /&gt;
cheb[0, z_] = 1; &lt;br /&gt;
cheb[1, z_] = z;&lt;br /&gt;
cheb[n_, z_] := cheb[n, z] = z*cheb[n - 1, z] - cheb[n - 2, z];&lt;br /&gt;
$$--&amp;gt;&lt;br /&gt;
&amp;lt;!--Robot Land, no human edits to &amp;quot;END&amp;quot;--&amp;gt;&lt;br /&gt;
{{In|&lt;br /&gt;
n  = 2 |&lt;br /&gt;
in = &amp;lt;nowiki&amp;gt;hopfLink=PD[X[3,1,4,2],X[2,4,1,3]];&lt;br /&gt;
bracket[n_]:=a^n-a^(-n);&lt;br /&gt;
bracketFact[n_]:=Product[bracket[i],{i,1,n}];&lt;br /&gt;
R[z_, n_] := Product[z + lambda[2*i], {i, 0, n - 1}];&lt;br /&gt;
cheb[0, z_] = 1; &lt;br /&gt;
cheb[1, z_] = z;&lt;br /&gt;
cheb[n_, z_] := cheb[n, z] = z*cheb[n - 1, z] - cheb[n - 2, z];&amp;lt;/nowiki&amp;gt; |&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;!--END--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--$$Expand[CableLink[hopfLink, &lt;br /&gt;
   R[Subscript[z, 1], 1]*cheb[2, Subscript[z, 2]], {1, 3}, {Subscript[&lt;br /&gt;
    z, 1], Subscript[z, 2]}] /. {A -&amp;gt; a^(1/2)}] //&lt;br /&gt;
Expand[(-1)^1*bracketFact[3]/bracket[1]]&lt;br /&gt;
$$--&amp;gt;&lt;br /&gt;
&amp;lt;!--Robot Land, no human edits to &amp;quot;END&amp;quot;--&amp;gt;&lt;br /&gt;
{{InOut|&lt;br /&gt;
n  = 3 |&lt;br /&gt;
in = &amp;lt;nowiki&amp;gt;Expand[CableLink[hopfLink, &lt;br /&gt;
   R[Subscript[z, 1], 1]*cheb[2, Subscript[z, 2]], {1, 3}, {Subscript[&lt;br /&gt;
    z, 1], Subscript[z, 2]}] /. {A -&amp;gt; a^(1/2)}]&lt;br /&gt;
Expand[(-1)^1*bracketFact[3]/bracket[1]]&amp;lt;/nowiki&amp;gt; |&lt;br /&gt;
out= &amp;lt;nowiki&amp;gt;-1/a^5 + 1/a + a - a^5 &lt;br /&gt;
-1/a^5 + 1/a + a - a^5&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&amp;lt;!--END--&amp;gt;&lt;br /&gt;
&amp;lt;!--$$Expand[CableLink[hopfLink, &lt;br /&gt;
   R[Subscript[z, 1], 2]*cheb[4, Subscript[z, 2]], {1, 3}, {Subscript[&lt;br /&gt;
    z, 1], Subscript[z, 2]}] /. {A -&amp;gt; a^(1/2)}]&lt;br /&gt;
Expand[(-1)^2*bracketFact[5]/bracket[1]] //&lt;br /&gt;
$$--&amp;gt;&lt;br /&gt;
{{InOut|&lt;br /&gt;
n  = 4 |&lt;br /&gt;
in = &amp;lt;nowiki&amp;gt;Expand[CableLink[hopfLink, &lt;br /&gt;
   R[Subscript[z, 1], 2]*cheb[4, Subscript[z, 2]], {1, 3}, {Subscript[&lt;br /&gt;
    z, 1], Subscript[z, 2]}] /. {A -&amp;gt; a^(1/2)}]&lt;br /&gt;
Expand[(-1)^1*bracketFact[3]/bracket[1]]&amp;lt;/nowiki&amp;gt; |&lt;br /&gt;
out= &amp;lt;nowiki&amp;gt;2 + 1/a^14 - 1/a^10 - 1/a^8 - 1/a^6 + 1/a^2 + a^2 - a^6 - a^8 - a^10 + a^14&lt;br /&gt;
2 + 1/a^14 - 1/a^10 - 1/a^8 - 1/a^6 + 1/a^2 + a^2 - a^6 - a^8 - a^10 + a^14&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&amp;lt;!--END--&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sam.panitch</name></author>
	</entry>
	<entry>
		<id>https://katlas.org/index.php?title=Threading_a_link_by_a_polynomial&amp;diff=1725847</id>
		<title>Threading a link by a polynomial</title>
		<link rel="alternate" type="text/html" href="https://katlas.org/index.php?title=Threading_a_link_by_a_polynomial&amp;diff=1725847"/>
		<updated>2025-08-05T22:26:19Z</updated>

		<summary type="html">&lt;p&gt;Sam.panitch: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;code&amp;gt;CableLink[link,poly,strandList,vars]&amp;lt;/code&amp;gt;, whose code is available [[cableLink.m|here]], computes the Kauffman bracket of link (given as a PD) with components L1,L2,...,Ln, cabled by the polynomial poly in the variables z1,z2,...,zn. strandList is a list of strand labels of length n, where the ith element is the first strand label corresponding to component Li.&lt;br /&gt;
As an example, we can verify some formulas from Mausbaum:&lt;br /&gt;
&amp;lt;!--$$Import[&amp;quot;http://katlas.org/w/index.php?title=CableLink.m&amp;amp;action=raw&amp;quot;];$$--&amp;gt;&lt;br /&gt;
&amp;lt;!--$$Import[&amp;quot;http://katlas.org/w/index.php?title=CableLink.m&amp;amp;action=raw&amp;quot;];$$--&amp;gt;&lt;br /&gt;
&amp;lt;!--Robot Land, no human edits to &amp;quot;END&amp;quot;--&amp;gt;&lt;br /&gt;
{{In|&lt;br /&gt;
n  = 1 |&lt;br /&gt;
in = &amp;lt;nowiki&amp;gt;Import[&amp;quot;http://katlas.org/w/index.php?title=CableComponent.m&amp;amp;action=raw&amp;quot;];&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&amp;lt;!--END--&amp;gt;&lt;br /&gt;
&amp;lt;!--$$hopfLink=PD[X[3,1,4,2],X[2,4,1,3]]; //&lt;br /&gt;
bracket[n_]:=a^n-a^(-n); //&lt;br /&gt;
bracketFact[n_]:=Product[bracket[i],{i,1,n}]; //&lt;br /&gt;
R[z_, n_] := Product[z + lambda[2*i], {i, 0, n - 1}]; //&lt;br /&gt;
cheb[0, z_] = 1; &lt;br /&gt;
cheb[1, z_] = z;&lt;br /&gt;
cheb[n_, z_] := cheb[n, z] = z*cheb[n - 1, z] - cheb[n - 2, z];&lt;br /&gt;
$$--&amp;gt;&lt;br /&gt;
&amp;lt;!--Robot Land, no human edits to &amp;quot;END&amp;quot;--&amp;gt;&lt;br /&gt;
{{In|&lt;br /&gt;
n  = 2 |&lt;br /&gt;
in = &amp;lt;nowiki&amp;gt;hopfLink=PD[X[3,1,4,2],X[2,4,1,3]];&lt;br /&gt;
bracket[n_]:=a^n-a^(-n);&lt;br /&gt;
bracketFact[n_]:=Product[bracket[i],{i,1,n}];&lt;br /&gt;
R[z_, n_] := Product[z + lambda[2*i], {i, 0, n - 1}];&lt;br /&gt;
cheb[0, z_] = 1; &lt;br /&gt;
cheb[1, z_] = z;&lt;br /&gt;
cheb[n_, z_] := cheb[n, z] = z*cheb[n - 1, z] - cheb[n - 2, z];&amp;lt;/nowiki&amp;gt; |&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;!--END--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--$$Expand[CableLink[hopfLink, &lt;br /&gt;
   R[Subscript[z, 1], 1]*cheb[2, Subscript[z, 2]], {1, 3}, {Subscript[&lt;br /&gt;
    z, 1], Subscript[z, 2]}] /. {A -&amp;gt; a^(1/2)}] //&lt;br /&gt;
Expand[(-1)^1*bracketFact[3]/bracket[1]]&lt;br /&gt;
$$--&amp;gt;&lt;br /&gt;
&amp;lt;!--Robot Land, no human edits to &amp;quot;END&amp;quot;--&amp;gt;&lt;br /&gt;
{{InOut|&lt;br /&gt;
n  = 3 |&lt;br /&gt;
in = &amp;lt;nowiki&amp;gt;Expand[CableLink[hopfLink, &lt;br /&gt;
   R[Subscript[z, 1], 1]*cheb[2, Subscript[z, 2]], {1, 3}, {Subscript[&lt;br /&gt;
    z, 1], Subscript[z, 2]}] /. {A -&amp;gt; a^(1/2)}]&lt;br /&gt;
Expand[(-1)^1*bracketFact[3]/bracket[1]]&amp;lt;/nowiki&amp;gt; |&lt;br /&gt;
out= &amp;lt;nowiki&amp;gt;-1/a^5 + 1/a + a - a^5 &lt;br /&gt;
-1/a^5 + 1/a + a - a^5&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&amp;lt;!--END--&amp;gt;&lt;br /&gt;
&amp;lt;!--$$Expand[CableLink[hopfLink, &lt;br /&gt;
   R[Subscript[z, 1], 2]*cheb[4, Subscript[z, 2]], {1, 3}, {Subscript[&lt;br /&gt;
    z, 1], Subscript[z, 2]}] /. {A -&amp;gt; a^(1/2)}]&lt;br /&gt;
Expand[(-1)^2*bracketFact[5]/bracket[1]] //&lt;br /&gt;
$$--&amp;gt;&lt;br /&gt;
{{InOut|&lt;br /&gt;
n  = 4 |&lt;br /&gt;
in = &amp;lt;nowiki&amp;gt;Expand[CableLink[hopfLink, &lt;br /&gt;
   R[Subscript[z, 1], 2]*cheb[4, Subscript[z, 2]], {1, 3}, {Subscript[&lt;br /&gt;
    z, 1], Subscript[z, 2]}] /. {A -&amp;gt; a^(1/2)}]&lt;br /&gt;
Expand[(-1)^1*bracketFact[3]/bracket[1]]&amp;lt;/nowiki&amp;gt; |&lt;br /&gt;
out= &amp;lt;nowiki&amp;gt;2 + 1/a^14 - 1/a^10 - 1/a^8 - 1/a^6 + 1/a^2 + a^2 - a^6 - a^8 - a^10 + a^14&lt;br /&gt;
2 + 1/a^14 - 1/a^10 - 1/a^8 - 1/a^6 + 1/a^2 + a^2 - a^6 - a^8 - a^10 + a^14&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&amp;lt;!--END--&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sam.panitch</name></author>
	</entry>
	<entry>
		<id>https://katlas.org/index.php?title=Threading_a_link_by_a_polynomial&amp;diff=1725846</id>
		<title>Threading a link by a polynomial</title>
		<link rel="alternate" type="text/html" href="https://katlas.org/index.php?title=Threading_a_link_by_a_polynomial&amp;diff=1725846"/>
		<updated>2025-08-05T21:29:05Z</updated>

		<summary type="html">&lt;p&gt;Sam.panitch: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;code&amp;gt;CableLink[link,poly,strandList,vars]&amp;lt;/code&amp;gt;, whose code is available [[cableLink.m|here]], computes the Kauffman bracket of link (given as a PD) with components L1,L2,...,Ln, cabled by the polynomial poly in the variables z1,z2,...,zn. strandList is a list of strand labels of length n, where the ith element is the first strand label corresponding to component Li.&lt;br /&gt;
As an example, we can verify some formulas from Mausbaum:&lt;br /&gt;
&amp;lt;!--$$Import[&amp;quot;http://katlas.org/w/index.php?title=CableLink.m&amp;amp;action=raw&amp;quot;];$$--&amp;gt;&lt;br /&gt;
&amp;lt;!--END--&amp;gt;&lt;br /&gt;
&amp;lt;!--$$hopfLink=PD[X[3,1,4,2],X[2,4,1,3]]; //&lt;br /&gt;
bracket[n_]:=a^n-a^(-n); //&lt;br /&gt;
bracketFact[n_]:=Product[bracket[i],{i,1,n}]; //&lt;br /&gt;
R[z_, n_] := Product[z + lambda[2*i], {i, 0, n - 1}]; //&lt;br /&gt;
cheb[0, z_] = 1; &lt;br /&gt;
cheb[1, z_] = z;&lt;br /&gt;
cheb[n_, z_] := cheb[n, z] = z*cheb[n - 1, z] - cheb[n - 2, z];&lt;br /&gt;
$$--&amp;gt;&lt;br /&gt;
&amp;lt;!--END--&amp;gt;&lt;br /&gt;
&amp;lt;!--$$Expand[CableLink[hopfLink, &lt;br /&gt;
   R[Subscript[z, 1], 1]*cheb[2, Subscript[z, 2]], {1, 3}, {Subscript[&lt;br /&gt;
    z, 1], Subscript[z, 2]}] /. {A -&amp;gt; a^(1/2)}] //&lt;br /&gt;
Expand[(-1)^1*bracketFact[3]/bracket[1]]&lt;br /&gt;
$$--&amp;gt;&lt;br /&gt;
&amp;lt;!--END--&amp;gt;&lt;br /&gt;
&amp;lt;!--$$Expand[CableLink[hopfLink, &lt;br /&gt;
   R[Subscript[z, 1], 2]*cheb[4, Subscript[z, 2]], {1, 3}, {Subscript[&lt;br /&gt;
    z, 1], Subscript[z, 2]}] /. {A -&amp;gt; a^(1/2)}]&lt;br /&gt;
Expand[(-1)^2*bracketFact[5]/bracket[1]] //&lt;br /&gt;
$$--&amp;gt;&lt;br /&gt;
&amp;lt;!--END--&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sam.panitch</name></author>
	</entry>
	<entry>
		<id>https://katlas.org/index.php?title=CableLink.m&amp;diff=1725845</id>
		<title>CableLink.m</title>
		<link rel="alternate" type="text/html" href="https://katlas.org/index.php?title=CableLink.m&amp;diff=1725845"/>
		<updated>2025-08-05T21:28:47Z</updated>

		<summary type="html">&lt;p&gt;Sam.panitch: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;(*&lt;br /&gt;
&lt;br /&gt;
The program &amp;lt;code&amp;gt;CableLink&amp;lt;/code&amp;gt; is documented on the page [[Threading a link by a polynomial]]. It is not part of the package &amp;lt;code&amp;gt;KnotTheory`&amp;lt;/code&amp;gt; but is designed to work with it. Use &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Import[&amp;quot;http://katlas.org/w/index.php?title=CableLink.m&amp;amp;action=raw&amp;quot;]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; to download into a mathematica session, or copy-paste the text below ignoring the &amp;lt;code&amp;gt;*&amp;amp;#41;&amp;lt;/code&amp;gt; on the first line and the &amp;lt;code&amp;gt;&amp;amp;#40;*&amp;lt;/code&amp;gt; on the last.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
*)&lt;br /&gt;
(*Kauffman bracket*)&lt;br /&gt;
KB1[pd_PD] := KB1[pd, {}, 1];&lt;br /&gt;
KB1[pd_PD, inside_, web_] := &lt;br /&gt;
  Module[{pos = &lt;br /&gt;
     First[Ordering[Length[Complement[List @@ #, inside]] &amp;amp; /@ pd]]}, &lt;br /&gt;
   pd[[pos]] /.  &lt;br /&gt;
    X[a_, b_, c_, d_] :&amp;gt; &lt;br /&gt;
     KB1[Delete[pd, pos], Union[inside, {a, b, c, d}], &lt;br /&gt;
      Expand[web*(A P[a, d] P[b, c] + 1/A P[a, b] P[c, d])] //. {P[e_,&lt;br /&gt;
            f_] P[f_, g_] :&amp;gt; P[e, g], P[e_, _]^2 :&amp;gt; P[e, e], &lt;br /&gt;
        P[e_, e_] -&amp;gt; -A^2 - 1/A^2}]];&lt;br /&gt;
KB1[PD[], _, web_] := Expand[web]&lt;br /&gt;
(*determine position of a strand label at a crossing*)&lt;br /&gt;
strandAtCrossing[crossing_, s_] := Module[{pos},&lt;br /&gt;
   pos = Position[crossing, s];&lt;br /&gt;
   If[Length[pos] &amp;gt; 0, pos[[1, 1]], False]&lt;br /&gt;
   ];&lt;br /&gt;
(*determine orientation of overstrand. Complicated by components with only 2 labels*)&lt;br /&gt;
orientationOfOverStrand[crossing_, link_] := Module[{otherCrossings},&lt;br /&gt;
   (*find the other crossings containing the strand labels of the overstrand crossing*)&lt;br /&gt;
   otherCrossings = &lt;br /&gt;
    DeleteElements[&lt;br /&gt;
     Select[link, &lt;br /&gt;
      ContainsAny[&lt;br /&gt;
        List[Delete[#, 0]], {crossing[[2]], &lt;br /&gt;
         crossing[[4]]}] &amp;amp;], {crossing}];&lt;br /&gt;
   (*if the length of othercrossings is 1, &lt;br /&gt;
   then the overstrand labels are part of a component with only two \&lt;br /&gt;
strand labels*)&lt;br /&gt;
   If[Length[otherCrossings] == 1,&lt;br /&gt;
    (*first check if a strand label is in the first position of the \&lt;br /&gt;
other crossing.*)&lt;br /&gt;
    Which[otherCrossings[[1, 1]] == crossing[[2]],&lt;br /&gt;
     True,&lt;br /&gt;
     otherCrossings[[1, 1]] == crossing[[4]],&lt;br /&gt;
     False,&lt;br /&gt;
     (*Otherwise, the strands are always overcrossings, &lt;br /&gt;
     in which case we just choose to orient from small to large*)&lt;br /&gt;
     True,&lt;br /&gt;
     crossing[[2]] &amp;gt; crossing[[4]]&lt;br /&gt;
     ],&lt;br /&gt;
    (*otherwise, &lt;br /&gt;
    the overcrossing is oriented from 4 to 2 if pos 2 is 1 more than \&lt;br /&gt;
pos 4, or if pos 4 is more than 1 greater than pos 2.*)&lt;br /&gt;
     crossing[[2]] - crossing[[4]] == 1 || &lt;br /&gt;
     crossing[[4]] - crossing[[2]] &amp;gt; 1&lt;br /&gt;
    ]&lt;br /&gt;
   ];&lt;br /&gt;
(*find crossing where a strand label enters*)&lt;br /&gt;
findEnteringVertex[link_, s_] := &lt;br /&gt;
  Module[{crossingsContainingS, firstCrossing, pos},&lt;br /&gt;
   (*find crossings containing s*)&lt;br /&gt;
   crossingsContainingS = &lt;br /&gt;
    Select[link, IntegerQ[strandAtCrossing[#, s]] &amp;amp;];&lt;br /&gt;
   firstCrossing = crossingsContainingS[[1]];&lt;br /&gt;
   pos = strandAtCrossing[firstCrossing, s];&lt;br /&gt;
   Which[&lt;br /&gt;
    (*if pos is 1, then it is definitely an incoming strand*)&lt;br /&gt;
    pos == 1,&lt;br /&gt;
    firstCrossing,&lt;br /&gt;
    (pos == 2 &amp;amp;&amp;amp; ! &lt;br /&gt;
        orientationOfOverStrand[firstCrossing, link]) || (pos == 4 &amp;amp;&amp;amp; &lt;br /&gt;
       orientationOfOverStrand[firstCrossing, link]),&lt;br /&gt;
    firstCrossing,&lt;br /&gt;
    (*otherwise it must be the entering strand at the other vertex \&lt;br /&gt;
containing that label*)&lt;br /&gt;
    True,&lt;br /&gt;
    crossingsContainingS[[2]]&lt;br /&gt;
    ]&lt;br /&gt;
   ];&lt;br /&gt;
increaseStrandLabels[link_, s_] := &lt;br /&gt;
  Replace[link, n_?(# &amp;gt; s &amp;amp;) -&amp;gt; n + 1, {2}];&lt;br /&gt;
decreaseStrandLabels[link_, s_] := &lt;br /&gt;
  Replace[link, n_?(# &amp;gt; s &amp;amp;) -&amp;gt; n - 1, {2}];&lt;br /&gt;
(*duplicate a crossing*)&lt;br /&gt;
duplicateVertex[link_, crossing_, strands_] := &lt;br /&gt;
  Module[{pos = strandAtCrossing[crossing, strands[[1]]], &lt;br /&gt;
    newLabel = Length[link]*2 + 2, &lt;br /&gt;
    newLink = DeleteElements[link, {crossing}], p1 = crossing[[1]], &lt;br /&gt;
    p2 = crossing[[2]], p3 = crossing[[3]], p4 = crossing[[4]]},&lt;br /&gt;
   Which[&lt;br /&gt;
    (*pos is 1 and the upper strand is oriented from 4 to 2*)&lt;br /&gt;
    pos == 1  &amp;amp;&amp;amp; orientationOfOverStrand[crossing, link],&lt;br /&gt;
    {Union[&lt;br /&gt;
      increaseStrandLabels[newLink, p4],&lt;br /&gt;
      PD[&lt;br /&gt;
       X[If[p1 &amp;lt; p2, p1, p1 + 1], p4 + 1, If[p3 &amp;lt; p2, p3, p3 + 1], &lt;br /&gt;
        p4]],&lt;br /&gt;
      PD[X[newLabel, If[p2 &amp;gt; p4, p2 + 1, p2], newLabel + 1, p4 + 1]]&lt;br /&gt;
      ],&lt;br /&gt;
     Map[If[# &amp;lt;= p2, #, # + 1] &amp;amp;, Prepend[strands[[2 ;;]], p3]]&lt;br /&gt;
     },&lt;br /&gt;
    (*pos is 1 and the upper strand is oriented from 2 to 4*)&lt;br /&gt;
    pos == 1,&lt;br /&gt;
    {Union[&lt;br /&gt;
      increaseStrandLabels[newLink, p2],&lt;br /&gt;
      PD[&lt;br /&gt;
       X[If[p1 &amp;lt; p2, p1, p1 + 1], p2 + 1, If[p3 &amp;lt; p2, p3, p3 + 1], &lt;br /&gt;
        If[p4 &amp;lt; p2, p4, p4 + 1]]],&lt;br /&gt;
      PD[X[newLabel, p2, newLabel + 1, p2 + 1]]&lt;br /&gt;
      ],&lt;br /&gt;
     Map[If[# &amp;lt;= p2, #, # + 1] &amp;amp;, Prepend[strands[[2 ;;]], p3]]&lt;br /&gt;
     },&lt;br /&gt;
    (*pos is 2*)&lt;br /&gt;
    pos == 2,&lt;br /&gt;
    {Union[&lt;br /&gt;
      increaseStrandLabels[newLink, p1],&lt;br /&gt;
      PD[&lt;br /&gt;
       X[p1, If[p2 &amp;lt; p1, p2, p2 + 1], p1 + 1, &lt;br /&gt;
        If[p4 &amp;lt; p1, p4, p4 + 1]]],&lt;br /&gt;
      PD[X[p1 + 1, newLabel, If[p3 &amp;lt; p1, p3, p3 + 1], newLabel + 1]]&lt;br /&gt;
      ],&lt;br /&gt;
     Map[If[# &amp;lt;= p1, #, # + 1] &amp;amp;, Prepend[strands[[2 ;;]], p4]]&lt;br /&gt;
     },&lt;br /&gt;
    (*pos is 4*)&lt;br /&gt;
    True,&lt;br /&gt;
    {Union[&lt;br /&gt;
      increaseStrandLabels[newLink, p1],&lt;br /&gt;
      PD[&lt;br /&gt;
       X[p1 + 1, If[p2 &amp;lt; p1, p2, p2 + 1], If[p3 &amp;lt; p1, p3, p3 + 1], &lt;br /&gt;
        If[p4 &amp;lt; p1, p4, p4 + 1]]],&lt;br /&gt;
      PD[X[p1, newLabel + 1, p1 + 1, newLabel]]&lt;br /&gt;
      ],&lt;br /&gt;
     Map[If[# &amp;lt;= p1, #, # + 1] &amp;amp;, Prepend[strands[[2 ;;]], p2]]&lt;br /&gt;
     }&lt;br /&gt;
    ]&lt;br /&gt;
   ];&lt;br /&gt;
(*delete a crossing*)&lt;br /&gt;
deleteVertex[link_, crossing_, s_, strandList_] := &lt;br /&gt;
 Module[{newCrossing = crossing, &lt;br /&gt;
   newLink = DeleteElements[link, {crossing}], min, max, &lt;br /&gt;
   pos = strandAtCrossing[crossing, s], outgoingStrandPos, &lt;br /&gt;
   newStrandList = strandList},&lt;br /&gt;
  (*we create an unknot if the two labels of the other strand at the \&lt;br /&gt;
crossing are equal*)&lt;br /&gt;
  Which[(pos == 1 &amp;amp;&amp;amp; crossing[[2]] == crossing[[4]]) , &lt;br /&gt;
   newStrandList = &lt;br /&gt;
    Replace[newStrandList, &lt;br /&gt;
     crossing[[2]] -&amp;gt; 0, {1}], (pos == 2 || pos == 4 ) &amp;amp;&amp;amp; &lt;br /&gt;
    crossing[[1]] == crossing[[3]], &lt;br /&gt;
   newStrandList = Replace[newStrandList, crossing[[1]] -&amp;gt; 0, {1}]];&lt;br /&gt;
  (*&amp;quot;&lt;br /&gt;
	we need to keep track of the outgoing strand label. There&#039;s actually \&lt;br /&gt;
two ways to know we&#039;re done:&lt;br /&gt;
	either the outgoing strand is the same as the incoming strand, or \&lt;br /&gt;
the whole vertex only involves 2 different labels.&lt;br /&gt;
&amp;quot;*)&lt;br /&gt;
  outgoingStrandPos = Which[pos == 1, 3, pos == 2, 4, True, 2];&lt;br /&gt;
  If[crossing[[outgoingStrandPos]] == s || &lt;br /&gt;
    CountDistinct[{Delete[crossing, 0]}] &amp;lt; 3, &lt;br /&gt;
   outgoingStrandPos = -1];&lt;br /&gt;
  (*adjust link after combining pos 1 and pos 3*)&lt;br /&gt;
  If[crossing[[1]] &amp;gt; crossing[[3]],&lt;br /&gt;
   newLink = &lt;br /&gt;
    decreaseStrandLabels[&lt;br /&gt;
     Replace[newLink, crossing[[1]] -&amp;gt; crossing[[3]], {2}], &lt;br /&gt;
     newCrossing[[1]]];&lt;br /&gt;
   newCrossing = &lt;br /&gt;
    decreaseStrandLabels[{Replace[newCrossing, &lt;br /&gt;
        crossing[[1]] -&amp;gt; crossing[[3]], {1}]}, &lt;br /&gt;
      newCrossing[[1]]][[1]];&lt;br /&gt;
   newStrandList = &lt;br /&gt;
    Map[If[# &amp;gt; newCrossing[[1]], # - 1, #] &amp;amp;, &lt;br /&gt;
     Replace[newStrandList, crossing[[1]] -&amp;gt; crossing[[3]], {1}]]&lt;br /&gt;
   ,&lt;br /&gt;
   newLink = decreaseStrandLabels[newLink, newCrossing[[1]]];&lt;br /&gt;
   newCrossing = &lt;br /&gt;
    decreaseStrandLabels[{newCrossing}, newCrossing[[1]]][[1]];&lt;br /&gt;
   newStrandList = &lt;br /&gt;
    Map[If[# &amp;gt; newCrossing[[1]], # - 1, #] &amp;amp;, newStrandList]&lt;br /&gt;
   ];&lt;br /&gt;
  (*adjust link after combining pos 2 and pos 4*)&lt;br /&gt;
  min = Min[newCrossing[[2]], newCrossing[[4]]];&lt;br /&gt;
  max = Max[newCrossing[[2]], newCrossing[[4]]];&lt;br /&gt;
  If[max - min &amp;gt; 1,&lt;br /&gt;
   newLink = &lt;br /&gt;
    decreaseStrandLabels[Replace[newLink, max -&amp;gt; min, {2}], max];&lt;br /&gt;
   newCrossing = &lt;br /&gt;
    decreaseStrandLabels[{Replace[newCrossing, max -&amp;gt; min, {1}]}, &lt;br /&gt;
      max][[1]];&lt;br /&gt;
   newStrandList = &lt;br /&gt;
    Map[If[# &amp;gt; max, # - 1, #] &amp;amp;, &lt;br /&gt;
     Replace[newStrandList, max -&amp;gt; min, {1}]],&lt;br /&gt;
   newLink = decreaseStrandLabels[newLink, min];&lt;br /&gt;
   newCrossing = decreaseStrandLabels[{newCrossing}, min][[1]];&lt;br /&gt;
   newStrandList = Map[If[# &amp;gt; max, # - 1, #] &amp;amp;, newStrandList]&lt;br /&gt;
   ];&lt;br /&gt;
  {newLink, &lt;br /&gt;
   If[outgoingStrandPos &amp;gt; 0, newCrossing[[outgoingStrandPos]], -1], &lt;br /&gt;
   newStrandList}&lt;br /&gt;
  ]&lt;br /&gt;
cableComponent[link_, s_, strandList_] := &lt;br /&gt;
  Module[{initialStrands, newComponentLabel = 2 Length[link] + 1},&lt;br /&gt;
   initialStrands = Join[{s, s, newComponentLabel}, strandList];&lt;br /&gt;
   recurse[newLink_, strands_] := &lt;br /&gt;
    Module[{currentStrand = strands[[1]], firstStrand = strands[[2]], &lt;br /&gt;
      currentCrossing, updatedLink, &lt;br /&gt;
      updatedStrands},(*copy the current crossing*)&lt;br /&gt;
     currentCrossing = findEnteringVertex[newLink, currentStrand];&lt;br /&gt;
     {updatedLink, updatedStrands} = &lt;br /&gt;
      duplicateVertex[newLink, currentCrossing, strands];&lt;br /&gt;
     (*check if we&#039;ve returned to the first strand*)&lt;br /&gt;
     If[updatedStrands[[1]] == updatedStrands[[2]],&lt;br /&gt;
      (*replace the largest strand label with the first strand label \&lt;br /&gt;
of the new component*)&lt;br /&gt;
      {Replace[updatedLink, &lt;br /&gt;
        n_?(# == 2 Length[updatedLink] + 1 &amp;amp;) -&amp;gt; &lt;br /&gt;
         updatedStrands[[3]], {2}], &lt;br /&gt;
       updatedStrands[[4 ;;]]},(*keep adding crossings*)&lt;br /&gt;
      recurse[updatedLink, updatedStrands]]&lt;br /&gt;
     ];&lt;br /&gt;
   recurse[link, initialStrands]&lt;br /&gt;
   ];&lt;br /&gt;
deleteComponent[link_, s_, strandList_] := &lt;br /&gt;
  Module[{newLink, currentStrand, newStrandList, currentCrossing},&lt;br /&gt;
   If[s &amp;lt;= 0,&lt;br /&gt;
    (*we&#039;re done deleting stuff*)&lt;br /&gt;
    {link, strandList},&lt;br /&gt;
    (*keep deleting*)&lt;br /&gt;
    currentCrossing = findEnteringVertex[link, s];&lt;br /&gt;
    {newLink, currentStrand, newStrandList} = &lt;br /&gt;
     deleteVertex[link, currentCrossing, s, strandList];&lt;br /&gt;
    deleteComponent[newLink, currentStrand, newStrandList]&lt;br /&gt;
    ]&lt;br /&gt;
   ];&lt;br /&gt;
cableLinkMonomial[link_, strandList_, degreeList_] := &lt;br /&gt;
  Module[{newLink = link, newStrandList, newDegreeList, coeff = 1},&lt;br /&gt;
   (*reorder so that we&#039;re deleting components first*)&lt;br /&gt;
   {newDegreeList, newStrandList} = {degreeList, strandList}[[All, &lt;br /&gt;
     Ordering@degreeList]];&lt;br /&gt;
   (*start cabling*)&lt;br /&gt;
   Do[&lt;br /&gt;
    Which[&lt;br /&gt;
     newStrandList[[i]] == 0,&lt;br /&gt;
     (*it&#039;s an unknot*)&lt;br /&gt;
     coeff = coeff*(-A^2 - A^(-2))^newDegreeList[[i]],&lt;br /&gt;
     newDegreeList[[i]] == 0,&lt;br /&gt;
     (*we need to delete it*)&lt;br /&gt;
     {newLink, newStrandList} = &lt;br /&gt;
      deleteComponent[newLink, newStrandList[[i]], newStrandList],&lt;br /&gt;
     True,&lt;br /&gt;
     (*cable the component*)&lt;br /&gt;
     Do[&lt;br /&gt;
      {newLink, newStrandList} = &lt;br /&gt;
       cableComponent[newLink, newStrandList[[i]], newStrandList]&lt;br /&gt;
      , {j, 1, newDegreeList[[i]] - 1}]&lt;br /&gt;
     ]&lt;br /&gt;
    , {i, 1, Length[newStrandList]}&lt;br /&gt;
    ];&lt;br /&gt;
   coeff*KB1[newLink]&lt;br /&gt;
   ];&lt;br /&gt;
CableLink[link_, poly_, strandList_, vars_] := &lt;br /&gt;
 Module[{monomials = CoefficientRules[poly, vars], temp},&lt;br /&gt;
  Total[&lt;br /&gt;
   Map[&lt;br /&gt;
    #[[2]]*cableLinkMonomial[link, strandList, #[[1]]] &amp;amp;&lt;br /&gt;
    , monomials]]&lt;br /&gt;
  ]&lt;/div&gt;</summary>
		<author><name>Sam.panitch</name></author>
	</entry>
	<entry>
		<id>https://katlas.org/index.php?title=Threading_a_link_by_a_polynomial&amp;diff=1725844</id>
		<title>Threading a link by a polynomial</title>
		<link rel="alternate" type="text/html" href="https://katlas.org/index.php?title=Threading_a_link_by_a_polynomial&amp;diff=1725844"/>
		<updated>2025-08-05T21:28:15Z</updated>

		<summary type="html">&lt;p&gt;Sam.panitch: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;code&amp;gt;CableLink[link,poly,strandList,vars]&amp;lt;/code&amp;gt;, whose code is available [[cableLink.m|here]], computes the Kauffman bracket of link (given as a PD) with components L1,L2,...,Ln, cabled by the polynomial poly in the variables z1,z2,...,zn. strandList is a list of strand labels of length n, where the ith element is the first strand label corresponding to component Li.&lt;br /&gt;
As an example, we can verify some formulas from Mausbaum:&lt;br /&gt;
&amp;lt;!--$$Import[&amp;quot;http://katlas.org/w/index.php?title=CableLink.m&amp;amp;action=raw&amp;quot;];$$--&amp;gt;&lt;br /&gt;
&amp;lt;!--END--&amp;gt;&lt;br /&gt;
&amp;lt;!--$$hopfLink=PD[X[3,1,4,2],X[2,4,1,3]]; //&lt;br /&gt;
bracket[n_]:=a^n-a^(-n); //&lt;br /&gt;
bracketFact[n_]:=Product[bracket[i],{i,1,n}]; //&lt;br /&gt;
R[z_, n_] := Product[z + lambda[2*i], {i, 0, n - 1}]; //&lt;br /&gt;
cheb[0, z_] = 1; &lt;br /&gt;
cheb[1, z_] = z;&lt;br /&gt;
cheb[n_, z_] := cheb[n, z] = z*cheb[n - 1, z] - cheb[n - 2, z];&lt;br /&gt;
$$--&amp;gt;&lt;br /&gt;
&amp;lt;!--END--&amp;gt;&lt;br /&gt;
&amp;lt;!--$$Expand[cableLink[hopfLink, &lt;br /&gt;
   R[Subscript[z, 1], 1]*cheb[2, Subscript[z, 2]], {1, 3}, {Subscript[&lt;br /&gt;
    z, 1], Subscript[z, 2]}] /. {A -&amp;gt; a^(1/2)}] //&lt;br /&gt;
Expand[(-1)^1*bracketFact[3]/bracket[1]]&lt;br /&gt;
$$--&amp;gt;&lt;br /&gt;
&amp;lt;!--END--&amp;gt;&lt;br /&gt;
&amp;lt;!--$$Expand[cableLink[hopfLink, &lt;br /&gt;
   R[Subscript[z, 1], 2]*cheb[4, Subscript[z, 2]], {1, 3}, {Subscript[&lt;br /&gt;
    z, 1], Subscript[z, 2]}] /. {A -&amp;gt; a^(1/2)}]&lt;br /&gt;
Expand[(-1)^2*bracketFact[5]/bracket[1]] //&lt;br /&gt;
$$--&amp;gt;&lt;br /&gt;
&amp;lt;!--END--&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sam.panitch</name></author>
	</entry>
	<entry>
		<id>https://katlas.org/index.php?title=CableLink.m&amp;diff=1725843</id>
		<title>CableLink.m</title>
		<link rel="alternate" type="text/html" href="https://katlas.org/index.php?title=CableLink.m&amp;diff=1725843"/>
		<updated>2025-08-05T21:23:44Z</updated>

		<summary type="html">&lt;p&gt;Sam.panitch: Created page with &amp;quot;(*  The program &amp;lt;code&amp;gt;CableLink&amp;lt;/code&amp;gt; is documented on the page Threading a link by a polynomial. It is not part of the package &amp;lt;code&amp;gt;KnotTheory`&amp;lt;/code&amp;gt; but is designed to work with it. Use &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Import[&amp;quot;http://katlas.org/w/index.php?title=CableLink.m&amp;amp;action=raw&amp;quot;]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; to download into a mathematica session, or copy-paste the text below ignoring the &amp;lt;code&amp;gt;*&amp;amp;#41;&amp;lt;/code&amp;gt; on the first line and the &amp;lt;code&amp;gt;&amp;amp;#40;*&amp;lt;/code&amp;gt; on the last. &amp;lt;pre&amp;gt; *) (*Kauffman...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;(*&lt;br /&gt;
&lt;br /&gt;
The program &amp;lt;code&amp;gt;CableLink&amp;lt;/code&amp;gt; is documented on the page [[Threading a link by a polynomial]]. It is not part of the package &amp;lt;code&amp;gt;KnotTheory`&amp;lt;/code&amp;gt; but is designed to work with it. Use &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Import[&amp;quot;http://katlas.org/w/index.php?title=CableLink.m&amp;amp;action=raw&amp;quot;]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; to download into a mathematica session, or copy-paste the text below ignoring the &amp;lt;code&amp;gt;*&amp;amp;#41;&amp;lt;/code&amp;gt; on the first line and the &amp;lt;code&amp;gt;&amp;amp;#40;*&amp;lt;/code&amp;gt; on the last.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
*)&lt;br /&gt;
(*Kauffman bracket*)&lt;br /&gt;
KB1[pd_PD] := KB1[pd, {}, 1];&lt;br /&gt;
KB1[pd_PD, inside_, web_] := &lt;br /&gt;
  Module[{pos = &lt;br /&gt;
     First[Ordering[Length[Complement[List @@ #, inside]] &amp;amp; /@ pd]]}, &lt;br /&gt;
   pd[[pos]] /.  &lt;br /&gt;
    X[a_, b_, c_, d_] :&amp;gt; &lt;br /&gt;
     KB1[Delete[pd, pos], Union[inside, {a, b, c, d}], &lt;br /&gt;
      Expand[web*(A P[a, d] P[b, c] + 1/A P[a, b] P[c, d])] //. {P[e_,&lt;br /&gt;
            f_] P[f_, g_] :&amp;gt; P[e, g], P[e_, _]^2 :&amp;gt; P[e, e], &lt;br /&gt;
        P[e_, e_] -&amp;gt; -A^2 - 1/A^2}]];&lt;br /&gt;
KB1[PD[], _, web_] := Expand[web]&lt;br /&gt;
(*determine position of a strand label at a crossing*)&lt;br /&gt;
strandAtCrossing[crossing_, s_] := Module[{pos},&lt;br /&gt;
   pos = Position[crossing, s];&lt;br /&gt;
   If[Length[pos] &amp;gt; 0, pos[[1, 1]], False]&lt;br /&gt;
   ];&lt;br /&gt;
(*determine orientation of overstrand. Complicated by components with only 2 labels*)&lt;br /&gt;
orientationOfOverStrand[crossing_, link_] := Module[{otherCrossings},&lt;br /&gt;
   (*find the other crossings containing the strand labels of the overstrand crossing*)&lt;br /&gt;
   otherCrossings = &lt;br /&gt;
    DeleteElements[&lt;br /&gt;
     Select[link, &lt;br /&gt;
      ContainsAny[&lt;br /&gt;
        List[Delete[#, 0]], {crossing[[2]], &lt;br /&gt;
         crossing[[4]]}] &amp;amp;], {crossing}];&lt;br /&gt;
   (*if the length of othercrossings is 1, &lt;br /&gt;
   then the overstrand labels are part of a component with only two \&lt;br /&gt;
strand labels*)&lt;br /&gt;
   If[Length[otherCrossings] == 1,&lt;br /&gt;
    (*first check if a strand label is in the first position of the \&lt;br /&gt;
other crossing.*)&lt;br /&gt;
    Which[otherCrossings[[1, 1]] == crossing[[2]],&lt;br /&gt;
     True,&lt;br /&gt;
     otherCrossings[[1, 1]] == crossing[[4]],&lt;br /&gt;
     False,&lt;br /&gt;
     (*Otherwise, the strands are always overcrossings, &lt;br /&gt;
     in which case we just choose to orient from small to large*)&lt;br /&gt;
     True,&lt;br /&gt;
     crossing[[2]] &amp;gt; crossing[[4]]&lt;br /&gt;
     ],&lt;br /&gt;
    (*otherwise, &lt;br /&gt;
    the overcrossing is oriented from 4 to 2 if pos 2 is 1 more than \&lt;br /&gt;
pos 4, or if pos 4 is more than 1 greater than pos 2.*)&lt;br /&gt;
     crossing[[2]] - crossing[[4]] == 1 || &lt;br /&gt;
     crossing[[4]] - crossing[[2]] &amp;gt; 1&lt;br /&gt;
    ]&lt;br /&gt;
   ];&lt;br /&gt;
(*find crossing where a strand label enters*)&lt;br /&gt;
findEnteringVertex[link_, s_] := &lt;br /&gt;
  Module[{crossingsContainingS, firstCrossing, pos},&lt;br /&gt;
   (*find crossings containing s*)&lt;br /&gt;
   crossingsContainingS = &lt;br /&gt;
    Select[link, IntegerQ[strandAtCrossing[#, s]] &amp;amp;];&lt;br /&gt;
   firstCrossing = crossingsContainingS[[1]];&lt;br /&gt;
   pos = strandAtCrossing[firstCrossing, s];&lt;br /&gt;
   Which[&lt;br /&gt;
    (*if pos is 1, then it is definitely an incoming strand*)&lt;br /&gt;
    pos == 1,&lt;br /&gt;
    firstCrossing,&lt;br /&gt;
    (pos == 2 &amp;amp;&amp;amp; ! &lt;br /&gt;
        orientationOfOverStrand[firstCrossing, link]) || (pos == 4 &amp;amp;&amp;amp; &lt;br /&gt;
       orientationOfOverStrand[firstCrossing, link]),&lt;br /&gt;
    firstCrossing,&lt;br /&gt;
    (*otherwise it must be the entering strand at the other vertex \&lt;br /&gt;
containing that label*)&lt;br /&gt;
    True,&lt;br /&gt;
    crossingsContainingS[[2]]&lt;br /&gt;
    ]&lt;br /&gt;
   ];&lt;br /&gt;
increaseStrandLabels[link_, s_] := &lt;br /&gt;
  Replace[link, n_?(# &amp;gt; s &amp;amp;) -&amp;gt; n + 1, {2}];&lt;br /&gt;
decreaseStrandLabels[link_, s_] := &lt;br /&gt;
  Replace[link, n_?(# &amp;gt; s &amp;amp;) -&amp;gt; n - 1, {2}];&lt;br /&gt;
(*duplicate a crossing*)&lt;br /&gt;
duplicateVertex[link_, crossing_, strands_] := &lt;br /&gt;
  Module[{pos = strandAtCrossing[crossing, strands[[1]]], &lt;br /&gt;
    newLabel = Length[link]*2 + 2, &lt;br /&gt;
    newLink = DeleteElements[link, {crossing}], p1 = crossing[[1]], &lt;br /&gt;
    p2 = crossing[[2]], p3 = crossing[[3]], p4 = crossing[[4]]},&lt;br /&gt;
   Which[&lt;br /&gt;
    (*pos is 1 and the upper strand is oriented from 4 to 2*)&lt;br /&gt;
    pos == 1  &amp;amp;&amp;amp; orientationOfOverStrand[crossing, link],&lt;br /&gt;
    {Union[&lt;br /&gt;
      increaseStrandLabels[newLink, p4],&lt;br /&gt;
      PD[&lt;br /&gt;
       X[If[p1 &amp;lt; p2, p1, p1 + 1], p4 + 1, If[p3 &amp;lt; p2, p3, p3 + 1], &lt;br /&gt;
        p4]],&lt;br /&gt;
      PD[X[newLabel, If[p2 &amp;gt; p4, p2 + 1, p2], newLabel + 1, p4 + 1]]&lt;br /&gt;
      ],&lt;br /&gt;
     Map[If[# &amp;lt;= p2, #, # + 1] &amp;amp;, Prepend[strands[[2 ;;]], p3]]&lt;br /&gt;
     },&lt;br /&gt;
    (*pos is 1 and the upper strand is oriented from 2 to 4*)&lt;br /&gt;
    pos == 1,&lt;br /&gt;
    {Union[&lt;br /&gt;
      increaseStrandLabels[newLink, p2],&lt;br /&gt;
      PD[&lt;br /&gt;
       X[If[p1 &amp;lt; p2, p1, p1 + 1], p2 + 1, If[p3 &amp;lt; p2, p3, p3 + 1], &lt;br /&gt;
        If[p4 &amp;lt; p2, p4, p4 + 1]]],&lt;br /&gt;
      PD[X[newLabel, p2, newLabel + 1, p2 + 1]]&lt;br /&gt;
      ],&lt;br /&gt;
     Map[If[# &amp;lt;= p2, #, # + 1] &amp;amp;, Prepend[strands[[2 ;;]], p3]]&lt;br /&gt;
     },&lt;br /&gt;
    (*pos is 2*)&lt;br /&gt;
    pos == 2,&lt;br /&gt;
    {Union[&lt;br /&gt;
      increaseStrandLabels[newLink, p1],&lt;br /&gt;
      PD[&lt;br /&gt;
       X[p1, If[p2 &amp;lt; p1, p2, p2 + 1], p1 + 1, &lt;br /&gt;
        If[p4 &amp;lt; p1, p4, p4 + 1]]],&lt;br /&gt;
      PD[X[p1 + 1, newLabel, If[p3 &amp;lt; p1, p3, p3 + 1], newLabel + 1]]&lt;br /&gt;
      ],&lt;br /&gt;
     Map[If[# &amp;lt;= p1, #, # + 1] &amp;amp;, Prepend[strands[[2 ;;]], p4]]&lt;br /&gt;
     },&lt;br /&gt;
    (*pos is 4*)&lt;br /&gt;
    True,&lt;br /&gt;
    {Union[&lt;br /&gt;
      increaseStrandLabels[newLink, p1],&lt;br /&gt;
      PD[&lt;br /&gt;
       X[p1 + 1, If[p2 &amp;lt; p1, p2, p2 + 1], If[p3 &amp;lt; p1, p3, p3 + 1], &lt;br /&gt;
        If[p4 &amp;lt; p1, p4, p4 + 1]]],&lt;br /&gt;
      PD[X[p1, newLabel + 1, p1 + 1, newLabel]]&lt;br /&gt;
      ],&lt;br /&gt;
     Map[If[# &amp;lt;= p1, #, # + 1] &amp;amp;, Prepend[strands[[2 ;;]], p2]]&lt;br /&gt;
     }&lt;br /&gt;
    ]&lt;br /&gt;
   ];&lt;br /&gt;
(*delete a crossing*)&lt;br /&gt;
deleteVertex[link_, crossing_, s_, strandList_] := &lt;br /&gt;
 Module[{newCrossing = crossing, &lt;br /&gt;
   newLink = DeleteElements[link, {crossing}], min, max, &lt;br /&gt;
   pos = strandAtCrossing[crossing, s], outgoingStrandPos, &lt;br /&gt;
   newStrandList = strandList},&lt;br /&gt;
  (*we create an unknot if the two labels of the other strand at the \&lt;br /&gt;
crossing are equal*)&lt;br /&gt;
  Which[(pos == 1 &amp;amp;&amp;amp; crossing[[2]] == crossing[[4]]) , &lt;br /&gt;
   newStrandList = &lt;br /&gt;
    Replace[newStrandList, &lt;br /&gt;
     crossing[[2]] -&amp;gt; 0, {1}], (pos == 2 || pos == 4 ) &amp;amp;&amp;amp; &lt;br /&gt;
    crossing[[1]] == crossing[[3]], &lt;br /&gt;
   newStrandList = Replace[newStrandList, crossing[[1]] -&amp;gt; 0, {1}]];&lt;br /&gt;
  (*&amp;quot;&lt;br /&gt;
	we need to keep track of the outgoing strand label. There&#039;s actually \&lt;br /&gt;
two ways to know we&#039;re done:&lt;br /&gt;
	either the outgoing strand is the same as the incoming strand, or \&lt;br /&gt;
the whole vertex only involves 2 different labels.&lt;br /&gt;
&amp;quot;*)&lt;br /&gt;
  outgoingStrandPos = Which[pos == 1, 3, pos == 2, 4, True, 2];&lt;br /&gt;
  If[crossing[[outgoingStrandPos]] == s || &lt;br /&gt;
    CountDistinct[{Delete[crossing, 0]}] &amp;lt; 3, &lt;br /&gt;
   outgoingStrandPos = -1];&lt;br /&gt;
  (*adjust link after combining pos 1 and pos 3*)&lt;br /&gt;
  If[crossing[[1]] &amp;gt; crossing[[3]],&lt;br /&gt;
   newLink = &lt;br /&gt;
    decreaseStrandLabels[&lt;br /&gt;
     Replace[newLink, crossing[[1]] -&amp;gt; crossing[[3]], {2}], &lt;br /&gt;
     newCrossing[[1]]];&lt;br /&gt;
   newCrossing = &lt;br /&gt;
    decreaseStrandLabels[{Replace[newCrossing, &lt;br /&gt;
        crossing[[1]] -&amp;gt; crossing[[3]], {1}]}, &lt;br /&gt;
      newCrossing[[1]]][[1]];&lt;br /&gt;
   newStrandList = &lt;br /&gt;
    Map[If[# &amp;gt; newCrossing[[1]], # - 1, #] &amp;amp;, &lt;br /&gt;
     Replace[newStrandList, crossing[[1]] -&amp;gt; crossing[[3]], {1}]]&lt;br /&gt;
   ,&lt;br /&gt;
   newLink = decreaseStrandLabels[newLink, newCrossing[[1]]];&lt;br /&gt;
   newCrossing = &lt;br /&gt;
    decreaseStrandLabels[{newCrossing}, newCrossing[[1]]][[1]];&lt;br /&gt;
   newStrandList = &lt;br /&gt;
    Map[If[# &amp;gt; newCrossing[[1]], # - 1, #] &amp;amp;, newStrandList]&lt;br /&gt;
   ];&lt;br /&gt;
  (*adjust link after combining pos 2 and pos 4*)&lt;br /&gt;
  min = Min[newCrossing[[2]], newCrossing[[4]]];&lt;br /&gt;
  max = Max[newCrossing[[2]], newCrossing[[4]]];&lt;br /&gt;
  If[max - min &amp;gt; 1,&lt;br /&gt;
   newLink = &lt;br /&gt;
    decreaseStrandLabels[Replace[newLink, max -&amp;gt; min, {2}], max];&lt;br /&gt;
   newCrossing = &lt;br /&gt;
    decreaseStrandLabels[{Replace[newCrossing, max -&amp;gt; min, {1}]}, &lt;br /&gt;
      max][[1]];&lt;br /&gt;
   newStrandList = &lt;br /&gt;
    Map[If[# &amp;gt; max, # - 1, #] &amp;amp;, &lt;br /&gt;
     Replace[newStrandList, max -&amp;gt; min, {1}]],&lt;br /&gt;
   newLink = decreaseStrandLabels[newLink, min];&lt;br /&gt;
   newCrossing = decreaseStrandLabels[{newCrossing}, min][[1]];&lt;br /&gt;
   newStrandList = Map[If[# &amp;gt; max, # - 1, #] &amp;amp;, newStrandList]&lt;br /&gt;
   ];&lt;br /&gt;
  {newLink, &lt;br /&gt;
   If[outgoingStrandPos &amp;gt; 0, newCrossing[[outgoingStrandPos]], -1], &lt;br /&gt;
   newStrandList}&lt;br /&gt;
  ]&lt;br /&gt;
cableComponent[link_, s_, strandList_] := &lt;br /&gt;
  Module[{initialStrands, newComponentLabel = 2 Length[link] + 1},&lt;br /&gt;
   initialStrands = Join[{s, s, newComponentLabel}, strandList];&lt;br /&gt;
   recurse[newLink_, strands_] := &lt;br /&gt;
    Module[{currentStrand = strands[[1]], firstStrand = strands[[2]], &lt;br /&gt;
      currentCrossing, updatedLink, &lt;br /&gt;
      updatedStrands},(*copy the current crossing*)&lt;br /&gt;
     currentCrossing = findEnteringVertex[newLink, currentStrand];&lt;br /&gt;
     {updatedLink, updatedStrands} = &lt;br /&gt;
      duplicateVertex[newLink, currentCrossing, strands];&lt;br /&gt;
     (*check if we&#039;ve returned to the first strand*)&lt;br /&gt;
     If[updatedStrands[[1]] == updatedStrands[[2]],&lt;br /&gt;
      (*replace the largest strand label with the first strand label \&lt;br /&gt;
of the new component*)&lt;br /&gt;
      {Replace[updatedLink, &lt;br /&gt;
        n_?(# == 2 Length[updatedLink] + 1 &amp;amp;) -&amp;gt; &lt;br /&gt;
         updatedStrands[[3]], {2}], &lt;br /&gt;
       updatedStrands[[4 ;;]]},(*keep adding crossings*)&lt;br /&gt;
      recurse[updatedLink, updatedStrands]]&lt;br /&gt;
     ];&lt;br /&gt;
   recurse[link, initialStrands]&lt;br /&gt;
   ];&lt;br /&gt;
deleteComponent[link_, s_, strandList_] := &lt;br /&gt;
  Module[{newLink, currentStrand, newStrandList, currentCrossing},&lt;br /&gt;
   If[s &amp;lt;= 0,&lt;br /&gt;
    (*we&#039;re done deleting stuff*)&lt;br /&gt;
    {link, strandList},&lt;br /&gt;
    (*keep deleting*)&lt;br /&gt;
    currentCrossing = findEnteringVertex[link, s];&lt;br /&gt;
    {newLink, currentStrand, newStrandList} = &lt;br /&gt;
     deleteVertex[link, currentCrossing, s, strandList];&lt;br /&gt;
    deleteComponent[newLink, currentStrand, newStrandList]&lt;br /&gt;
    ]&lt;br /&gt;
   ];&lt;br /&gt;
cableLinkMonomial[link_, strandList_, degreeList_] := &lt;br /&gt;
  Module[{newLink = link, newStrandList, newDegreeList, coeff = 1},&lt;br /&gt;
   (*reorder so that we&#039;re deleting components first*)&lt;br /&gt;
   {newDegreeList, newStrandList} = {degreeList, strandList}[[All, &lt;br /&gt;
     Ordering@degreeList]];&lt;br /&gt;
   (*start cabling*)&lt;br /&gt;
   Do[&lt;br /&gt;
    Which[&lt;br /&gt;
     newStrandList[[i]] == 0,&lt;br /&gt;
     (*it&#039;s an unknot*)&lt;br /&gt;
     coeff = coeff*(-A^2 - A^(-2))^newDegreeList[[i]],&lt;br /&gt;
     newDegreeList[[i]] == 0,&lt;br /&gt;
     (*we need to delete it*)&lt;br /&gt;
     {newLink, newStrandList} = &lt;br /&gt;
      deleteComponent[newLink, newStrandList[[i]], newStrandList],&lt;br /&gt;
     True,&lt;br /&gt;
     (*cable the component*)&lt;br /&gt;
     Do[&lt;br /&gt;
      {newLink, newStrandList} = &lt;br /&gt;
       cableComponent[newLink, newStrandList[[i]], newStrandList]&lt;br /&gt;
      , {j, 1, newDegreeList[[i]] - 1}]&lt;br /&gt;
     ]&lt;br /&gt;
    , {i, 1, Length[newStrandList]}&lt;br /&gt;
    ];&lt;br /&gt;
   coeff*KB1[newLink]&lt;br /&gt;
   ];&lt;br /&gt;
cableLink[link_, poly_, strandList_, vars_] := &lt;br /&gt;
 Module[{monomials = CoefficientRules[poly, vars], temp},&lt;br /&gt;
  Total[&lt;br /&gt;
   Map[&lt;br /&gt;
    #[[2]]*cableLinkMonomial[link, strandList, #[[1]]] &amp;amp;&lt;br /&gt;
    , monomials]]&lt;br /&gt;
  ]&lt;/div&gt;</summary>
		<author><name>Sam.panitch</name></author>
	</entry>
	<entry>
		<id>https://katlas.org/index.php?title=Template:Manual_TOC_Sidebar2&amp;diff=1725842</id>
		<title>Template:Manual TOC Sidebar2</title>
		<link rel="alternate" type="text/html" href="https://katlas.org/index.php?title=Template:Manual_TOC_Sidebar2&amp;diff=1725842"/>
		<updated>2025-08-05T21:15:22Z</updated>

		<summary type="html">&lt;p&gt;Sam.panitch: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;[[Image:Stop_hand.png]] Warning! Any changes you make here should also be reflected in the [[Printable Manual]]! Please remember to go there and make the appropriate changes.&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
{| cellpadding=&amp;quot;0&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=240 style=&amp;quot;clear: right; float: right&amp;quot;&lt;br /&gt;
|- align=left&lt;br /&gt;
|&amp;lt;div class=&amp;quot;NavFrame&amp;quot;&amp;gt;&amp;lt;div class=&amp;quot;NavHead&amp;quot;&amp;gt;[[KnotTheory`]]/[[Template:Manual TOC Sidebar2|Navigation]]&amp;amp;nbsp;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;NavContent&amp;quot; style=&amp;quot;text-align: left&amp;quot;&amp;gt;&lt;br /&gt;
[[The Mathematica Package KnotTheory`]]&lt;br /&gt;
* [[Acknowledgement]]&lt;br /&gt;
* [[Setup]]&lt;br /&gt;
* [[Naming and Enumeration]]&lt;br /&gt;
* [[Presentations]]&lt;br /&gt;
** [[Planar Diagrams]]&lt;br /&gt;
*** [[Planar Diagrams#Some further details|Some further details]]&lt;br /&gt;
** [[Gauss Codes]]&lt;br /&gt;
** [[DT (Dowker-Thistlethwaite) Codes]]&lt;br /&gt;
** [[Braid Representatives]]&lt;br /&gt;
** [[MorseLink Presentations]]&lt;br /&gt;
** [[Arc Presentations]]&lt;br /&gt;
** [[Conway Notation]]&lt;br /&gt;
* [[Graphical Input]]&lt;br /&gt;
* [[Graphical Output]]&lt;br /&gt;
** [[Drawing Planar Diagrams]]&lt;br /&gt;
*** [[Drawing Planar Diagrams#How does it work?|How does it work?]] &lt;br /&gt;
** [[Drawing MorseLink Presentations]]&lt;br /&gt;
** [[Drawing Braids]]&lt;br /&gt;
* [[Structure and Operations]]&lt;br /&gt;
* [[Invariants]]&lt;br /&gt;
** [[Invariants from Braid Theory]]&lt;br /&gt;
** [[Three Dimensional Invariants]]&lt;br /&gt;
** [[The Alexander-Conway Polynomial]]&lt;br /&gt;
** [[The Multivariable Alexander Polynomial]]&lt;br /&gt;
** [[The Determinant and the Signature]]&lt;br /&gt;
** [[The Jones Polynomial]]&lt;br /&gt;
*** [[The Jones Polynomial#How is the Jones polynomial computed?|How is the Jones polynomial computed?]]&lt;br /&gt;
** [[The Coloured Jones Polynomials]]&lt;br /&gt;
** [[The A2 Invariant]]&lt;br /&gt;
** [[Quantum knot invariants]]&lt;br /&gt;
** [[The HOMFLY-PT Polynomial]]&lt;br /&gt;
** [[The Kauffman Polynomial]]&lt;br /&gt;
** [[Finite Type (Vassiliev) Invariants]]&lt;br /&gt;
** [[Khovanov Homology]]&lt;br /&gt;
** [[Heegaard Floer Knot Homology]]&lt;br /&gt;
** [[R-Matrix Invariants]]&lt;br /&gt;
* [[Extras Included with KnotTheory`]]&lt;br /&gt;
** [[Drawing with TubePlot]]&lt;br /&gt;
*** [[Drawing with TubePlot#Standalone TubePlot|Standalone_TubePlot]]&lt;br /&gt;
** [[Using the LinKnot package]]&lt;br /&gt;
** [[WikiLink]]&lt;br /&gt;
** [[QuantumGroups`]]&lt;br /&gt;
* [[Lightly Documented Features]]&lt;br /&gt;
* [[A Sample KnotTheory` Session]]&lt;br /&gt;
* [[Further Usage Example]]&lt;br /&gt;
** [[Prime Links with a Non-Prime Component]]&lt;br /&gt;
** [[&amp;quot;Rubberband&amp;quot; Brunnian Links]]&lt;br /&gt;
** [[Identifying Knots within a List]]&lt;br /&gt;
** [[Cabling]]&lt;br /&gt;
** [[Burau&#039;s  Theorem]]&lt;br /&gt;
** [[Threading a link by a polynomial]]&lt;br /&gt;
* [[Further Knot Theory Software]]&lt;br /&gt;
** [[Further Knot Theory Software#KnotPlot|KnotPlot]]&lt;br /&gt;
** [[Further Knot Theory Software#Knotscape|Knotscape]]&lt;br /&gt;
** [[Further Knot Theory Software#Xknots|Xknots]]&lt;br /&gt;
* [[Extending/Modifying KnotTheory`|Extending/Modifying &amp;lt;code&amp;gt;KnotTheory`&amp;lt;/code&amp;gt;]]&lt;br /&gt;
* [[Bugs]]&lt;br /&gt;
* [[How to Edit this Manual...]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Sam.panitch</name></author>
	</entry>
	<entry>
		<id>https://katlas.org/index.php?title=Threading_a_link_by_a_polynomial&amp;diff=1725841</id>
		<title>Threading a link by a polynomial</title>
		<link rel="alternate" type="text/html" href="https://katlas.org/index.php?title=Threading_a_link_by_a_polynomial&amp;diff=1725841"/>
		<updated>2025-08-05T21:13:00Z</updated>

		<summary type="html">&lt;p&gt;Sam.panitch: Created page with &amp;quot;&amp;lt;code&amp;gt;cableLink[link,poly,strandList,vars]&amp;lt;/code&amp;gt;, whose code is available here, computes the Kauffman bracket of link (given as a PD) with components L1,L2,...,Ln, cabled by the polynomial poly in the variables z1,z2,...,zn. strandList is a list of strand labels of length n, where the ith element is the first strand label corresponding to component Li. As an example, we can verify some formulas from Mausbaum: &amp;lt;!--$$Import[&amp;quot;http://katlas.org/w/index.php?t...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;code&amp;gt;cableLink[link,poly,strandList,vars]&amp;lt;/code&amp;gt;, whose code is available [[cableLink.m|here]], computes the Kauffman bracket of link (given as a PD) with components L1,L2,...,Ln, cabled by the polynomial poly in the variables z1,z2,...,zn. strandList is a list of strand labels of length n, where the ith element is the first strand label corresponding to component Li.&lt;br /&gt;
As an example, we can verify some formulas from Mausbaum:&lt;br /&gt;
&amp;lt;!--$$Import[&amp;quot;http://katlas.org/w/index.php?title=CableComponent.m&amp;amp;action=raw&amp;quot;];$$--&amp;gt;&lt;br /&gt;
&amp;lt;!--END--&amp;gt;&lt;br /&gt;
&amp;lt;!--$$CableComponent[BR[3, {1, 2}], Knot[3, 1]] // DrawMorseLink$$--&amp;gt;&lt;br /&gt;
&amp;lt;!--END--&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sam.panitch</name></author>
	</entry>
	<entry>
		<id>https://katlas.org/index.php?title=Printable_Manual&amp;diff=1725839</id>
		<title>Printable Manual</title>
		<link rel="alternate" type="text/html" href="https://katlas.org/index.php?title=Printable_Manual&amp;diff=1725839"/>
		<updated>2025-08-05T21:12:02Z</updated>

		<summary type="html">&lt;p&gt;Sam.panitch: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!-- Warning! It&#039;s important that we keep this page synchronised with [[Manual Table of Contents]]. --&amp;gt;&lt;br /&gt;
&amp;lt;!-- If you&#039;ve added something there, make sure to make the corresponding change here. --&amp;gt;&lt;br /&gt;
&amp;lt;!-- Entries on [[Manual Table of Contents]] which point to a section of a page should *not* be listed here, --&amp;gt;&lt;br /&gt;
&amp;lt;!--    because that section will have already been transcluded as part of its containing page. --&amp;gt;&lt;br /&gt;
&amp;lt;!-- The levels indicated by * and ** on [[Manual Table of Contents]] are reflected here by the heading level below. --&amp;gt;&lt;br /&gt;
&amp;lt;!--    For example,&lt;br /&gt;
&amp;lt;!--       * [[Presentations]]&lt;br /&gt;
           ** [[Planar Diagrams ]]&lt;br /&gt;
        Becomes&lt;br /&gt;
           ==Presentations==&lt;br /&gt;
           {{:Presentations}}&lt;br /&gt;
           ===Planar Diagrams===&lt;br /&gt;
           {{:Planar Diagrams}}&lt;br /&gt;
        in the page below.&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
__NOEDITSECTION__&lt;br /&gt;
&lt;br /&gt;
[[Image:KnotTheory 240.gif|frame|[[Setup|Download / Setup]]]]&lt;br /&gt;
&lt;br /&gt;
This manual describes the [http://www.wolfram.com/ Mathematica] package KnotTheory`, the main tool used to produce The Knot Atlas.&lt;br /&gt;
&lt;br /&gt;
Return to the wiki [[The Mathematica Package KnotTheory`|manual]].&lt;br /&gt;
&lt;br /&gt;
==Acknowledgement==&lt;br /&gt;
{{:Acknowledgement}}&lt;br /&gt;
==Setup==&lt;br /&gt;
{{:Setup}}&lt;br /&gt;
==Naming and Enumeration==&lt;br /&gt;
{{:Naming and Enumeration}}&lt;br /&gt;
==Presentations==&lt;br /&gt;
{{:Presentations}}&lt;br /&gt;
===Planar Diagrams===&lt;br /&gt;
{{:Planar Diagrams}}&lt;br /&gt;
===Gauss Codes===&lt;br /&gt;
{{:Gauss Codes}}&lt;br /&gt;
===DT (Dowker-Thistlethwaite) Codes===&lt;br /&gt;
{{:DT (Dowker-Thistlethwaite) Codes}}&lt;br /&gt;
===Braid Representatives===&lt;br /&gt;
{{:Braid Representatives}}&lt;br /&gt;
===MorseLink Presentations===&lt;br /&gt;
{{:MorseLink Presentations}}&lt;br /&gt;
===Arc Presentations===&lt;br /&gt;
{{:Arc Presentations}}&lt;br /&gt;
===Conway Notation===&lt;br /&gt;
{{:Conway Notation}}&lt;br /&gt;
==Graphical Input==&lt;br /&gt;
{{:Graphical Input}}&lt;br /&gt;
==Graphical Output==&lt;br /&gt;
{{:Graphical Output}}&lt;br /&gt;
===Drawing Planar Diagrams===&lt;br /&gt;
{{:Drawing Planar Diagrams}}&lt;br /&gt;
===Drawing MorseLink Presentations===&lt;br /&gt;
{{:Drawing MorseLink Presentations}}&lt;br /&gt;
===Drawing Braids===&lt;br /&gt;
{{:Drawing Braids}}&lt;br /&gt;
==Structure and Operations==&lt;br /&gt;
{{:Structure and Operations}}&lt;br /&gt;
==Invariants==&lt;br /&gt;
{{:Invariants}}&lt;br /&gt;
===Invariants from Braid Theory===&lt;br /&gt;
{{:Invariants from Braid Theory}}&lt;br /&gt;
===Three Dimensional Invariants===&lt;br /&gt;
{{:Three Dimensional Invariants}}&lt;br /&gt;
===The Alexander-Conway Polynomial===&lt;br /&gt;
{{:The Alexander-Conway Polynomial}}&lt;br /&gt;
===The Multivariable Alexander Polynomial===&lt;br /&gt;
{{:The Multivariable Alexander Polynomial}}&lt;br /&gt;
===The Determinant and the Signature===&lt;br /&gt;
{{:The Determinant and the Signature}}&lt;br /&gt;
===The Jones Polynomial===&lt;br /&gt;
{{:The Jones Polynomial}}&lt;br /&gt;
===The Coloured Jones Polynomials===&lt;br /&gt;
{{:The Coloured Jones Polynomials}}&lt;br /&gt;
===The A2 Invariant===&lt;br /&gt;
{{:The A2 Invariant}}&lt;br /&gt;
===Quantum knot invariants===&lt;br /&gt;
{{:Quantum knot invariants}}&lt;br /&gt;
===The HOMFLY-PT Polynomial===&lt;br /&gt;
{{:The HOMFLY-PT Polynomial}}&lt;br /&gt;
===The Kauffman Polynomial===&lt;br /&gt;
{{:The Kauffman Polynomial}}&lt;br /&gt;
===Finite Type (Vassiliev) Invariants===&lt;br /&gt;
{{:Finite Type (Vassiliev) Invariants}}&lt;br /&gt;
===Khovanov Homology===&lt;br /&gt;
{{:Khovanov Homology}}&lt;br /&gt;
===Heegaard Floer Knot Homology===&lt;br /&gt;
{{:Heegaard Floer Knot Homology}}&lt;br /&gt;
===R-Matrix Invariants===&lt;br /&gt;
{{:R-Matrix Invariants}}&lt;br /&gt;
==Extras Included with KnotTheory`==&lt;br /&gt;
{{:Extras Included with KnotTheory`}}&lt;br /&gt;
===Drawing with TubePlot===&lt;br /&gt;
{{:Drawing with TubePlot}}&lt;br /&gt;
===Using the LinKnot package===&lt;br /&gt;
{{:Using the LinKnot package}}&lt;br /&gt;
===WikiLink===&lt;br /&gt;
{{:WikiLink}}&lt;br /&gt;
===QuantumGroups`===&lt;br /&gt;
{{:QuantumGroups`}}&lt;br /&gt;
==Lightly Documented Features==&lt;br /&gt;
{{:Lightly Documented Features}}&lt;br /&gt;
==A Sample KnotTheory` Session==&lt;br /&gt;
{{:A Sample KnotTheory` Session}}&lt;br /&gt;
==Further Usage Example==&lt;br /&gt;
{{:Further Usage Example}}&lt;br /&gt;
===Prime Links with a Non-Prime Component===&lt;br /&gt;
{{:Prime Links with a Non-Prime Component}}&lt;br /&gt;
===&amp;quot;Rubberband&amp;quot; Brunnian Links===&lt;br /&gt;
{{:&amp;quot;Rubberband&amp;quot; Brunnian Links}}&lt;br /&gt;
===Identifying Knots within a List===&lt;br /&gt;
{{:Identifying Knots within a List}}&lt;br /&gt;
===Cabling===&lt;br /&gt;
{{:Cabling}}&lt;br /&gt;
===Burau&#039;s Theorem===&lt;br /&gt;
{{:Burau&#039;s Theorem}}&lt;br /&gt;
===Threading a link by a polynomial===&lt;br /&gt;
{{:Threading a link by a polynomial}}&lt;br /&gt;
==Further Knot Theory Software==&lt;br /&gt;
{{:Further Knot Theory Software}}&lt;br /&gt;
==Extending/Modifying &amp;lt;code&amp;gt;KnotTheory`&amp;lt;/code&amp;gt;==&lt;br /&gt;
{{:Extending/Modifying KnotTheory`}}&lt;br /&gt;
==Bugs==&lt;br /&gt;
{{:Bugs}}&lt;br /&gt;
==How to Edit this Manual...==&lt;br /&gt;
{{:How to Edit this Manual...}}&lt;/div&gt;</summary>
		<author><name>Sam.panitch</name></author>
	</entry>
</feed>