One Hat Cyber Team
Your IP :
216.73.216.216
Server IP :
194.44.31.54
Server :
Linux zen.imath.kiev.ua 4.18.0-553.77.1.el8_10.x86_64 #1 SMP Fri Oct 3 14:30:23 UTC 2025 x86_64
Server Software :
Apache/2.4.37 (Rocky Linux) OpenSSL/1.1.1k
PHP Version :
5.6.40
Buat File
|
Buat Folder
Eksekusi
Dir :
~
/
usr
/
share
/
Macaulay2
/
Edit File:
SRdeformations.m2
-- -*- coding: utf-8 -*- newPackage( "SRdeformations", Version => "0.51", Date => "July 12, 2010", Authors => {{Name => "Janko Boehm", Email => "boehm@mathematik.uni-kl.de", HomePage => "http://www.math.uni-sb.de/ag/schreyer/jb/"} }, Headline => "deformations of Stanley-Reisner rings and related computations", Keywords => {"Combinatorial Commutative Algebra"}, DebuggingMode => false, PackageImports => { "ConvexInterface", "OldPolyhedra" }, Configuration => {"UseConvex"=>false} ) -- For information see documentation key "SRdeformations" below. -* Before using "ConvexInterface" via giving the option loadPackage("SRdeformations",Configuration=>{"UseConvex"=>true}) or editing the file init-SRdeformations.m2 please set up "ConvexInterface" first. "ConvexInterface" relies on "MapleInterface". If you don't have Maple/Convex or haven't set up "ConvexInterface" stay with the standard option UseConvex=>false. Then automatically the package "OldPolyhedra" is used, but that is several magnitudes slower compared to maple/convex. "OldPolyhedra" relies on the package "FourierMotzkin". These packages are only used for computing convex hulls and lattice points thereof. Methods of "SRdeformations" relying on this package are so far: convHull globalSections *- -- the commands available to the user export {"cokerElement","iszero","vectorToMonomial","preImage","FirstOrderDeformation", "simplexRing","bigTorusDegree","numeratorMonomial","denominatorMonomial","grading","isNonzero","isTrivial", "relationsCoefficients","gensSource","parameters","firstOrderDeformation", "trivialDeformations", "addCokerGrading","raysPPn","laurent","totalSpace","toHom","newEmptyComplex", "Face","face","vert","simplexDim","ofComplex","dualFace","isSubface","faceToMonomial","Complex","isEquidimensional", "noBoundary","complementComplex","dualComplex","polytopalFacets","embedded", "eulerCharacteristic","complex","complexFromFacets","addFaceDataToComplex","addFacetDataToComplex", "facets","coordinates","isPolytope","variables","edim","fvector","fc", "intersectFaces","embeddingComplex", "simplex","computeFaces","verticesDualPolytope","dualGrading", "boundaryCyclicPolytope","fullCyclicPolytope", "dualize", "boundaryOfPolytope", "idealToComplex","minimalNonFaces","complexToIdeal", "CoComplex","coComplex","idealToCoComplex","coComplexToIdeal", "link","closedStar", "possibleDenominators","deformationsFace", "globalSections","joinVectors", "convHull","deform","PT1","tropDef","mirrorSphere","file","saveDeformations","loadDeformations", "hull","isSimp"} --------------------------------------------------------------------------------- -- deformations of Stanley-Reisner rings --------------------------------------------------------------------------------- -- basic deformations stuff ----------------------------------------------------------- -------------------------------------------- -- some functions to make life easier -- >> export cokerElement=method() cokerElement(Vector,Matrix) := (v,A)->( f:=inducedMap(coker A,target A); f*v ) cokerElement(Matrix,Matrix) := (v,A)->( f:=inducedMap(coker A,target A); f*v ) iszero=method() iszero(Thing):=v->(v==0_(class v)) -- why does isZero not work ? --A= matrix {{-1, -1, -1}, {1, 0, 0}, {0, 1, 0}, {0, 0, 1}} --a1=cokerElement(vector {1,1,0,0},A) --a2=cokerElement(vector {1,-1,0,0},A) --a2==(0_(class a2)) --iszero a1 --iszero a2 numer=method() numer(Vector):=(m)->( R:=ring class m; n:=rank class m; q:=0; num:={}; while q<n do ( if m_q>0_R then ( num=append(num,m_q); ) else ( num=append(num,0_R); ); q=q+1); vector num) --numer vector {1,0,-1} denom=method() denom(Vector):=(m)->( R:=ring class m; n:=rank class m; q:=0; den:={}; while q<n do ( if m_q<0_R then ( den=append(den,-m_q); ) else ( den=append(den,0_R); ); q=q+1); vector den) --denom vector {1,0,-1} tolist=method() tolist(Vector):=(v)->( (entries transpose (toList v)#0)#0) --tolist vector {1,-1,0} -- >> export vectorToMonomial=method() vectorToMonomial(Vector,PolynomialRing):=(L,R)->( q:=0; m:=1_R; while q<rank source vars R do ( m=m*(R_q)^(L_q); q=q+1); m) -- R=QQ[x_0..x_4] -- m=vector {1,2,1,0,0} -- vectorToMonomial(m,R) -- >> export listToLaurentMonomial=method() listToLaurentMonomial(List,PolynomialRing):=(L,R)->( K:=frac R; q:=0; m:=1_R; while q<rank source vars R do ( m=m*(sub(R_q,K))^(L_q); q=q+1); m) -- R=QQ[x_0..x_4] -- m=vector {-1,2,-1,0,0} -- listToLaurentMonomial(m,R) -- big torus invariant first order deformation -- >> export FirstOrderDeformation = new Type of MutableHashTable FirstOrderDeformation.synonym = "first order deformation" FirstOrderDeformation#{Standard,AfterPrint} = m -> ( << endl; << concatenate(interpreterDepth:"o") << lineNumber << " : " << "first order deformation space of dimension "|dim(m) << endl;) -- Laurent monomial representation of --net FirstOrderDeformation := (f) -> net(matrix({tolist(f.bigTorusDegree)})) -- >> document net FirstOrderDeformation := (f) -> net(listToLaurentMonomial(tolist(f.bigTorusDegree),simplexRing f)) newFirstOrderDeformation=method() newFirstOrderDeformation(Ideal,Vector) := (I,m)-> ( newFirstOrderDeformation(gens I,m)) trivDef=method() trivDef(Vector):=(v0)->( v:=entries v0; d:=0; for j from 0 to #v-1 do if v#j<0 then d=d-v#j;( if d>1 then return(false); ); if d==1 then return(true); false) extendParameters=method() extendParameters(List,ZZ,Matrix):=(rmgidx,n,par)->( zr:=matrix {toList apply(0..-1+rank source par,j->0)}; c:=0; local parx; for j from 0 to n-1 do ( if member(j,rmgidx)==true then ( if j==0 then ( parx=par^{c}; c=c+1; ) else ( parx=parx||par^{c}; c=c+1; ); ) else ( if j==0 then( parx=zr; ) else ( parx=parx||zr; ); ); ); parx) --extendParameters({2,4},5,par) protect relevantGens newFirstOrderDeformation(Matrix,Vector) := (mg,m)-> ( A:=grading ring mg; ck:=cokerElement(m,A); -- if trivDef(m)==false then ( L:=relevantMonomials(mg,m); rmg:=L#0;rmgidx:=L#1; rel:=relationsCoefficients(rmg,m); par:=mingens ker transpose rel; dimdef:=rank source par; par=extendParameters(rmgidx,rank source mg,par); -- ) else ( -- dimdef=1; -- rel="unknown"; -- par="unknown"; -- relevantGens="unknown"; -- ); new FirstOrderDeformation from { symbol gens => mg, symbol relevantGens => rmg, symbol bigTorusDegree => m, symbol degree => ck, symbol isHomogeneous => iszero ck, symbol relationsCoefficients => rel, symbol parameters => par, symbol dim => dimdef, symbol isNonzero => (dimdef>0), symbol isTrivial => isTrivial m } ) -- symbol simplexRing => ring mg, -- symbol target => coker mg, -- symbol source => image mg, -- symbol numerator => numer m, -- symbol denominator => denom m, -- symbol numeratorMonomial => vectorToMonomial(numer m,ring mg), -- symbol denominatorMonomial => vectorToMonomial(denom m,ring mg), -- symbol grading => A, -- symbol numeratorMonomial => vectorToMonomial(numer m,ring I), -- symbol denominatorMonomial => vectorToMonomial(denom m,ring I), -- symbol gensSource => mg, ---------------------------------------------------- -- elementary functions on deformations FirstOrderDeformation == FirstOrderDeformation := (f1,f2)->( if ((f1.bigTorusDegree)!=(f2.bigTorusDegree)) then return(false); if f1.gens==f2.gens then return(true); if ((ideal f1.gens) == (ideal f2.gens)) then return(true); false) -- >> export simplexRing=method() simplexRing FirstOrderDeformation := f -> ring f.gens --simplexRing f -- >> document target FirstOrderDeformation := f -> coker(f.gens) --target f -- >> document source FirstOrderDeformation := f -> image(f.gens) --source f -- >> export bigTorusDegree=method() bigTorusDegree FirstOrderDeformation := f -> f.bigTorusDegree --bigTorusDegree f -- >> document numerator FirstOrderDeformation := f -> numer bigTorusDegree f -- >> document denominator FirstOrderDeformation := f -> denom bigTorusDegree f -- >> export numeratorMonomial=method() numeratorMonomial FirstOrderDeformation := f -> vectorToMonomial(numerator f,simplexRing f) -- >> export denominatorMonomial=method() denominatorMonomial FirstOrderDeformation := f -> vectorToMonomial(denominator f,simplexRing f) -- >> document degree FirstOrderDeformation := f -> f.degree -- >> export grading=method() grading FirstOrderDeformation := f -> (simplexRing f).grading -- >> document isHomogeneous FirstOrderDeformation := f -> f.isHomogeneous -- >> document dim FirstOrderDeformation := f -> f.dim -- >> export isNonzero=method() isNonzero(FirstOrderDeformation):=(f)->( f.isNonzero) -- check whether a deformation is trivial -- >> export isTrivial=method() isTrivial(FirstOrderDeformation):=(f)->( 1==sum tolist denominator f) isTrivial(Vector):=(m)->(1==sum tolist denom m) --m=vector {-1,0,1,0,0} --f=firstOrderDeformation(I,m) --isTrivial f ------------------------------------------------------------------ -- relevant monomials relevantMonomials=method() relevantMonomials(Matrix,Vector):=(M,m)->( I:=ideal M; idx:={}; L:={}; q:=0; r:=rank source M; Lm:=laurent(m,ring M); while q<r do ( mtst:=M_(0,q)*Lm; --print(mtst,numerator mtst); if ideal(numerator mtst)+I!=I then ( L=append(L,M_(0,q)); idx=append(idx,q); ); q=q+1); {matrix{L},idx}); --rmg=(relevantMonomials(mg,v))#0 -* rmg=relevantMonomials(mg,v) relationsCoefficientsSyzygies(rmg,v) *- ------------------------------------------------------------------- -- find the deformations in the m-graded part of deformation space -- relations coming from denominator not dividing the monomial relationsCoefficientsDivisible=method() relationsCoefficientsDivisible(Matrix,Vector):=(M,m)->( q:=0; r:=rank source M; R:=ring M; E:=id_(ZZ^r); rel:=E_{0}-E_{0}; while q<r do ( if mapByLaurent(m,M_(0,q))==0_R then rel=rel|E_{q}; q=q+1); rel); -- relationsCoefficientsDivisible(mingens I,m) -- relations coming from lifting syzygies relationsCoefficientsSyzygies=method() relationsCoefficientsSyzygies(Matrix,Vector):=(M,m)->( r:=rank source M; R:=ring M; E:=id_(ZZ^r); rel:=E_{0}-E_{0}; I:=ideal M; mtst:=symbol mtst; q:=0; while q<r do ( qq:=q+1; while qq<r do ( mtst=lcm(M_(0,q),M_(0,qq))*laurent(m,R); if denominator(mtst)==1 then --print(q,qq,M_(0,q),M_(0,qq),mtst,ideal(numerator mtst)+I!=I); --print(numerator mtst); if ideal(numerator mtst)+I!=I then ( -- print(q,qq,M_(0,q),M_(0,qq),mtst); rel=rel|(E_{q}-E_{qq}); ); qq=qq+1); q=q+1); rel); --relationsCoefficientsSyzygies(mg,v) --m=vector {-1,-1,0,2,0} --relationsCoefficientsDivisible(mingens I,m) --relationsCoefficientsSyzygies(mingens I,m) --relationsCoefficients(mingens I,m) --f=firstOrderDeformation(I,m) -- all relations -- >> export relationsCoefficients=method() relationsCoefficients(FirstOrderDeformation):=(f)->f.relationsCoefficients gensSource=method() gensSource(FirstOrderDeformation):=(f)-> f.gens relationsCoefficients(Matrix,Vector):=(M,m)->( rel:=relationsCoefficientsDivisible(M,m)|relationsCoefficientsSyzygies(M,m); mingens image rel) --relationsCoefficients(mingens I,vector {-1,1,0,0,0}) --relationsCoefficientsSyzygies(mingens I,vector {-1,1,0,0,0}) --f=firstOrderDeformation(mingens I, vector {-1,1,0,0,0}) -- compute the coefficients of the deformations in the m-graded part -- >> export parameters=method() parameters(FirstOrderDeformation):=(f)->f.parameters parameters(Matrix,Vector):=(M,m)->( mingens ker transpose relationsCoefficients(M,m)); --parameters(mingens I,m) -- the dimension of the m-graded part, is 1 or 0 for manifolds dimDef=method() dimDef(Matrix,Vector):=(M,m)->( rank source parameters(M,m)) ------------------------------------------------------------------------ -- generate a first order deformation user functions -- >> export firstOrderDeformation=method() firstOrderDeformation(Ideal,Vector):=(I,m)->( newFirstOrderDeformation(I,m)) -- >> export firstOrderDeformation(Matrix,Vector):=(M,m)->( newFirstOrderDeformation(M,m)) firstOrderDeformation(MonomialIdeal,Vector):=(I,m)->( newFirstOrderDeformation(ideal I,m)) ------------------------------------------------------------------------- -- add grading data by the cokernel of an integer matrix to a ring -- -- if A not specified use the standard rays of projective space fan -- >> export addCokerGrading=method() addCokerGrading(PolynomialRing,Matrix):=(R,A)->( v:=(entries vars R)#0; if #v!=rank target A then error("number of rows does not match the number of variables"); R.grading=A) -- firstOrderDeformation(I,m) -- >> export addCokerGrading(PolynomialRing):=(R)->( n:=(rank source vars R)-1; A:=raysPPn(n); addCokerGrading(R,A)) addCokerGrading(PolynomialRing,List):=(R,wt)->( addCokerGrading(R,raysPPn(wt))) raysPPn=method() -- standard rays of weighted projective space raysPPn(List):=(wt)->( if (wt#0)!=1 then error("expected first entry to be 1"); if #wt<2 then error("expected weight vector of length at least 2"); n:=-1+#wt; E:=id_(ZZ^n); (matrix({{apply(1..n,j->-wt#j)}}))||E) --raysPPn({1,1,2,2,3}) -- standard rays of projective space -- >> export raysPPn(ZZ):=(n)->( if n<1 then error("expected positive argument"); E:=id_(ZZ^n); (matrix({{apply(1..n,j->-1)}}))||E) --raysPPn(5) -- >> export grading PolynomialRing:=(R)->(R.grading) --f=firstOrderDeformation(I,m) --------------------------------------------------------------- -- total space -- laurent monomial associated to a deformation -- >> export laurent=method() laurent(FirstOrderDeformation):=(f)->( listToLaurentMonomial(tolist(f.bigTorusDegree),simplexRing f)) --laurent f laurent(Vector,PolynomialRing):=(m,R)->( listToLaurentMonomial(tolist(m),R)) --laurent(m,R) -- map a monomial by a laurent monomial associated to a deformation -- >> export mapByLaurent=method() mapByLaurent(FirstOrderDeformation,RingElement):=(f,m0)->( fm0:=m0*laurent(f); if (degree(denominator(fm0)))#0>0 then return(0_(ring m0)); numerator(fm0)) --mapByLaurent(f,x_0*x_1) mapByLaurent(Vector,RingElement):=(m,m0)->( R:=ring m0; fm0:=m0*laurent(m,R); if (degree(denominator(fm0)))#0>0 then return(0_(ring m0)); numerator(fm0)) -- mapByLaurent(m,x_0*x_1) mapByLaurent(FirstOrderDeformation):=(f)->( apply(f.generators,j->mapByLaurent(f,j))) -- general -- >> export totalSpace=method() totalSpace(FirstOrderDeformation,PolynomialRing):=(f,T)->( vT:=vars T; nt:=rank source vT; dimf:=dim f; if nt!=dimf then error("Number of variables of the parameter ring should match the dimension of the deformation space "|dim f); M:=gens source f; R:=simplexRing f; S:=T**R; pars:=parameters f; q:=0; qq:=0; L:={}; equ:=0_S; tl:=0_S; imm:=0_S; while q<rank source M do ( tl=0_S; imm=sub(mapByLaurent(f,M_(0,q)),S); qq=0; while qq<rank source pars do ( tl=tl+sub(vT_(0,qq),S)*pars_(q,qq)*imm; qq=qq+1); equ=sub(M_(0,q),S)+tl; L=append(L,equ); q=q+1); ideal L); --totalSpace({f},QQ[t,s]) -- for several first order deformations -- >> export totalSpace(List,PolynomialRing):=(L,T)->( vT:=vars T; nt:=rank source vT; dimf:=sum(apply(L,j->dim j)); --print dimf; if nt!=dimf then error("Number of variables of the parameter ring should match the dimension of the deformation space "|dimf); if #(tally apply(L,j->gens source j))!=1 then error("expected all deformations having the same source"); M:=gens source L#0; R:=simplexRing L#0; S:=T**R; pars0:=apply(L,parameters); pars:=pars0#0; f:=0; q:=1; while q<#pars0 do (pars=pars|pars0#q,q=q+1); q=0; qq:=0; qf:=0; L1:={}; equ:=0_S; tl:=0_S; imm:=0_S; parcount:=0; while q<rank source M do ( qf=0; parcount=0; tl=0_S; equ=0_S; while qf<#L do ( f=L#qf; imm=sub(mapByLaurent(f,M_(0,q)),S); tl=tl+sub(vT_(0,parcount),S)*sub(pars_(q,parcount),S)*imm; parcount=parcount+1; qf=qf+1); equ=sub(M_(0,q),S)+tl; L1=append(L1,equ); q=q+1); ideal L1); --R=QQ[x_0..x_4] --I=ideal(x_0*x_1,x_1*x_2,x_2*x_3,x_3*x_4,x_4*x_0) --f=firstOrderDeformation(mingens I, vector {-1,1,0,0,0}) --f1=firstOrderDeformation(mingens I,vector {-1,-1,0,2,0}) --f2=firstOrderDeformation(mingens I,vector {0,-1,-1,0,2}) --L={f1,f2,f} --totalSpace(L,QQ[t_0..t_2]) ------------------------------------------------------------- -- homomorphism representation of first order deformation -- >> export toHom=method() toHom(FirstOrderDeformation):=(f)->( if dim f >1 then error("Not implemented for higher-dimensional graded pieces"); sourcef:=source f; M:=gens sourcef; imM:=matrix {apply((entries M)#0,j->mapByLaurent(f,j))}; fhom:=map(coker M,sourcef,cokerElement(imM,M)); fhom) --fhom=toHom f --target fhom --source fhom --------------------------------------------------------------------------- -* A=matrix {{-1, -1, -1, -1}, {1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0},{0,0,0,1}} R=QQ[x_0..x_4] addCokerGrading(R,A) --addCokerGrading(R) I=ideal(x_0*x_1,x_1*x_2,x_2*x_3,x_3*x_4,x_4*x_0) m=vector {-1,-1,0,2,0} --m=vector {-1,0,1,0,0} f=firstOrderDeformation(I,m) *- ---------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------- -- implementing the structure-type results ---------------------------------------------- -- open star structure of the deformation space -* --------------------------------------------------------------------------------- --------------------------------------------------------------------------------- -- deformations of SR pairs liftDeformation=method() liftDeformation(FirstOrderDeformation,ideal):=(f,J)->( I:=ideal source f; if I+J!=J then error("expected ideal containing the ideal associated to the deformation"); ) --------------------------------------------------------------------------------- -- extend a first order deformation extendDeformation=method() extendDeformation(FirstOrderDeformation,PolynomialRing,ZZ):=(f,T,m)->( ) *- ------------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------------- -- embedded complexes and corresponding Stanley-Reisner rings -------------------------------------------------------------- --------------------------------------------------------- -- faces --------------------- -- kept as simple as possible -- if we have later a memory/performance issue then use as vertices elements in ZZ -- use lists instead of sets of monomials to prevent M2 from reordering -- >> export Face = new Type of MutableHashTable Face.synonym = "face" --net Face := (f)-> net toList vert(f) -- >> document net Face := (f)-> ( v:=f.vert; if #v==0 then return(net({})); horizontalJoin(apply(v,net))) Face#{Standard,AfterPrint} = m -> ( vstr:=symbol vstr; if #(m.vert)==0 then vstr="empty face"; if #(m.vert)==1 then vstr="face with "|#(m.vert)|" vertex"; if #(m.vert)>1 then vstr="face with "|#(m.vert)|" vertices"; << endl; << concatenate(interpreterDepth:"o") << lineNumber << " : " << vstr << endl;) -- >> export face = method(); face(List):=(verticesfc)->(new Face from {symbol vert=>verticesfc}); face(Set):=(verticesfc)->(face toList verticesfc); -- >> export vert=method() vert Face := F -> F.vert; -- >> export simplexDim=method() simplexDim Face := F -> -1+#F --vert F --simplexDim F -- >> document Set == Set := (S1,S2)->(S1===S2) -- >> document Face == Face :=(F,G)->((set vert F) == (set vert G)) -* F=face {x_0,x_1} G=face {x_1,x_0} F==G *- -- >> document dim(Face,PolynomialRing):=(F,R)->( A1:=grading R; A:=entries A1; verticesfc:=vert(F); if #verticesfc==0 then return(-1); vR:=(entries vars R)#0; if rank target A1 != #vR then error("number of rows does not match the number of variables"); L:={}; q:=0; qq:=0; while q<#verticesfc do ( qq=0; while qq<#vR do ( if vR#qq==verticesfc#q then L=append(L,prepend(1,A#q)); qq=qq+1); q=q+1); -1+rank matrix L ) --F=face {x_0,x_2} --dim(F,R) dim(Face):=(F)->( if member(symbol indices,keys F)==true then return(F.indices#0#0); if member(symbol ofComplex,keys F)==true or #vert(F)>0 then return(dim(F,simplexRing(F))); error("specify ring with coker grading")) -- >> document indices(Face):=(F)->(F.indices#0) simplexRing(Face):=(F)->( if member(symbol ofComplex,keys F)==true then return(((F.ofComplex)#0).simplexRing); if #vert(F)>0 then return(ring((vert F)#0)); error("simplex ring of empty face not known")) -- >> export ofComplex=method() ofComplex(Face):=(F)->((F.ofComplex)#0) -- >> document isSubface=method() isSubface(Face,Face):=(F,G)->( v1:=set vert F; v2:=set vert G; isSubset(v1,v2)) -- >> document faceToMonomial=method() faceToMonomial(Face,PolynomialRing):=(F,R)->( v:=vert(F); if v=={} then return(1_R); product(v)) faceToMonomial(Face):=(F)->( v:=vert(F); if v!={} then return(product(v)); R:=(ofComplex F).simplexRing; 1_R) -- we put the ring with possibly switching to ZZ vertices in mind -- and to avoid getting 1_ZZ for the empty face -------------------------------------------------------------------- -- functions dealing with lists of faces, used to create a complex isSimp=method() isSimp(List):=(L)->( tst:=true; q:=0; qq:=0; while q<#L and tst==true do ( qq=0; while qq<#(L#q) and tst==true do ( if #vert(L#q#qq)!=q then tst=false; qq=qq+1); q=q+1); tst) --v=(entries vars R)#0 --L=toList apply(0..#v,j->subsets(v,j)) --isSimp L isPolytope=method() isPolytope(List):=(L)->( numberOfFacets(L)==1 ) -- isPolytope L dimComplex=method() dimComplex(List):=(L)->( q:=0; d:=-1; tst:=true; while q<#L and tst==true do ( if #(L#q)>0 then d=q-1; q=q+1); d) -- dim(L) dimCoComplex=method() dimCoComplex(List):=(L)->( q:=#L-1; d:=#L-1; tst:=true; while q>=0 and tst==true do ( -- if #(L#q)>0 then d=#L-q-1; if #(L#q)>0 then d=q-1; q=q-1); d) -- dim(L) dim(List):=(L)->( if #(L#(#L-1))==0 then return(dimComplex(L)); if #(L#0)==0 then return(dimCoComplex(L)); dimComplex(L)) fvector=method() fvector(List):=(L)->( apply(L,j->#j)) isEquidimensional=method() isEquidimensional(List):=(L)->( anzdim:=0; q:=0; while q<#L and anzdim<=1 do ( if #(L#q)>0 then anzdim=anzdim+1; q=q+1); anzdim<=1); applyC=method() applyC(List,Function):=(L,f)->( apply(L,L1->apply(L1,jj->f(jj)))) applyToComplex=method() applyToComplex(List,Function):=(L,f)->( L1:={}; L2:={}; q:=0; qq:=0; while q<#L do ( qq=0; L2={}; while qq<#(L#q) do ( L2=append(L2,f(L#q#qq,q)); qq=qq+1); L1=append(L1,L2); q=q+1); L1) --applyToComplex(L,(j,q)->(#j)==q) forAllFaces=method() forAllFaces(List,Function):=(L,f)->( tst:=true; q:=0; qq:=0; while q<#L and tst==true do ( qq=0; while qq<#(L#q) and tst==true do ( if f(L#q#qq)!=true then tst=false; qq=qq+1); q=q+1); tst) ----------------------------------- emptySpaces=method() emptySpaces(String):=(S)->( n:=#S; S1:=""; for q from 1 to n do ( S1=S1|" "; ); S1) ------------------------------------------------------------------- -- Complexes -- if we face later a memory/performance issue then -- (in some case) we could try to store only the facets -- but in the applications in mind all faces are obtained anyway -- >> export Complex = new Type of MutableHashTable Complex.synonym = "embedded complex" Complex#{Standard,AfterPrint} = m -> ( sp:="non-simplicial"; eq:="equidimensional"; if m.isEquidimensional==false then eq="non-equidimensional"; lineprint:= lineNumber | " : "; lineprint2:=emptySpaces(lineprint|" "); fvstr:=""; if member(symbol fvector,keys m)==true then fvstr=", F-vector "|toString(m.fvector)|", Euler = "|toString(eulerCharacteristic(m.fvector)); if m.isSimp==true then sp="simplicial"; << endl; << concatenate(interpreterDepth:"o") << lineNumber << " : " << "complex of dim "|m.dim|" embedded in dim "|m.edim|" (printing facets)" << endl << lineprint2 << eq|", "|sp|fvstr << endl;) -- >> export net Complex := (C) -> ( --fct:=toList apply(-1..dim(C),j->C.facets_j); if numberOfFacets(C)==0 then return(net "empty complex"); fct:=C.facets; L:={}; nq:=symbol nq; for q from 0 to #fct-1 do ( if #(fct_q)>0 then ( nq=(net(q-1))|(net ": "); for qq from 0 to #(fct_q)-1 do ( nq=nq|net(fct_q_qq)|net(" "); ); L=append(L,nq); ); ); stack(L)) -- product vert --dC=boundaryOfPolytope(C) -- >> export addComplexToFace=method() addComplexToFace(Face,Complex):=(F,C)->( if member(symbol complex,keys F)==true then ( F.ofComplex=join(F.ofComplex,{C}); ) else ( F.ofComplex={C}; ); "done"); addComplexToFace(Face,Complex,ZZ,ZZ):=(F,C,d,j)->( if member(symbol complex,keys F)==true and member(symbol indices,keys F)==true then ( F.ofComplex=join(F.ofComplex,{C}); F.indices=join(F.indices,{d,j}) ) else ( F.ofComplex={C}; F.indices={{d,j}} ); "done"); -* checkFaces=method() checkFaces(List):=(L)->( true) *- face(List,Complex):=(verticesfc,C)->(new Face from {symbol vert=>verticesfc, symbol ofComplex=>{C}}); face(List,Complex,ZZ,ZZ):=(verticesfc,C,d,j)->(new Face from {symbol vert=>verticesfc, symbol ofComplex=>{C}, symbol indices=>{{d,j}}}); eulerCharacteristic=method() eulerCharacteristic(Complex):=(C)->(eulerCharacteristic(C.fvector)) eulerCharacteristic(List):=(L)->( q:=0; ec:=0; while q<#L do ( ec=ec+(-1)^(q+1)*L#q; q=q+1); ec) newComplex=method() newComplex(PolynomialRing,List,List,PolynomialRing) := (R,faceslist,facetlist,Rdual)-> ( fc0:=new ScriptedFunctor from {subscript => i-> faceslist_(i+1)}; L:={ symbol simplexRing => R, -- symbol dualSimplexRing => Rdual, symbol grading => R.grading, -- symbol dualGrading => Rdual.grading, symbol isSimp => isSimp(faceslist), symbol edim => rank source R.grading, symbol dim => dim (faceslist), symbol fvector => fvector(faceslist), symbol facets => facetlist, symbol fc => fc0, symbol isEquidimensional => isEquidimensional(facetlist), symbol dualComplex=>newEmptyComplex(Rdual) }; new Complex from L ) newComplex(PolynomialRing,List,List) := (R,faceslist,facetlist)-> ( fc0:=new ScriptedFunctor from {subscript => i-> faceslist_(i+1)}; L:={ symbol simplexRing => R, -- symbol dualSimplexRing => false, symbol grading => R.grading, -- symbol dualGrading => false, symbol isSimp => isSimp(facetlist), symbol edim => rank source R.grading, symbol dim => dim (facetlist), symbol fvector => fvector(faceslist), symbol facets => facetlist, symbol fc => fc0, symbol isEquidimensional => isEquidimensional(facetlist) }; new Complex from L ) newComplexFromFacets=method() newComplexFromFacets(PolynomialRing,List,PolynomialRing):= (R,facetlist,Rdual)-> ( -- fc:=new ScriptedFunctor from {subscript => i-> {}}; L:={ symbol simplexRing => R, symbol grading => R.grading, symbol isSimp => isSimp(facetlist), symbol edim => rank source R.grading, symbol dim => dim (facetlist), symbol facets => facetlist, -- symbol fc => fc, symbol isEquidimensional => isEquidimensional(facetlist), symbol dualComplex=>newEmptyComplex(Rdual) }; new Complex from L ) newComplexFromFacets(PolynomialRing,List):= (R,facetlist)-> ( -- fc:=new ScriptedFunctor from {subscript => i-> {}}; L:={ symbol simplexRing => R, symbol grading => R.grading, symbol isSimp => isSimp(facetlist), symbol edim => rank source R.grading, symbol dim => dim (facetlist), symbol facets => facetlist, -- symbol fc => fc, symbol isEquidimensional => isEquidimensional(facetlist), }; new Complex from L ) -- user functions complex=method() -- >> export complex(PolynomialRing,List,List,PolynomialRing) := (R,faceslist,facetlist,Rdual)-> ( newComplex(R,faceslist,facetlist,Rdual)) -- >> export complex(PolynomialRing,List,PolynomialRing) := (R,faceslist,Rdual)-> ( complex(R,faceslist,facets(faceslist),Rdual)) -- >> export complex(PolynomialRing,List,List) := (R,faceslist,facetlist)-> ( newComplex(R,faceslist,facetlist)) -- >> export complex(PolynomialRing,List) := (R,faceslist)-> ( newComplex(R,faceslist,facets(faceslist))) --C=complex(R,L) -- >> export complexFromFacets=method() complexFromFacets(PolynomialRing,List,PolynomialRing) := (R,facetslist,Rdual)-> ( newComplexFromFacets(R,facetslist,Rdual)) -- >> export complexFromFacets(PolynomialRing,List) := (R,facetslist)-> ( newComplexFromFacets(R,facetslist)) -- >> export newEmptyComplex=method() newEmptyComplex(PolynomialRing):=(R)->( ed:=rank source R.grading; faceslist:=toList apply(-1..ed,j->{}); complexFromFacets(R,faceslist)) -* newEmptyComplex(PolynomialRing,PolynomialRing):=(R,Rdual)->( ed:=rank source R.grading; faceslist:=toList apply(-1..ed,j->{}); complexFromFacets(R,faceslist,Rdual)) *- -- >> export addFaceDataToComplex=method() addFaceDataToComplex(Complex,List,List):=(C,faceslist,facetlist)->( fc:=new ScriptedFunctor from {subscript => i-> faceslist_(i+1)}; C.isSimp=isSimp(facetlist); C.dim=dim(facetlist); C.fvector = fvector(faceslist); C.facets = facetlist; C.fc = fc; C.isEquidimensional =isEquidimensional(facetlist); C) addFaceDataToComplex(Complex,List):=(C,faceslist)->( addFaceDataToComplex(C,faceslist,facets(faceslist))) addFacetDataToComplex=method() addFacetDataToComplex(Complex,List):=(C,facetlist)->( C.isSimp=isSimp(facetlist); C.dim=dim(facetlist); C.facets = facetlist; C.isEquidimensional =isEquidimensional(facetlist); "done") -* R=QQ[x_0..x_4] addCokerGrading(R) I=ideal(x_0*x_1,x_1*x_2,x_2*x_3,x_3*x_4,x_4*x_0) C=idealToComplex(I) Cl=newEmptyComplex(R) addFaceDataToComplex(Cl,faces C) Cl==C *- -*Note: To save memory the goal is to store face of complexes and their subcomplexes only once. If (e.g. by boundaryOfPolytope, idealToCoComplex,...) a complex C1 is computed which is a subcomplex of C and is a face of C1 then F.ofComplex returns still C. This e.g. allows us to dualize F if C was a polytope *- -------------------------------------------------- -- computing the facets of a complex isNonFacetComplex=method() -- for faces and listlists of these isNonFacetComplex(ZZ,Face,List):=(qF,F,L)->( tst:=false; q:=qF; qq:=0; L2:={}; --print(q,F,L#q); while q<#L and tst==false do ( L2={}; qq=0; while qq<#(L#q) and tst==false do ( if isSubset(vert F, vert L#q#qq) then tst=true; qq=qq+1); q=q+1); tst) -- for lists and listlist of these (not used any more) isNonFacetComplex(ZZ,List,List):=(qF,F,L)->( tst:=false; q:=qF; qq:=0; L2:={}; --print(q,F,L#q); while q<#L and tst==false do ( L2={}; qq=0; while qq<#(L#q) and tst==false do ( if isSubset(F,L#q#qq) then tst=true; qq=qq+1); q=q+1); tst) -- L=faces C --isNonFacetComplex(2,L#2#0,L) facetsComplex=method() facetsComplex(List):=(L)->( q:=0; qq:=0; L1:={}; L2:={}; while q<#L do ( L2={}; qq=0; while qq<#(L#q) do ( if isNonFacetComplex(q+1,L#q#qq,L)==false then L2=append(L2,L#q#qq); qq=qq+1); L1=append(L1,L2); q=q+1); L1) --facets(faces C) -- >> export facets=method() facets(List):=(L)->( if #(L#0)==0 then return(facetsCoComplex(L)); if #(L#(#L-1))==0 then return(facetsComplex(L)); facetsComplex(L)) numberOfFacets=method() numberOfFacets(List):=(L)->( sum(apply(L,j->#j)) ) numberOfFacets(Complex):=(C)->( numberOfFacets(C.facets)) ------------------------------------------------------- -- some simple functions on complexes -- >> document dim(Face,Complex):=(F,C)->( R:=simplexRing C; dim(F,R)) -- >> export coordinates=method() coordinates(Face,Complex):=(F,C)->( v:=vert(F); A:=grading(C); L:={}; vr:=vars simplexRing C; for q from 0 to #v-1 do ( for qq from 0 to rank source vr-1 do ( if vr_(0,qq)==v#q then L=append(L,(entries(A^{qq}))#0); ); ); L) coordinates(Face):=(F)->( if member(symbol ofComplex,keys F)==true or #vert(F)>0 then return(coordinates(F,ofComplex(F))); error("specify complex")) --coordinates(C.fc_1_0) --coordinates(face {x_1,x_3,x_0},C) -- >> export isPolytope Complex:=(C)->( if member(symbol isPolytope,keys C)==true then return(C.isPolytope); numberOfFacets(C)==1) -- >> export isSimp Complex:=(C)->C.isSimp -- >> document dim Complex:= (C)->(C.dim) -- >> export -- to get vertices as faces do C.fc_0 vert Complex :=(C)->( sort toList set join toSequence apply(join toSequence facets C,vert)) variables=method() variables Complex :=(C)->( (entries vars simplexRing C)#0) edim=method() edim Complex:= (C)->(C.edim) -- >> document fvector(Complex):=(C)->(C.fvector) -- >> document grading(Complex):=(C)->(C.grading) -- >> export isEquidimensional(Complex):=(C)->(C.isEquidimensional) -- >> export simplexRing(Complex):=(C)->(C.simplexRing) -- >> export facets(Complex):=(C)->(C.facets) --faces=method() --faces(Complex):=(C)->(C.fc) -- >> export fc=method() fc(Complex):=(C)->( if member(symbol fc,keys C)==true then return(toList apply(-1..edim(C),j->C.fc_j)); if member(symbol isSimp,keys C)==true then ( if C.isSimp==true then ( -- faceslist:=computeFacesOfSimplicialComplex(C); -- fc:=new ScriptedFunctor from {subscript => i-> faceslist_(i+1)}; C.fc=computeFacesOfSimplicialComplex(C); C.fvector=fvector fc C; return(fc C); ); ); if member(symbol noBoundary,keys C)==true then ( if C.noBoundary==true then ( C.fc=computeFacesOfCompleteComplex(C); C.fvector=fvector fc C; return(fc C); ); ); error("faces unknown")) fc(Complex,ZZ):=(C,d)->( fc(C); C.fc_d) --------------------------------------------------------------------- -- compute faces of a compact complex -- too slow, improve: computeFacesOfCompleteComplex=method() computeFacesOfCompleteComplex(Complex):=(C)->( L:=new MutableList from toList apply(0..edim(C)+1,j->{}); --L#0={new Face from {symbol vert=>{},symbol ofComplex=>{C},symbol indices=>{{-1,0}}}}; fc:=join toSequence facets C; tst:=false; q:=1; qq:=0; anznew:=0; while tst==false do ( L1:=apply(subsets(fc,q),intersectFaces); anznew=0; qq=0; while qq<#L1 do ( L#(1+dim(L1#qq))=setAppend(L#(1+dim(L1#qq)),L1#qq); anznew=anznew+1; qq=qq+1); if anznew==0 then tst=true; q=q+1); new ScriptedFunctor from {subscript => i-> L#(i+1)}) -* L={vector {1,0,0},vector {-1,0,0},vector {0,1,0},vector {0,-1,0},vector {0,0,1},vector {0,0,-1}} P=convHull L dP=boundaryOfPolytope(P) computeFacesOfCompleteComplex(dP) *- setAppend=method() setAppend(List,Thing):=(L,F)->( q:=0; tst:=false; while q<#L and tst==false do ( if L#q==F then tst=true; q=q+1); if tst==false then return(append(L,F)); L) --setAppend({1,2,4,5},3) --setAppend({1,2,4,5},4) --computeFacesOfCompleteComplex C intersectFaces=method() intersectFaces(List):=(S)->( if #S==1 then return(S#0); q:=2; it:=intersectFaces(S#0,S#1); while q<#S do ( it=intersectFaces(it,S#q); q=q+1); it) intersectLists=method() intersectLists(List):=(S)->( if #S==1 then return(S#0); q:=2; it:=intersectLists(S#0,S#1); while q<#S do ( it=intersectLists(it,S#q); q=q+1); it) polytopalFacets=method() polytopalFacets(Complex):=(C)->(C.polytopalFacets) intersectFaces(Face,Face):=(F1,F2)->( if member(symbol ofComplex,keys F1)==true and member(symbol ofComplex,keys F2)==true then ( if not(F1.ofComplex===F2.ofComplex) then error("expected faces of the same complex"); -- if member(symbol dualFace,F1)==true then ( -- return(new Face from {symbol vert=>intersectLists(vert F1,vert F2), symbol ofComplex=>{F1.ofComplex}, symbol dualFace=>union(F1.dualFace,F2.dualFace)}) -- ); return(new Face from {symbol vert=>intersectLists(vert F1,vert F2), symbol ofComplex=>F1.ofComplex}); ); new Face from {symbol vert=>intersectLists(vert F1,vert F2)}) intersectLists(List,List):=(L1,L2)->( toList((set L1)*(set L2))) --union(List,List):=(L1,L2)->( --toList((set L1)+(set L2))) -*intersectLists({x_1,x_2},{x_2,x_3}) union({x_1,x_2},{x_2,x_3}) intersectFaces(C.fc_2_0,C.fc_2_1) intersectFaces({C.fc_2_0,C.fc_2_1,C.fc_2_2}) *- --------------------------------------------------------------------- -- compute faces of a simplicial complex computeFacesOfSimplicialComplex=method() computeFacesOfSimplicialComplex(Complex):=(C)->( aface:=findAface C; C0:=(aface.ofComplex)#0; d:=dim(C); v:=variables(C); fc:=facets C; q:=0; L:={}; while q<=d+1 do ( L=append(L,apply(select(subsets(v,q),j->isSubfaceOfFacets(j,fc)),jj-> new Face from {symbol vert=>jj, symbol ofComplex=>{C0}, symbol indices=>{{d,q}}} )); q=q+1); for q from d+2 to edim(C)+1 do L=append(L,{}); pf:=member(symbol polytopalFacets,keys C); new ScriptedFunctor from {subscript => i->( if pf==true and i==dim(C)-1 then return(C.polytopalFacets); L_(i+1) )}) --C=simplex(R) --computeFacesOfSimplicialComplex(C) isSubfaceOfFacets=method() isSubfaceOfFacets(List,List):=(F,L)->( q:=0; tst:=false; d:=0; while d<#L and tst==false do ( q=0; while q<#(L#d) and tst==false do ( if isSubset(set F,vert L#d#q)==true then tst=true; q=q+1); d=d+1); tst) -* fcC=facets C; isSubfaceOfFacets({x_1},fcC) *- -* C0=simplex R C=boundaryOfPolytope C0 Cf=complexFromFacets(R,facets C) peek Cf fc Cf peek Cf dualize Cf Cf=complexFromFacets(R,facets C) Cf.noBoundary=true fc Cf dualize Cf *- --------------------------------------------------------------- applyToComplex(Complex,Function):=(C,f)->( applyToComplex(fc(C),f)) -------------------------------------------------------------------- -* compare two complexes: note that in many real world examples of high codimension (given through their faces) the Stanley-Reisner ideal is not computeable as it is too big to write down, so we can't use it *- -- >> document Complex == Complex :=(C1,C2)->( if not(C1.simplexRing===C2.simplexRing) then return(false); if C1.grading!=C2.grading then return(false); if C1.dim!=C2.dim then return(false); return(compareFaces(C1.facets,C2.facets)) ) compareFaces=method() compareFaces(List,List):=(L1,L2)->( tst:=true; j:=0; while j<#L1 and tst==true do ( if compareFacesj(L1#j,L2#j)==false then tst=false; j=j+1); tst) --compareFaces(C.facets,C.facets) compareFacesj=method() compareFacesj(List,List):=(L1,L2)->( anz:=0; tst:=true; j:=0; while j<#L1 and tst==true do ( anz=0; for jj from 0 to #L2-1 do ( if L2#jj == L1#j then anz=anz+1; ); if anz!=1 then tst=false; j=j+1); tst) --compareFaces((C.facets)#5,(C.facets)#5) ----------------------------------------------------------------------- -- dual faces of a polytope -* -- obsolete addDualFaces=method() addDualFaces(Complex,PolynomialRing):=(C,Rdual)->( if isPolytope(C)==false then error("expected polytope"); fc:=C.fc_(dim(C)-1); C.dualSimplexRing=Rdual; C.dualGrading=Rdual.grading; d:=-1; q:=0; while d<=dim(C) do ( print(d); q=0; while q<#(C.fc_d) do ( --(C.fc_d_q).dualVertices=computeDualVertices(C.fc_d_q,fc,Rdual); computeDualVertices(C.fc_d_q,fc,Rdual); q=q+1); d=d+1); fc) addDualFaces(Complex):=(C)->( n:=#(C.fc_(dim(C)-1)); K:=coefficientRing simplexRing C; v:=symbol v; Rdual:=K[v_0..v_(n-1)]; Rdual.grading=0; addDualFaces(C,Rdual)) *- -* R=QQ[x_0..x_10] Rdual=QQ[v_0..v_10] addCokerGrading(R) addCokerGrading(Rdual) C=simplex(R) addDualFaces(C,Rdual) peek C.fc_2_2 peek C.fc_-1_0 peek C.fc_dim(C)_0 *- computeDualVertices=method() computeDualVertices(Face,List,PolynomialRing):=(F,fcts,Rdual)->( v:=(entries vars(Rdual))#0; L:={}; q:=0; while q<#fcts do ( if isSubface(F,fcts#q)==true then L=append(L,v#q); q=q+1); L) computeDualVertices(Face,List):=(F,fcts)->( L:={}; q:=0; while q<#fcts do ( if isSubface(F,fcts#q)==true then L=append(L,q); q=q+1); L) -* -- obsolete computeDualVertices(List,List,PolynomialRing):=(F,fcts,Rdual)->( v:=(entries vars(Rdual))#0; L:={}; q:=0; while q<#fcts do ( if isSubset(F,fcts#q)==true then L=append(L,v#q); q=q+1); L) *- ----------------------------------------------------------------------- -- make a simplex with dual faces -- >> export -* -- obsolete simplexWithDualFaces=method() simplexWithDualFaces(PolynomialRing):=(R)->( n:=rank source vars R; K:=coefficientRing R; v:=symbol v; Rdual:=K[v_0..v_(n-1)]; Rdual.grading=R.grading; ------------------------------------------------------------------- fix this simplex(R,Rdual)) simplexWithDualFaces(PolynomialRing,PolynomialRing):=(R,Rdual)->( v:=(entries vars R)#0; A:=grading R; Cl:=newEmptyComplex(R,Rdual); F:=symbol F; S:=symbol S; fc:=subsets(v,#v-1); if (rank A)<(#v-1) then error("grading matrix does not have correct rank"); faceslist:=toList apply(0..#v,j->( if j!=#v-1 then ( S=subsets(v,j); ) else ( S=fc; ); toList apply(0..#S-1, jj->new Face from {symbol vert=>S#jj, symbol ofComplex=>{Cl}, symbol indices=>{{j-1,jj}} ,symbol dualVertices=> toList apply(select(0..#fc-1,jjj->isSubset(S#jj,fc#jjj)),jjjj->Rdual_jjjj) } ) )); q:=0; facetlist:={}; while q<#v do ( facetlist=append(facetlist,{}); q=q+1); facetlist=append(facetlist,{ new Face from {symbol vert=>v, symbol ofComplex=>{Cl}, symbol indices=>{{#v-1,0}} ,symbol dualVertices=>{} } }); addFaceDataToComplex(Cl,faceslist,facetlist); Cl) *- embeddingComplex=method() embeddingComplex(Complex):=(C)->( F:=findAface C; (F.ofComplex)#0) -------------------------------------------------------------------- --> export simplex=method(Options=>{computeFaces=>null}) simplex(PolynomialRing):=opts->(R)->( if member(symbol grading,keys R)==false then addCokerGrading(R); A:=grading R; n:=rank source vars R; K:=coefficientRing R; v:=symbol v; Rdual:=K[v_0..v_(n-1)]; --Rdual.grading=R.grading; simplex(R,Rdual,opts)) --> export verticesDualPolytope=method() verticesDualPolytope(Complex):=(C)->( n:=#vert(C.polytopalFacets#0); if isPolytope(C)==false then error("expected a polytope"); if rank(C.grading)!=rank source C.grading then error("expected a polytope of full dimension"); if member(symbol polytopalFacets,keys C)==false then ( C.polytopalFacets=C.fc_(dim C-1); ); T:=transpose(matrix{toList(apply(0..n-2,j->-1))})|((ZZ^(n-1))_{0..n-2}); rels:=apply(apply(C.polytopalFacets,coordinates),matrix); L:=apply(apply(apply(apply(rels,j->T*j),ker),gens),transpose); L1:={}; q:=0; for q from 0 to #L-1 do ( rv:=(L#q*(transpose(rels#q)))_(0,0); L1=append(L1,(entries((-1/rv)*sub(L#q,QQ)))#0) ); matrix L1) --verticesDualPolytope C --> export dualGrading=method() dualGrading(Complex):=(C)->(C.dualComplex.grading) simplex(PolynomialRing,PolynomialRing):=opts->(R,Rdual)->( v:=(entries vars R)#0; A:=grading R; n:=rank source vars R; if rank source A!=n-1 or rank target A!=n or rank A!=n-1 then error("vertices do not form a simplex of full dimension"); Cl:=newEmptyComplex(R); q:=0; facetlist:={}; while q<#v do ( facetlist=append(facetlist,{}); q=q+1); facetlist=append(facetlist,{face(v,Cl,#v-1,0)}); Cl.noBoundary=false; --S:=apply(0..#v-1,j->remove(v,j)); S:=subsets(v,#v-1); Cl.polytopalFacets=toList apply(0..#S-1,jj->face(S#jj,Cl,#v-2,jj)); Cl.isSimp=true; Cl.isPolytope=true; Rdual.grading=verticesDualPolytope(Cl); dCl:=newEmptyComplex(Rdual); dCl.dualComplex=Cl; dCl.noBoundary=false; dCl.isPolytope=true; -- dv:=(entries vars Rdual)#0; dS:=subsets(dv,#dv-1); dCl.polytopalFacets=toList apply(0..#dS-1,jj->face(dS#jj,Cl,#dv-2,jj)); dfacetlist:={}; q=0; while q<#dv do ( dfacetlist=append(dfacetlist,{}); q=q+1); dfacetlist=append(dfacetlist,{face(dv,dCl,#dv-1,0)}); addFacetDataToComplex(dCl,dfacetlist); Cl.dualComplex=dCl; if class(opts.computeFaces)===Boolean then ( if opts.computeFaces==false then ( addFacetDataToComplex(Cl,facetlist); --dCl.dim=Cl.dim; return(Cl); ); ); F:=symbol F; if (rank A)<(#v-1) then error("grading matrix does not have correct rank"); faceslist:=toList apply(0..#v,j->( S=subsets(v,j); toList apply(0..#S-1,jj->face(S#jj,Cl,j-1,jj)) )); addFaceDataToComplex(Cl,faceslist,facetlist); --dCl.dim=Cl.dim; Cl) --simplex(R,Rdual) -- implement dual simplex in facet representation i.e. for computeFaces=>false -* simplex(R) simplex(R,computeFaces=>true) simplex(R,computeFaces=>false) *- -* simplex(PolynomialRing):=(R)->( n:=rank source vars R; A:=raysPPn(n-1); simplex(R,A)) *- -* R=QQ[x_0..x_5] addCokerGrading(R) C0=simplex(R) dC0=boundaryOfPolytope(C0) *- -------------------------------------------------------- -- cyclic polytopes positionRing=method() positionRing(RingElement):=(m)->( v:=(entries vars ring m)#0; for q from 0 to #v-1 do ( if v#q==m then return(q); ); ); --R=QQ[x_1..x_10] --positionRing(x_1) isContigous=method() isContigous(List):=(X)->( if X=={} then return(false); X1:=sort(X); p2:=X1#(#X1-1); p1:=X1#0; if abs(positionRing(p2)-positionRing(p1))==#X1-1 then return(true); false); -* isContigous({x_2,x_3,x_6,x_4,x_5,x_8,x_7}) isContigous({x_2,x_3,x_6,x_4,x_5,x_8,x_7}) isContigous({x_1,x_2,x_5,x_3}) *- contigousSubsets=method() contigousSubsets(List):=(W)->( select(subsets(W),isContigous)) -* contigousSubsets({x_4,x_5}) contigousSubsets({x_3,x_4}) contigousSubsets({x_1,x_2,x_3}) contigousSubsets({x_2,x_3,x_4}) contigousSubsets({x_1,x_2,x_4}) *- maximalElements=method() maximalElements(List):=(L)->( L2:=L; L1:=maxmon(L2); while #L1<#L2 do ( L2=L1; L1=maxmon(L2); ); L1) --maximalElements({{x_1,x_2,x_3},{x_1,x_2},{x_3,x_4},{x_2,x_3,x_4,x_7,x_8}}) maxmon=method() maxmon(List):=(L)->( rm:=-1; j:=0; jj:=0; while j<#L and rm==-1 do ( jj=0; while jj<#L and rm==-1 do ( if j!=jj and isSubset(set L#j,set L#jj)==true then rm=j; jj=jj+1); j=j+1); --print(rm); L1:={}; j=0; while j<#L do ( if j!=rm then L1=append(L1,L#j); j=j+1); L1); --maxmon({{x_1,x_2,x_3},{x_1,x_2},{x_3,x_4},{x_2,x_3,x_4,x_7,x_8}}) maximalContigousSubsets=method() maximalContigousSubsets(List):=(L)->( maximalElements(contigousSubsets(L))) -* maximalContigousSubsets({x_1,x_2,x_4}) maximalContigousSubsets({x_1,x_2,x_4,x_5,x_7,x_8,x_9}) *- isEndset=method() isEndset(List):=(L)->( v:=(entries vars ring L#0)#0; if isSubset({v#0},L)==true or isSubset({v#(#v-1)},L)==true then return(true); false) -* isEndset({x_1,x_2}) isEndset({x_1,x_3}) isEndset({x_2,x_3}) *- removeEndsets=method() removeEndsets(List):=(L)->( L1:={}; j:=0; for j from 0 to #L-1 do ( if isEndset(L#j)==false then L1=append(L1,L#j); ); L1); -* removeEndsets({{x_1,x_2},{x_3,x_4}}) removeEndsets({{x_1,x_3},{x_7,x_8}}) removeEndsets(maximalContigousSubsets({x_1,x_2,x_4})) removeEndsets(maximalContigousSubsets({x_1,x_2,x_4,x_5,x_7,x_8})) *- oddContigousNonEndsets=method() oddContigousNonEndsets(List):=(L)->( L2:={}; j:=0; L1:=removeEndsets(maximalContigousSubsets(L)); for j from 0 to #L1-1 do ( if odd(#(L1#j))==true then L2=append(L2,L1#j); ); L2) -* maximalContigousSubsets({x_1,x_2,x_4,x_5,x_7,x_8,x_9}) removeEndsets(oo) oddContigousNonEndsets({x_1,x_2,x_4,x_5,x_7,x_8,x_9}) *- isFaceOfCyclicPolytope=method() isFaceOfCyclicPolytope(List,ZZ):=(W,d)->( if W=={} then return(true); if #oddContigousNonEndsets(W)<=d-#W then return(true); false); -* isFaceOfCyclicPolytope({x_2,x_3},3) isFaceOfCyclicPolytope({x_3,x_4},3) isFaceOfCyclicPolytope({x_4,x_9},3) *- boundaryCyclicPolytope0=method() boundaryCyclicPolytope0(ZZ,PolynomialRing):=(d,R)->( C0:=simplex(R,computeFaces=>false); Cl:=newEmptyComplex(R); M:=(entries vars R)#0; F:=face {}; addComplexToFace(F,C0); L:={{F}}; S:={}; S1:={}; for j from 1 to #M do ( if j<=d then ( S=subsets(M,j); S1={}; for jj from 0 to #S-1 do ( if isFaceOfCyclicPolytope(S#jj,d)==true then ( F=face S#jj; addComplexToFace(F,C0); S1=append(S1,F) ); ); L=append(L,S1); ) else ( L=append(L,{}); ); ); addFaceDataToComplex(Cl,L); Cl); -* R=QQ[x_0..x_7] --addCokerGrading(R) --simplex(R) C=boundaryCyclicPolytope0(4,R) peek C.fc_2_0 dC=dualize C dC.grading *- boundaryCyclicPolytope=method() boundaryCyclicPolytope(ZZ,PolynomialRing):=(d,R)->( if member(symbol grading,keys R)==false then addCokerGrading(R); boundaryCyclicPolytope0(d,R)) fullCyclicPolytope=method() fullCyclicPolytope(ZZ,PolynomialRing):=(d,R)->( Cl:=cyclicPolytopeFaces(d,R); K:=coefficientRing R; v:=symbol v; n:=#(Cl.polytopalFacets); Rdual:=K[v_0..v_(n-1)]; Rdual.grading=verticesDualPolytope(Cl); dCl:=newEmptyComplex(Rdual); dCl.dualComplex=Cl; dCl.isPolytope=true; dCl.isSimp=false; dCl.dim=Cl.dim; Cl.dualComplex=dCl; Cl) fullCyclicPolytope(ZZ,PolynomialRing,PolynomialRing):=(d,R,Rdual)->( Cl:=cyclicPolytopeFaces(d,R); Rdual.grading=verticesDualPolytope(Cl); dCl:=newEmptyComplex(Rdual); dCl.dim=Cl.dim; dCl.dualComplex=Cl; Cl.dualComplex=dCl; Cl) cyclicPolytopeFaces=method() cyclicPolytopeFaces(ZZ,PolynomialRing):=(d,R)->( if member(symbol grading,keys R)==true then print("Warning: Coker grading has been overwritten"); -- or option overwriteGrading=>true; M:=(entries vars R)#0; n:=#M; Lv:=toList apply(0..n-1,j->toList apply(1..d,jj->j^jj)); tv:=sum Lv; Lv=apply(Lv,j->n*j-tv); A:=matrix Lv; addCokerGrading(R,A); Cl:=newEmptyComplex(R); Cl.noBoundary=false; Cl.isSimp=false; L:={{face({},Cl)}}; S:={}; S1:={}; for j from 1 to d+1 do ( if j<=d then ( S=subsets(M,j); S1={}; for jj from 0 to #S-1 do ( if isFaceOfCyclicPolytope(S#jj,d)==true then ( S1=append(S1,face(S#jj,Cl)) ); ); L=append(L,S1); ) else ( L=append(L,{face(M,Cl)}); ); ); addFaceDataToComplex(Cl,L); Cl.polytopalFacets=L#(#L-2); Cl); -* R=QQ[x_0..x_6] C=fullCyclicPolytope(4,R) *- ---------------------------------------------------- dualize=method() dualize(Face):=(F)->( idx:=0; dF:=symbol dF; if member(symbol dualFace,keys F)==true then return(F.dualFace); if member(symbol ofComplex,keys F)==false then error("expected face of a complex or co-complex"); C:=(F.ofComplex)#0; if isPolytope(C)==false then error("expected face of polytope"); if member(symbol dualComplex,keys C)==true then ( if member(symbol indices, keys F)==true then idx=(F.indices)#0#1; dF=new Face from {symbol vert=>computeDualVertices(F,C.polytopalFacets,C.dualComplex.simplexRing), symbol dualFace=>F, symbol ofComplex=>{C.dualComplex}, symbol indices=>{{edim(C) - dim(F)-1,idx}}}; F.dualFace=dF; return(dF); ); dF=new Face from {symbol vert=>computeDualVertices(F,C.fc_(dim(C)-1)), symbol dualFace=>F}; F.dualFace=dF; dF) -* R=QQ[x_0..x_4] addCokerGrading R R.grading C=simplex R F=C.fc_2_0 peek F dF=dualize F peek dF dF.ofComplex dF.ofComplex.simplexRing dF.ofComplex.grading F==dualize dF F===dualize dF *- findAface=method() findAface(Complex):=(C)->( fc:=C.facets; q:=0; qq:=0; while q<#fc do ( if #(fc#q)>0 then return(fc#q#0); q=q+1); error("empty complex")) -* n:=#(C.fc_(dim(C)-1)); K:=coefficientRing simplexRing C; v:=symbol v; Rdual:=K[v_0..v_(n-1)]; Rdual.grading=false; *- dualize(Complex):=(C)->( if member(symbol dualComplex,keys C)==true then ( if member(symbol fc,keys C.dualComplex)==true or numberOfFacets(C.dualComplex)>0 then return(C.dualComplex); ); if member(symbol fc,keys C)==false then fc(C); aface:=findAface C; C0:=(aface.ofComplex)#0; --print(C0); if member(symbol dualComplex,keys C0)==false then error("expected face of a complex which has a dual complex"); L:={}; L1:={}; q:=0; d:=dim(C0); --print(d); while d>=-1 do ( q=0; L1={}; while q<#(C.fc_d) do ( L1=append(L1,dualize(C.fc_d_q)); q=q+1); L=append(L,L1); d=d-1); --print(L); dC:=symbol dC; if member(symbol dualComplex,keys C)==true then ( dC=C.dualComplex; dC.dualComplex=C; addFaceDataToComplex(dC,L); if #(L#0)==0 then dC=new CoComplex from dC; return(dC) ); dC=complex(C0.dualComplex.simplexRing,L); if #(L#0)==0 then dC=new CoComplex from dC; dC.dualComplex=C; C.dualComplex=dC; dC) -* R=QQ[x_0..x_4] addCokerGrading R C=simplex(R) dC=dualize C peek dC.fc_2_0 R=QQ[x_0..x_4] addCokerGrading R C=simplex(R) bC=boundaryOfPolytope C dbC=dualize bC bC.dualComplex==dbC dbC.dualComplex==bC dF=dbC.fc_2_0 peek dF dualize C peek dF *- --------------------------------------- -- boundary of a polytope replaceDim=method() replaceDim(List,ZZ,Thing):=(L,d,L2)->( L1:={}; for j from 0 to #L-1 do ( if j==d then ( L1=append(L1,L2); ) else ( --if class L2 === List then apply(L#j,jj->addComplexToFace(jj,C,0,0)); L1=append(L1,L#j); ); ); L1) --replaceDim(C.facets,3,{}) -- >> export boundaryOfPolytope=method() boundaryOfPolytope(Complex):=(C)->( R:=C.simplexRing; if isPolytope(C)==false then error("expected polytope"); newfacets:=replaceDim(replaceDim(facets(C),dim(C)+1,{}),dim(C),C.polytopalFacets); -- newfacets:=replaceDim(replaceDim(facets(C),dim(C)+1,{}),dim(C),C.fc_(dim(C)-1)); L:={}; if member(symbol fc,keys C)==false then ( L={ symbol simplexRing => C.simplexRing, symbol grading => R.grading, symbol isPolytope => false, symbol isSimp => isSimp newfacets, symbol edim => C.edim, symbol dim => -1+C.dim, symbol facets => newfacets, symbol isEquidimensional => true, symbol noBoundary=>true -- symbol dualComplex=>newEmptyComplex(C.dualComplex.simplexRing); }; return(new Complex from L) ); newfaces:=replaceDim(fc(C),dim(C)+1,{}); fc0:=new ScriptedFunctor from {subscript => i-> (newfaces)_(i+1)}; newfvector:=replaceDim(C.fvector,dim(C)+1,0); L={ symbol simplexRing => C.simplexRing, symbol grading => R.grading, symbol isPolytope => false, symbol isSimp => isSimp newfacets, symbol edim => C.edim, symbol dim => -1+C.dim, symbol fvector => newfvector, symbol facets => newfacets, symbol fc => fc0, symbol isEquidimensional => true, symbol noBoundary=>true -- symbol dualComplex=>newEmptyComplex(C.dualComplex.simplexRing); }; new Complex from L ) -* R=QQ[x_0..x_4] addCokerGrading R C=simplex(R) dC=dualize C bC=boundaryOfPolytope(C) dbC=dualize(bC) C=boundaryOfPolytope simplex(R,computeFaces=>false) *- ----------------------------------------------------------------------------- ------------------------------------------------------------------------------ -- Stanley-Reisner correspondence idealToComplex=method() -- >> export idealToComplex(Ideal):=(I)->( idealToComplex monomialIdeal I) -* idealToComplex(MonomialIdeal):=(I)->( n:=-1+rank source vars ring I; A:=raysPPn(n); idealToComplex(I,A)) idealToComplex(Ideal,Matrix):=(I,A)->( idealToComplex(monomialIdeal I,A)) *- --idealToComplex(MonomialIdeal,Matrix):=(I,A)->( --if rank target A != rank source vars ring I then error("number of rows does not match the number of variables"); --if isSquareFree(I)==false then error("Expected squarefree monomial ideal"); -- >> export idealToComplex(MonomialIdeal):=(I)->( L:={}; L1:={}; R:=ring I; C0:=simplex(R,computeFaces=>false); Cl:=newEmptyComplex(R); A:=R.grading; --addCokerGrading(R,A); v:=(entries vars R)#0; n:=#v; tst:=true; pfc:=symbol pfc; d:=0; j:=0; while d<=n do ( if tst==true then ( pfc=apply(subsets(v,d),j->face j); L1=select(pfc,j->isFaceIdeal(j,I)); for j from 0 to #L1-1 do -- addComplexToFace(L1#j,Cl,d-1,j); addComplexToFace(L1#j,C0); --if #L1==0 then tst=false; ) else ( L1={}; ); L=append(L,L1); d=d+1); addFaceDataToComplex(Cl,L); Cl.ideal=I; Cl) isFaceIdeal=method() isFaceIdeal(Face,MonomialIdeal):=(F,I)->( tst:=false; m:=faceToMonomial(F,ring I); -- I==I+ideal(m); gI:=gens I; n:=rank source gI; q:=0; while q<n and tst==false do ( if (degree(denominator(m/gI_(0,q))))#0==0 then tst=true; q=q+1); not tst) --isFaceIdeal(face {x_0,x_1},I) --idealToComplex(I) idealToComplex(Ideal,Complex):=(I,C)->( idealToComplex(monomialIdeal I,C)) idealToComplex(MonomialIdeal,Complex):=(I,C)->( if member(symbol fc,keys C)==false then error("the complex must have face data"); L:={}; L1:={}; R:=ring I; Cl:=newEmptyComplex(R); A:=R.grading; --addCokerGrading(R,A); v:=(entries vars R)#0; n:=#v; tst:=true; pfc:=symbol pfc; d:=-1; j:=0; while d<n do ( if tst==true then ( L1=select(C.fc_d,j->isFaceIdeal(j,I)); --for j from 0 to #L1-1 do addComplexToFace(L1#j,C); --if #L1==0 then tst=false; ) else ( L1={}; ); L=append(L,L1); d=d+1); addFaceDataToComplex(Cl,L); Cl.ideal=I; Cl) -* C0=simplex R C=idealToComplex(I,C0) dualize C C0=simplex(R,computeFaces=>false) idealToComplex(I,C0) *- -------------------------------------------------------------- -- the minimal non-faces -- this is of course equivalent to IdealToComplex if we -- are dealing with a subcomplex of a simplex -- get rid of faces C -- >> export minimalNonFaces=method(Options=>{embedded=>null}) minimalNonFaces(Complex):=opts->(C)->( if class(opts.embedded)===Boolean then ( if opts.embedded==true then return(minimalNonFacesEmbedded(C)); ); L:={}; j:=1; jj:=0; jjj:=0; R:=simplexRing C; v:=(entries vars R)#0; nondivisiblenonfc:={}; tst:=symbol tst; isface:=symbol isface; fc:={}; start:=true; while (j<=#v and #nondivisiblenonfc>0) or start==true do ( --print(j); start=false; fc=subsets(v,j); nondivisiblenonfc={}; for jj from 0 to #fc-1 do ( tst=true; jjj=0; while jjj<#L and tst==true do ( if isSubset(set vert L#jjj,set fc#jj)==true then tst=false; jjj=jjj+1); if tst==true then nondivisiblenonfc=append(nondivisiblenonfc,fc#jj); ); for jj from 0 to #nondivisiblenonfc-1 do ( isface=false; jjj=0; while jjj<#(C.fc_(j-1)) and isface==false do ( if (set vert ((C.fc_(j-1))#jjj))==(set (nondivisiblenonfc#jj)) then ( isface=true ); jjj=jjj+1); if isface==false then ( L=append(L,face nondivisiblenonfc#jj); ); ); --print(L); j=j+1); L) --minimalNonFaces C --C=IdealToComplex(I) --minimalNonFaces(C) minimalNonFacesEmbedded=method() minimalNonFacesEmbedded(Complex):=(C)->( aface:=findAface C; C0:=(aface.ofComplex)#0; L:={}; j:=0; jj:=0; jjj:=0; R:=simplexRing C0; nondivisiblenonfc:={}; tst:=symbol tst; isface:=symbol isface; fc:={}; start:=true; while (j<=dim(C0) and #nondivisiblenonfc>0) or start==true do ( start=false; fc=C0.fc_j; nondivisiblenonfc={}; for jj from 0 to #fc-1 do ( tst=true; jjj=0; while jjj<#L and tst==true do ( if isSubset(set vert L#jjj,set vert fc#jj)==true then tst=false; jjj=jjj+1); if tst==true then nondivisiblenonfc=append(nondivisiblenonfc,fc#jj); ); for jj from 0 to #nondivisiblenonfc-1 do ( isface=false; jjj=0; while jjj<#(C.fc_j) and isface==false do ( if (set vert ((C.fc_j)#jjj))==(set vert(nondivisiblenonfc#jj)) then ( isface=true ); jjj=jjj+1); if isface==false then ( L=append(L,nondivisiblenonfc#jj); ); ); --print(L); j=j+1); L) --minimalNonFacesEmbedded C --C.fc_(dim C) -- >> export complexToIdeal=method(Options=>{embedded=>null}) complexToIdeal(Complex):=opts->(C)->( R:=simplexRing C; I:=ideal apply(minimalNonFaces(C,opts),j->faceToMonomial(j,R)); C.ideal=I; I) --C=IdealToComplex(I) --complexToIdeal C --complexToIdeal(C,embedded=>true) ----------------------------------------------------------------------------- -- the geometric picture -- SR complex is really a cocomplex (which is in inclusion reversing bijection to -- a complex if sitting inside a simplex by taking the complement face -- this is the Stanley-Reisner complex -- but the cocomplex is always dual to a complex in the polytope -- which is the true geometric strata of the vanishing locus of the ideal -- in the Cox ring of the toric variety) --------------------------------------------------------- -- cocomplexes: -- >> export CoComplex = new Type of Complex CoComplex.synonym = "embedded co-complex" CoComplex#{Standard,AfterPrint} = m -> ( sp:="non-simplicial"; eq:="equidimensional"; if m.isEquidimensional==false then eq="non-equidimensional"; lineprint:= lineNumber | " : "; lineprint2:=emptySpaces(lineprint|" "); if m.isSimp==true then sp="simplicial"; << endl; << concatenate(interpreterDepth:"o") << lineNumber << " : " << "co-complex of dim "|m.dim|" embedded in dim "|m.edim|" (printing facets)" << endl << lineprint2 << eq|", "|sp|", F-vector "|toString(m.fvector)|", Euler = "|toString(eulerCharacteristic(m.fvector)) << endl;) coComplex=method() -- >> export coComplex(PolynomialRing,List,List,PolynomialRing) := (R,faceslist,facetlist,Rdual)-> ( new CoComplex from complex(R,faceslist,facetlist,Rdual)) -- >> export coComplex(PolynomialRing,List,PolynomialRing) := (R,faceslist,Rdual)-> ( coComplex(R,faceslist,facets(faceslist),Rdual)) -- >> export coComplex(PolynomialRing,List) := (R,faceslist)-> ( coComplex(R,faceslist,facets(faceslist))) -- >> export coComplex(PolynomialRing,List,List) := (R,faceslist,facetlist)-> ( new CoComplex from complex(R,faceslist,facetlist) ) ---------------------------- -- the geometric cocomplex -- think of D as the faces over a Fano polytope -- >> export idealToCoComplex=method() idealToCoComplex(MonomialIdeal):=(I)->( D:=simplex ring I; idealToCoComplex(I,D)) idealToCoComplex(Ideal):=(I)->( idealToCoComplex(monomialIdeal I)); idealToCoComplex(Ideal,Complex):=(I,D)->( idealToCoComplex(monomialIdeal I,D)); idealToCoComplex(MonomialIdeal,Complex):=(I,D)->( if isSquareFree(I)==false then error("Expected squarefree monomial ideal"); if not(set((entries vars ring I)#0)== set((entries vars simplexRing D)#0) ) then error("Expected ideal and complex over rings with same variables"); tst:=false; completecomplex:=false; n:=edim(D); gI:=gens I; L:={}; L1:={}; for d from -1 to n do ( L1={}; for j from 0 to #(D.fc_d)-1 do ( tst=false; if completecomplex==true then tst=true; --if tst==true then print(D.fc_d_j); if tst==false then ( if containsFaceOf(D.fc_d_j,L)==true then tst=true; ); if tst==false then ( if testFaceCoComplex(D.fc_d_j,gI)==true then tst=true; ); if tst==true then L1=append(L1,D.fc_d_j); ); L=append(L,L1); if #L1==#(D.fc_d) then completecomplex=true; ); C:=coComplex(simplexRing D,L); C.ideal=I; C); containsFaceOf=method() containsFaceOf(Face,List):=(F,L)->( vF:=set vert F; tst:=false; q:=0; qq:=0; while q<#L and tst==false do ( qq=0; while qq<#(L#q) and tst==false do ( if isSubset(set vert(L#q#qq),vF)==true then tst=true; qq=qq+1); q=q+1); tst); testFaceCoComplex=method() testFaceCoComplex(Face,Matrix):=(F,gI)->( vF:=vert F; --print(vF,gI); tst:=true; tst2:=false; q:=0; qq:=0; while q<rank source gI and tst==true do ( --print(gI_(0,q)); tst2=false; qq=0; while qq<#vF and tst2==false do ( if (degree(denominator(gI_(0,q)/vF#qq)))#0==0 then tst2=true; qq=qq+1); if tst2==false then tst=false; q=q+1); tst) coComplexToIdeal=method() coComplexToIdeal(CoComplex):=(C)->( fc:=facets(C); I:=monomialIdeal(1_(simplexRing C)); q:=0; qq:=0; while q<#fc do ( qq=0; while qq<#(fc_q) do ( I=intersect(I,monomialIdeal vert fc_q_qq); qq=qq+1); q=q+1); I=ideal I; C.ideal=I; I) --store dual face in face structure --------------------------------------------------------------------------------- -- embedded cocomplexes -------------------------------------------------- -- computing the facets of a CoComplex isNonFacetCoComplex=method() isNonFacetCoComplex(ZZ,List,List):=(qF,F,L)->( tst:=false; q:=qF; qq:=0; L2:={}; --print(q,F,L#q); while q>=0 and tst==false do ( L2={}; qq=0; while qq<#(L#q) and tst==false do ( if isSubset(L#q#qq,F) then tst=true; qq=qq+1); q=q-1); tst) isNonFacetCoComplex(ZZ,Face,List):=(qF,F,L)->( tst:=false; q:=qF; qq:=0; L2:={}; --print(q,F,L#q); while q>=0 and tst==false do ( L2={}; qq=0; while qq<#(L#q) and tst==false do ( if isSubset(vert L#q#qq, vert F) then tst=true; qq=qq+1); q=q-1); tst) -- L=fc C --isNonFacetCoComplex(2,L#2#0,L) facetsCoComplex=method() facetsCoComplex(List):=(L)->( q:=0; qq:=0; L1:={}; L2:={}; while q<#L do ( L2={}; qq=0; while qq<#(L#q) do ( if isNonFacetCoComplex(q-1,L#q#qq,L)==false then L2=append(L2,L#q#qq); qq=qq+1); L1=append(L1,L2); q=q+1); L1) --------------------------------------------------------------------------------- complement(Complex):=(C)->( if member(symbol complementComplex,keys C)==true then return(C.complementComplex); aface:=findAface C; C0:=(aface.ofComplex)#0; d:=dim(C0); q:=0; L:={}; L1:={}; while d>=-1 do ( q=0; L1={}; while q<#(C.fc_d) do ( L1=append(L1,complement(C.fc_d_q)); q=q+1); L=append(L,L1); d=d-1); cC:=complex(C0.simplexRing,L); if #(L#0)==0 then cC=new CoComplex from cC; C.complementComplex=cC; cC.complementComplex=C; cC) complement(Face):=(F)->( C0:=(F.ofComplex)#0; R:=C0.simplexRing; v:=(entries(vars R))#0; n:=#v; if C0.isSimp==false or n!=dim(C0)+1 then error("expected a subcomplex of a simplex"); face(toList((set v)-(set vert F)),C0)) -* C=dCP(3,QQ[x_0..x_4]) F=C.fc_1_0 complement F cC=complement C dcC=dualize cC cC.fc_2 dcC.fc_1 C.fc_1 coordinates dcC.fc_1_0 coordinates cC.fc_1_0 *- --------------------------------------------------------------------------------- -* R=QQ[x_0..x_15] addCokerGrading(R) C0=simplex(R) boundaryOfPolytope(C0) A=matrix {{-1, -1, -1, -1}, {1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0},{0,0,0,1}} R=QQ[x_0..x_4] addCokerGrading(R,A) C0=simplex(R) R=QQ[x_0..x_4] addCokerGrading(R) C0=simplex(R) I=ideal(x_0*x_1,x_1*x_2,x_2*x_3,x_3*x_4,x_4*x_0) C=idealToComplex(I) embeddingComplex C idealToComplex(I,C0) complexToIdeal(C) cC=idealToCoComplex(I,C0) cC==complement C I==coComplexToIdeal(cC) dualize cC R=QQ[x_0..x_5] C=boundaryCyclicPolytope(3,R) I=complexToIdeal(C) betti(cc=res I) cc.dd_2 I=ideal(product (entries vars R)#0) C=idealToComplex(I) --fc C cC=idealToCoComplex(I) --fc cC dualize cC *- -------------------------------------------------------------------------------------- -->export selectFaces=method() selectFaces(Complex,Function):=(C,f)->( L1:={}; L2:={}; q:=-1; qq:=0; while q<=edim(C) do ( qq=0; L2={}; while qq<#(C.fc_q) do ( if f(C.fc_q_qq)==true then L2=append(L2,C.fc_q_qq); qq=qq+1); L1=append(L1,L2); q=q+1); complex(C.simplexRing,L1)) isLinkFace=method() isLinkFace(Face,Face,Complex):=(G,F,C)->( if dim(intersectFaces(F,G))>-1 then return(false); q:=0; qq:=0; gf:=set vert(F) + set vert(G); while q<=edim(C) do ( qq=0; while qq<#(C.fc_q) do ( if (set vert(C.fc_q_qq))==gf then (return(true)); qq=qq+1); q=q+1); false) --link(F,C) -- > export link=method() link(Face,Complex):=(F,C)->( selectFaces(C,j->isLinkFace(j,F,C))) -- caveat: this is really a cocomplex in C, fix this openStar=method() openStar(Face,Complex):=(F,C)->( selectFaces(C,j->isSubface(F,j))) isClosedStarFace=method() isClosedStarFace(Face,Face,Complex):=(G,F,C)->( q:=0; qq:=0; gf:=set vert(F) + set vert(G); while q<=edim(C) do ( qq=0; while qq<#(C.fc_q) do ( if (set vert(C.fc_q_qq))==gf then (return(true)); qq=qq+1); q=q+1); false) closedStar=method() closedStar(Face,Complex):=(F,C)->( selectFaces(C,j->isClosedStarFace(j,F,C))) -* R=QQ[x_0..x_4] C=boundaryOfPolytope simplex(R) F=C.fc_0_0 link(F,C) closedStar(F,C) F=C.fc_1_0 link(F,C) closedStar(F,C) R=QQ[x_0..x_4] I=ideal(x_0*x_1,x_1*x_2,x_2*x_3,x_3*x_4,x_4*x_0) C=idealToComplex I F=C.fc_0_0 link(F,C) closedStar(F,C) F=C.fc_1_0 link(F,C) closedStar(F,C) R=QQ[x_0..x_4] I=ideal(x_0*x_1*x_2,x_3*x_4) C=idealToComplex I F=C.fc_0_0 link(F,C) closedStar(F,C) F=C.fc_1_0 link(F,C) closedStar(F,C) F=C.fc_2_0 link(F,C) closedStar(F,C) *- --------------------------------------------------------------------------------------- possibleDenominators=method() possibleDenominators(List,List):=(fc,v)->( degreeList:=sort(apply(fc,j->(degree j)#0)); maxDegree:=max degreeList; L:={}; for q from 1 to maxDegree do ( L=append(L,select(subsets(v,q),j->dividesGenerator(j,fc))); ); L); dividesGenerator=method() dividesGenerator(List,List):=(m,L)->( pm:=product m; for q from 0 to #L-1 do ( if denominator(L#q/pm)==1 then return(true); ); false) --> export possibleDenominators(Ideal):=(I)->( possibleDenominators((entries mingens I)#0,(entries vars ring I)#0)) --> export possibleDenominators(Ideal,List):=(I,v)->( possibleDenominators((entries mingens I)#0,v)) -* R=QQ[x_0..x_4] I=ideal(x_0*x_1*x_2,x_3*x_4) possibleDenominators(I) possibleDenominators(I,{x_0,x_1,x_3}) C=idealToComplex I F=C.fc_0_0 *- deformationsFace=method() deformationsFace(Face,Complex):=(F,C)->( I:=symbol I; if member(symbol ideal,keys C)==false then ( I=complexToIdeal C; ) else ( I=C.ideal; ); deformationsFace(F,C,I)); faceToIndices=method() faceToIndices(Face):=(F)->( R:=(ofComplex F).simplexRing; vt:=vert F; apply(vt,j->findIndexOfVertex(j,R)) ) listToIndices=method() listToIndices(List):=(F)->( R:=ring(F#0); apply(F,j->findIndexOfVertex(j,R)) ) findIndexOfVertex=method() findIndexOfVertex(RingElement,PolynomialRing):=(m,R)->( v:=(entries vars R)#0; for qq from 0 to #v-1 do ( if m==v#qq then return(qq); )) --findIndexOfVertex(x_1,R) --faceToIndices(F) deformationsFace(Face,Complex,Ideal):=(F,C,I)->( if member(symbol deform,keys F)==true then ( if (F.deform)#0===C then return((F.deform)#1); --return((F.deform)#1); ); if dim F==-1 then return({}); lk:=link(F,C); vlk:=vert lk; mg:=gens I; pden:=possibleDenominators(I,vlk); pden=select(pden,j->(#j>0)); pden=apply(join toSequence pden,j->vector (exponents product(j))#0); A:=C.simplexRing.grading; idxF:=faceToIndices(F); defs:={}; for j from 0 to #pden-1 do ( H0vF:=globalSections(A,pden#j,idxF); defs=join(defs,apply(H0vF,j->firstOrderDeformation(mg,j))); ); L:=select(defs,j->(dim j>0)); F.deform={C,L}; L) -* R=QQ[x_0..x_4] I=ideal(x_0*x_1,x_1*x_2,x_2*x_3,x_3*x_4,x_4*x_0) C1=idealToComplex I F=C1.fc_0_1 lkF=link(F,C1) L=deformationsFace(F,C1) *- applyC(Complex,Function):=(C,f)->( apply(fc C,L1->apply(L1,jj->f(jj)))) deform=method() deform(Complex):=(C)->( if member(symbol deform,keys C)==true then (return(C.deform)); L:={}; applyC(C,F->( defs:=deformationsFace(F,C); L=setJoin(L,defs); )); L=setJoin(L,trivialDeformations(C)); C.deform=L; L) --deform(C1) setJoin=method() setJoin(List,List):=(L,F)->( q:=0; L1:=L; while q<#F do ( L1=setAppend(L1,F#q); q=q+1); L1) ---------------------------------------------------------- -- save deformation data saveDeformations=method() saveDeformations(Complex,String):=(C,fn)->( defs:=C.deform; S:=apply(apply(defs,bigTorusDegree),j->(entries transpose ((toList j)#0))#0); F := openOut(fn); F<<toString S<<endl; close F; defs) --saveDeformations(C1,"defsC23.m2") loadDeformations=method() loadDeformations(Complex,String):=(C,fn)->( F := openIn(fn); S:=value(get(F)); mg:=gens complexToIdeal C; C.deform=apply(S,j->firstOrderDeformation(mg,vector j))) --loadDeformations(C1,"defsC23.m2") -------------------------------------------------------------------------------------- -- trivial deformations trivialDeformations=method() trivialDeformations(Matrix):=(A)->( n:=rank target A; M:=(ring A)^n; L:={}; for j from 0 to -1+n do ( L=setAppend(L,removeFromList(globalSections(A,M_j),0)); ); L); trivialDeformations(Ideal,Matrix):=(I,A)->( n:=rank target A; M:=(ring A)^n; L:={}; for j from 0 to -1+n do ( L=join(L,removeFromList(globalSections(A,M_j),0_M)); ); mg:=gens I; --L=apply(L,j->vector (entries(transpose j))#0); L=apply(L,j->firstOrderDeformation(mg,j))); removeFromList=method() removeFromList(List,Thing):=(L,m)->( L1:={}; for j from 0 to #L-1 do ( if L#j!=m then L1=append(L1,L#j); ); L1) trivialDeformations(Complex):=(C)->( if member(symbol trivialDeformations,keys C)==true then ( return(C.trivialDeformations) ); R:=simplexRing C; A:=grading C; I:=symbol I; if member(symbol ideal,keys C)==false then ( I=complexToIdeal C; ) else ( I=C.ideal; ); tdef:=trivialDeformations(I,A); C.trivialDeformations=tdef; tdef); --trivialDeformations C1 -- global sections globalSectionsPPn=method() globalSectionsPPn(Vector):=(v)->( M:=entries v; n:=#M; d:=sum(M); g:=symbol g; R:=QQ[g_1..g_n]; L:=apply((entries basis(d,R))#0,monomialToVector); apply(L,j->j-v)); globalSectionsPPn(Vector,ZZ):=(v,d)->( M:=entries v; n:=#M; g:=symbol g; R:=QQ[g_1..g_n]; L:=apply((entries((product toList(g_1..g_n))*basis(d-n,R)))#0,monomialToVector); L); monomialToVector=method() monomialToVector(RingElement):=(m)->( vector((exponents(m))#0)) --globalSectionsPPn(b) globalSectionsPPn(Vector,List):=(v,var)->( M:=entries v; n:=#M; d:=sum(M); v1:=selectCoordinates(v,var); L:=globalSectionsPPn(v1,d); L=apply(L,j->extendCoordinates(j,var,n)); apply(L,j->j-v)); globalSectionsPPn(List,Vector):=(degs,v)->( M:=entries v; n:=#M; d:=sum toList(apply(0..n-1,j->degs#j*M#j)); g:=symbol g; R:=QQ[g_1..g_n,Degrees=>degs]; --print(d,basis(d,R)); L:=apply((entries basis(d,R))#0,monomialToVector); apply(L,j->j-v)); --degs={1,1,2,2,3} --globalSectionsPPn(degs,vector {0,0,1,1,0}) globalSectionsPPn(List,Vector,List):=(degs,v,var)->( M:=entries v; n:=#M; d:=sum toList(apply(0..n-1,j->degs#j*M#j)); v1:=selectCoordinates(v,var); degs1:=selectCoordinates(degs,var); L:=globalSectionsPPn(degs1,v1,d); L=apply(L,j->extendCoordinates(j,var,n)); apply(L,j->j-v)); globalSectionsPPn(List,Vector,ZZ):=(degs,v,d)->( M:=entries v; n:=#M; g:=symbol g; R:=QQ[g_1..g_n,Degrees=>degs]; d1:=sum degs; L:=apply((entries((product toList(g_1..g_n))*basis(d-d1,R)))#0,monomialToVector); L); --globalSectionsPPn(degs,vector {0,0,1,1,0},{1,2}) -* A=raysPPn(4) b=vector {2,3,0,0,0} globalSections(A,b,{2,3}) b=vector {1,1,0,0,0} globalSections(A,b,{2,3,4}) globalSectionsPPn(b,6) *- selectCoordinates=method() selectCoordinates(Vector,List):=(v,var)->( L:=entries v; vector apply(var,j->L#j)) selectCoordinates(List,List):=(L,var)->( apply(var,j->L#j)) extendCoordinates=method() extendCoordinates(Vector,List,ZZ):=(v,var,n)->( L:={}; jj:=0; for j from 0 to n-1 do ( if member(j,var)==false then ( L=append(L,0); ) else ( L=append(L,v_jj); jj=jj+1; ); ); vector L) --extendCoordinates(vector {3,4},{2,7},8) --> export globalSections=method() globalSections(Matrix,Vector):=(A,v)->( if A==raysPPn(-1+rank target A) then return(globalSectionsPPn(v)); degs:=prepend(1,(entries(-A))#0); if A==raysPPn(degs) then return(globalSectionsPPn(degs,v)); le:=linesEquations(A,v); be:=boundaryEquations(A); C:=posHull(be,le); dC:=-(C#"dualgens")#0; L:=apply(entries transpose dC,j->cutRay vector j); Lv:=apply(L,j->sub(j,ZZ)-v); preLv:=apply(Lv,j->preImage(A,j)); vt:=joinVectors(preLv); P:=convexHull vt; lP:=latticePoints P; apply(lP,j->matrixToVector(A*j))); -* A=matrix {{1, 0}, {0, 1}, {-1, -1}} b=vector {2,0,0} globalSections(A,b) A=matrix {{1, 0}, {0, 1}, {-1, -1},{1,1}} b=vector {2,2,0,0} globalSections(A,b) *- globalSections(Matrix,Vector,List):=(A,v,var)->( if A==raysPPn(-1+rank target A) then return(globalSectionsPPn(v,var)); degs:=prepend(1,(entries(-A))#0); if A==raysPPn(degs) then return(globalSectionsPPn(degs,v,var)); cL:=sort toList(set(0..-1+rank target A) - set var); le:=linesEquations(A,v); be:=boundaryEquations(A); for j from 0 to #cL-1 do ( be=be|(-be_{cL#j}); ); C:=posHull(be,le); dC:=-(C#"dualgens")#0; L:=apply(entries transpose dC,j->cutRay vector j); Lv:=apply(L,j->sub(j,ZZ)-v); preLv:=apply(Lv,j->preImage(A,j)); vt:=joinVectors(preLv); P:=convexHull vt; -- this is needed for a bug in OldPolyhedra if dim(P)==0 then ( lP:={vertices P}; ) else ( lP=latticePoints P; ); apply(lP,j->matrixToVector(A*j))); -* A=matrix {{1, 0}, {0, 1}, {-1, -1}} b=vector {1,1,0} globalSections(A,b,{0,1,2}) globalSections(A,b,{1,2}) globalSections(A,b,{1}) globalSections(A,b,{2}) *- matrixToVector=method() matrixToVector(Matrix):=(M)->( vector (entries transpose M)#0) --matrixToVector(matrix {{1},{2}}) joinVectors=method() joinVectors(List):=(L)->( LM:=apply(L,vectorToMatrix); S:=apply(LM,ring); if member(QQ,S)==true then LM=apply(LM,j->sub(j,QQ)); M:=LM#0; for j from 1 to #L-1 do M=M|(LM#j); M) -* v1=vector {1/2,1} v2=vector {1,1} joinVectors({v1,v2}) *- cutRay=method() cutRay(Vector):=(v)->( L:=tolist v; vector toList apply(0..#L-2,j->L#j/L#(#L-1))) -* cutRay(vector{1,2,0,-1}) *- vectorToMatrix=method() vectorToMatrix(Vector):=(v)->((toList v)#0) linesEquations=method() linesEquations(Matrix,Vector):=(A,v)->( kA:=gens ker transpose A; rh:=-transpose((transpose kA)*vectorToMatrix(v)); kA||rh) -* A=matrix {{1, 0}, {0, 1}, {-1, -1},{1,1}} v=vector {2,0,0,0} linesEquations(A,v) *- boundaryEquations=method() boundaryEquations(Matrix):=(A)->( n:=rank target A; B:=id_(ZZ^n); nv:=matrix {toList apply(0..n-1,j->0_ZZ)}; B||nv) -* A=matrix {{1, 0}, {0, 1}, {-1, -1}} boundaryEquations(A) *- preImage=method() preImage(Matrix,Vector):=(A,b)->( n:=rank source A; --print(ring A,ring ((toList(b))#0)); kh:=gens ker(A|sub((toList(b))#0,ring A)); if kh==0 then return(false); --sub((kh_(n,0))^(-1)*sub(kh^(toList (0..n-1)),QQ),ZZ) v:=-(kh_(n,0))^(-1)*kh^(toList (0..n-1)); vector (entries transpose v)#0) -* A=matrix {{1, 0}, {0, 1}, {-1, -1}} b=vector {-2,2,0} v=preImage(A,b) A*v *- --------------------------------------------------------------------------------------- -- cones hull=method(Options=>{file=>null}) hull(List):=opts->(L)->( -- use "Convex" if available if ((options SRdeformations).Configuration)#"UseConvex"==true then return(hullConvex(L,opts)); vA:=joinVectors(L); P:=posHull vA; d:=P#"dimension of the cone"; embdim:=P#"ambient dimension"; if embdim!=d or P#"dimension of lineality space">0 then error("expected cone of full dimension without lineality space"); A:=sub(transpose rays(P),ZZ); Adual:=-sub(transpose rays dualCone P,ZZ); n:=rank target A; dn:=rank target Adual; y := getSymbol "y"; R:=QQ[y_0..y_(n-1)]; R.grading=A; v := getSymbol "v"; Rdual:=QQ[v_0..v_(dn-1)]; Rdual.grading=-Adual; Cl:=newEmptyComplex(R); dCl:=newEmptyComplex(Rdual); --fc:=faces(1,P); --fc=apply(fc,j->sub(transpose vertices j,ZZ)); --fc=apply(fc,j->face(matrixToVarlist(j,R),Cl)); --L1:={}; --for j from -1 to d-1 do (L1=append(L1,{})); --L1=append(L1,{face((entries vars R)#0,Cl)}); --addFacetDataToComplex(Cl,L1); --L1:={{},{face({},Cl,-1,0)}}; L1:={{face({},Cl,-1,0)}}; for j from 1 to d-1 do ( fc:=faces(d-j,P); fc=apply(fc,j->sub(transpose rays j,ZZ)); fc=apply(toList(0..(#fc-1)),jj->face(matrixToVarlist(fc#jj,R),Cl,j-1,jj)); L1=append(L1,fc); ); L1=append(L1,{face((entries vars R)#0,Cl,d-1,0)}); addFaceDataToComplex(Cl,L1); Cl.polytopalFacets=L1#(#L1-2); Cl.noBoundary=false; Cl.isPolytope=true; dCl.isPolytope=true; dCl.dualComplex=Cl; Cl.dualComplex=dCl; Cl.edim=Cl.edim-1; dCl.edim=dCl.edim-1; Cl) hull(String):=opts->(fn)->( {A,Adual,fcL}:=toSequence readPosHullFaces(fn); makeHull(A,Adual,fcL)) protect toFile hullConvex=method(Options=>{file=>null}) hullConvex(List):=opts->(L)->( {A,Adual,fcL}:=toSequence mPosHullFacesAndDuals(L,toFile=>opts.file); makeHull(A,Adual,fcL)) makeHull=method() makeHull(Matrix,Matrix,List):=(A,Adual,fcL)->( n:=rank target A; dn:=rank target Adual; y:=symbol y; R:=QQ[y_0..y_(n-1)]; R.grading=A; v:= symbol v; Rdual:=QQ[v_0..v_(dn-1)]; Rdual.grading=Adual; Cl:=newEmptyComplex(R); dCl:=newEmptyComplex(Rdual); fcL1:=apply(toList(0..(#fcL-1)),j->apply(toList(0..(#(fcL#j)-1)),jj->( F:=face(numberFace(fcL#j#jj#0,R),Cl,j-1,jj); dF:=face(numberFace(fcL#j#jj#1,Rdual),dCl,#fcL-2-j,jj); F.dualFace=dF; dF.dualFace=F; {F,dF}) )); fcL2:=apply(fcL1,j->apply(j,jj->jj#0)); dfcL1:=apply(fcL1,j->apply(j,jj->jj#1)); dfcL1=apply(toList(1..#dfcL1),j->dfcL1#(#dfcL1-j)); addFaceDataToComplex(Cl,fcL2); addFaceDataToComplex(dCl,dfcL1); Cl.polytopalFacets=Cl.fc_(-1+dim Cl); Cl.isPolytope=true; dCl.isPolytope=true; dCl.dualComplex=Cl; Cl.dualComplex=dCl; Cl.edim=Cl.edim-1; dCl.edim=dCl.edim-1; Cl) ---------------------------------------------------------------------------------------- convHull=method(Options=>{file=>null}) convHull(List):=opts->(L)->( -- use "Convex" if available if ((options SRdeformations).Configuration)#"UseConvex"==true then return(convHullConvex(L,opts)); vA:=joinVectors(L); P:=convexHull vA; d:=P#"dimension of polyhedron"; embdim:=P#"ambient dimension"; if embdim!=d or P#"dimension of lineality space">0 then error("expected polytope of full dimension without lineality space"); -- put QQ-ZZ test here !!!!!!!!!!!! A:=sub(transpose vertices(P),ZZ); n:=rank target A; y := getSymbol "y"; R:=QQ[y_0..y_(n-1)]; R.grading=A; Cl:=newEmptyComplex(R); --fc:=faces(1,P); --fc=apply(fc,j->sub(transpose vertices j,ZZ)); --fc=apply(fc,j->face(matrixToVarlist(j,R),Cl)); --L1:={}; --for j from -1 to d-1 do (L1=append(L1,{})); --L1=append(L1,{face((entries vars R)#0,Cl)}); --addFacetDataToComplex(Cl,L1); L1:={{face({},Cl,-1,0)}}; AdualL:={}; for j from 0 to d-1 do ( fc:=faces(d-j,P); if j==d-1 then AdualL=apply(fc,j1->-1/((j1#"hyperplanes"#1)_(0,0))*(entries(j1#"hyperplanes"#0))#0); fc=apply(fc,j->sub(transpose vertices j,ZZ)); fc=apply(toList(0..(#fc-1)),jj->face(matrixToVarlist(fc#jj,R),Cl,j,jj)); L1=append(L1,fc); ); L1=append(L1,{face((entries vars R)#0,Cl,d,0)}); addFaceDataToComplex(Cl,L1); Cl.polytopalFacets=L1#(#L1-2); Cl.noBoundary=false; Cl.isPolytope=true; --print(AdualL); --Adual:=transpose vertices polar P; --print(Adual); Adual:=matrix AdualL; dn:=rank target Adual; v := getSymbol "v"; Rdual:=QQ[v_0..v_(dn-1)]; Rdual.grading=Adual; dCl:=newEmptyComplex(Rdual); dCl.isPolytope=true; dCl.dualComplex=Cl; Cl.dualComplex=dCl; Cl) convHull(String):=opts->(fn)->( {A,Adual,fcL}:=toSequence readConvexHullFaces(fn); makeConvHull(A,Adual,fcL)) convHullConvex=method(Options=>{file=>null}) convHullConvex(List):=opts->(L)->( {A,Adual,fcL}:=toSequence mConvexHullFacesAndDuals(L,toFile=>opts.file); makeConvHull(A,Adual,fcL)) makeConvHull=method() makeConvHull(Matrix,Matrix,List):=(A,Adual,fcL)->( n:=rank target A; dn:=rank target Adual; y:=symbol y; R:=QQ[y_0..y_(n-1)]; R.grading=A; v:= symbol v; Rdual:=QQ[v_0..v_(dn-1)]; Rdual.grading=Adual; Cl:=newEmptyComplex(R); dCl:=newEmptyComplex(Rdual); fcL1:=apply(toList(0..(#fcL-1)),j->apply(toList(0..(#(fcL#j)-1)),jj->( F:=face(numberFace(fcL#j#jj#0,R),Cl,j-1,jj); dF:=face(numberFace(fcL#j#jj#1,Rdual),dCl,#fcL-2-j,jj); F.dualFace=dF; dF.dualFace=F; {F,dF}) )); fcL2:=apply(fcL1,j->apply(j,jj->jj#0)); dfcL1:=apply(fcL1,j->apply(j,jj->jj#1)); dfcL1=apply(toList(1..#dfcL1),j->dfcL1#(#dfcL1-j)); addFaceDataToComplex(Cl,fcL2); addFaceDataToComplex(dCl,dfcL1); Cl.polytopalFacets=Cl.fc_(-1+dim Cl); Cl.isPolytope=true; dCl.isPolytope=true; dCl.dualComplex=Cl; Cl.dualComplex=dCl; Cl) numberFace=method() numberFace(List,PolynomialRing):=(L,R)->( apply(L,j->R_(j-1))) --numberFace({1,3},QQ[x_0..x_6]) -* installPackage "SRdeformations" --L={vector {1,0,0},vector {0,1,0},vector {0,0,1},vector {-1,-1,-1}} --L={vector {1,0,0,0,0},vector {0,1,0,0,0},vector {0,0,1,0,0},vector {0,0,0,1,0},vector {0,0,0,0,1},vector {-1,-1,-1,-1,-1}} L={vector {1,0,0},vector {-1,0,0},vector {0,1,0},vector {0,-1,0},vector {0,0,1},vector {0,0,-1}} P=convHull(L,file=>"tst2.txt") convHull "tst2.txt" *- matrixToVarlist=method() matrixToVarlist(Matrix,PolynomialRing):=(B,R)->( A:=R.grading; v:=(entries vars R)#0; L:={}; for j from 0 to -1+rank target B do ( for jj from 0 to #v-1 do ( --print(A^{jj},B^{j}); if A^{jj}==B^{j} then L=append(L,v#jj); ); ); L) -* L={vector {1,0},vector {0,1},vector {-1,-1},vector {1,1}} --L={vector {1,0},vector {0,1},vector {-1,-1}} L={vector {1,0},vector {0,1},vector {-1,0},vector {0,-1}} P=convHull L dP=boundaryOfPolytope P fc dP R=QQ[x_0..x_3] I=ideal(x_0*x_3,x_1*x_2) C=idealToComplex I defs=deform C defs=join(defs,{firstOrderDeformation(I,vector {0,1,-1,0}), firstOrderDeformation(I,vector {0,-1,1,0}), firstOrderDeformation(I,vector {-1,0,0,1}), firstOrderDeformation(I,vector {1,0,0,-1})}) defslattice=apply(defs,j->preImage(R.grading,bigTorusDegree j)) P=convHull defslattice dP=boundaryOfPolytope P --computeFacesOfCompleteComplex dP P=convexHull joinVectors defslattice P.polytopalFacets fP=faces(1,P) fP=apply(fP,j->sub(transpose vertices j,ZZ)) Rv=QQ[v_0..v_7] Rv.grading=sub(transpose vertices P,ZZ) fP=apply(fP,j->matrixToVarlist(j,Rv)) *- ------------------------------------------------------------------- -- deformations polytope, tropical faces of it PT1=method(Options=>{file=>null}) PT1(Complex):=opts->(C)->( A:=C.grading; defs:=deform C; defsX:=apply(defs,j->bigTorusDegree j); defslattice:=apply(defsX,j->preImage(A,j)); convHull(defslattice,opts)); --PT1(C1) -* PT1(Complex):=(C)->( A:=C.grading; defs:=deform C; defsX:=apply(defs,j->bigTorusDegree j); defslattice:=apply(defsX,j->preImage(A,j)); convexHull joinVectors defslattice); *- tropDef=method() tropDef(Complex,Complex):=(C,P)->( defs:=deform C; ge:=(entries (defs#0).generators)#0; imgdefs:=apply(defs,j->apply(ge,jj->mapByLaurent(j,jj))); --patt:=apply(apply(defs,toHom),toPattern); patt:=apply(imgdefs,toPattern); A:=C.grading; ldefs:=apply(defs,j->preImage(A,j.bigTorusDegree)); B:=P.grading; Bv:=apply(entries B,vector); var:=(entries vars P.simplexRing)#0; varPatt:=apply(Bv,j->latticeToPattern(j,ldefs,patt)); --print(var,varPatt); L:={}; minimalTropicalFaces:={}; L1:={}; for j from -1 to edim(P) do ( L1={}; for jj from 0 to #(P.fc_j)-1 do ( if isSuperfaceList(minimalTropicalFaces,P.fc_j_jj)==true then ( L1=append(L1,P.fc_j_jj); ) else ( if isTropical(P.fc_j_jj,var,varPatt)==true then ( L1=append(L1,P.fc_j_jj); minimalTropicalFaces=append(minimalTropicalFaces,P.fc_j_jj); --print minimalTropicalFaces; ); ); ); L=append(L,L1)); coComplex(P.simplexRing,L,P.dualComplex.simplexRing)) --tropDef(C,defC) isSuperfaceList=method() isSuperfaceList(List,Face):=(L,F)->( tst:=false; j:=0; while j<#L and tst==false do ( if isSubface(L#j,F)==true then tst=true; j=j+1); tst) isTropical=method() isTropical(Face,List,List):=(F,var,varPatt)->( if #vert(F)==0 then return(false); -- !!!!!!!!!!! switch to lattice points instead of vertices; contractAND(faceToPattern(F,var,varPatt))) --isTropical(F,var,varPatt) toPattern=method() toPattern(Matrix):=(M)->( apply((entries M)#0,j->j!=0)) toPattern(List):=(L)->( apply(L,j->j!=0)) contractPattern=method() contractPattern(List):=(L)->( tst:=L#0; for j from 1 to #L-1 do ( tst=contractPair(tst,L#j); ); tst) --contractPattern(img) contractPair=method() contractPair(List,List):=(L1,L2)->( apply(toList(0..#L1-1),j->(L1#j or L2#j))) --contractPair({true,false},{false,false}) faceToPattern=method() faceToPattern(Face,List,List):=(F,var,varPatt)->( contractPattern(apply(vert F,j->variableToPattern(j,var,varPatt)))) --faceToPattern(F,var,varPatt) contractAND=method() contractAND(List):=(L)->( tst:=L#0; for j from 1 to #L-1 do ( tst=tst and L#j; if tst==false then return(false); ); tst) latticeToPattern=method() latticeToPattern(Vector,List,List):=(v,ldefs,patt)->( patt#((select(0..#ldefs-1,j->(ldefs#j==v)))#0)) --latticeToPattern(Bv#0,ldefs,patt) variableToPattern=method() variableToPattern(Thing,List,List):=(v,var,varPatt)->( j:=(select(0..#var-1,jj->(var#jj==v)))#0; varPatt#j) --variableToPattern(var#0,var,varPatt) -* installPackage "SRdeformations" R=QQ[x_0..x_3] C=idealToComplex ideal(x_0*x_1,x_2*x_3) defC=PT1 C TdefC=tropDef(C,defC) dualize TdefC defs=deform C; patt=apply(apply(defs,toHom),toPattern) A=C.grading ldefs=apply(defs,j->preImage(A,j.bigTorusDegree)) B=TdefC.grading Bv=apply(entries B,vector) var=(entries vars TdefC.simplexRing)#0 varPatt=apply(Bv,j->latticeToPattern(j,ldefs,patt)) *- -------------------------------------------------------------------- -- saving and loading complexes to files (todo) -* saveComplex=method() saveComplex(Complex,String):=(C,filename)->( F := openOut(filename|".txt"); F<<"new Complex from {"; F<<"symbol simplexRing =>"<<toString(C.simplexRing)<<","<<endl; F<<"symbol dim=>"|toString(C.dim)<<","<<endl; F<<"symbol edim=>"|toString(C.edim)<<","<<endl; F<<"symbol isEquidimensional=>"|toString(C.isEquidimensional)<<","<<endl; F<<"symbol isSimp=>"|toString(C.isSimp)<<","<<endl; F<<"symbol fvector=>"|toString(C.fvector)<<","<<endl; F<<"symbol grading=>"|toString(C.grading)<<"};"<<endl; close F; filename) saveComplex(C,"testc") toString(Face):=(F)->( S:=""; S=S| ) toString F loadComplex=method() loadComplex(String):=(filename)->( F := openIn(filename|".txt"); value get(F)) loadComplex("testc") *- ------------------------------------------------------------ -- homology of a complex homology(Complex):=opts->(C)->( if ((options SRdeformations).Configuration)#"UseConvex"==false then error("Only available via ConvexInterface and MapleInterface"); Lc:=apply(fc C,j->apply(j,coordinates)); mHomology Lc) -------------------------------------------------------------------- -* Copyright (C) [2009] [Janko Boehm] This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, see <http://www.gnu.org/licenses/> *- beginDocumentation() doc /// Key SRdeformations Headline Deformations of Stanley-Reisner rings and related computations. Description Text {\bf Overview:} The goal of this package is to provide a basic framework for deformations of Stanley-Reisner rings, the deformations polytope, its tropical subcomplex and tropical mirror symmetry in general. This is work in progress, many interesting pieces still missing and more testing is necessary. The efficiency and robustness of some of the pieces has to be improved. See the Macaulay 2 package repository for new versions of this file. All suggestions and contributions are welcome. {\bf Contents:} This package so far consists of the following parts: The first part provides a data structure for deformations of monomial ideals (including a toric grading). The class @TO FirstOrderDeformation@ stores (and computes the dimension of) a big torus graded part of the vector space of first order deformations (specified by a Laurent monomial). The second part gives an implementation of (not necessarily simplicial) embedded complexes and co-complexes and their correspondence to monomial ideals. The main focus here is on a flexible implementation, computing and storing data only as soon as it is needed. See @TO Complex@, @TO CoComplex@, @TO Face@. The third part computes all first order deformations of Stanley-Reisner ideals using part one and two via the results of Klaus Altmann and Jan Arthur Christophersen who reduce the problem to links of faces of simplicial complexes. See @TO deformationsFace@ and @TO deform@. The fourth part gives functions to compute the first order deformations polytope (see @TO PT1@) and its tropical subcocomplex (see @TO tropDef@). {\bf What' new:} {\it Jul 13, 2010 (Version 0.52)} Some changes to ensure compatibility with the current version of OldPolyhedra (1.1), in particular the method isSimplicial has been renamed to @TO isSimp@, as OldPolyhedra is now using the name name isSimplicial. {\it Jan 28, 2010 (Version 0.51)} Minor changes to ensure compatibility with the previous M2 version 1.2. Note that you will nevertheless need to install a more recent version of OldPolyhedra which also works with 1.2 (tested with 1.0.6). {\it Oct 24, 2009 (Version 0.50)} Added methods @TO (addCokerGrading,PolynomialRing,List)@ and @TO (raysPPn,List)@ to give the rays of the standard fan of weighted projective space. Fixed a bug in the multigrading. {\it Oct 18, 2009 (Version 0.49)} Fixed a problem in @TO convHull@ (correspondence of P.polytopalFacets with the vertices of the dual). This was only a problem when using OldPolyhedra.m2. {\it Oct 6, 2009 (Version 0.48)} Resolved a compatibility issue with the new version of the M2 package {\it OldPolyhedra}. {\it Oct 3, 2009 (Version 0.47)} Improvements to the documentation. {\it Sept 20, 2009 (Version 0.46)} Added a function @TO hull@ to compute the positive hull of a list of vectors. {\it Sept 8, 2009 (Version 0.45)} Adjusted the methods using ConvexInterface.m2 to version 0.25 which now indexes the vertices instead of using coordinates. This improves the performance substantially. Improved the computation of the dimension of a @TO FirstOrderDeformation@ using a much smaller linear system of equations. Fixed a bug in @TO (dim,Face)@. Exported the symbol @TO dualFace@ which stores the dual of a face to make this key available for the user. @TO convHull@ now stores in the faces their dimensions (see the key indices). Added an @TO Option@ @TO file@ to @TO convHull@ and @TO PT1@ to store the result in a file. @TO convHull@ applied to a @TO String@ reads a convex hull from a file. Improved speed of @TO globalSections@ when dealing with ideals in the Cox ring of projective space. Added an optional key deform to complexes storing the associated deformations, see @TO deform@. Added functions @TO saveDeformations@ and @TO loadDeformations@ to save to and load from a file the deformations associated to a @TO Complex@. {\bf Technical note:} In the future some of the methods and keys may change their name. At some point @TO Complex@ and @TO CoComplex@ will get a common ancestor. {\bf Installation:} @TO installPackage@("SRdeformations") {\bf Options:} Computations with polyhedra are used in this package so far in by following functions: @TO convHull@ -- The convex hull complex @TO globalSections@ -- The global sections of a toric divisor which again are called by @TO PT1@, @TO deform@ and @TO deformationsFace@. If @TO deform@ and @TO deformationsFace@ are used for @TO Complex@es inside a standard simplex, i.e., Stanley-Reisner ideals with the standard projective space grading, then they don't rely on polyhedra computations. There are two choices of M2 packages to be called for computations with polyhedra: @TO OldPolyhedra@: Works without additional configuration, but is not very fast. It uses the M2 package {\it FourierMotzkin}. To use {\it OldPolyhedra} do @TO loadPackage@("SRdeformations",Configuration=>\{"UseConvex"=>false\}) This is the standard configuration, i.e., it is synonymous to @TO loadPackage@("SRdeformations") {\it ConvexInterface}: This package has to be installed first, see its documentation for this. It calls the Maple package Convex and is faster than OldPolyhedra, hence the preferable choice. If you want to do non-trivial examples you have to go for it. To use it type @TO loadPackage@("SRdeformations",Configuration=>\{"UseConvex"=>true\}) Note that you can change the standard option by editing the file init-SRdeformations.m2 in the .Macaulay directory in your home directory (it will be overwritten when you reinstall a newer version of the package, but there will be a backup). {\bf Examples:} @TO mirrorSphere@ uses the above functions to compute the mirror sphere of a Calabi-Yau. The author was supported by DFG (German Research Foundation) through Grant BO3330/1-1. /// --------------------------------------------------------------------- -- various doc /// Key cokerElement (cokerElement,Vector,Matrix) (cokerElement,Matrix,Matrix) Headline Gives an element in the cokernel of a matrix. Usage cokerElement(v,A) Inputs v:Vector A:Matrix Outputs :Thing Description Text Gives the element in the @TO cokernel@ of A represented by v. The @TO Vector@ v has to lie in @TO target@ of A. Example A= matrix {{-1, -1, -1}, {1, 0, 0}, {0, 1, 0}, {0, 0, 1}} c1=cokerElement(vector {1,1,0,0},A) c2=cokerElement(vector {1,-1,0,0},A) c2==(0_(class c2)) iszero c2 SeeAlso inducedMap /// doc /// Key iszero (iszero,Thing) Headline Tests whether something is zero. Usage iszero(c) Inputs c:Thing Outputs :Boolean Description Text Makes the test c == 0_@TO class@ c. Why does @TO zero@ not work for elements in the cokernel of a matrix? Example A= matrix {{-1, -1, -1}, {1, 0, 0}, {0, 1, 0}, {0, 0, 1}} c1=cokerElement(vector {1,1,0,0},A) c2=cokerElement(vector {1,-1,0,0},A) c2==(0_(class c2)) iszero c2 iszero c1 SeeAlso zero cokerElement /// doc /// Key vectorToMonomial (vectorToMonomial,Vector,PolynomialRing) Headline Converts an exponent vector into a monomial. Usage vectorToMonomial(v,R) Inputs v:Vector R:PolynomialRing Outputs :RingElement Description Text Converts the exponent vector v into a monomial in the variables of R. The number of variables of R has to match the length of v. Example R=QQ[x_0..x_4] m=vector {1,2,1,0,0} vectorToMonomial(m,R) SeeAlso laurent /// doc /// Key laurent (laurent,Vector,PolynomialRing) (laurent,FirstOrderDeformation) Headline Converts an exponent vector or a deformation into a Laurent monomial. Usage laurent(v,R) laurent(f) Inputs v:Vector f:FirstOrderDeformation R:PolynomialRing Outputs :RingElement Description Text Converts the exponent vector v into a Laurent monomial in the variables of R. The result lies in @TO frac@ R. The number of variables of R has to match the length of v. If given a @TO FirstOrderDeformation@ it returns the corresponding laurent monomial. Example R=QQ[x_0..x_4] m=vector {1,-2,1,0,0} laurent(m,R) Text Example R=QQ[x_0..x_4] addCokerGrading(R); I=ideal(x_0*x_1,x_1*x_2,x_2*x_3,x_3*x_4,x_4*x_0) mg=mingens I; f=firstOrderDeformation(mg, vector {-1,-1,0,2,0}) laurent f SeeAlso laurent /// ----------------------------------------------------------------------------------------- -- first order deformations of monomial ideals doc /// Key FirstOrderDeformation Headline The class of all first order deformations of monomial ideals. Description Text The class of all first order deformations of reduced monomial ideals. Elements represent a big torus (i.e., torus on the variables of a @TO PolynomialRing@) graded part of the vector space of first order deformations. By results of Klaus Altmann and Jan Arthur Christophersen the dimension is either 0 or 1 (for manifolds, though this is not required by the implementation). First order deformations can be created by @TO firstOrderDeformation@ by specifying a matrix with generators of a reduced monomial ideal and the exponent vector of a Laurent-monomial (i.e., a big torus degree). {\bf Functions producing (sets of) first order deformations:} @TO deform@ -- Compute the deformations associated to a Stanley-Reisner complex. @TO deformationsFace@ -- Compute the deformations associated to a face @TO trivialDeformations@ -- Compute the trivial deformations @TO firstOrderDeformation@ -- Makes a first order deformation {\bf The data stored in a first order deformation f are} {\it f.gens}, a @TO matrix@ with generators of @TO source@ of the homomorphisms represented by f. {\it f.bigTorusDegree}, the exponent vector of the Laurent monomial. {\it f.degree}, the small torus (i.e., with respect to the grading added to R by @TO addCokerGrading@) degree of f. {\it f.isHomogeneous}, a @TO Boolean@ indicating if f.degree is zero. {\it f.relevantGens}, a @TO Matrix@ with those elements of f.gens which are relevant to the deformation f (i.e., those m which have numerator(m*laurent(f)) not in ideal(f.gens)). {\it f.relationsCoefficients}, @TO matrix@ of relations on coefficients of f. The rows correspond to the generators given in f.relevantGens. {\it f.parameters}, a @TO Matrix@ whose image is the @TO kernel@ of the @TO transpose@ of f.relationsCoefficients extended by zeros for the elements of f.gens not in f.relevantGens. The rows correspond to the generators given in f.gens. {\it f.dim}, the dimension of the f-graded part of the deformation space of @TO ideal@ f.gens. {\it f.isNonzero}, a @TO Boolean@ indicating whether f is non-zero. {\it f.isTrivial}, a @TO Boolean@ indicating whether f is trivial, i.e., @TO denominatorMonomial@ f has degree 1. For an example see @TO "Example first order deformation"@. This data can also be accessed by the methods listed below. @TO laurent@ represents f as a Laurent monomial, @TO toHom@ represents f as a homomorphism. @TO totalSpace@ computes the total space of f. Example R=QQ[x_0..x_4]; addCokerGrading(R) I=ideal(x_0*x_1,x_1*x_2,x_2*x_3,x_3*x_4,x_4*x_0) mg=mingens I; f=firstOrderDeformation(mg, vector {-1,-1,0,2,0}) degree f dim f f1=firstOrderDeformation(mg,vector {-1,1,0,0,0}) isTrivial f1 f2=firstOrderDeformation(mg,vector {0,-1,-1,2,0}) isNonzero f2 SeeAlso simplexRing (target,FirstOrderDeformation) (source,FirstOrderDeformation) gensSource bigTorusDegree (numerator,FirstOrderDeformation) (denominator,FirstOrderDeformation) numeratorMonomial denominatorMonomial (degree,FirstOrderDeformation) (grading,FirstOrderDeformation) (isHomogeneous,FirstOrderDeformation) relationsCoefficients parameters (dim,FirstOrderDeformation) isNonzero isTrivial laurent toHom totalSpace trivialDeformations Caveat If we run into performance issues some of the redundant data will be removed, so for future compatibility access the data by the corresponding @TO method@ not via the @TO MutableHashTable@. /// doc /// Key "Example first order deformation" Headline Example accessing the data stored in a first order deformation. Description Text Example for accessing the data stored in a first order deformation: Example R=QQ[x_0..x_4]; addCokerGrading(R) I=ideal(x_0*x_1,x_1*x_2,x_2*x_3,x_3*x_4,x_4*x_0) mg=mingens I; f=firstOrderDeformation(mg, vector {-1,-1,0,2,0}) f.gens f.bigTorusDegree simplexRing f target f source f numerator f denominator f bigTorusDegree f numeratorMonomial f degree f grading f isHomogeneous f relationsCoefficients f parameters f dim f isNonzero f isTrivial f SeeAlso simplexRing (target,FirstOrderDeformation) (source,FirstOrderDeformation) bigTorusDegree (numerator,FirstOrderDeformation) (denominator,FirstOrderDeformation) numeratorMonomial denominatorMonomial (degree,FirstOrderDeformation) (grading,FirstOrderDeformation) (isHomogeneous,FirstOrderDeformation) relationsCoefficients parameters (dim,FirstOrderDeformation) isNonzero isTrivial laurent toHom totalSpace /// doc /// Key simplexRing Headline The underlying polynomial ring of a deformation or face or complex. Description Text The underlying polynomial ring of a deformation or face or complex. /// doc /// Key (simplexRing,FirstOrderDeformation) Headline The underlying polynomial ring of a deformation or face. Usage simplexRing(f) Inputs f:FirstOrderDeformation Outputs :PolynomialRing Description Text Returns the underlying @TO PolynomialRing@ of f. Example R=QQ[x_0..x_4]; addCokerGrading(R); I=ideal(x_0*x_1,x_1*x_2,x_2*x_3,x_3*x_4,x_4*x_0) mg=mingens I; f=firstOrderDeformation(mg, vector {-1,-1,0,2,0}) simplexRing f SeeAlso FirstOrderDeformation firstOrderDeformation addCokerGrading /// doc /// Key bigTorusDegree (bigTorusDegree,FirstOrderDeformation) Headline The big torus degree of a deformation. Usage bigTorusDegree(f) Inputs f:FirstOrderDeformation Outputs :Vector Description Text Returns the exponent vector of the Laurent monomial representing f. Example R=QQ[x_0..x_4] addCokerGrading(R) I=ideal(x_0*x_1,x_1*x_2,x_2*x_3,x_3*x_4,x_4*x_0) mg=mingens I; f=firstOrderDeformation(mg, vector {-1,-1,0,2,0}) bigTorusDegree f SeeAlso FirstOrderDeformation firstOrderDeformation addCokerGrading /// doc /// Key (target,FirstOrderDeformation) Headline The target of a deformation. Usage target(f) Inputs f:FirstOrderDeformation Outputs :Module Description Text Returns the @TO target@ of the homomorphisms represented by f. Example R=QQ[x_0..x_4]; addCokerGrading(R); I=ideal(x_0*x_1,x_1*x_2,x_2*x_3,x_3*x_4,x_4*x_0) mg=mingens I; f=firstOrderDeformation(mg, vector {-1,-1,0,2,0}) target f SeeAlso FirstOrderDeformation firstOrderDeformation addCokerGrading /// doc /// Key (source,FirstOrderDeformation) Headline The source of a deformation. Usage source(f) Inputs f:FirstOrderDeformation Outputs :Module Description Text Returns the @TO source@ of the homomorphisms represented by f. Example R=QQ[x_0..x_4] addCokerGrading(R) I=ideal(x_0*x_1,x_1*x_2,x_2*x_3,x_3*x_4,x_4*x_0) mg=mingens I; f=firstOrderDeformation(mg, vector {-1,-1,0,2,0}) source f SeeAlso FirstOrderDeformation firstOrderDeformation addCokerGrading /// doc /// Key (numerator,FirstOrderDeformation) Headline The numerator of a deformation as a vector. Usage numerator(f) Inputs f:FirstOrderDeformation Outputs :Vector Description Text Returns the numerator of a deformation as a vector. Example R=QQ[x_0..x_4]; addCokerGrading(R); I=ideal(x_0*x_1,x_1*x_2,x_2*x_3,x_3*x_4,x_4*x_0) mg=mingens I; f=firstOrderDeformation(mg, vector {-1,-1,0,2,0}) numerator f SeeAlso FirstOrderDeformation numeratorMonomial denominatorMonomial (denominator,FirstOrderDeformation) firstOrderDeformation addCokerGrading /// doc /// Key (denominator,FirstOrderDeformation) Headline The denominator of a deformation as a vector. Usage denominator(f) Inputs f:FirstOrderDeformation Outputs :Vector Description Text Returns the denominator of a deformation as a vector. Example R=QQ[x_0..x_4]; addCokerGrading(R); I=ideal(x_0*x_1,x_1*x_2,x_2*x_3,x_3*x_4,x_4*x_0) mg=mingens I; f=firstOrderDeformation(mg, vector {-1,-1,0,2,0}) denominator f SeeAlso FirstOrderDeformation denominatorMonomial numeratorMonomial (numerator,FirstOrderDeformation) firstOrderDeformation addCokerGrading /// doc /// Key numeratorMonomial (numeratorMonomial,FirstOrderDeformation) Headline The numerator monomial of a deformation. Usage numeratorMonomial(f) Inputs f:FirstOrderDeformation Outputs :RingElement Description Text Returns the numerator monomial of a deformation. Example R=QQ[x_0..x_4]; addCokerGrading(R); I=ideal(x_0*x_1,x_1*x_2,x_2*x_3,x_3*x_4,x_4*x_0) mg=mingens I; f=firstOrderDeformation(mg, vector {-1,-1,0,2,0}) numeratorMonomial f SeeAlso FirstOrderDeformation denominatorMonomial (denominator,FirstOrderDeformation) (numerator,FirstOrderDeformation) firstOrderDeformation addCokerGrading /// doc /// Key denominatorMonomial (denominatorMonomial,FirstOrderDeformation) Headline The denominator monomial of a deformation. Usage denominatorMonomial(f) Inputs f:FirstOrderDeformation Outputs :RingElement Description Text Returns the denominator monomial of a deformation. Example R=QQ[x_0..x_4]; addCokerGrading(R); I=ideal(x_0*x_1,x_1*x_2,x_2*x_3,x_3*x_4,x_4*x_0) mg=mingens I; f=firstOrderDeformation(mg, vector {-1,-1,0,2,0}) denominatorMonomial f SeeAlso FirstOrderDeformation numeratorMonomial (denominator,FirstOrderDeformation) (numerator,FirstOrderDeformation) firstOrderDeformation addCokerGrading /// doc /// Key (degree,FirstOrderDeformation) Headline The small torus degree of a deformation. Usage degree(f) Inputs f:FirstOrderDeformation Outputs :Thing Description Text Computes the small torus degree (i.e., with respect to the grading added to R = @TO simplexRing@ f by @TO addCokerGrading@) of f. Example R=QQ[x_0..x_4]; addCokerGrading(R); I=ideal(x_0*x_1,x_1*x_2,x_2*x_3,x_3*x_4,x_4*x_0) mg=mingens I; f=firstOrderDeformation(mg, vector {-1,-1,0,2,0}) degree f SeeAlso grading (isHomogeneous,FirstOrderDeformation) addCokerGrading firstOrderDeformation /// doc /// Key grading Headline The grading of a first order deformation or complex or polynomial ring. Description Text The coker grading of a @TO FirstOrderDeformation@ or @TO Complex@ or @TO PolynomialRing@. /// -* SeeAlso (grading,FirstOrderDeformation) (grading,Complex) (grading,PolynomialRing) *- doc /// Key (grading,PolynomialRing) Headline The coker grading of a polynomial ring. Usage grading(R) Inputs R:PolynomialRing Outputs :Matrix Description Text Returns the small torus grading (coker grading) of R , i.e., the grading added to R by @TO addCokerGrading@. Example R=QQ[x_0..x_4]; addCokerGrading(R); grading R SeeAlso addCokerGrading /// doc /// Key (grading,FirstOrderDeformation) Headline The small torus grading of a deformation. Usage grading(f) Inputs f:FirstOrderDeformation Outputs :Matrix Description Text Returns the small torus grading of R = @TO simplexRing@ C, i.e., the grading added to R by @TO addCokerGrading@. Example R=QQ[x_0..x_4]; addCokerGrading(R); I=ideal(x_0*x_1,x_1*x_2,x_2*x_3,x_3*x_4,x_4*x_0) mg=mingens I; f=firstOrderDeformation(mg, vector {-1,-1,0,2,0}) grading f SeeAlso (degree,FirstOrderDeformation) (isHomogeneous,FirstOrderDeformation) addCokerGrading firstOrderDeformation /// doc /// Key (isHomogeneous,FirstOrderDeformation) Headline Check whether a deformation is homogeneous. Usage isHomogeneous(f) Inputs f:FirstOrderDeformation Outputs :Boolean Description Text Checks whether a deformation f is homogeneous with respect to the small torus grading, i.e., the grading added to R = @TO simplexRing@ f by @TO addCokerGrading@. Example R=QQ[x_0..x_4]; addCokerGrading(R); I=ideal(x_0*x_1,x_1*x_2,x_2*x_3,x_3*x_4,x_4*x_0) mg=mingens I; f=firstOrderDeformation(mg, vector {-1,-1,0,2,0}) isHomogeneous f SeeAlso (degree,FirstOrderDeformation) grading firstOrderDeformation addCokerGrading /// doc /// Key (dim,FirstOrderDeformation) Headline Compute the dimension of a deformation. Usage dim(f) Inputs f:FirstOrderDeformation Outputs :ZZ non-negative Description Text Computes the dimension of the big torus degree f part of the deformation space of @TO (source,FirstOrderDeformation)@ f. Example R=QQ[x_0..x_4]; addCokerGrading(R); I=ideal(x_0*x_1,x_1*x_2,x_2*x_3,x_3*x_4,x_4*x_0) mg=mingens I; f=firstOrderDeformation(mg, vector {-1,-1,0,2,0}) dim f SeeAlso relationsCoefficients parameters firstOrderDeformation addCokerGrading /// doc /// Key isNonzero (isNonzero,FirstOrderDeformation) Headline Check whether a deformation is non-zero. Usage isNonzero(f) Inputs f:FirstOrderDeformation Outputs :Boolean Description Text Check whether f is non-zero. Example R=QQ[x_0..x_4]; addCokerGrading(R); I=ideal(x_0*x_1,x_1*x_2,x_2*x_3,x_3*x_4,x_4*x_0) mg=mingens I; f=firstOrderDeformation(mg, vector {-1,-1,0,2,0}) isNonzero f f1=firstOrderDeformation(mg, vector {-1,-1,2,0,0}) isNonzero f1 SeeAlso dim isTrivial firstOrderDeformation addCokerGrading /// doc /// Key isTrivial (isTrivial,FirstOrderDeformation) (isTrivial,Vector) Headline Check whether a deformation is trivial. Usage isTrivial(f) Inputs f:FirstOrderDeformation Outputs :Boolean Description Text Check whether f is trivial, i.e., @TO denominatorMonomial@ f has degree 1. Example R=QQ[x_0..x_4]; addCokerGrading(R); I=ideal(x_0*x_1,x_1*x_2,x_2*x_3,x_3*x_4,x_4*x_0) mg=mingens I; f=firstOrderDeformation(mg, vector {-1,-1,0,2,0}) isTrivial f f1=firstOrderDeformation(mg, vector {-1,1,0,0,0}) isTrivial f1 SeeAlso isNonzero denominatorMonomial firstOrderDeformation addCokerGrading trivialDeformations /// doc /// Key (net,FirstOrderDeformation) Headline Pretty print for deformations. Usage net(f) Inputs f:FirstOrderDeformation Outputs :Net Description Text Pretty print for deformations. Prints @TO laurent@ f and @TO (dim,FirstOrderDeformation)@ f. Example R=QQ[x_0..x_4] addCokerGrading(R) I=ideal(x_0*x_1,x_1*x_2,x_2*x_3,x_3*x_4,x_4*x_0) mg=mingens I; f=firstOrderDeformation(mg, vector {-1,-1,0,2,0}) SeeAlso Net net /// doc /// Key gensSource (gensSource,FirstOrderDeformation) Headline Generators of the source of a deformation. Usage gensSource(f) Inputs f:FirstOrderDeformation Outputs :Matrix Description Text Returns generators of the @TO (source,FirstOrderDeformation)@ f. Example R=QQ[x_0..x_4]; addCokerGrading(R); I=ideal(x_0*x_1,x_1*x_2,x_2*x_3,x_3*x_4,x_4*x_0) mg=mingens I; f=firstOrderDeformation(mg, vector {-1,-1,0,2,0}) gensSource f SeeAlso (source,FirstOrderDeformation) firstOrderDeformation addCokerGrading /// doc /// Key totalSpace (totalSpace,FirstOrderDeformation,PolynomialRing) (totalSpace,List,PolynomialRing) Headline Total space of a deformation. Usage totalSpace(f,R) totalSpace(L,R) Inputs f:FirstOrderDeformation L:List of @TO FirstOrderDeformation@s. T:PolynomialRing Outputs :Ideal Description Text Compute the total space of a first order deformation f or a list of first order deformations. The polynomial ring T is used for the base. The number of variables of T should match @TO (dim,FirstOrderDeformation)@ f (respectively the sum over the deformations in L). Example R=QQ[x_0..x_4]; addCokerGrading(R); I=ideal(x_0*x_1,x_1*x_2,x_2*x_3,x_3*x_4,x_4*x_0) mg=mingens I; f=firstOrderDeformation(mg, vector {-1,-1,0,2,0}) S=QQ[t] totalSpace(f,S) f1=firstOrderDeformation(mg, vector {0,-1,-1,0,2}) S=QQ[t1,t2] totalSpace({f,f1},S) SeeAlso firstOrderDeformation addCokerGrading /// doc /// Key toHom (toHom,FirstOrderDeformation) Headline Convert a first order deformation into a homomorphism. Usage toHom(f) Inputs f:FirstOrderDeformation Outputs :Matrix Description Text Convert f into a homomorphism @TO (source,FirstOrderDeformation)@ f -> @TO (target,FirstOrderDeformation)@ f. Requires @TO (dim,FirstOrderDeformation)@ f to be 0 or 1. Example R=QQ[x_0..x_4]; addCokerGrading(R); I=ideal(x_0*x_1,x_1*x_2,x_2*x_3,x_3*x_4,x_4*x_0) mg=mingens I; f=firstOrderDeformation(mg, vector {-1,-1,0,2,0}) fhom=toHom f source fhom target fhom SeeAlso (source,FirstOrderDeformation) (target,FirstOrderDeformation) firstOrderDeformation addCokerGrading /// doc /// Key relationsCoefficients (relationsCoefficients,FirstOrderDeformation) (relationsCoefficients,Matrix,Vector) Headline Relations between the coefficients of a deformation. Usage relationsCoefficients(f) Inputs f:FirstOrderDeformation Outputs :Matrix Description Text Computes the @TO matrix@ whose columns generate the relations on the coefficients of the @TO image@s of the @TO generators@ of @TO (source,FirstOrderDeformation)@ f considering it as a homomorphism. Example R=QQ[x_0..x_4]; addCokerGrading(R); I=ideal(x_0*x_1,x_1*x_2,x_2*x_3,x_3*x_4,x_4*x_0) mg=mingens I; f=firstOrderDeformation(mg, vector {-1,1,0,0,0}) relationsCoefficients f SeeAlso (source,FirstOrderDeformation) parameters firstOrderDeformation addCokerGrading /// doc /// Key parameters (parameters,FirstOrderDeformation) (parameters,Matrix,Vector) Headline Parameters of a deformation. Usage parameters(f) Inputs f:FirstOrderDeformation Outputs :Matrix Description Text Computes a @TO matrix@ whose columns correspond to the parameters of f (i.e., to the coefficients of the @TO image@s of the @TO generators@ of @TO (source,FirstOrderDeformation)@ f considering it as a homomorphism. Example R=QQ[x_0..x_4]; addCokerGrading(R); I=ideal(x_0*x_1,x_1*x_2,x_2*x_3,x_3*x_4,x_4*x_0) mg=mingens I; f=firstOrderDeformation(mg, vector {-1,1,0,0,0}) relationsCoefficients f parameters f SeeAlso (dim,FirstOrderDeformation) relationsCoefficients firstOrderDeformation addCokerGrading /// doc /// Key firstOrderDeformation (firstOrderDeformation,Ideal,Vector) (firstOrderDeformation,MonomialIdeal,Vector) (firstOrderDeformation,Matrix,Vector) Headline Makes a first order deformation. Usage firstOrderDeformation(mg,v) firstOrderDeformation(I,v) Inputs I:Ideal monomial, reduced, in a @TO PolynomialRing@, or I:MonomialIdeal reduced mg:Matrix row, with generators of a reduced monomial ideal. Outputs :FirstOrderDeformation Description Text Generates a first order deformation @TO ideal@ mg. If it is given an ideal I then @TO generators@ of I are stored to have a reference for @TO parameters@. You can also give non-minimal generators. Example R=QQ[x_0..x_4]; addCokerGrading(R) I=ideal(x_0*x_1,x_1*x_2,x_2*x_3,x_3*x_4,x_4*x_0) mg=mingens I; f=firstOrderDeformation(mg, vector {-1,1,0,0,0}) SeeAlso FirstOrderDeformation (dim,FirstOrderDeformation) addCokerGrading /// doc /// Key (symbol ==,FirstOrderDeformation,FirstOrderDeformation) Headline Compare two first order deformations. Usage f1==f2 Inputs f1:FirstOrderDeformation f2:FirstOrderDeformation Outputs :Boolean Description Text Checks whether f1 and f2 are equal. Example R=QQ[x_0..x_4]; addCokerGrading(R) I=ideal(x_0*x_1,x_1*x_2,x_2*x_3,x_3*x_4,x_4*x_0) mg=mingens I; f1=firstOrderDeformation(mg, vector {-1,1,0,0,0}) f2=firstOrderDeformation(mg, vector {0,2,0,-1,-1}) f2==f2 f2==f1 /// doc /// Key trivialDeformations (trivialDeformations,Complex) (trivialDeformations,Matrix) (trivialDeformations,Ideal,Matrix) Headline Compute the trivial deformations. Usage trivialDeformations(C) Inputs C:Complex Outputs :List of @TO FirstOrderDeformation@ Description Text Compute the deformations induced by root automorphisms of the embedding space (i.e., excluding those coming from the torus). Example R=QQ[x_0..x_4]; addCokerGrading(R) I=ideal(x_0*x_1,x_1*x_2,x_2*x_3,x_3*x_4,x_4*x_0) C=idealToComplex I T=trivialDeformations C tally apply(T,isTrivial) /// -* Everything should also work for non-reduced monomial ideals, but not tested. *- ------------------------------------------------------------------------------------------- -- complexes and cocomplexes doc /// Key addCokerGrading (addCokerGrading,PolynomialRing) (addCokerGrading,PolynomialRing,List) (addCokerGrading,PolynomialRing,Matrix) Headline Stores a cokernel grading in a polynomial ring. Usage addCokerGrading(R) addCokerGrading(R,L) addCokerGrading(R,A) Inputs R:PolynomialRing L:List A:Matrix Outputs :Matrix the integer grading matrix. Description Text Stores a cokernel grading (Cox grading) in a polynomial ring. This data is accessed by @TO FirstOrderDeformation@ to compute the small torus @TO (degree,FirstOrderDeformation)@ of a deformation, and by @TO Complex@ and @TO CoComplex@ to store the vertices. The number or rows of A has to match the number of variables of R. If A is not specified, @TO raysPPn@ R is used. If L is specified then the grading of a weighted projective space is added. This command does not change the behaviour of R with respect to the standard Macaulay2 image grading, which we want to use independently. Example R=QQ[x_0..x_4]; addCokerGrading(R); R.grading Text Weighted projective space: Example R=QQ[x_0..x_4]; addCokerGrading(R,{1,1,2,2,3}); R.grading SeeAlso FirstOrderDeformation raysPPn /// doc /// Key raysPPn (raysPPn,ZZ) (raysPPn,List) Headline The rays of the standard fan of projective space or weighted projective space. Usage raysPPn(n) Inputs n:ZZ positive L:List with at least 2 elements and first entry 1 Outputs :Matrix Description Text Returns a matrix which has in its rows the rays of the standard fan of projective space of dimension n or weighted projective space with the weights L. Example raysPPn(2) SeeAlso addCokerGrading /// doc /// Key Face Headline The class of all faces of complexes or co-complexes. Description Text The class of all faces of @TO Complex@es or @TO CoComplex@es. {\bf Creating faces:} Faces can be created by @TO face@ by specifying a @TO List@ or @TO Set@ of variables of a @TO PolynomialRing@ and some more optional data. Usually faces are accessed as faces of a @TO complex@ C using the @TO ScriptedFunctor@ C.fc with the subscripts "dimension of the face" and "index of the face". {\bf The data stored in a face F:} {\it F.vert}, a list with the vertices of F, which are variables of a @TO PolynomialRing@ R. We use a list to prevent Macaulay from reordering sets or monomials. {\it F.ofComplex}, a list with the @TO Complex@es and @TO CoComplex@es of which F is a face (optional). {}it F.indices}, a list with the indices of the face in its complexes. An index is a list {dim F, index of F in C.fc_(dim F)}. {\it F.dualFace}, the dual face of F (optional, is stored for later use when computed by @TO dualize@). Note that also the dual face dF of F then has dF.dualFace=F. This data can also be accessed by the methods listed below. Note that the lattice data of the vertices is stored in R.grading via @TO addCokerGrading@. If no coker grading is present then many functions, like @TO simplex@, @TO idealToComplex@, @TO idealToCoComplex@ add the standard projective space grading @TO raysPPn@. {\bf Notes on the implementation:} In order to save memory identical faces are not created several times, e.g., if sub@TO Complex@es are created from given ones any face of the subcomplex is identical to a face of the given one. So far the list F.ofComplex is only used for the complex which created F, but later we will perhaps append also all other complexes F is a face of. As we will append to the list this will be backwards compatible. Example R=QQ[x_0..x_4] addCokerGrading R C=simplex R F=C.fc_1_0 F.vert coordinates F (F.ofComplex)#0==C bC=boundaryOfPolytope C F==bC.fc_1_0 SeeAlso Complex CoComplex ofComplex vert dual addCokerGrading simplex boundaryOfPolytope coordinates /// doc /// Key (dim,Complex) Headline Compute the dimension of a complex or co-complex. Usage dim(C) Inputs C:Complex Outputs :ZZ bigger or equal to -1 Description Text Computes the dimension of a complex. Example R=QQ[x_0..x_4] addCokerGrading R C=simplex R dim C bC=boundaryOfPolytope C dim bC dbC=dualize bC dim dbC SeeAlso Complex CoComplex /// doc /// Key (dim,Face) Headline Compute the dimension of a face. Usage dim(F) Inputs F:Face Outputs :ZZ bigger or equal to -1 Description Text Computes the dimension of a face. If F.indices is present (usually the case by construction) this requires no computations. If F.indices is not present but a polynomial ring R can be associated to F (which is the case if F.ofComplex is present (or given as a second argument) or F is non-empty) then R.grading (which can be installed by @TO addCokerGrading@) is used to compute the dimension of the plane spanned by F. Example R=QQ[x_0..x_4] addCokerGrading R C=simplex R bC=boundaryOfPolytope C F=bC.fc_2_0 dim(face vert F,R) SeeAlso Complex CoComplex Caveat If F.indices is not present this returns a dimension as explained above but note that this does not check whether F is a face of the convex hull of the rows of R.grading. /// doc /// Key (dim,Face,Complex) Headline Compute the dimension of a face. Usage dim(F,C) Inputs F:Face C:Complex Outputs :ZZ bigger or equal to -1 Description Text Computes the dimension of a face. If F.indices is present (usually the case by construction) this requires no computations. If F.indices is not present but a polynomial ring R can be associated to F (which is the case if F.ofComplex is present (or given as a second argument) or F is non-empty) then R.grading (which can be installed by @TO addCokerGrading@) is used to compute the dimension of the plane spanned by F. Example R=QQ[x_0..x_4] addCokerGrading R C=simplex R bC=boundaryOfPolytope C F=bC.fc_2_0 dim(face vert F,C) SeeAlso Complex CoComplex Caveat If F.indices is not present this returns a dimension as explained above but note that this does not check whether F is a face of the convex hull of the rows of R.grading. /// doc /// Key (dim,Face,PolynomialRing) Headline Compute the dimension of a face. Usage dim(F,R) Inputs F:Face R:PolynomialRing with coker grading. Outputs :ZZ bigger or equal to -1 Description Text Computes the dimension of a face. If F.indices is present (usually the case by construction) this requires no computations. If F.indices is not present but a polynomial ring R can be associated to F (which is the case if F.ofComplex is present (or given as a second argument) or F is non-empty) then R.grading (which can be installed by @TO addCokerGrading@) is used to compute the dimension of the plane spanned by F. Example R=QQ[x_0..x_4] addCokerGrading R C=simplex R bC=boundaryOfPolytope C F=bC.fc_2_0 dim F SeeAlso Complex CoComplex Caveat If F.indices is not present this returns a dimension as explained above but note that this does not check whether F is a face of the convex hull of the rows of R.grading. /// doc /// Key (complement,Face) Headline Compute the complement face of a simplex. Usage complement(F) Inputs F:Face Outputs :Face Description Text Computes the complement face of a face of a simplex (or subcomples thereof). Example R=QQ[x_0..x_4] C=simplex R bC=boundaryOfPolytope C F=bC.fc_2_0 complement F SeeAlso (complement,Complex) /// doc /// Key (complement,Complex) Headline Compute the complement CoComplex. Usage complement(C) Inputs C:Complex Outputs :CoComplex Description Text Given a @TO Complex@ it returns the @TO CoComplex@ of complement @TO Face@s and vice versa. The complement (co)complex cC is remembered in C.complementComplex=cC and cC.complementComplex=C. Example R=QQ[x_0..x_4] addCokerGrading R C=simplex R bC=boundaryOfPolytope C cbC=complement bC complement cbC == bC SeeAlso (complement,Face) /// doc /// Key coordinates (coordinates,Face) (coordinates,Face,Complex) Headline The coordinates of a face. Usage coordinates(C) Inputs F:Face Outputs :List Description Text Returns the coordinates of a face if some coker graded ring can be associated to F (if there is non one can give the second argument C). Example R=QQ[x_0..x_4] addCokerGrading R C=simplex R bC=boundaryOfPolytope C F=bC.fc_2_0 coordinates F SeeAlso addCokerGrading /// doc /// Key dualize (dualize,Face) (dualize,Complex) Headline The dual of a face or complex. Usage dualize(F) dualize(C) Inputs F:Face C:Complex C:CoComplex Outputs :CoComplex Description Text Returns the dual of a face or a (co)complex. This is in the sense of dual face of Polytopes, so the faces of C have to be faces of a polytope. The dual (co)complex dC is stored in C.dualComplex=dC and dC.dualComplex=C. Note that if C is a Stanley-Reisner subcomplex of a simplex then dualize complement C is the isomorphic geometric complex of strata. Example R=QQ[x_0..x_4] addCokerGrading R C=simplex R bC=boundaryOfPolytope C F=bC.fc_2_0 coordinates F dualize F coordinates dualize F dbC=dualize bC complement F coordinates complement F complement bC dualize complement bC bC coordinates dualize complement F coordinates F SeeAlso (complement,Face) (complement,Complex) /// doc /// Key (indices,Face) Headline The indices of a face. Usage indices(F) Inputs F:Face Outputs :List Description Text Returns the indices of the face with respect to the first complex in F.ofComplex. The first entry d is the dimension and the second the index of F in the list (ofComplex F).fc_d. Example R=QQ[x_0..x_4]; C=simplex R F=C.fc_2_0 indices F SeeAlso ofComplex /// doc /// Key ofComplex (ofComplex,Face) Headline The complex of a face. Usage ofComplex(F) Inputs F:Face Outputs :Complex Description Text Returns the complex of F, i.e., the first entry in F.ofComplex. Example R=QQ[x_0..x_4]; C=simplex R F=C.fc_2_0 ofComplex F SeeAlso (indices,Face) /// doc /// Key (symbol ==,Face,Face) Headline Compare two faces. Usage F==G Inputs F:Face G:Face Outputs :Boolean Description Text Checks whether F and G are equal. Example R=QQ[x_0..x_4]; face {x_0,x_1} == face {x_1,x_0} addCokerGrading R; C=simplex R; bC=boundaryOfPolytope C; F=bC.fc_2_0 dF=dualize F F== dualize dF SeeAlso Face face Complex facets fc /// doc /// Key (symbol ==,Complex,Complex) Headline Compare two complexes. Usage C1==C2 Inputs C1:Complex C2:Complex Outputs :Boolean Description Text Checks whether C1 and C2 are equal. Uses the facets of C1 and C2 (as in many examples the Stanley-Reisner ideal cannot be computed as it is too big to write down). Example R=QQ[x_0..x_4]; C=simplex R; bC=boundaryOfPolytope C dbC=dualize bC bC==dualize dbC SeeAlso (symbol ==,Face,Face) Complex dualize facets /// doc /// Key faceToMonomial (faceToMonomial,Face) (faceToMonomial,Face,PolynomialRing) Headline The monomial of a face. Usage faceToMonomial(F) Inputs F:Face R:PolynomialRing Outputs :Complex Description Text Returns the product of the vertices of a face. Example R=QQ[x_0..x_4]; C=simplex R F=C.fc_2_0 vert F faceToMonomial F SeeAlso vert /// doc /// Key intersectFaces (intersectFaces,Face,Face) (intersectFaces,List) Headline The intersection of two faces. Usage intersectFaces(F,G) Inputs F:Face G:Face Outputs :Face Description Text Returns the intersection of two faces or a list of faces. Example R=QQ[x_0..x_4]; C=simplex R F=C.fc_2_0 G=C.fc_2_1 intersectFaces(F,G) H=C.fc_2_2 intersectFaces({F,G,H}) SeeAlso vert /// doc /// Key (net,Face) Headline Printing faces. Usage net(F) Inputs F:Face Outputs :Net Description Text Prints a face. The vertices are printed without any brackets. The number of vertices is printed. Example R=QQ[x_0..x_4]; C=simplex R; F=C.fc_2_0 SeeAlso net /// doc /// Key simplexDim (simplexDim,Face) Headline The dimension of a face inside the vertex simplex. Usage simplexDim(F) Inputs F:Face Outputs :ZZ bigger or equal to -1 Description Text The dimension of a face inside the vertex simplex, i.e., the number of @TO vert@ F minus 1. Example R=QQ[x_0..x_4]; C=simplex R; F=C.fc_2_0 simplexDim F SeeAlso vert (dim,Face) /// doc /// Key isSubface (isSubface,Face,Face) Headline Checks whether a face is a subface of another face. Usage isSubface(F,G) Inputs F:Face G:Face Outputs :Boolean Description Text Checks whether F is a subface of G. Example R=QQ[x_0..x_4]; C=simplex R; G=C.fc_3_0 F=C.fc_2_0 H=C.fc_3_3 isSubface(F,G) isSubface(F,H) /// doc /// Key vert (vert,Face) (vert,Complex) Headline The vertices of a face or complex. Usage vert(F) vert(C) Inputs F:Face C:Complex Outputs :List Description Text The vertices of F or C. Example R=QQ[x_0..x_4]; addCokerGrading R; C=simplex R; vert C F=C.fc_2_0 vert F SeeAlso coordinates /// doc /// Key (simplexRing,Face) Headline The underlying polynomial ring of a face. Usage simplexRing(F) Inputs F:Face Outputs :PolynomialRing Description Text The underlying polynomial ring of F. Example R=QQ[x_0..x_4]; C=simplex R; F=C.fc_2_0 simplexRing F R.grading /// doc /// Key (simplexRing,Complex) Headline The underlying polynomial ring of a complex. Usage simplexRing(C) Inputs C:Complex Outputs :PolynomialRing Description Text The underlying polynomial ring of C. Example R=QQ[x_0..x_4]; C=simplex R; simplexRing C R.grading /// doc /// Key closedStar (closedStar,Face,Complex) Headline The closed star of a face of a complex. Usage closedStar(F) Inputs F:Face C:Complex Outputs :Complex Description Text The closed star of the face F of the complex C. Example R=QQ[x_0..x_4] C=boundaryOfPolytope simplex(R) F=C.fc_0_0 link(F,C) closedStar(F,C) F=C.fc_1_0 link(F,C) closedStar(F,C) Text Example R=QQ[x_0..x_4] I=ideal(x_0*x_1,x_1*x_2,x_2*x_3,x_3*x_4,x_4*x_0) C=idealToComplex I F=C.fc_0_0 link(F,C) closedStar(F,C) F=C.fc_1_0 link(F,C) closedStar(F,C) SeeAlso link /// doc /// Key link (link,Face,Complex) Headline The link of a face of a complex. Usage link(F) Inputs F:Face C:Complex Outputs :Complex Description Text The link of the face F of the complex C. Example R=QQ[x_0..x_4] C=boundaryOfPolytope simplex(R) F=C.fc_0_0 link(F,C) closedStar(F,C) F=C.fc_1_0 link(F,C) closedStar(F,C) Text Example R=QQ[x_0..x_4] I=ideal(x_0*x_1,x_1*x_2,x_2*x_3,x_3*x_4,x_4*x_0) C=idealToComplex I F=C.fc_0_0 link(F,C) closedStar(F,C) F=C.fc_1_0 link(F,C) closedStar(F,C) SeeAlso closedStar /// doc /// Key simplex (simplex,PolynomialRing) (simplex,PolynomialRing,PolynomialRing) Headline Simplex in the variables of a polynomial ring. Usage simplex(R) simplex(R,Rdual) Inputs R:PolynomialRing Rdual:PolynomialRing Outputs :Complex Description Text Returns a simplex on the variables of R. If R does not have a coker grading then the standard projective space fan rays are added, see @TO addCokerGrading@ and @TO raysPPn@. The Option computeFaces=>false suppresses the computation of all faces. If Rdual is specified it is used for the vertices of the dual simplex, if not a new polynomial ring is created. It is graded by the coordinates of the vertices of the dual simplex. The dual simplex is always created without face data. Example R=QQ[x_0..x_4] C=simplex(R) grading C dC=C.dualComplex grading dC fc(dC); dC SeeAlso grading dualGrading /// doc /// Key dualGrading (dualGrading,Complex) Headline The dual vertices of a polytope. Usage dualGrading(C) Inputs C:Complex a polytope Outputs :Matrix Description Text Returns the dual grading of (i.e., a matrix whose row are) the dual polytope of C. The rows are sorted according to the @TO polytopalFacets@ of C. Example R=QQ[x_0..x_4] C=simplex(R) grading C dA=dualGrading C dA===grading dualize C dA===C.dualComplex.simplexRing.grading pf=polytopalFacets C coordinates pf#0 (dualGrading C)^{0} SeeAlso verticesDualPolytope grading polytopalFacets dualize isPolytope facets Caveat This just returns C.dualComplex.grading. If this data has not been computed use @TO verticesDualPolytope@. Integrate into this verticesDualPolytope. /// doc /// Key verticesDualPolytope (verticesDualPolytope,Complex) Headline The dual vertices of a polytope. Usage verticesDualPolytope(C) Inputs C:Complex a polytope Outputs :Matrix Description Text Computes the vertices of the dual polytope of C in the row of a matrix. The rows are sorted according to the @TO polytopalFacets@ of C. Example R=QQ[x_0..x_4] C=simplex(R) verticesDualPolytope C SeeAlso dualGrading grading polytopalFacets dualize isPolytope facets /// doc /// Key computeFaces [simplex,computeFaces] Headline Compute faces of a simplex. Description Text Determines whether all faces of a simplex are being computed. Example R=QQ[x_0..x_4] simplex(R,computeFaces=>false) SeeAlso simplex /// doc /// Key boundaryOfPolytope (boundaryOfPolytope ,Complex) Headline The boundary of a polytope. Usage boundaryOfPolytope(C) Inputs C:Complex Outputs :Complex Description Text Returns the boundary of a complex C which is a polytope. Example R=QQ[x_0..x_4] C=simplex(R) isPolytope C boundaryOfPolytope C /// doc /// Key boundaryCyclicPolytope (boundaryCyclicPolytope ,ZZ,PolynomialRing) Headline The boundary complex of a cyclic polytope. Usage boundaryCyclicPolytope(d,R) Inputs d:ZZ positive R:PolynomialRing Outputs :Complex Description Text Returns the boundary complex of a cyclic polytope of dimension d inside the standard simplex of the variables of R. So the vertices are those of the standard simplex. Example R=QQ[x_0..x_5] boundaryCyclicPolytope(3,R) SeeAlso fullCyclicPolytope /// doc /// Key fc (fc ,Complex) (fc ,Complex,ZZ) Headline The faces of a complex. Usage fc(C) fc(C,d) Inputs C:Complex d:ZZ positive Outputs :List Description Text Returns a list with entries lists with the faces of C starting in dimension -1. If d is given then faces of dimension d are returned. Example R=QQ[x_0..x_5] C=boundaryCyclicPolytope(3,R) fc C fc(C,1) /// doc /// Key fullCyclicPolytope (fullCyclicPolytope,ZZ,PolynomialRing) (fullCyclicPolytope,ZZ,PolynomialRing,PolynomialRing) Headline Cyclic polytope. Usage fullCyclicPolytope(d,R) Inputs d:ZZ positive R:PolynomialRing Outputs C:Complex Description Text Returns the full cyclic polytope of dimension d with vertices the variables of R. A coker grading is added to R via the vertices of the moment curve (if R already has a coker grading then a warning is displayed) and translated such that 0 lies in the interior of C. Example R=QQ[x_0..x_5] C=fullCyclicPolytope(3,R) SeeAlso boundaryCyclicPolytope /// doc /// Key convHull (convHull,List) (convHull,String) Headline The convex hull complex. Usage convHull(L) convHull(fn) Inputs L:List of @TO Vector@s fn:String Outputs C:Complex Description Text Returns the convex hull of lattice vectors lying all in the same space. The output has C.isPolytope==true. If applied to the string fn the result of a previous computation stored via the option @TO file@ is read from the file fn. The 0-point has to lie in the convex hull. Example L={vector {1,0,0},vector {-1,0,0},vector {0,1,0},vector {0,-1,0},vector {0,0,1},vector {0,0,-1}} P=convHull(L) dP=boundaryOfPolytope P SeeAlso Complex Caveat This uses the package OldPolyhedra.m2 to compute the facets. Too slow compared to Maple/convex. If the package {\it ConvexInterface} is loaded, then this command calls Maple/Convex. See the corresponding option explained at @TO SRdeformations@. /// doc /// Key polytopalFacets (polytopalFacets ,Complex) Headline The facets of a polytope. Usage polytopalFacets(C) Inputs C:Complex a polytope R:PolynomialRing Outputs C:Complex Description Text The facets of a polytope. Note that this is not facets(C) (which is the polytope itself). Example R=QQ[x_0..x_5] C=fullCyclicPolytope(3,R) facets C polytopalFacets(C) SeeAlso isPolytope facets /// doc /// Key facets (facets,Complex) (facets,List) Headline The maximal faces of a complex. Usage facets(C) Inputs C:Complex R:PolynomialRing Outputs :List Description Text The maximal faces of C arranged in a list of lists with ascending dimension of the facets. Example R=QQ[x_0..x_5] C=fullCyclicPolytope(3,R) facets C dC=boundaryOfPolytope(C); facets dC SeeAlso fc polytopalFacets /// doc /// Key isPolytope (isPolytope,Complex) (isPolytope,List) Headline Check whether a complex is a polytope. Usage isPolytope(C) Inputs C:Complex Outputs :Boolean Description Text Check whether a complex C is a polytope. Example R=QQ[x_0..x_5]; C=fullCyclicPolytope(3,R) isPolytope C /// doc /// Key eulerCharacteristic (eulerCharacteristic ,Complex) (eulerCharacteristic ,List) Headline The Euler characteristic of a complex. Usage eulerCharacteristic(C) Inputs C:Complex Outputs :ZZ Description Text The Euler characteristic of C. This is printed always when printing a complex and the faces are known. Example R=QQ[x_0..x_5]; C=fullCyclicPolytope(3,R); fvector C eulerCharacteristic C dC=boundaryOfPolytope(C); fvector dC eulerCharacteristic dC SeeAlso fvector fc /// doc /// Key fvector (fvector ,Complex) (fvector ,List) Headline The F-vector of a complex. Usage fvector(C) Inputs C:Complex Outputs :List Description Text The fvector of C. This is printed always when printing a complex and the faces are known. Example R=QQ[x_0..x_5]; C=fullCyclicPolytope(3,R); fvector C eulerCharacteristic C dC=boundaryOfPolytope(C); fvector dC eulerCharacteristic dC SeeAlso eulerCharacteristic fc /// doc /// Key globalSections (globalSections,Matrix,Vector) (globalSections,Matrix,Vector,List) Headline The global sections of a toric divisor. Usage globalSections(A,v) globalSections(A,v,L) Inputs A:Matrix v:Vector L:List Outputs :List Description Text Computes the global sections of a toric Weil divisor D with coefficients v with respect to the coker grading by A. In the same way as v they are represented by vectors (exponent vectors of Laurent monomials in rank target A variables). If a list of indices L in {0..rank target A -1} is specified, then those Laurent monomial exponents are computed, which induce a linear equivalence of D to an effective divisor with support precisely on L. Example A=matrix {{1, 0}, {0, 1}, {-1, -1}} b=vector {2,0,0} globalSections(A,b) A=matrix {{1, 0}, {0, 1}, {-1, -1},{1,1}} b=vector {2,0,0,0} globalSections(A,b) globalSections(A,b,{1}) Caveat This uses the package OldPolyhedra.m2 (if ConvexInterface.m2 is not present) to compute the lattice points of a convex hull. constructHilbertBasis of the package OldPolyhedra.m2 used by latticePoints overwrites global variable C. Fixed this in my local version. /// doc /// Key coComplexToIdeal (coComplexToIdeal,CoComplex) Headline The monomial ideal associated to a CoComplex. Usage coComplexToIdeal(C) Inputs C:CoComplex Outputs :Ideal Description Text The monomial ideal associated to a CoComplex, i.e., the intersection of all @TO ideal@ @TO vert@ F for @TO Face@s F of C. Example R=QQ[x_0..x_4] addCokerGrading(R) C0=simplex(R) I=ideal(x_0*x_1,x_1*x_2,x_2*x_3,x_3*x_4,x_4*x_0) C=idealToComplex(I) embeddingComplex C idealToComplex(I,C0) complexToIdeal(C) cC=idealToCoComplex(I,C0) cC==complement C I==coComplexToIdeal(cC) dualize cC SeeAlso complexToIdeal idealToComplex idealToCoComplex /// doc /// Key embedded [complexToIdeal,embedded] [minimalNonFaces,embedded] Headline Use only faces of the embedding complex. Description Text If the option embedded=>true is given, then only @TO Face@s of @TO embeddingComplex@ C are used. SeeAlso complexToIdeal minimalNonFaces coComplexToIdeal idealToComplex idealToCoComplex embeddingComplex /// doc /// Key complexToIdeal (complexToIdeal,Complex) Headline The monomial ideal associated to a complex. Usage complexToIdeal(C) Inputs C:Complex Outputs :Ideal Description Text The Stanley-Reisner ideal associated to a complex, i.e., the ideal of non-faces of C. If the option embedded=>true is given, then only @TO Face@s of @TO embeddingComplex@ C are used. Example R=QQ[x_0..x_4] addCokerGrading(R) C0=simplex(R) I=ideal(x_0*x_1,x_1*x_2,x_2*x_3,x_3*x_4,x_4*x_0) C=idealToComplex(I) embeddingComplex C idealToComplex(I,C0) complexToIdeal(C) cC=idealToCoComplex(I,C0) cC==complement C I==coComplexToIdeal(cC) dualize cC SeeAlso coComplexToIdeal idealToComplex idealToCoComplex embeddingComplex /// doc /// Key idealToComplex (idealToComplex,Ideal) (idealToComplex,MonomialIdeal) (idealToComplex,Ideal,Complex) (idealToComplex,MonomialIdeal,Complex) Headline The complex associated to a reduced monomial ideal. Usage idealToComplex(I) idealToComplex(I,C) Inputs I:Ideal I:MonomialIdeal C:Complex Outputs :Complex Description Text The Stanley-Complex associated to a reduced monomial ideal. This is a complex of faces of either C, or if C is not given, a complex of faces of @TO simplex@ @TO ring@ I. Example R=QQ[x_0..x_4] addCokerGrading(R) C0=simplex(R) I=ideal(x_0*x_1,x_1*x_2,x_2*x_3,x_3*x_4,x_4*x_0) C=idealToComplex(I) embeddingComplex C idealToComplex(I,C0) complexToIdeal(C) cC=idealToCoComplex(I,C0) cC==complement C I==coComplexToIdeal(cC) dualize cC SeeAlso coComplexToIdeal complexToIdeal idealToCoComplex embeddingComplex /// doc /// Key idealToCoComplex (idealToCoComplex,Ideal) (idealToCoComplex,MonomialIdeal) (idealToCoComplex,Ideal,Complex) (idealToCoComplex,MonomialIdeal,Complex) Headline The co-complex associated to a reduced monomial ideal. Usage idealToCoComplex(I) idealToCoComplex(I,C) Inputs I:Ideal I:MonomialIdeal C:Complex Outputs :CoComplex Description Text The co-complex of ideals of the strata of the locus of a reduced monomial ideal. This is a co-complex of faces of either C, or if C is not given, a complex of faces of @TO simplex@ @TO ring@ I. Example R=QQ[x_0..x_4] addCokerGrading(R) C0=simplex(R) I=ideal(x_0*x_1,x_1*x_2,x_2*x_3,x_3*x_4,x_4*x_0) C=idealToComplex(I) embeddingComplex C idealToComplex(I,C0) complexToIdeal(C) cC=idealToCoComplex(I,C0) cC==complement C I==coComplexToIdeal(cC) dualize cC SeeAlso coComplexToIdeal idealToComplex complexToIdeal embeddingComplex /// doc /// Key embeddingComplex (embeddingComplex,Complex) Headline The embedding complex of a complex or co-complex. Usage embeddingComplex(C) Inputs C:Complex Outputs :Complex Description Text The embedding complex of a complex or co-complex. Example R=QQ[x_0..x_4] addCokerGrading(R) C0=simplex(R) I=ideal(x_0*x_1,x_1*x_2,x_2*x_3,x_3*x_4,x_4*x_0) C=idealToComplex(I) embeddingComplex C idealToComplex(I,C0) complexToIdeal(C) cC=idealToCoComplex(I,C0) cC==complement C I==coComplexToIdeal(cC) dualize cC SeeAlso complexToIdeal /// doc /// Key Complex Headline The class of all embedded complexes. Description Text The class of all embedded complexes, not necessarily simplicial or compact or equidimensional. These are complexes with coordinates assigned to their vertices. {\bf Creating complexes:} The following functions return complexes: @TO simplex@ -- Simplex in the variables of a polynomial ring @TO boundaryCyclicPolytope@ -- The boundary complex of a cyclic polytope with standard projective space vertices @TO fullCyclicPolytope@ -- The full cyclic polytope with moment curve vertices @TO convHull@ -- The convex hull @TO hull@ -- The positive hull @TO boundaryOfPolytope@ -- The boundary of a polytope @TO newEmptyComplex@ -- Generates an empty complex. @TO idealToComplex@ -- The complex associated to a reduced monomial ideal @TO dualize@ -- The dual of a co-complex. @TO complement@ -- The complement of a co-complex. @TO complex@ -- Make a complex from a list of faces @TO complexFromFacets@ -- Make a complex from a list of facets @TO embeddingComplex@ -- The complex containing a subcomplex For examples see the documentation of these functions. {\bf The data stored in a complex C:} {\it C.simplexRing}, the polynomial ring of vertices of C. {\it C.grading}, is C.simplexRing.grading, a matrix with the coordinates of the vertices of C in its rows. {\it C.facets}, a list with the facets of C sorted into lists by dimension. {\it C.edim}, the embedding dimension of C, i.e., @TO rank@ @TO source@ C.grading. {\it C.dim}, the dimension of the complex. {\it C.isSimp}, a @TO Boolean@ indicating whether C is simplicial. {\it C.isEquidimensional}, a @TO Boolean@ indicating whether C is equidimensional. If not just the facets but the faces of C a known (e.g., after computed with @TO fc@) then the following data is present: {\it C.fc}, a @TO ScriptedFunctor@ with the faces of C sorted and indexed by dimension. {\it C.fvector}, a @TO List@ with the F-vector of C. The following may be present (if known due to creation of C or due to calling some function): {\it C.dualComplex}, the dual co-complex of C in the sense of dual faces of a polytope. See @TO dualize@. {\it C.isPolytope}, a @TO Boolean@ indicating whether C is a polytope. {\it C.polytopalFacets}, a @TO List@ with the boundary faces of the polytope C. {\it C.complementComplex}, the complement co-complex of C (if C is a subcomplex of a simplex). See @TO complement@. Example R=QQ[x_0..x_5] C=boundaryCyclicPolytope(3,R) C.simplexRing C.grading C.fc_2 C.facets dualize C complement C Text Example R=QQ[x_0..x_5] C=simplex R C.isPolytope C.polytopalFacets SeeAlso CoComplex Face (homology,Complex) /// doc /// Key noBoundary Headline Optional data of Complex. Description Text Optional data in the @TO MutableHashTable@ @TO Complex@ indicating whether the complex has no relative boundary. SeeAlso Complex CoComplex /// doc /// Key complementComplex Headline Optional data of Complex. Description Text Optional data in the @TO MutableHashTable@ @TO Complex@ storing the complement complex. SeeAlso Complex CoComplex /// doc /// Key dualComplex Headline Optional data of Complex. Description Text Optional data in the @TO MutableHashTable@ @TO Complex@ storing the dual complex. SeeAlso Complex CoComplex /// doc /// Key dualFace Headline Optional data of Face. Description Text Optional data in the @TO MutableHashTable@ @TO Face@ storing the dual face. SeeAlso dualize /// doc /// Key CoComplex Headline The class of all embedded co-complexes. Description Text The class of all embedded co-complexes, not necessarily simplicial. {\bf Creating co-complexes:} The following functions return co-complexes: @TO idealToCoComplex@ -- The co-complex associated to a reduced monomial ideal @TO dualize@ -- The dual of a complex. @TO complement@ -- The complement of a complex. @TO coComplex@ -- Make a co-complex from a list of faces For further examples see the documentation of these functions. {\bf The data stored in a co-complex C:} {\it C.simplexRing}, the polynomial ring of vertices of C (note these are only faces of C if C is a polytope). {\it C.grading}, is C.simplexRing.grading, a matrix with the coordinates of the vertices of C in its rows. {\it C.facets}, a list with the facets of C sorted into lists by dimension. {\it C.edim}, the embedding dimension of C, i.e., @TO rank@ @TO source@ C.grading. {\it C.dim}, the dimension of C, i.e., the minimal dimension of the faces. {\it C.isSimp}, a @TO Boolean@ indicating whether C is simplicial. {\it C.isEquidimensional}, a @TO Boolean@ indicating whether C is equidimensional. {\it C.fc}, a @TO ScriptedFunctor@ with the faces of C sorted and indexed by dimension. {\it C.fvector}, a @TO List@ with the F-vector of C. The following may be present (if known due to creation of C or due to calling some function): {\it C.dualComplex}, the dual complex of C in the sense of dual faces of a polytope. See @TO dualize@. {\it C.isPolytope}, a @TO Boolean@ indicating whether C is a polytope. {\it C.polytopalFacets}, a @TO List@ with the boundary faces of the polytope C. {\it C.complementComplex}, the complement complex of C (if C is a subcocomplex of a simplex). See @TO complement@. Example R=QQ[x_0..x_5] C=boundaryCyclicPolytope(3,R) C.simplexRing C.grading C.fc_2 C.facets dC=dualize C cC=complement C dualize cC SeeAlso Complex Face Caveat So far a co-complex is of class complex and the methods checks of which type it really is. At some point both will have a common ancestor. /// doc /// Key complex (complex,PolynomialRing,List) (complex,PolynomialRing,List,List) (complex,PolynomialRing,List,PolynomialRing) (complex,PolynomialRing,List,List,PolynomialRing) Headline Make a complex. Usage complex(R,facelist) complex(R,facelist,facetlist) complex(R,facelist,Rdual) complex(R,facelist,facetlist,Rdual) Inputs R:PolynomialRing facelist:List of the faces, sorted by dimension facetlist:List of the facets, sorted by dimension Rdual:PolynomialRing Outputs :Complex Description Text Make a complex from a list of faces and/or facets. This is mostly used internally but may be occasionally useful for the end user. Example R=QQ[x_0..x_5] C=boundaryCyclicPolytope(3,R) fC=fc C C1=complex(R,fC) C==C1 SeeAlso Face complexFromFacets Caveat If both the list of faces and facets is specified there is no consistency check. /// doc /// Key complexFromFacets (complexFromFacets,PolynomialRing,List) (complexFromFacets,PolynomialRing,List,PolynomialRing) Headline Make a complex from its facets. Usage complexFromFacets(R,facetlist) complexFromFacets(R,facetlist,Rdual) Inputs R:PolynomialRing facetlist:List of the facets, sorted by dimension Rdual:PolynomialRing Outputs :Complex Description Text Make a complex from a list of faces and/or facets. This is mostly used internally but may be occasionally useful for the end user. Example R=QQ[x_0..x_5] C=boundaryCyclicPolytope(3,R) fC=facets C C1=complexFromFacets(R,fC) C1==C fc C1; C1 SeeAlso Face complex fc Caveat If both the list of faces and facets is specified there is no consistency check. /// doc /// Key coComplex (coComplex,PolynomialRing,List) (coComplex,PolynomialRing,List,List) (coComplex,PolynomialRing,List,PolynomialRing) (coComplex,PolynomialRing,List,List,PolynomialRing) Headline Make a co-complex. Usage coComplex(R,facelist) coComplex(R,facelist,facetlist) coComplex(R,facelist,Rdual) coComplex(R,facelist,facetlist,Rdual) Inputs R:PolynomialRing facelist:List of the faces, sorted by dimension facetlist:List of the facets, sorted by dimension Rdual:PolynomialRing Outputs :CoComplex Description Text Make a co-complex from a list of faces and/or facets. This is mostly used internally but may be occasionally useful for the end user. Example R=QQ[x_0..x_5] C=boundaryCyclicPolytope(3,R) grading R dC=dualize C fdC=fc dC Rdual=simplexRing dC grading Rdual dC1=coComplex(Rdual,fdC) dC==dC1 SeeAlso Face Caveat If both the list of faces and facets is specified there is no consistency check. /// doc /// Key variables (variables,Complex) Headline The variables of a complex or co-complex. Usage variables(C) Inputs C:Complex Outputs :Complex Description Text The variables of a complex of co-complex. Compare with @TO vert@. Example R=QQ[x_0..x_5] C=boundaryCyclicPolytope(3,R) F=C.fc_0_0 lkF=link(F,C) variables lkF vert lkF SeeAlso vert /// doc /// Key edim (edim,Complex) Headline The embedding dimension of a complex or co-complex. Usage edim(C) Inputs C:Complex Outputs :ZZ Description Text The embedding dimension of a complex or co-complex. Example R=QQ[x_0..x_5] C=boundaryCyclicPolytope(3,R) dim C edim C SeeAlso (dim,Complex) /// doc /// Key isSimp (isSimp,Complex) (isSimp,List) Headline Check whether a complex or co-complex is simplicial. Usage isSimp(C) Inputs C:Complex Outputs :Boolean Description Text Check whether a complex or co-complex is simplicial. Example R=QQ[x_0..x_5] C=boundaryCyclicPolytope(3,R) isSimp C R=QQ[x_0..x_5] C1=fullCyclicPolytope(3,R) isSimp C1 SeeAlso boundaryCyclicPolytope fullCyclicPolytope /// doc /// Key isEquidimensional (isEquidimensional,Complex) (isEquidimensional,List) Headline Check whether a complex or co-complex is equidimensional. Usage isEquidimensional(C) Inputs C:Complex Outputs :Boolean Description Text Check whether a complex or co-complex is equidimensional. Example R=QQ[x_0..x_5]; C=boundaryCyclicPolytope(3,R) isEquidimensional(C) R=QQ[x_0..x_2]; I=intersect(ideal(x_0),ideal(x_1,x_2)) C=idealToComplex I isEquidimensional(C) SeeAlso boundaryCyclicPolytope idealToComplex /// doc /// Key face (face,List) (face,Set) (face,List,Complex) (face,List,Complex,ZZ,ZZ) Headline Generate a face. Usage face(L) face(S) face(L,C) face(L,C,d,j) Inputs L:List S:Set C:Complex d:ZZ bigger or equal to -1 j:ZZ non-negative Outputs :Face Description Text Generate a @TO Face@ F from a list L (or set S) of vertices. If the additional argument C is given it sets F.ofComplex={C} to store the complex of which F is a face of. If d and j are given then F.indices={{d,j}} for storing the face dimension d and its index j in (F.ofComplex)#0. Example R=QQ[x_0..x_4] I=ideal(x_0*x_1,x_1*x_2,x_2*x_3,x_3*x_4,x_4*x_0) C=idealToComplex I F=C.fc_1_0 F==face(vert F,C,1,0) SeeAlso Face Complex CoComplex /// doc /// Key addFaceDataToComplex (addFaceDataToComplex,Complex,List) (addFaceDataToComplex,Complex,List,List) Headline Adds to a complex face data. Usage addFaceDataToComplex(C,facelist) addFaceDataToComplex(C,facelist,facetlist) Inputs C:Complex facelist:List whose i-th entry is a list of the faces of C of dimension i-1 facetlist:List whose i-th entry is a list of the facets of C of dimension i-1 Outputs C:Complex Description Text Adds to a complex the face data and facet data (computed if not specified), i.e., C.fc, C.facets, C.dim, C.fvector, C.isEquidimensional, C.isSimp are updated. This allows us to add the face data later to a complex generated previously by @TO newEmptyComplex@. Note that the input C is modified by this method. This function is mainly used internally, but may occasionally be useful to the user and is hence exported. Example R=QQ[x_0..x_4] addCokerGrading(R) I=ideal(x_0*x_1,x_1*x_2,x_2*x_3,x_3*x_4,x_4*x_0) C=idealToComplex(I) Cl=newEmptyComplex(R) addFaceDataToComplex(Cl,fc C) Cl==C SeeAlso newEmptyComplex dim fvector fc isSimp isEquidimensional Caveat If both facelist and facetlist are specified this function does not make any consistency check. /// doc /// Key addFacetDataToComplex (addFacetDataToComplex,Complex,List) Headline Adds to a complex facet data. Usage addFacetDataToComplex(C,facetlist) Inputs C:Complex facetlist:List whose i-th entry is a list of the facets of C of dimension i-1 Outputs C:Complex Description Text Adds to a complex the facet data, i.e., C.facets, C.dim, C.fvector, C.isEquidimensional, C.isSimp are updated. This allows us to add the facet data later to a complex generated previously by @TO newEmptyComplex@. Note that the input C is modified by this method. This function is mainly used internally, but may occasionally be useful to the user and is hence exported. Example R=QQ[x_0..x_4] addCokerGrading(R) I=ideal(x_0*x_1,x_1*x_2,x_2*x_3,x_3*x_4,x_4*x_0) C=idealToComplex(I) Cl=newEmptyComplex(R) addFacetDataToComplex(Cl,facets C) Cl==C SeeAlso newEmptyComplex addFaceDataToComplex dim fvector facets isSimp isEquidimensional /// doc /// Key newEmptyComplex (newEmptyComplex,PolynomialRing) Headline Generates an empty complex. Usage newEmptyComplex(R) Inputs R:PolynomialRing with coker grading added by @TO addCokerGrading@ Outputs C:Complex Description Text Generates an empty @TO complex@. Face and facet data or just facet data can be added later by @TO addFaceDataToComplex@ or @TO addFacetDataToComplex@. This function is mainly used internally to create an empty complex data structure to be filled later, but may occasionally be useful to the user and is hence exported. Example R=QQ[x_0..x_4] addCokerGrading(R) I=ideal(x_0*x_1,x_1*x_2,x_2*x_3,x_3*x_4,x_4*x_0) C=idealToComplex(I) Cl=newEmptyComplex(R) addFacetDataToComplex(Cl,facets C) Cl==C SeeAlso addFaceDataToComplex addFacetDataToComplex dim fvector facets isSimp isEquidimensional /// doc /// Key (net,Complex) Headline Printing complexes. Usage net(C) Inputs C:Complex Outputs :Net Description Text Printing complexes. It prints the @TO facets@ of the complex C sorted by dimension. Example R=QQ[x_0..x_4] I=ideal(x_0*x_1,x_1*x_2,x_2*x_3,x_3*x_4,x_4*x_0) C=idealToComplex I; net C SeeAlso net /// doc /// Key (grading,Complex) Headline The grading of a complex. Usage grading(C) Inputs C:Complex Outputs :Matrix Description Text Returns C.simplexRing.grading. The output has the coordinates of the vertices of C in its rows. Example R=QQ[x_0..x_4] I=ideal(x_0*x_1,x_1*x_2,x_2*x_3,x_3*x_4,x_4*x_0) C=idealToComplex I; grading C SeeAlso idealToComplex /// ------------------------------------------------------------------------ -- deformations of Stanley-Reisner ideals doc /// Key deformationsFace (deformationsFace,Face,Complex) (deformationsFace,Face,Complex,Ideal) Headline Compute the deformations associated to a face. Usage deformationsFace(F,C) deformationsFace(F,C,I) Inputs F:Face C:Complex I:Ideal reduced monomial Outputs :List Description Text Compute the homogeneous (i.e., @TO (degree,FirstOrderDeformation)@ zero) deformations associated to a face F of the complex C. The additional parameter I should be the Stanley-Reisner ideal of C and can be given to avoid computation of the Stanley-Reisner ideal if it is already known. Usually this is not necessary: Once I is computed it is stored in C.ideal, so deformationsFace(F,C,I) is equivalent to deformationsFace(F,C). Note also that all methods producing a complex from an ideal (like @TO idealToComplex@) store the ideal in C.ideal. The deformations and C are stored in F.deform = {C, deformations}. Note that usually C is not ofComplex F. Example R=QQ[x_0..x_4] I=ideal(x_0*x_1*x_2,x_3*x_4) C1=idealToComplex I F=C1.fc_0_0 deformationsFace(F,C1) F=C1.fc_0_1 deformationsFace(F,C1) F=C1.fc_1_0 deformationsFace(F,C1) F=C1.fc_2_0 deformationsFace(F,C1) Text Example R=QQ[x_0..x_4] I=ideal(x_0*x_1,x_1*x_2,x_2*x_3,x_3*x_4,x_4*x_0) C1=idealToComplex I F=C1.fc_0_1 deformationsFace(F,C1) F=C1.fc_1_1 deformationsFace(F,C1) SeeAlso deform link globalSections Caveat To homogenize the denominators of deformations (which are supported inside the link) we use globalSections to deal with the toric case. Speed of this should be improved. For ordinary projective space globalSections works much faster. /// doc /// Key deform (deform,Complex) Headline Compute the deformations associated to a Stanley-Reisner complex. Usage deform(C) Inputs C:Complex Outputs :List Description Text Compute a list with the homogeneous (i.e., @TO (degree,FirstOrderDeformation)@ zero) deformations associated to Stanley-Reisner complex C. The result of the computation is stored in the key C.deform and this data can be stored to and loaded from a file by @TO saveDeformations@ and @TO loadDeformations@. Example R=QQ[x_0..x_4] I=ideal(x_0*x_1,x_1*x_2,x_2*x_3,x_3*x_4,x_4*x_0) C1=idealToComplex I deform C1 SeeAlso deformationsFace loadDeformations saveDeformations link globalSections Caveat To homogenize the denominators of deformations (which are supported inside the link) we use globalSections to deal with the toric case. Speed of this should be improved. For ordinary projective space globalSections works much faster. /// doc /// Key joinVectors (joinVectors,List) Headline Converts a list of vectors to a matrix. Usage joinVectors(C) Inputs L:List of @TO Vector@s Outputs :Matrix Description Text Puts the vectors in a list into a matrix. Example joinVectors {vector {1,2},vector {3,4},vector {5,6}} /// doc /// Key minimalNonFaces (minimalNonFaces,Complex) Headline The minimal non-faces of a complex. Usage minimalNonFaces(C) Inputs C:Complex Outputs :List Description Text The minimal non-faces of a complex. All subsets of the variables of @TO simplexRing@(C) are tested as standard. If the option embedded=>true is specified then only faces of @TO embeddingComplex@(C) are tested. Example R=QQ[x_0..x_4]; I=ideal(x_0*x_1,x_1*x_2,x_2*x_3,x_3*x_4,x_4*x_0); C=idealToComplex I minimalNonFaces C SeeAlso idealToComplex complexToIdeal embeddingComplex /// doc /// Key possibleDenominators (possibleDenominators,Ideal) (possibleDenominators,Ideal,List) (possibleDenominators,List,List) Headline Possible denominators of deformations. Usage possibleDenominators(I) possibleDenominators(I,v) Inputs I:Ideal monomial, reduced. v:List of variables of @TO ring@ I. Outputs L:List Description Text Computes a list L of possible denominators of Laurent monomials representing @TO FirstOrderDeformation@s of I. The list L is stratified into lists with ascending degree of the denominators. Each denominator is represented as a list of variables. If the second argument v is given, one obtains only denominators contained (as a list) in v. Example R=QQ[x_0..x_4]; I=ideal(x_0*x_1,x_1*x_2,x_2*x_3,x_3*x_4,x_4*x_0); possibleDenominators(I) possibleDenominators(I,{x_0,x_1,x_2}); SeeAlso deformationsFace deform /// doc /// Key preImage (preImage,Matrix,Vector) Headline Compute the preimage. Usage preImage(A,v) Inputs A:Matrix of full rank. v:Vector in @TO target@ A. Outputs :Vector in @TO source@ A. Description Text Computes the preimage of v under A. If v is not in @TO image@ A then returns false. Example A=matrix {{1, 0}, {0, 1}, {-1, -1}} b=vector {-2,2,0} v=preImage(A,b) A*v /// -* doc /// Key selectFaces (selectFaces,Complex,Function) Headline Compute the subcomplex of faces satisfying a condition. Usage selectFaces(C,f) Inputs C:Complex f:Function Outputs :Complex Description Text Compute the subcomplex of faces satisfying a condition. /// *- doc /// Key (homology,Complex) Headline Compute the homology of a complex. Usage homology(C) Inputs C:Complex Outputs :List of finitely generated abelian groups (type defined in ConvexInterface) Description Text Computes the homology of a complex (not necessarily simplicial). Caveat To use this the package {\it ConvexInterface} has to be installed. /// --------------------------------------------------------------------------------------- -- deformation polytope and its tropical sub-co-complex doc /// Key PT1 (PT1,Complex) Headline Compute the deformation polytope associated to a Stanley-Reisner complex. Usage PT1(C) Inputs C:Complex Outputs :Complex Description Text Compute the deformation polytope of C, i.e., the convex hull of all homogeneous (i.e., @TO (degree,FirstOrderDeformation)@ zero) deformations associated to C, considering them as lattice monomials (i.e., their preimages under C.grading). Example R=QQ[x_0..x_3] I=ideal(x_0*x_1,x_2*x_3) C=idealToComplex I PT1C=PT1 C SeeAlso deformationsFace link globalSections tropDef Caveat To homogenize the denominators of deformations (which are supported inside the link) we use globalSections to deal with the toric case. The speed of this should be improved. For ordinary projective space homogenization with support on F is done much faster. /// doc /// Key tropDef (tropDef,Complex,Complex) Headline The co-complex of tropical faces of the deformation polytope. Usage tropDef(P,C) Inputs C:Complex a simplicial complex P:Complex the deformation polytope of C as returned by @TO PT1@ C. Outputs :CoComplex Description Text Computes the co-complex of tropical faces of the deformation polytope. This is work in progress. Example R=QQ[x_0..x_3] I=ideal(x_0*x_1,x_2*x_3) C=idealToComplex I PT1C=PT1 C tropDefC=tropDef(C,PT1C) tropDefC.grading SeeAlso PT1 saveDeformations (convHull,String) deform Caveat The implementation of testing whether a face is tropical so far uses a trick to emulate higher order. For complicated (non-complete intersections and non-Pfaffians) examples this may lead to an incorrect result. Use with care. This will be fixed at some point. If using @TO OldPolyhedra@ to compute convex hulls and its faces instead of {\it ConvexInterface} you are limited to rather simple examples. /// ----------------------------------------------------------------------- -- example doc /// Key mirrorSphere Headline Example how to compute the mirror sphere. Description Text Example how to compute the mirror sphere as an @TO Complex@. This is work in progress. Many interesting pieces are not yet implemented. Example R=QQ[x_0..x_4] I=ideal(x_0*x_1,x_2*x_3*x_4) C=idealToComplex I PT1C=PT1 C tropDefC=tropDef(C,PT1C) tropDefC.grading B=dualize tropDefC B.grading fvector C fvector B SeeAlso PT1 tropDef (homology,Complex) Caveat The implementation of testing whether a face is tropical so far uses a trick to emulate higher order. For very complicated (non-complete intersections and non-Pfaffians) examples this may lead to an incorrect result. Use with care. This will be fixed at some point. If using @TO OldPolyhedra@ to compute convex hulls and its faces instead of {\it ConvexInterface} you are limited to rather simple examples. /// -* Text Example R=QQ[x_0..x_6] I=ideal(x_0*x_1,x_2*x_3,x_4*x_5*x_6) C=idealToComplex I PT1C=PT1 C tropDefC=tropDef(C,PT1C) tropDefC.grading B=dualize tropDefC B.grading fvector C fvector B Text Example R=QQ[x_0..x_4] I=ideal(x_0*x_1,x_1*x_2,x_2*x_3,x_3*x_4,x_4*x_0); C=idealToComplex I PT1C=PT1 C tropDefC=tropDef(C,PT1C) tropDefC.grading B=dualize tropDefC B.grading fvector C fvector B Text Example R=QQ[x_0..x_6] C=boundaryCyclicPolytope(4,R) I=complexToIdeal C betti res I def=deform C #def T1=select(def,j->(isTrivial j)==false) #T1 for j from 0 to #T1-1 do print(j,toHom T1#j); PT1C=PT1 C tropDefC=tropDef(C,PT1C) tropDefC.grading B=dualize tropDefC B.grading fvector C fvector B *- doc /// Key file [convHull,file] [PT1,file] [hull,file] Headline Store result of a computation in a file. Description Text If the option file=>fn with a @TO String@ fn is given then the result of the computation is stored in the file fn. SeeAlso PT1 convHull hull Caveat This works only when using the package ConvexInterface. /// doc /// Key saveDeformations (saveDeformations,Complex,String) Headline Store the deformation data of a complex in a file. Usage saveDeformations(C,fn) Inputs C:Complex fn:String file name. Outputs :List with all @TO FirstOrderDeformation@s. Description Text Store the deformation data of a complex C in a file with name fn. SeeAlso loadDeformations deform /// doc /// Key loadDeformations (loadDeformations,Complex,String) Headline Read the deformation data of a complex from a file. Usage loadDeformations(C,fn) Inputs C:Complex fn:String file name. Outputs :Complex Description Text Read the deformation data of a complex C from a file with name fn. The deformations are stored in C.deform. SeeAlso saveDeformations deform Caveat This does not change deformation data which may be stored in the individual faces. /// doc /// Key hull (hull,List) (hull,String) Headline The positive hull complex. Usage hull(L) hull(fn) Inputs L:List of @TO Vector@s lying all in the same space. fn:String Outputs C:Complex Description Text Returns the cone which is the hull of lattice vectors in L. The output has C.isPolytope==true. If applied to the string fn the result of a previous computation stored via the option @TO file@ is read from the file fn. The hull of L has to be strictly convex. Example L= {{0,1,1,0,0},{0,1,0,1,0},{0,1,0,0,0},{1,0,0,0,1},{1,0,-1,-1,-1},{1,0,0,0,0}}; L=apply(L,vector) C=hull L C.grading dC=dualize C dC.grading SeeAlso Complex Caveat The cone is represented as a complex on its rays, hence if @TO (dim,Face)@ is applied to a @TO Face@ it will return the dimension of the corresponding cone minus one. This uses the package OldPolyhedra.m2 to compute the facets. Too slow compared to Maple/convex. If the package {\it ConvexInterface} is loaded, then this command calls Maple/Convex. See the corresponding option explained at @TO SRdeformations@. /// -* installPackage("SRdeformations") installPackage("SRdeformations",RerunExamples=>true) *-
Simpan