-- Given a matrix listing the vertex coordinates) and the toList of -- the complex of top dimension (specified as tuples of vertices), the -- program builds the chain complexes corresponding to J, R, and R/J -- An important note: Splines are distinguished by the fact -- that they are syzygies on a certain matrix of the form Boundary|diag -- where the entries in Boundary have a single +1 and a single -1 in -- each row. This corresponds to a specific orientation on the max. -- simplices, NOT the one where the vertices are lex ordered. However, -- it turns out that if we modify the top boundary map by diag orient(s,v) -- this gives us the SPLINES, but we don't really need this, because -- what we get using the lex ordering is isomorphic to the module of -- splines. Last modified to work with M2 version 0.9.2 HKS diag = (f) -> map(R^(#f), #f,(i,j) -> if i == j then promote(f#i,R) else 0) orient = (simp, verts) -> toList apply(#simp, i -> 1/det verts_(simp#i)) zeromat = (m,n) -> (matrix(R^m, n, (i,j) -> 0)) signedbd = (C, r) -> ( m := # C.ifaces#(r-1); n := # C.ifaces#r; signs(C.ifaces#r); map(R^m,R^n, (i,j) -> if t#?(C.ifaces#r#j, C.ifaces#(r-1)#i) then t#(C.ifaces#r#j, C.ifaces#(r-1)#i) else 0)) -- Produce the rth boundary map for REDUCED (mod boundary) homology. -- Entry i, j corresponds to the boundary component of the jth r-face which -- lies in the ith r-1 face, and to see the orientation of it, we look at t, -- which is indexed on these faces HS 10/15/95 bd = (f) -> apply(#f, i -> drop(f, {i,i})) faces = (f) -> unique flatten apply(f, bd) topbfaces = (faces) -> ( facets = flatten apply(faces, bd); u := new MutableHashTable; scan(facets, g -> if u#?g then u#g = false else u#g = true); select(keys u, f -> u#f == true)) signs = (f) -> ( t = new MutableHashTable; u := new MutableHashTable; scan(0..# f - 1, i -> ( u#i = bd(f#i); scan(0..# u#i - 1, j -> t#(f#i,u#i#j) = (-1)^j);))) -- create an indexed object to reflect boundary orientation. i.e. -- if f = {{0 1 2}{2 3 4}} then t#(f#0,u#0#1) = t#({0 1 2},{0 2}) -- should be -1 HS 10/15/95 ------------------------------------------------------------------------------ --Spline portion uses parts from outside - signs, bd, faces, topbfaces. --This just builds the matrix consisting of the top bd map and the diag --matrix of hyperplanes, then computes the kernel and projects. For this, --we don't need any of the fancy simplicial complex stuff, so ignore it. spline = (sim, ver, r) ->( n := (#sim#0) - 1; -- R = ZZ/31991[x_0..x_n]; R = QQ[x_0..x_n]; submatrix(gens kernel(topbd(sim)*diag(orient1(sim,ver)) | e1(sim,ver,r)), {0..#sim-1},)) --returns a matrix whose columns are the splines topbd = (topfaces) -> ( nfaces = toList apply(topfaces, i -> sort i); nminus1faces = faces nfaces; nminus1bfaces = topbfaces nfaces; nminus1ifaces = toList ((set nminus1faces) - (set nminus1bfaces)); m := # nminus1ifaces; n := # nfaces; signs(nfaces); map(R^m,R^n, (i,j) -> if t#?(nfaces#j, nminus1ifaces#i) then t#(nfaces#j, nminus1ifaces#i) else 0)) -- Produce the top boundary map for REDUCED (mod boundary) homology. -- Remark - if we really want the SPLINES, then we have to modify the -- topbd map by a matrix reflecting the real orientation of the top -- simplices. In other words, we will multiply topbd by diag orient1 -- Modified HS 12/30/96 orient1 = (simp, verts) -> toList apply(#simp, i -> if (det verts_(simp#i) < 0) then -1 else 1) faceideal1 = (f, ver) -> minors(1+#f, (transpose vars R) | ver_f**R) -- find the linear form vanishing on a top - 1 dimensional face e1 = (sim, ver, r) -> ( m := #nminus1ifaces; map(R^m, R^{m:(-r-1)}, (i,j) -> if i =!= j then 0 else (generators(faceideal1(nminus1ifaces#i,ver)))_(0,0)^(r+1))) -- build the diagonal matrix of r+1 powers of the linear forms -- modified to work with version of M2 of 11/7/96 - changes in last else above. ----------------------------------------------------------------------------- --Homology portion, wherein we build all the chain complexes. CCR = (C) -> ( D := new ChainComplex; D.ring = R; scan(-1..C.dim+1, i -> D#i = R^(# C.ifaces#i)); scan(0..C.dim+1, i -> D.dd#i = signedbd(C,i)); D) -- Takes a simplicial complex C (given by it's top dimensional part), produces -- the chain complex corresponding to the sheaf R. HS 10/15/95 Splitup = (m) -> ( n = transpose m; I = id_(target m); p = rank target m; degs = apply(p, i -> i*(p+1)); transpose (I ** n)_degs) -- Takes a matrix and makes each row a row with all non-row entries 0 in the -- new object. CCJ = (C, vertices, r) -> ( J = new ChainComplex; J.ring = R; K = new ChainComplex; a = new ChainComplexMap; K = CCR(C); temp = eqns(C,vertices,r); --J#(C.dim-1) = coker presentation image temp; J#(C.dim-1) = image temp; a#(C.dim-1) = map(K_(C.dim-1), J_(C.dim-1), temp); scan(reverse(0..C.dim-2), i -> ( temp = mingens image Splitup(K.dd_(i+1)*temp); --changed J#i = coker presentation image temp; --J_i is obtained by doing the boundary map, and then --"expanding" so that we get, on each i face, the sum --of all the hyperplanes thru it a#i = map(K_i,J_i, temp);)); J#(C.dim+1) = J#(C.dim) = J#-1 = R^0; a#(-1) = map(K_-1, J_-1, 0); a#(C.dim) = map(K_(C.dim), J_(C.dim), 0); a#(C.dim+1) = map(K_(C.dim+1), J_(C.dim+1), 0); scan(reverse(0..C.dim), i -> ( J.dd#i = map(J_(i-1), J_i, (K.dd_i*a_i) // a_(i-1));)); --changed J) -- Takes a simplicial complex C, a list of the vertex locations (J depends on -- embedding, R does not), and the order of differentiability desired, and -- returns the chain complex J. Also creates a ChainComplexMap a: J -> R qComplex = (U,tu) -> ( K := new ChainComplex; b = new ChainComplexMap; scan(drop(sort keys U, 2), i -> (K#i = coker matrix tu_i)); scan(0..max keys U, i -> (K.dd#i = map(K_(i-1), K_i, U.dd_i))); K.ring = R; K) --Given a complex U, and a map of complexes tu, forms the cokernel complex Init = (simp, vertices, r) -> ( D = new SimplicialComplex from simp; B = CCR(D); A = CCJ(D, vertices, r); C = qComplex(B,a);) SimplicialComplex <- new Type of MutableHashTable SimplicialComplex.name = "SimplicialComplex" new SimplicialComplex from List := (s,x) -> ( C := new MutableHashTable; n := C.dim = (# x#0) - 1; -- R = ZZ/31991[vars(0..n)]; R = QQ[vars(0..n)]; C.faces = new MutableHashTable; C.bfaces = new MutableHashTable; C.ifaces = new MutableHashTable; C.faces#n = toList apply(x, i -> sort i); C.ifaces#n = C.faces#n; D := C.faces#(n-1) = faces C.faces#n; E := C.bfaces#(n-1) = topbfaces C.faces#n; C.ifaces#(n-1) = toList ((set D) - (set E)); scan(reverse (0..n-2), i -> ( D = C.faces#i = faces C.faces#(i+1); E = C.bfaces#i = faces C.bfaces#(i+1); C.ifaces#i = toList ((set D) - (set E)); )); C.ifaces#-1 = C.faces#-1 = C.bfaces#-1 = {}; C.ifaces#(n+1) = C.faces#(n+1) = C.bfaces#(n+1) = {}; C) -- 0 faces are vertices, and the -1, n+1 face is the 0 module (added in to -- compute homology) Also, by sorting the top boundary faces, we avoid -- any ambiguity HS 10/15/95 -- faceideal = (C, f, vertices) -> -- minors(1 + #f, (transpose vars R) | promote(vertices_f,R)) -- error 3/26/97 promote has been replaced by tensor faceideal = (C, f, vertices) -> minors(1 + #f, (transpose vars R) | vertices_f**R) --eqns = (C, vertices, r) -> ( -- n := C.dim; -- m := #C.ifaces#(n-1); -- map(R^m, R^{m:(-r-1)}, (i,j) -> -- if i =!= j then 0 -- else ((faceideal(C,C.ifaces#(n-1)#i,vertices))_(0,0))^(r+1))) eqns = (C, vertices, r) -> ( n := C.dim; m := #C.ifaces#(n-1); map(R^m, R^{m:(-r-1)}, (i,j) -> if i =!= j then 0 else ((generators(faceideal(C,C.ifaces#(n-1)#i,vertices)))_(0,0))^(r+1))) --replaced old eqns (above) 11/20/96, due to change in M2. HKS ------------------------------------------------------------------------------ --Examples line = {{0,1},{1,2},{2,3}} lverts1 = transpose matrix( {{0,1},{2,1},{3,1},{4,1}}) lverts2 = transpose matrix( {{1,1},{3,1},{5,1},{7,1}}) lverts3 = transpose matrix( {{1,1},{2,1},{4,1},{8,1}}) lverts4 = transpose matrix( {{1,1},{2,1},{4,1},{7,1}}) line2= {{0,1},{1,2},{2,3},{3,4}} l2verts = transpose matrix( {{0,1},{2,1},{3,1},{4,1},{5,1}}) triv1= {{0,1,2},{0,2,3},{0,1,3}} trivverts1 = transpose matrix( {{0,0,1}, {0,1,1}, {1,0,1}, {-1,-1,1}}) triv= {{0,1,2},{0,2,3},{0,3,4},{0,1,4}} trivverts = transpose matrix( {{0,0,1}, {0,1,1}, {1,0,1}, {0,-1,1}, {-1,0,1}}) tri1 = {{0,1,2},{0,1,4},{0,2,5},{1,2,3},{2,3,5},{1,3,4},{3,4,5}} t1 = transpose matrix( {{0,4,1}, {2,-2,1}, {0,2,1}, {-2,-2,1}, {6,-4,1}, {-6,-4,1}}) --t1 has a hidden symmetry!!!!!! t1a = transpose matrix( {{0,4,1}, {2,-2,1}, {0,2,1}, {-2,-2,1}, {6,-5,1}, {-6,-4,1}}) t2 = transpose matrix( {{0,5,1}, {1,0,1}, {-1,0,1}, {0,-2,1}, {6,-4,1}, {-6,-4,1}}) t3 = transpose matrix( {{0,5,1}, {1,0,1}, {-1,0,1}, {0,-3,1}, {6,-4,1}, {-6,-3,1}}) s1 = {{0,1,3},{1,3,4},{1,2,4},{2,4,7},{4,6,7},{3,4,6},{3,5,6},{0,3,5}} sverts=transpose matrix( {{0,2,1}, {2,2,1}, {4,2,1}, {1,1,1}, {3,1,1}, {0,0,1}, {2,0,1}, {4,0,1}}) tri2 = {{0,1,2},{0,1,4},{0,2,5},{2,3,5},{1,3,4},{3,5,6},{3,6,4},{4,6,5},{1,2,3}} tri2g1 = {{0,1,2},{0,1,4},{0,2,5},{2,3,5},{1,3,4},{3,5,6},{3,6,4},{4,6,5}} tri2vertices = transpose matrix( {{0,8,1}, {2,-2,1}, {0,2,1}, {-2,-2,1}, {8,-6,1}, {-8,-6,1}, {-1,-4,1}}) symmg1={{0,3,4},{0,1,4},{1,4,5},{1,5,6},{1,2,6},{2,6,7},{2,7,8},{0,2,8},{0,3,8}} s2={{0,1,2},{0,3,4},{0,1,4},{1,4,5},{1,5,6},{1,2,6},{2,6,7},{2,7,8},{0,2,8},{0,3,8}} s2verts = transpose matrix( {{0,1,1}, {1,-1,1}, {-1,-1,1}, {0,5,1}, {2,1,1}, {4,-3,1}, {0,-3,1}, {-4,-3,1}, {-2,1,1}}) tetra = {{0,2,5,6},{0,3,6,7},{0,7,5,1},{4,5,6,7},{0,1,2,3},{2,3,4,6},{1,2,4,5},{1,4,3,7} ,{2,4,5,6},{1,5,4,7},{3,4,6,7},{0,2,1,5},{0,3,2,6},{0,1,3,7},{1,2,3,4}} tetrag1 = {{0,2,5,6},{0,3,6,7},{0,7,5,1},{4,5,6,7},{2,3,4,6},{1,2,4,5},{1,4,3,7},{2,4,5,6} ,{1,5,4,7},{3,4,6,7},{0,2,1,5},{0,3,2,6},{0,1,3,7},{0,1,2,3}} tetravertices = transpose matrix( {{0,0,3,1}, {1,1,1,1}, {0,-2,1,1}, {-1,1,1,1}, {0,0,0,1}, {6,-4,-1,1}, {-6,-4,-1,1}, {0,5,-1,1}}) tet1 = transpose matrix( {{0,1,10,1}, {1,1,1,1}, {0,-2,1,1}, {-1,1,1,1}, {0,0,0,1}, {7,-4,-1,1}, {-6,-4,-1,1}, {0,5,-1,1}}) tet2 = transpose matrix( {{0,1,10,1}, {1,1,1,1}, {0,-2,1,1}, {0,1,1,1}, {0,0,0,1}, {7,-4,-1,1}, {-6,-4,-1,1}, {0,5,-1,1}}) tetravertices1= transpose matrix( {{0,0,5,1}, {1,-1,1,1}, {-1,-1,1,1}, {0,1,1,1}, {0,0,0,1}, {6,-4,-1,1}, {-6,-4,-1,1}, {0,5,-1,1}}) tetravertices2= transpose matrix( {{0,0,6,1}, {1,1,1,1}, {0,-2,1,1}, {-1,1,1,1}, {0,0,0,1}, {6,-6,-1,1}, {-6,-6,-1,1}, {0,6,-1,1}}) tetravertices3= transpose matrix( {{0,0,6,1}, {1,1,1,1}, {0,-1,1,1}, {-1,1,1,1}, {0,0,-1,1}, {6,-6,-6,1}, {-6,-6,-6,1}, {0,6,-6,1}}) tetravertices4= transpose matrix( {{1,0,5,1}, {1,-1,1,1}, {-1,-1,1,1}, {0,1,1,1}, {0,0,0,1}, {16,-16,-5,1}, {-12,-10,-4,1}, {0,5,-1,1}}) oct = {{0,1,2,5},{0,1,2,6},{0,1,4,5},{0,1,4,6},{0,2,3,5},{0,2,3,6},{0,3,4,5},{0,3,4,6} } oct1vertices = transpose matrix( {{0,0,0,1}, {-4,3,-1,1}, {3,3,2,1}, {3,-3,0,1}, {-2,-3,1,1}, {-2,1,10,1}, {0,0,-10,1}}) oct2vertices = transpose matrix( {{0,0,0,1}, {1,0,0,1}, {0,1,0,1}, {-1,0,0,1}, {0,-1,0,1}, {0,0,1,1}, {0,0,-1,1}}) oct3vertices = transpose matrix( {{1,1,1,1}, {4,0,0,1}, {0,4,0,1}, {-4,0,0,1}, {0,-4,0,1}, {0,0,4,1}, {0,0,-4,1}}) oct4vertices = transpose matrix( {{1,1,1,1}, {4,0,0,1}, {0,4,0,1}, {-4,0,0,1}, {0,-4,1,1}, {0,0,4,1}, {0,0,-4,1}}) ogon = {{0,1,2,3},{0,1,2,6},{0,1,3,5},{0,1,5,6},{0,2,3,4},{0,2,4,6},{0,3,4,5},{0,4,5,6} } o3vertices = transpose matrix( {{0,0,0,1}, {4,0,0,1}, {0,4,0,1}, {0,0,4,1}, {-4,0,0,1}, {0,-4,0,1}, {0,0,-4,1}}) o4vertices = transpose matrix( {{0,0,0,1}, {3,0,1,1}, {0,4,0,1}, {0,0,4,1}, {-4,0,0,1}, {0,-4,0,1}, {0,0,-4,1}}) o5vertices = transpose matrix( {{0,0,0,1}, {2,1,1,1}, {0,4,0,1}, {0,0,4,1}, {-4,0,0,1}, {0,-4,0,1}, {0,0,-4,1}}) o6vertices = transpose matrix( {{1,0,0,1}, {4,0,0,1}, {0,4,0,1}, {0,0,4,1}, {-4,0,0,1}, {0,-4,0,1}, {0,0,-4,1}}) o6avertices = transpose matrix( {{0,0,0,1}, {3,0,1,1}, {0,3,-1,1}, {0,0,4,1}, {-4,0,0,1}, {0,-4,0,1}, {0,0,-4,1}}) o7vertices = transpose matrix( {{0,0,0,1}, {2,1,1,1}, {0,3,1,1}, {0,0,4,1}, {-4,0,0,1}, {0,-4,0,1}, {0,0,-4,1}}) o8vertices = transpose matrix( {{0,0,0,1}, {2,1,1,1}, {1,2,1,1}, {0,0,4,1}, {-4,0,0,1}, {0,-4,0,1}, {0,0,-4,1}}) o9vertices = transpose matrix( {{1,0,1,1}, {4,0,0,1}, {0,4,0,1}, {0,0,4,1}, {-4,0,0,1}, {0,-4,0,1}, {0,0,-4,1}}) o10vertices = transpose matrix( {{1,0,1,1}, {3,0,1,1}, {0,4,0,1}, {0,0,4,1}, {-4,0,0,1}, {0,-4,0,1}, {0,0,-4,1}}) o11vertices = transpose matrix( {{1,0,1,1}, {2,1,1,1}, {0,4,0,1}, {0,0,4,1}, {-4,0,0,1}, {0,-4,0,1}, {0,0,-4,1}}) o12vertices = transpose matrix( {{1,1,1,1}, {4,0,0,1}, {0,4,0,1}, {0,0,4,1}, {-4,0,0,1}, {0,-4,0,1}, {0,0,-4,1}}) o13vertices = transpose matrix( {{0,0,0,1}, {4,0,1,1}, {0,4,1,1}, {0,1,4,1}, {-4,0,-1,1}, {0,-4,-1,1}, {0,-1,-4,1}}) o14vertices = transpose matrix( {{0,1,0,1}, {4,0,1,1}, {0,4,1,1}, {0,1,4,1}, {-4,0,-1,1}, {0,-4,-1,1}, {0,-1,-4,1}}) isbundle = (cpx, verts,r)->( Init(cpx,verts, r); t := HH_3 C; i:=3; while i>0 do ( print i; print dim Ext^i(t,R); i=i-1) ) isbundle1 = (cpx, verts,r)->( Init(cpx,verts, r); print "dim H_2"; print dim HH_2 C; print "dim H_1"; print dim HH_1 C) bpyr = {{0,1,2,3},{0,1,3,4},{0,2,3,4},{0,1,2,5},{0,1,4,5},{0,2,4,5}} bverts = transpose matrix( {{0,0,0,1}, {0,3,0,1}, {3,0,0,1}, {0,0,3,1}, {-2,-1,1,1}, {1,2,-3,1}}) --free for r=1, nonfree for r=2 (and get all 9 hypers) bverts0 = transpose matrix( {{0,0,0,1}, {0,3,0,1}, {3,0,0,1}, {0,0,3,1}, {-2,-2,1,1}, {1,0,-3,1}}) --free for r <5, Nonfree r=5!, free r =6, nonfree r=7 bverts1 = transpose matrix( {{0,0,0,1}, {0,3,0,1}, {3,0,0,1}, {0,0,3,1}, {-2,-2,1,1}, {0,0,-3,1}}) --free for all r bverts2 = transpose matrix( {{0,0,0,1}, {0,3,0,1}, {3,0,0,1}, {0,0,3,1}, {-2,-1,1,1}, {1,0,-3,1}}) --free for r <5, Nonfree r=5!, free r =6, nonfree r=7 bverts3 = transpose matrix( {{0,0,0,1}, {0,3,0,1}, {3,0,0,1}, {0,0,3,1}, {-2,-1,1,1}, {0,1,-3,1}}) --free for r <5, Nonfree r=5!, free r =6, nonfree r=7 simps2 = {{0,1,2,4},{0,2,3,4},{2,3,4,5}} verts2 = transpose matrix( {{0,0,0,1}, {3,0,0,1}, {0,3,0,1}, {0,0,3,1}, {3,0,3,1}, {0,3,3,1}}) --free for all r (dual graph a segment) mtet= {{0,1,2,3},{0,1,2,4},{0,2,3,4},{0,1,3,4}} vertsm = transpose matrix( {{0,0,1,1}, {-1,-1,0,1}, {1,0,0,1}, {0,1,0,1}, {0,0,5,1}}) --free for all r (dual graph a segment)