Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
| Download
GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
Project: cocalc-sagemath-dev-slelievre
Views: 418346####################################################################### #0 #F RigidFacetsSubdivision ## Input: A pair of positive integers (m,n) ## ## Output: The first n+1 terms of a free ZG-resolution ## where G is SL2Z(1/m) ## InstallGlobalFunction(RigidFacetsSubdivision, function(arg) local W, StabRec, i, j, N, M, x, bdry, s1, s2, p, k, w, t, DimRec, BoundaryRec, id, dims, NotRigid, NewCell, IsAdjacent, Cell, Elts, Boundary, Dimension, CLeftCosetElt, pos, Stab, Mult,DimTemp, BoundaryTemp, Partition, Stabilizer, Action, IsRigidCell, ReplaceCell, SubdividingCell, Orbit, C; C:=arg[1]; i:=0; while C!.dimension(i)>0 do i:=i+1; od; N:=i-1; # Length of the chain complex M:=N; if Length(arg)=2 then M:=Minimum(N,arg[2]); fi; Elts:=C!.elts; StabRec:=[]; DimRec:=[]; ################################################################## # If g in Elts return the position of g in the list, # otherwise, add g to Elts and return the position. pos:=function(g) local posit; posit:=Position(Elts,g); if posit=fail then Add(Elts,g); return Length(Elts); else return posit; fi; end; ################################################################## id:=pos(One(C!.group)); ################################################################## # return the stabilizer of g*e, # Stab:=function(e,g) return ConjugateGroup(StabRec[e[1]+1][AbsInt(e[2])],Elts[g]^-1); end; ################################################################## # returns a "canonical" representative of the right coset # Elts[g]*Stab[i+1][j] CLeftCosetElt:=function(i,j,g) return pos(CanonicalRightCountableCosetElement (StabRec[AbsInt(i)+1][j],Elts[g]^-1)^-1); end; ################################################################## ## ## Input: A list L, degree k, position g of an element ## Output: Product of g and L. ## Mult:=function(L,k,g) local x,w,t,h,y,vv,LL; vv:=[]; LL:=ShallowCopy(L); for x in [1..Length(LL)] do w:=Elts[g]*Elts[LL[x][2]]; t:=CLeftCosetElt(k,AbsInt(LL[x][1]),pos(w)); Add(vv,[LL[x][1],t]); od; return vv; end; ################################################################### # Store essential data: stabilizers, boundaries, dimensions NewCell:=[]; for i in [1..N] do NewCell[i]:=[]; od; Orbit:=[]; for i in [1..N+1] do Orbit[i]:=[]; od; for i in [0..N] do StabRec[i+1]:=[]; DimRec[i+1]:=C!.dimension(i); for j in [1..C!.dimension(i)] do StabRec[i+1][j]:=C!.stabilizer(i,j); od; od; BoundaryRec:=[]; for i in [1..N] do BoundaryRec[i]:=[]; for j in [1..DimRec[i+1]] do bdry:=C!.boundary(i,j); BoundaryRec[i][j]:=[]; for x in bdry do s1:=C!.action(i-1,AbsInt(x[1]),x[2]); p:=pos(CanonicalRightCountableCosetElement (C!.stabilizer(i-1,AbsInt(x[1])),Elts[x[2]]^-1)^-1); s2:=C!.action(i-1,AbsInt(x[1]),p); Add(BoundaryRec[i][j],[s1*s2*x[1],p]); od; od; od; ################################################################## # Data type for a k-cell with stabilizer stab and boundary bdry Cell:=function(k,stab,bdry) return rec( dimension:=k, stabilizer:=stab, boundary:=bdry ); end; ################################################################## # Check if the cell is whether rigid or not IsRigidCell:=function(k,m) local bdry, intst, L; bdry:=BoundaryRec[k][m]; L:=List(bdry,w->Elements(ConjugateGroup(StabRec[k][AbsInt(w[1])],Elts[w[2]]^-1))); intst:=Intersection(L); if not Elements(StabRec[k+1][m])=Elements(intst) then return false; else return true; fi; end; ################################################################## # Check if 2 cells are adjacent IsAdjacent:=function(k,e,f,w) local bdry1,bdry2,i,l1,l2,s1,s2,s,a,s0,x; bdry1:=Mult(BoundaryRec[k][AbsInt(e[1])],k-1,e[2]); bdry2:=Mult(BoundaryRec[k][AbsInt(f[1])],k-1,f[2]); #Print("\n [bdry1,bdry2] = ",[e,f,bdry1,bdry2],"\n"); l1:=List(bdry1,w->[AbsInt(w[1]),w[2]]); l2:=List(bdry2,w->[AbsInt(w[1]),w[2]]); a:=Intersection(Elements(l1),Elements(l2)); if IsEmpty(a) then return false;fi; return true; # s:=Elements(Stab([k+1,w[1]],w[2])); # s1:=Elements(Stab([k,e[1]],e[2])); # s2:=Elements(Stab([k,f[1]],f[2])); # s0:=Elements(Stab([k-1,a[1][1]],a[1][2])); #Print("\n [s0,s1,s2]=",[s0=s1,s1=s2],"\n"); # if s1=s2 and s2=s0 then # return true; # else # return false; # fi; end; ################################################################## # Subdividing a cell SubdividingCell:=function(k,i) local bdry, w, x, d, y, a, b, sub, j, j1,j2, z, t, c, Flag, s, s1, ConnectToCenter, SearchComponent,temp, l1, bdry1, bdry2, Orb, IsSameOrbit, OrbFlag, OrbElm; DimRec[1]:=DimRec[1]+1; Add(StabRec[1],StabRec[k+1][i]); bdry:=ShallowCopy(BoundaryRec[k][i]); ############################################################# # Components SearchComponent:=function(q) local x,z,j,w; x:=[]; w:=[]; Add(w,q); for j in [1..Length(Orb)] do if OrbFlag[j]=0 then for j1 in [1..Length(Orb[j])] do if Flag[j][j1]=0 and IsAdjacent(k-1,q,Orb[j][j1],[i,id]) then Add(x,Orb[j][j1]); Flag[j][j1]:=1; OrbFlag[j]:=1; break; fi; od; fi; od; for j in x do Append(w,SearchComponent(j)); od; return w; end; ############################################################# ################################################################# # Connect the cell e to the barycenter of the cell f # e and f are in the form [k,i,g]: dimension k, obtain by sending # ith-representative under the action of the element g in G ConnectToCenter:=function(e) local bdry1, x, stab, bdrye, w, stablst, redbdry, y, a, LCoset, AddCell; ################################################################## # returns a "canonical" representative of the right coset # Elts[g]*Stab[i+1][j] # LCoset:=function(i,j,g) # return pos(CanonicalRightCountableCosetElement # (StabTemp[AbsInt(i)+1][j],Elts[g]^-1)^-1); # end; ################################################################## # Add a k-cell with stabilizer stab and boundary bdry # to the cell complex AddCell:=function(m,stab,bdry,e) local j,g,s,w,u,v; if m<k then w:=e[1]; for j in [1..DimTemp[m+1]] do u:=BoundaryTemp[m+1][j]; #Print("[w,u]=",[w,u],"\n"); s:=DimRec[m+1]-DimTemp[m+1]+j; if AbsInt(w[1])=AbsInt(u[1]) then # v:=StructuralCopy(StabRec[m+1][s]); v:=StructuralCopy(StabRec[m][AbsInt(u[1])]); v:=List(v,a->Elts[w[2]]*a*Elts[u[2]]^-1); #Print("\n v=",v,"\n"); g:=Intersection(v,Elements(StabRec[k+1][i])); #Print("\n [m,s,g]",[m,s,g],"\n"); if not IsEmpty(g) then #Print("\n [m,s,g]",[m,s,g[1]],"\n"); #Print("\n CLeftCoset", CLeftCosetElt(m,s,pos(g[1])),"\n"); return [s, CLeftCosetElt(m,s,pos(g[1]))]; fi; fi; od; DimTemp[m+1]:=DimTemp[m+1]+1; Add(BoundaryTemp[m+1],e[1]); DimRec[m+1]:=DimRec[m+1]+1; Add(StabRec[m+1],stab); Add(BoundaryRec[m],bdry); else DimRec[m+1]:=DimRec[m+1]+1; Add(StabRec[m+1],stab); Add(BoundaryRec[m],bdry); fi; #Print("\n [m,DimRec[m+1],id]",[m,DimRec[m+1],id],"\n"); #Print("\n CLeftCoset", CLeftCosetElt(m,DimRec[m+1],id),"\n"); return [DimRec[m+1],CLeftCosetElt(m,DimRec[m+1],id)]; end; ################################################################## if e[1]=0 then bdry1:=[[-SignInt(e[2][1][1])*DimRec[1],CLeftCosetElt(0,DimRec[1],id)],[e[2][1][1],e[2][1][2]]]; # stab:=Intersection(Elements(Stab([0,e[2][1][1]],e[2][1][2])),Elements(StabRec[k+1][i])); stab:=Intersection(Stab([0,e[2][1][1]],e[2][1][2]),StabRec[k+1][i]); return AddCell(1,stab,bdry1,e[2]); fi; #Print("test"); stablst:=[]; bdry1:=[]; Append(bdry1,e[2]); bdrye:=[]; for y in e[2] do a:=Mult(BoundaryRec[e[1]][AbsInt(y[1])],e[1]-1,y[2]); if y[1]<0 then a:=NegateWord(a);fi; Append(bdrye,a); Add(stablst,Stab([e[1],y[1]],y[2])); od; Add(stablst,StabRec[k+1][i]); bdrye:=AlgebraicReduction(bdrye); #if e[1]=(k-1) then #Print("\n Length of bdrye=",Length(bdrye),"\n"); #fi; #Print("bdrye=",bdrye,"\n"); for x in bdrye do w:=ConnectToCenter([e[1]-1,[[AbsInt(x[1]),x[2]]]]); Add(bdry1,[-SignInt(x[1])*w[1],w[2]]); # Add(stablst,Stab([e[1],w[1]],w[2])); od; stab:=Intersection(stablst); #Print("\n stab=",stab,"\n"); return AddCell(e[1]+1,stab,bdry1,e[2]); end; ################################################################## IsSameOrbit:=function(e,f) local s1,s; if AbsInt(e[1])=AbsInt(f[1]) then s:=StabRec[k+1][i]; s1:=StabRec[k][AbsInt(e[1])]; for x in s do if Elts[f[2]]^-1*x*Elts[e[2]] in s1 then return SignInt(e[1])*SignInt(f[1])*pos(x); fi; od; return false; else return false; fi; end; ################################################################### # Group the boundary cells into orbits under the action of the stabilizer Orb:=[]; Orb[1]:=[]; OrbElm:=[]; OrbElm[1]:=[]; Add(Orb[1],bdry[1]); Add(OrbElm[1],id); # s:=1; for j in [2..Length(bdry)] do t:=0; for j1 in [1..Length(Orb)] do s:=IsSameOrbit(bdry[j],Orb[j1][1]); if not (s=false) then Add(Orb[j1],bdry[j]); Add(OrbElm[j1],s); break; fi; t:=t+1; od; if t=Length(Orb) then Add(Orb,[bdry[j]]);Add(OrbElm,[id]);fi; od; #Print("\n bdry = ",bdry,"\n"); #Print("\n Orb=:",Orb,"\n"); ################################################################## # Divide the boundary into rigid parts in the big cell [k,i] Flag:=[]; for j in [1..Length(Orb)] do Flag[j]:=[]; for j1 in [1..Length(Orb[j])] do Flag[j][j1]:=0; od; od; sub:=[]; for j in [1..Length(Orb[1])] do sub[j]:=[Orb[1][j]]; Flag[1][j]:=1; od; # for j in [1..Length(sub)] do OrbFlag:=[]; for j1 in [1..Length(Orb)] do OrbFlag[j1]:=0; od; OrbFlag[1]:=1; # sub[j]:=SearchComponent(sub[j][1]); sub[1]:=SearchComponent(sub[1][1]); # od; ################################################################### w:=[]; BoundaryTemp:=[]; DimTemp:=[]; for j in [0..(k)] do BoundaryTemp[j+1]:=[]; DimTemp[j+1]:=0; od; #Print("\n Flag ",Flag,"\n"); #Print("sub=",sub); d:=ConnectToCenter([k-1,sub[1]]); #Print("\n connecttocenter=",d,"\n"); #Print("dim1=",DimTemp[2]); Add(w,d); for j in [2..Length(OrbElm[1])] do Add(w,[SignInt(OrbElm[1][j])*d[1],pos(Elts[AbsInt(OrbElm[1][j])]*Elts[d[2]])]); od; # for j in [2..Length(sub)] do # bdry1:=ShallowCopy(sub[1]); # bdry2:=ShallowCopy(sub[j]); # for a in Elements(StabRec[k+1][i]) do # t:=pos(a); # l1:=Mult(bdry1,k-1,t); # # if Set(l1)=Set(bdry2) then # Add(w,[d[1],t]); # break; # fi; # if Set(l1)=Set(NegateWord(bdry2)) then # Add(w,[-d[1],t]); # break; # fi; # od; # # od; #Print("\n subdividing cell=",w,"\n"); return w; end; ################################################################## # Replacing a cell by its subdivision ReplaceCell:=function(k,m) local i, j, p, w, x, bdry, y, ww; w:=ShallowCopy(SubdividingCell(k,m)); if k=N then Partition:=StructuralCopy(w); for i in [1..Length(Partition)] do Partition[i][1]:=AbsInt(Partition[i][1]-SignInt(Partition[i][1])); od; fi; # if k<N then if k<=M and k<N then for i in [1..DimRec[k+2]] do bdry:=ShallowCopy(BoundaryRec[k+1][i]); p:=PositionsProperty(bdry,w->AbsInt(w[1])=m); for j in p do x:=bdry[j]; ww:=ShallowCopy(w); if x[1]<0 then ww:=NegateWord(ww);fi; ww:=Mult(ww,k,x[2]); #Print("\n ww=",ww,"\n"); Append(bdry,ww); od; y:=bdry{p}; bdry:=Set(bdry); SubtractSet(bdry,y); BoundaryRec[k+1][i]:=bdry; #Print("\n bdry=",bdry,"\n"); od; fi; BoundaryRec[k][m]:="del"; StabRec[k+1][m]:="del"; end; ################################################################## # Main part: subdividing the fundamental domain NotRigid:=[]; dims:=ShallowCopy(DimRec); i:=1; # Print("The cells which are not rigid: \n"); while i<=M do # while i<=N do j:=1; while j<=dims[i+1] do if not IsRigidCell(i,j) then # Print([i,j]); Add(NotRigid,[i,j]); fi; j:=j+1; od; i:=i+1; od; for x in NotRigid do # Print("\n The cell ",x," is in process of subdividing \n"); ReplaceCell(x[1],x[2]); od; #Delete cells which are already replaced by its subdivision # Print("Deleting cells which are already replaced by its subdivision... \n"); t:=1; for w in [1..Length(NotRigid)] do k:=NotRigid[w][1]; j:=NotRigid[w][2]; if k<N then for i in [1..DimRec[k+2]] do bdry:=BoundaryRec[k+1][i]; if not IsString(bdry) then for x in bdry do if AbsInt(x[1])>j then x[1]:=x[1]-SignInt(x[1]); fi; od; fi; BoundaryRec[k+1][i]:=bdry; od; fi; dims[k+1]:=dims[k+1]-1; DimRec[k+1]:=DimRec[k+1]-1; Remove(BoundaryRec[k],j); Remove(StabRec[k+1],j); if IsBound(NotRigid[w+1]) and NotRigid[w+1][1]=NotRigid[w][1] then NotRigid[w+1][2]:=NotRigid[w+1][2]-t; t:=t+1; else t:=1; fi; od; # Print("Done!","\n"); ################################################################## Boundary:=function(k,m) if m<0 then return NegateWord(BoundaryRec[k][AbsInt(m)]);fi; return BoundaryRec[k][m]; end; Stabilizer:=function(k,m) return StabRec[k+1][m]; end; Dimension:=function(k) if k>N then return 0;fi; return DimRec[k+1]; end; Action:=function(k,i,j) return 1; end; ################################################################## return Objectify(HapNonFreeResolution, rec( dimension:=Dimension, Partition:=Partition, boundary:=Boundary, homotopy:=fail, elts:=Elts, group:=C!.group, stabilizer:=Stabilizer, action:=Action, subdividing:=SubdividingCell, replacecell:=ReplaceCell, # issameorbit:=IsSameOrbit, isrigid:=IsRigidCell, properties:= [["length",Maximum(1000,N)], ["characteristic",0], ["type","resolution"]] )); end); ################### end of ControlledSubdivision ############################