{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "##This code computes various d invariants of large surgery, as well as the invariants Y_c\n", "##There are two classes, CF and CFKinfty\n", "##The class CF is a class which represents a free f.g. chain complex over F[U]\n", "## The class CFKinfty represents a knot-like chain complex resembing CFK-infty\n", "##The most important methods are\n", "##CFKinfty()### (to initialize)\n", "##Tensor([C_1,C_2,C_3,...,C_n])### (to tensor CFKinfty complexes together)\n", "##PrintYGrid(C)### computes and prints all the Y_{c,g} invariants\n", "##C.dual() computes the dual knot complex of a CFKinfty complex C\n", "\n", "\n", "\n", "\n", "class CF(object):\n", " #gen should be a list of Maslov gradings (of the generators over F[U])\n", " #diff is a list of lists, of the same length as gen.\n", " #e.g. [[],[1,2],[3],[]]. in diff[i] we put all of the indices of the intersection points such that there is \n", " # a nonzero differential from i to j (the U-powers are filled in later).\n", " # We assume that the complex inputted has HF^infty equal to one tower,\n", " # supported in even gradings\n", " def __init__(self,gen,diff):\n", " self.gen=gen\n", " self.diff=diff\n", " self.rank=len(gen)\n", " \n", " \n", " \n", "class CFKinfty(object):\n", " #gen should be a list of 3 element lists of the form [gr,i,j] represent the generators of CFK^infty.\n", " #An element [gr,i,j] represents x u^i v^j (so i and j are opposite from Ozsvath and Szabo's convention)\n", " #these are generators of the Alexander grading 0 version, so we assume that A(x)+j-i=0.\n", " #Here, gr is the Maslov (or homological) grading.\n", " #They can be any generators, so, e.g., incrementing i and j both by 1 is ok and has no effect.\n", " #diff is a list of lists, of the same length as gen.\n", " #diff[i] is a list of integers, and j is in diff[i] if and only if there is an arrow from i to j (with some weighting)\n", " #(The weighting need not be entered, since it is determined by the grading)\n", " #length of diff and gen should be equal.\n", " def __init__(self, gen, diff):\n", " self.gen=gen\n", " self.diff=diff\n", " self.rank=len(gen)\n", " #the following returns the generators and differential for CF of the large surgeries complex\n", " def AComplex(self,indexn):\n", " NewGens=[]\n", " for oldg in self.gen:\n", " oldgrading=oldg[0]\n", " indexi=oldg[1]\n", " indexj=oldg[2]\n", " newgrading=oldgrading+2*min(indexi,indexj+indexn)\n", " NewGens.append(newgrading)\n", " diffcopy=deepcopy(self.diff)\n", " Complex=CF(NewGens,diffcopy)\n", " return Complex\n", " def dual(self):\n", " NewGens=[[-x[0],-x[1],-x[2]] for x in self.gen]\n", " NewDiff=[[] for i in range(self.rank)]\n", " for i in range(self.rank):\n", " for j in self.diff[i]:\n", " NewDiff[j].append(i)\n", " return CFKinfty(NewGens,NewDiff)\n", " \n", "#input CFK^infty-cx\n", "#output is a CF-minus cx\n", "#n>=0 assumed\n", "#could instead just tensor C with S_{-n} (negative staircase with n length 1 steps)\n", "def StairCaseCx(C, n):\n", " if n==0:\n", " return C.AComplex(0)\n", " #henceforth we assume n>0\n", " OldGens=C.gen\n", " OldDiff=C.diff\n", " NewGens=[]\n", " rank=C.rank\n", " NewDiff=[[] for x in range((2*n+1)*rank)]\n", " #i enumerates all of the summands of S-n\n", " for i in range(2*n+1):\n", " #i in this range corresponds to the summand A_{-n+i}, so we set s=-n+i\n", " s=n-i\n", " for x in OldGens:\n", " #we now add generators, with shifts in grading as in AComplex, as well as with the formal shifts\n", " grnew=x[0]+2*min(x[1],x[2]+s)-s+n\n", " NewGens.append(grnew)\n", " for j in range(rank):\n", " for y in C.diff[j]:\n", " #add the internal differentials\n", " NewDiff[i*rank+j].append(i*rank+y)\n", " #we now add the cone arrows to A_n (left most)\n", " for i in range(rank):\n", " NewDiff[i].append(i+rank)\n", " # now add the cone arrows for the right most arrow A_{-n}\n", " for i in range(rank):\n", " NewDiff[(2*n)*rank+i].append((2*n-1)*rank+i)\n", " for i in range(1,n):\n", " #we now add the remaining cone arrows\n", " for j in range(rank):\n", " NewDiff[2*i*rank+j].append((2*i-1)*rank+j)\n", " NewDiff[2*i*rank+j].append((2*i+1)*rank+j)\n", " return CF(NewGens,NewDiff)\n", "\n", "# Input is a CFK-infty complex and an integer n. Output is the CF complex A_n\n", "def AComplex(C,n):\n", " return C.AComplex(n)\n", " \n", " \n", "#input is two CFKinfty complexes\n", "#Output is their knot-tensor product.\n", "#NOTE: There is a function which tensors a list of CFK complexes together (As many as one likes)\n", "#See the function Tensor, below\n", "def Tensor2(C1,C2):\n", " gen1=C1.gen\n", " gen2=C2.gen\n", " diff1=C1.diff\n", " diff2=C2.diff\n", " rank1=C1.rank\n", " rank2=C2.rank\n", " newGens=[]\n", " newDiffs=[[] for x in range(rank1*rank2)]\n", " for i in range(rank1):\n", " gi=gen1[i]\n", " for j in range(rank2):\n", " gj=gen2[j]\n", " gigj=[sum(x) for x in zip(gi, gj)]\n", " newGens.append(gigj)\n", " for k in diff1[i]:\n", " newDiffs[i*rank2+j].append(k*rank2+j)\n", " for m in diff2[j]:\n", " newDiffs[i*rank2+j].append(i*rank2+m)\n", " return CFKinfty(newGens,newDiffs)\n", "\n", "#input is a knot complex, output is V_0,V_1,V_2,...\n", "def Vlist(C):\n", " VInvariants=[]\n", " Index=0\n", " VInvariants.append(-d(C.AComplex(0))/2)\n", " while(not VInvariants[-1]== 0):\n", " Index=Index+1\n", " VInvariants.append(-d(C.AComplex(Index))/2)\n", " return VInvariants\n", "\n", "# Outputs a list of the Y, similar to Vlist.\n", "def Ylist(C):\n", " YInvariants=[]\n", " Index=0\n", " YInvariants.append(-d(StairCaseCx(C,0))/2)\n", " while(not YInvariants[-1]== 0):\n", " Index=Index+1\n", " YInvariants.append(-d(StairCaseCx(C,Index))/2)\n", " return YInvariants\n", " \n", "\n", "#input is a list of CFKinfty complexes, e.g. Tensor([C_1,C_2,C_3,...,C_n])\n", "def Tensor(Complexes):\n", " if len(Complexes)==1:\n", " return Complexes[0]\n", " C=Complexes[0]\n", " for j in range(1, len(Complexes)):\n", " C=Tensor2(C,Complexes[j])\n", " return C\n", " \n", "\n", "#The following is a helper function:\n", "#takes a list and deletes elements that appear twice (and leaves one if they appear an odd number of times)\n", "def mod2(L):\n", " K=deepcopy(L)\n", " for x in K:\n", " if L.count(x)>1:\n", " L.remove(x)\n", " L.remove(x)\n", " return L\n", " \n", "\n", "#The following is a helper function:\n", "#Input is old differential\n", "#outputs new differential\n", "#note, this changes the old differential\n", "#We assume that x_i and x_j have the same parity\n", "#We assume g(x_j)>g(x_i)\n", "#The change of basis is that x_i is replaced by x_i+U^k x_j\n", "#x_j is left the same\n", "def BasisChange(diff,i,j):\n", " #first changes differentials going to i an j\n", " for x in diff:\n", " if i in x:\n", " x.append(j)\n", " mod2(x)\n", " for y in diff[j]:\n", " diff[i].append(y)\n", " mod2(diff[i])\n", " return diff\n", "\n", "#The following is a helper function:\n", "#The following deletes all arrows with a power of U^i, where i=power\n", "# It does this via a change of basis, and then deleting 2 step complexes\n", "#Note, the program assumes that there are no arrows weighted by U^n for n1:\n", " BasisChange(Diff, ySpecial,Diff[x][0])\n", " for xOther in range(rank):\n", " if ySpecial in Diff[xOther] and not xOther==x:\n", " BasisChange(Diff, xOther,x)\n", " toDelete.append(ySpecial)\n", " toDelete.append(x)\n", " toDelete.sort(reverse=True)\n", " # deletes all the entries of toDelete, and shifts Diff correctly each time\n", " for i in toDelete:\n", " del Diff[i]\n", " del Gen[i]\n", " for Dxs in Diff:\n", " for j in range(len(Dxs)):\n", " if Dxs[j]>i:\n", " Dxs[j]=Dxs[j]-1\n", " \n", "#input is a CF complex\n", "def d(C):\n", " Diff=deepcopy(C.diff)\n", " Gen=deepcopy(C.gen)\n", " power=0\n", " while(len(Diff)>1):\n", " DeleteArrows(Diff,Gen,power)\n", " power=power+1\n", " return Gen[0]\n", "\n" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "T23Gens=[[-2,0,1],[-2,1,0],[-1,0,0]]\n", "T23Diff=[[],[],[0,1]]\n", "T23=CFKinfty(T23Gens,T23Diff)\n", "\n", "Fig8Gens=[[0,0,0],[-1,0,1],[-1,1,0],[0,0,0],[0,0,0]]\n", "Fig8Diff=[[1,2],[3],[3],[],[]]\n", "Fig8=CFKinfty(Fig8Gens,Fig8Diff)\n", "\n", "T38Gens=[[-14,7,0],[-13,6,0],[-14,6,2],[-13,5,2],[-14,5,4],[-13,4,4],[-14,4,5],[-13,2,5],[-14,2,6],[-13,0,6],[-14,0,7]]\n", "T38Diff=[[],[0,2],[],[2,4],[],[4,6],[],[6,8],[],[8,10],[]]\n", "T38=CFKinfty(T38Gens,T38Diff)\n", "\n", "T213Gens=[[-12,6,0],[-11,5,0],[-12,5,1],[-11,4,1],[-12,4,2],[-11,3,2],[-12,3,3],[-11,2,3],[-12,2,4],[-11,1,4],[-12,1,5],[-11,0,5],[-12,0,6]]\n", "T213Diff=[[],[0,2],[],[2,4],[],[4,6],[],[6,8],[],[8,10],[],[10,12],[]]\n", "T213=CFKinfty(T213Gens,T213Diff)\n", "\n", "T45Gens=[[-12,0,6],[-11,0,5],[-12,3,5],[-11,3,3],[-12,5,3],[-11,5,0],[-12,6,0]]\n", "T45Diff=[[],[0,2],[],[2,4],[],[4,6],[]]\n", "T45=CFKinfty(T45Gens,T45Diff)\n", "\n", "T56Gens=[[-20, 0, 10],[-19, 0, 9],[-20, 4, 9],[-19, 4, 7],[-20, 7, 7],[-19, 7, 4],[-20, 9, 4],[-19, 9, 0],[-20, 10, 0]]\n", "T56Diff=[[], [0, 2], [], [2, 4], [], [4, 6], [], [6, 8], []]\n", "T56=CFKinfty(T56Gens,T56Diff)\n" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[3, 3, 2, 2, 2, 1, 1, 1, 0]" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Vlist(Tensor([T23,T38]))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "SageMath 9.1", "language": "sage", "name": "sagemath" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.3" } }, "nbformat": 4, "nbformat_minor": 2 }