User:Ben/KRhomology

From Knot Atlas
< User:Ben
Revision as of 16:43, 28 November 2005 by Ben (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigationJump to search

So, here is my KR homology stuff.

Actual calculations

Here is a table of known KR homologies. We let be the Hilbert series of KR homology. Note that a factor of the Hilbert series of the unknot appears in all of them. This will not be true of links, I believe.

0_1
3_1
4_1
5_1
5_2
6_2


Macaulay2 program

Save this as a file (called KR.m2), open Macaulay2 (in command line or emacs), and type load "KR.m2". KRpoly is probabby the command you want (but it only works for knots at the moment). It outputs . Using texMath puts things in format for LaTeX.


Here's a sample session:

Macaulay 2, version 0.9
--Copyright 1993-2001, D. R. Grayson and M. E. Stillman
--Singular-Factory 1.3b, copyright 1993-2001, G.-M. Greuel, et al.
--Singular-Libfac 0.3.2, copyright 1996-2001, M. Messollen

i1 : load "KR.m2"
KR.m2:113:11: warning: local declaration of N shields variable with same name
--loaded KR.m2

i2 : texMath KRpoly K01

o2 = 1

i3 : texMath KRpoly K31

o3 = s^{2} t^{2}+{q} t^{2}+1

i4 : 

Here's the code for the program.

--KR.m2
--This file defines a new object for Macaulay2, called a "Link."
--Like all objects in Macaulay2, a Link is just a hash table.
--Defining a link lets you store information about it for later use.  

Link = new Type of MutableHashTable 
Link.synonym = "link"
new Link := Link => (cl) -> (
     C:=newClass(Link,new MutableHashTable);
     C)

--braidClosure is currently the only useful way of defining a link.  
--I think it should be clear from the examples below how to use it.
--(Remember to use {}, not () or [])
braidClosure = L ->(
     K=new Link;
     K#braid=L;
     K)

--This defines all links of 7 or fewer crossings by a braid closure.
K01=braidClosure {1};
K31=braidClosure {1,1,1};
K41=braidClosure {1,-2,1,-2};
K51=braidClosure {1,1,1,1,1};
K52=braidClosure {-1,-1,-2,1,-2};
K61=braidClosure {1,1,2,-1,-3,2,-3};
K62=braidClosure {-1,-1,-1,2,-1,2};
K63=braidClosure {-1,-1,2,-1,2,2};
K71=braidClosure {-1,-1,-1,-1,-1,-1,-1}
K72=braidClosure {-1,-1,-1,-2,1,-2,-3,2,-3}
K73=braidClosure {1,1,1,1,1,2,-1,2}
K74=braidClosure {1,1,2,-1,2,2,3,-2,3}
K75=braidClosure {-1,-1,-1,-1,-2,1,-2,-2}
K76=braidClosure {-1,-1,2,-1,-3,2,-3}
K77=braidClosure {1,-2,1,-2,3,-2,3}

--This outputs a List of complexes, one in each Hochschild degree.
--The homology of these complexes is actual KR homology.  Mostly this function
--just feeds into others.
KR = K -> (
     if K#?KR then return K#KR else (
     	  if not K#?braid then error "no braid representation" else (
     	       Kb=K#braid;
	       P=K#nbcross=#Kb;
     	       Ka=apply(Kb,abs);
     	       Kt=apply(Kb,i->(i>0));
     	       Ks=sort Ka;
     	       --error Ks;
     	       bind=K#bindex=last(Ks)+1;
     	       R=QQ[vars(1 .. 2*P+bind)];
     	       Kmod = chainComplex( gradedModule(R^1));
     	       Cvars=new MutableList from toList (0..bind);
      	       --error Cvars#3;
     	       for I from 0 to P-1 do (
	  	    Kmod=Kmod**KhMods(Cvars#(Ka_I)-1,Cvars#(Ka_I+1)-1,bind+2*I,R,Kt_I);
	  	    Cvars#(Ka_I)=bind+2*I+1;
	  	    Cvars#(Ka_I+1)=bind+2*I+2;
	  	    );
               Ml=toList (1..bind);
     	       M=matrix {apply(Ml, I-> R_(Cvars#I-1)-R_(I-1))};
     	       K#KR=Torify(Kmod,M);
	       return K#KR)
       	  )
     )

--this function just makes the modules used in the complex above.
KhMods = (H,I,J,S,W) -> (
          Mp=S^1/ideal(S_H+S_I-S_J-S_(J+1),S_H*S_I-S_J*S_(J+1));
	  Np=S^{-1}/ideal(S_H-S_J,S_I-S_(J+1));
	  Mn=S^{1}/ideal(S_H+S_I-S_J-S_(J+1),S_H*S_I-S_J*S_(J+1));
	  Nn=S^{1}/ideal(S_H-S_J,S_I-S_(J+1));
	  if W then C=chainComplex(map(Mp,Np,(S_J-S_I))) else C=chainComplex(map(Nn,Mn))[1];
	  C)

--these extend Macaulay2's ability to take tensor products and induced maps.
ChainComplex ** Matrix := ChainComplexMap => (C,f) ->(
     map(C ** target f,C** source f,i -> id_(C_i)**f))

RingMap ** GradedModule := GradedModule => (f,C) -> (
     D := new GradedModule;
     D#ring= target f;
     scan(spots C, i->D#i=f**C#i);
     D) 

inducedchainMap = (C,D,f) -> (
     map(
	  C,D,i->inducedMap(C_i,D_i)
	  )
     )

--This has input a chain complex C and output a list of the complexes
--Tor^i(C,coker M), provided M is a regular sequence.
Torify = (C,M) -> (
     J:=rank source M;
     L:=(0..J);
     Lt=apply(L,I->(
	  F:=koszul(I,M);
	  G:=koszul(I+1,M);
	  FB=C**F;
	  GB=C**G;
	  CB=source FB;
     	  --error CB==target GB;
	  H=inducedchainMap(ker FB,image GB,id_CB);
	  --error H;
	  E=coker H;
	  E));
     Lt)

--input, a link.  output, KR homology (as modules).  this is less useful than you think, just because of the difficulty of reading the output.
KRHom = K -> (
     if K#?KRHom then N:=K#KRHom else (
     	  L:=KR(K);
     	  M:=apply(L,homology);
     	  N:=apply(M,prune);
	  K#KRHom=N;
	  );
     stack(apply(N,net)))

--This sends a chain complex to the list of degrees for which Macaulay2 remembers a module in it.
spots = C -> select(keys C, i -> class i === ZZ)

degrees(GradedModule) := Function => C -> (
     i -> degrees C_i)

--input, a knot K. output ((1-t)/(1+q*t))*(the graded Hilbert 
--polynomial of K).  THIS CURRENTLY ONLY WORKS FOR KNOTS, NOT LINKS.
KRpoly = K -> (
     if K#?KRpoly then return K#KRpoly;
     if not K#?KRHom then KRHom(K);
     L:=K#KRHom;
     R:=ring L_0;
     Rn:=#generators R;
     S:=QQ[t];
     f=map(S,R,apply(toList (1..Rn),i->t));
     M:=apply(L, C -> f**C);
     N:=apply(M,degrees);
     K#KRdeg=N;
     Pring=QQ[q,s,t,Inverses=>true];
     spoM:=sort (spots M_0);
     P:=sum(apply(toList (0..#M-1), i-> (
		    q^i*sum(apply(spoM, j-> (
				   s^j*sum(apply(flatten N_i j, k->t^k))
				   )
			 ))
	       )
	)); 
     K#KRpoly=P;
     if not isSubset(ideal(P),ideal(q*t+1)) then error (ideal(q*t+1),ideal(P));
     P//(q*t+1))
     
KRdisp =K -> (
     if not K#?KRdeg then KRpoly K;
     N=K#KRdeg;
     spoM=spots K#KRHom_0;
     net P || "  " || ( "  " || stack apply(spoM, net)) | "  " | horizontalJoin between("  ", apply(
	       toList (0..#M-1),i-> net i || stack(
		    apply(
			 spoM,j->net(flatten(N_i j))
			 )
		    )
	       )
	  )
     )