One Hat Cyber Team
Your IP :
216.73.216.115
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
/
View File Name :
SlackIdeals.m2
newPackage( "SlackIdeals", Version => "1.0", Date => "March 15, 2020", Authors => {{Name => "Amy Wiebe", Email => "w.amy.math@gmail.com"}, {Name => "Antonio Macchia", Email => "macchia.antonello@gmail.com"}}, Headline => "Slack ideals of polytopes and matroids", Keywords => {"Commutative Algebra", "Matroids"}, PackageExports => {"Polyhedra", "Matroids", "EdgeIdeals", "LLLBases", "Elimination"} ) export {"slackMatrix", "getFacetBases", "slackFromPlucker", "slackFromGalePlucker", "slackFromGaleCircuits", "specificSlackMatrix", "symbolicSlackMatrix", "symbolicSlackOfPlucker", "slackIdeal", "grassmannSectionIdeal", "graphFromSlackMatrix", "graphicIdeal", "cycleIdeal", "universalIdeal", "toricPolytope", "setOnesForest", "rehomogenizePolynomial", "rehomogenizeIdeal", "findFlag", "containsFlag", "reconstructSlackMatrix", "reducedSlackMatrix", -- Options "Object", "Vars", "Tolerance", "Saturate", "FlagElement", "FlagIndices" } -- INTERNAL -- auxiliary functions -- nonzeroEntries, -- polytopeSlack, -- matroidSlack, -- sgn, -- reducedRowEchelon -- toBin, -- toricIdeal, -- slackToPluckerMatrix, -- fromBinomial, -- varEntriesIndices, -- distVU, -- abstractFaceLattice, -- findAbstractDim, -- flagFromPosetCoatoms, -- simplicialColExtend, -- smallColExtend, -- options -- Strategy --Abstract Incidence structure helpers abstractFaceLattice := V -> ( -- INPUT: list V of facet indices of abstract polytope (coatoms of desired poset) -- CAVEAT: V is NOT a list of vertex coordinates!! -- OUTPUT: poset representing face lattice of polytope v := #V; atoms := unique flatten V; L := for s in subsets(v) list ( I := set atoms; scan(s, e -> I = I*set(V_e)); {I, s} ); -- get unique sets that occur in the poset without index sets elts := unique apply(L, e -> e_0); -- collect each unique element from L with all its index sets smallL := for i from 0 to #elts-1 list ( sameElts := select(L, e -> e_0===elts_i); {elts_i, apply(sameElts, e -> e_1)} ); -- create poset by comparing first element of each member of smallL poset(smallL, (x, y) -> isSubset(x_0, y_0)) ) findAbstractDim := V -> ( -- INPUT: list V of facet indices of abstract polytope (coatoms of desired poset) -- CAVEAT: V is NOT a list of vertex coordinates!! -- OUTPUT: dimension of the polytope Pos := abstractFaceLattice V; M := maximalChains Pos; m := max apply(M, e->#e); -- dimension is 2 less than elements in longest max chain m-2 ) flagFromPosetCoatoms := (i, coatoms) -> ( -- Helper function for findFlag -- INPUT: List coatoms contains all coatoms of some Poset as sets of atom labels, index i of coatom to start flag -- OUTPUT: a list F of indices of coatoms elements that make up a flag in the Poset Pos := abstractFaceLattice coatoms; M := maximalChains Pos; -- get the longest maximal chains (if we have a full face lattice then all are same length -- otherwise, some might be shorter due to missing coatoms) C := M_0; for m in M do ( if #m > #C_0 then C = {m} else if #m == #C_0 then C = append(C, m); ); d := #C_0-1; flags := {}; -- get correct index set of zero that actually forms a chain for c in C do ( F := {{}}; for j from 0 to d do ( F = select(1, (c_(d-j))_1, e -> (isSubset(F_0, e) and #e==j)); ); flags = append(flags, F_0); ); (select(1, flags, f -> member(i, f)))_0 ) nonzeroEntries := M -> ( -- Helper function: symbolicSlackMatrix, -- INPUT: matrix M -- OUTPUT: nnz=number of nonzero entries of the matrix M nnz := 0; for i in (0..numgens target M-1) do ( for j in (0..numgens source M-1) do ( if M_(i, j) != 0 then nnz = nnz+1; ); ); nnz ) polytopeSlack := P -> ( -- Helper function for slackMatrix -- INPUT: bounded Polyhedron P -- OUTPUT: slack matrix of P if not isCompact(P) then ( error "Please use a bounded polyhedron" ) else (-- facets/vertices doesn't work without Polyhedra$ because of shadowed defns V := Polyhedra$vertices P; n := numgens source V; F := Polyhedra$facets P; W := matrix(entries transpose F_1 | -entries transpose F_0); one := for i to n-1 list {1}; -- convexHull(V) and V are often ordered differently << "\nOrder of vertices is " << endl << entries transpose V << endl; (matrix one | transpose V)*W ) ) matroidSlack := M -> ( -- Helper function for slackMatrix -- INPUT: realization of matroid M with ground set the columns of a matrix -- OUTPUT: slack matrix of M V := apply(M_*, v -> flatten entries v); H := hyperplanes M; d := (rank M)-1; I := independentSets(M, d); S := {}; for i from 0 to #V-1 do ( row := {}; for h in H do ( -- find a maximal independent set in each hyperplane dSub := subsets(h, d); j := 0; J := dSub_j; while not member(J, I) do ( j = j+1; J = dSub_j; ); J = sort(toList J); -- calculate slack from independent set entry := det(matrix({V_i} | V_J)); row = append(row, entry); ); S = append(S, row); ); matrix S ) slackMatrix = method(Options => {Object => "polytope"}) slackMatrix List := Matrix => opts -> V -> ( -- INPUT: a list V of points to be treated as vertices of polytope, vectors of a matroid, or generators of a cone -- 'matroid' option treats V as affine points and appends 1 to each to put into projective space -- OUTPUT: a slack matrix M of V VV := matrix V; if opts.Object == "matroid" then ( V1 := for i to #V-1 list {1} | V_i; M := matroid(transpose matrix V1); matroidSlack M ) else if opts.Object == "polytope" then ( P := convexHull(transpose matrix V); polytopeSlack P ) else if opts.Object == "cone" then ( C := coneFromVData(transpose matrix V); slackMatrix C ) else ( error "Please choose a valid object" ) ) slackMatrix Matroid := Matrix => opts -> M -> ( -- check that ground set of M could be a realization V := M_*; if instance(V_0, List) then ( r := rank M; if #(V_0) < r then ( error "Please give a realization of the matroid" ) else ( print(" -- warning: Treating ground set as realization"); matroidSlack(matroid(transpose matrix(V))) ) ) else if instance(V_0, Matrix) then ( matroidSlack(M) ) else ( error "Please give a realization of the matroid" ) ) slackMatrix Polyhedron := Matrix => opts -> P -> ( if isCompact(P) then ( polytopeSlack(P) ) else ( error "Please give a bounded polyhedron or cone" ) ) slackMatrix Cone := Matrix => opts -> C -> ( -- INPUT: cone C -- OUTPUT: a slack matrix of C W := Polyhedra$halfspaces C; V := rays C; -- coneFromVData(V) and V are often ordered differently << "\nOrder of rays is " << endl << entries transpose V <<endl; (transpose V)*(transpose W) ) getAbstractFacetBases := coatoms -> ( -- Helper function for getFacetBases -- INPUT: a list coatoms of codim 1 elements of an abstract "face" lattice listed as the atom indices they contain -- OUTPUT: a list B of a basis (size d set of atoms not contained in any other coatom) for each coatom d := findAbstractDim coatoms; -- find d subsets of each facet not contained in any other facet (i.e., independent) B := for f in coatoms list ( haveBasis := false; S := subsets(#f, d); i := 0; while not haveBasis and i < #S do ( b := f_(S_i); isBasis := true; j := 0; while isBasis and j < #f-1 do ( f2 := (delete(f, coatoms))_j; if isSubset(b, f2) then ( isBasis = false; ); j = j+1; ); if isBasis then haveBasis = true else i = i+1; ); b ); B ) -- Helper method for (symbolic)SlackFromPlucker functions getFacetBases = method(Options => {Object => "polytope"}) getFacetBases Matrix := (List, List) => opts -> S -> ( -- INPUT: (symbolic) slack matrix S of rank d+1 -- OUTPUT: first list is empty since there are no vertices to reorder, a list B of d spanning elements for each facet coatoms := apply(entries transpose S, r -> positions(r, e -> e==0_(ring S))); ({},getAbstractFacetBases coatoms) ) getFacetBases Polyhedron := (List, List) => opts -> P -> ( -- INPUT: polytope P -- OUTPUT: first list is empty since vertices are not reordered, a list B of d spanning elements for each facet coatoms := apply(Polyhedra$faces(1, P), e -> e_0); ({}, getAbstractFacetBases coatoms) ) getFacetBases Matroid := (List, List) => opts -> M -> ( -- INPUT: matroid M -- OUTPUT: first list is empty since ground set elements are not reordered, a list B of d spanning elements for each hyperplane coatoms := apply(hyperplanes M, e -> toList e); ({}, getAbstractFacetBases coatoms) ) getFacetBases List := (List, List) => opts -> V -> ( -- INPUT: list V of vertices of d-polytope, vectors of a rank d+1 matroid, or (d+1)-cone generators -- OUTPUT: a list newV of V in the order corresponding to B, and B the list of d spanning elements for each facet newV := {}; if opts.Object == "abstractPolytope" then ( (sort unique flatten V, getAbstractFacetBases V) ) else if opts.Object == "polytope" then ( P := convexHull(transpose matrix V); newV = entries transpose Polyhedra$vertices(P); (newV, (getFacetBases P)_1) ) else if opts.Object == "cone" then ( C := coneFromVData(transpose matrix V); newV = entries transpose rays(C); (newV, (getFacetBases C)_1) ) else if opts.Object == "matroid" then ( newV = for v in V list {1} | v; M := matroid(transpose matrix newV); (newV, (getFacetBases M)_1) ) else error "Please choose a valid object" ) slackFromPlucker = method(Options => {Object => "polytope"}) slackFromPlucker (List, List) := Matrix => opts -> (V, B) -> ( -- INPUT: list of coordinates V for polytope vertices, cone generators, or matroid vectors; a set B of hyperplane spanning set indices -- OUTPUT: slack matrix filled with Plücker coordinates -- CAVEAT: does not check if B actually spans for given V, does not check orientation of simplices in B v := #V; X := matrix for p in V list join({1}, p); if opts.Object == "cone" then ( X = matrix V; ) else if opts.Object == "abstractPolytope" then ( error "Please give a realization" ) else if (opts.Object != "polytope" and opts.Object != "matroid") then ( error "Please choose a valid object object" ); -- check we can calculate plucker coordinates from determinants d := (numgens source X)-1; if #(B_0) != d then ( error "Please give a realization in the correct dimension" ); -- get matrix of Plücker index sets M := for i from 0 to v-1 list for b in B list join(b, {i}); matrix apply(M, r -> apply(r, e -> det(submatrix(X, e, )))) ) slackFromPlucker List := Matrix => opts -> V -> ( -- INPUT: list of coordinates V for polytope vertices, cone generators, or matroid vectors -- OUTPUT: slack matrix filled with Plücker coordinates (newV, B) := getFacetBases(V, Object => opts.Object); if opts.Object == "polytope" or opts.Object == "cone" then ( << "\nInput has been reordered to" << endl << newV << endl; ); slackFromPlucker(newV, B, Object => opts.Object) ) slackFromPlucker Polyhedron := Matrix => opts -> P -> ( -- INPUT: polytope P -- OUTPUT: slack matrix filled with Plücker coordinates V := Polyhedra$vertices P; (newV, B) := getFacetBases P; slackFromPlucker(entries transpose V, B, Object => "polytope") ) slackFromPlucker Matroid := Matrix => opts -> M -> ( -- INPUT: matroid M -- OUTPUT: slack matrix filled with Plücker coordinates v := #(M_*); X := M_0; for i from 1 to v-1 do X = X | M_i; d := (numgens target X)-1; (newV, B) := getFacetBases M; if #(B_0) != d then ( error "Please give a realization in the correct dimension" ); -- get matrix of Plücker index sets N := for i from 0 to v-1 list for b in B list join(b, {i}); matrix apply(N, r -> apply(r, e -> det(submatrix(X, , e)))) ) sgn = (I, J) -> ( -- Helper function for slackFromGalePlucker and slackToPluckerMatrix -- INPUT: list of subset I of [n], list of subset J of [n] -- OUTPUT: the sign of the permutation that puts I, J in the correct order, assuming the elements of I, J are already ordered increasingly count := 0; for j in J do ( for i in I do ( if j < i then count = count + 1; ); ); (-1)^count ) slackFromGalePlucker = method() slackFromGalePlucker (List, List) := Matrix => (B, G) -> ( -- INPUT: a set B of hyperplane spanning set indices; list of Gale vectors G -- OUTPUT: slack matrix filled with Plücker coordinates -- CAVEAT: does not check if B actually spans for given V, does not check orientation of simplices in B\ -- CAVEAT: make sure elements of G are listed in the order corresponding to indices in B v := #G; d := v-1-#(G_0); if #(B_0) != d then error "Dimensions do not match."; -- get matrix of Plücker index sets and sign of the permutation that puts them in the order M := for i from 0 to v-1 list for b in B list {sgn(toList(set(0..v-1)-join(b, {i})), join(b, {i}))*sgn(b, {i}), sort(toList(set(0..v-1) - join(b, {i})))}; -- account for the fact that [v]-J is incorrect size if J contains repeats matrix apply(M, r->apply(r, e -> if #e_1 != v-d-1 then 0 else (e_0)*det(submatrix(matrix G, e_1, )))) ) slackFromGalePlucker (List, Matrix) := Matrix => (B, MG) -> ( -- INPUT: a set B of hyperplane spanning set indices; matrix of Gale vectors MG -- OUTPUT: slack matrix filled with Plücker coordinates -- CAVEAT: does not check if B actually spans for given V, does not check orientation of simplices in B if (numgens source MG)>(numgens target MG) then ( slackFromGalePlucker(B, entries transpose MG) ) else slackFromGalePlucker(B, entries MG) ) reducedRowEchelon = method(Options => {Tolerance => 14}) reducedRowEchelon Matrix := Matrix => opts -> M -> ( -- Helper function for slackFromGaleCircuits -- INPUT: matrix M of the form matrix(RR, {...}), positive integer to set the tolerance to 10^(-tol) -- OUTPUT: reduced row-echelon form (or Gauss-Jordan form) of the matrix M rows := numgens target M; -- number of rows cols := numgens source M; -- number of columns N := mutableMatrix M; eps := 10^(-opts.Tolerance); lead := 0; for r in (0..rows-1) do ( if lead >= cols then ( return matrix N; ); i := r; while abs(N_(i, lead)) < eps do ( i = i + 1; if i == rows then ( i = r; lead = lead + 1; if cols == lead then ( return matrix N; ); ); ); rowSwap(N, i, r); if abs(N_(r, lead)) >= eps then ( rowMult(N, r, 1/N_(r, lead)); for h in (0..cols-1) do ( if abs(N_(r, h)) < eps then N_(r, h) = 0; ); ); for i in (0..rows-1) do ( if i != r then ( rowAdd(N, i, -N_(i, lead), r); for h in (0..cols-1) do ( if abs(N_(i, h))<eps then N_(i, h) = 0; ); ); ); lead = lead + 1; ); matrix(N) ) slackFromGaleCircuits = method(Options => {Tolerance => 14}) slackFromGaleCircuits Matrix := Matrix => opts -> G -> ( -- INPUT: matrix of the form matrix(RR, {...}) whose columns are the vectors of a Gale transform, -- optional positive integer Tolerance to set entries less than 10^(-Tolerance) to zero -- OUTPUT: slack matrix of a polytope P having G as Gale transform print("-- warning: experimental computation over inexact field begun, results not reliable"); -- Put Gale transform into ring with real numbers so computation runs properly G = substitute(G,RR); v := numgens source G; w := numgens target G; d := v - w - 1; circuits := {}; slack := {}; for i in (2..w+1) do ( L := subsets(v, i); for z in L do ( M := submatrix(G, , z); rkMi := false; if w >= i then ( r := subsets(w, w); c := subsets(z, w); -- check that rank(M)<w by computing all w-minors of M mins := {}; for a in r do ( for b in c do mins = mins | {determinant(submatrix(G, a, b))}; ); rkMi = all(mins, m -> abs(m) < 10^(-opts.Tolerance)); ); -- if rank(M) < min(w, i), compute the minimal positive circuits if rkMi or w < i then ( P := reducedRowEchelon(M, Tolerance => opts.Tolerance); circ := flatten entries P_(i-1); if all(circ_{0..i-2}, c -> c < 0) and not(any(circuits, c->isSubset(c, z))) then ( slack = slack | {-circ_{0..i-2} | {1}}; circuits = circuits | {z}; ); ); ); ); -- constructing the slack matrix numCirc := #circuits; SP := mutableMatrix(RR, v, numCirc); for b in (0..numCirc-1) do ( for a in (0..#(circuits_b)-1) do SP_((circuits_b)_a, b) = (slack_b)_a; ); matrix SP ) specificSlackMatrix = method() specificSlackMatrix String := Matrix => name -> ( -- INPUT: string identifying a polytope or matroid in the following list: "perles1", "perles2", "barnette", "toric-non-graphic", "pu-non-mcmullen", "fano-matroid", "complex-matroid", "nonfano-matroid", "perles-matroid", "perles-matroid-QQ" -- CAVEAT: "perles1" and "perles2" are the two nonrational polytopes due to Perles (they refer respectively to the polytopes coming from the Gale diagrams in Figure 5.5.1 and Figure 5.5.2 in Grünbaum, Convex Polytopes, Springer GTM, New York, 2003,Second Edition) -- CAVEAT: "barnette" is a four-dimensional prism over a square pyramid with a nonprescribable cubical facet (Section 4.2 in Gouveia, Macchia, Thomas, Wiebe, The slack realization space of a polytope, SIAM J. Discrete Math. 33 (3):1637–1653, 2019) -- CAVEAT: "toric-non-graphic" is an example of polytope with toric but not graphic slack ideal (Example 3.7 in Gouveia, Macchia, Thomas, Wiebe, Projectively unique polytopes and toric slack ideals, J. Pure Appl. Algebra 224 (5):106229, 2020) -- CAVEAT: "pu-non-mcmullen" is a projectively unique polytope that does not come from McMullens constructions (Theorem 4.4.1 in Wiebe, Realization spaces of polytopes and matroids, PhD thesis, University of Washington, Seattle, 2019) -- CAVEAT: "fano-matroid", "complex-matroid", "nonfano-matroid", "perles-matroid", "perles-matroid-QQ" are the matroids respectively from Example 4.3, Example 4.4, Example 5.13 and Example 5.14 in Brandt, Wiebe, The slack realization space of a matroid, Algebraic Combinatorics 2 (4):663–681, 2019) R := QQ(monoid[vars 0]); a := R_0; if name == "perles1" then ( print("dimension", 8); matrix(RR, {{0, 0, 0, 2/(3+sqrt(5)), 2*sqrt(5)/(5+sqrt(5)), 2*sqrt(5)/(5*sqrt(5)+5), 0, 0, 0, 0, 0, 0, 0, -(sqrt(5)-5)/(5+sqrt(5)), -(3-sqrt(5))/(sqrt(5)-5), -(5-3*sqrt(5))/(5+sqrt(5)), -(sqrt(5)-1)/(sqrt(5)-5), -(5-3*sqrt(5))/(5+sqrt(5)), -(-sqrt(5)+1)/(sqrt(5)+1), -(-3-sqrt(5))/(10+4*sqrt(5)), -(-sqrt(5)-1)/(3+sqrt(5)), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 2/(sqrt(5)+1), 0, 0, 2*sqrt(5)/(5+sqrt(5)), (sqrt(5)+1)/(2*sqrt(5)+4), 2*sqrt(5)/(5*sqrt(5)+5), 0, 0, 0, 0, -2+sqrt(5), -(sqrt(5)-5)/(-5+5*sqrt(5)), 3/2-(1/2)*sqrt(5), -(5-3*sqrt(5))/(-5+5*sqrt(5)), 0, 0, 0, 0, -(-3-sqrt(5))/(10+4*sqrt(5)), -(5-3*sqrt(5))/(5+sqrt(5)), -(-sqrt(5)+1)/(sqrt(5)+1), 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 3/2-(1/2)*sqrt(5), 0, 0, 3/2-(1/2)*sqrt(5), 1/2-(1/10)*sqrt(5), 0, 0, -(-sqrt(5)+1)/(sqrt(5)+1), 1/2-(1/10)*sqrt(5), 0, 0, 3/2-(1/2)*sqrt(5), -2+sqrt(5), 0, 0, 2/(5+sqrt(5)), 0, 0, 0, -(25-11*sqrt(5))/(-15+5*sqrt(5)), 1, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 3/2-(1/2)*sqrt(5), 0, 0, 0, 0, 0, 0, 1/2-(1/10)*sqrt(5), 3/2-(1/2)*sqrt(5), 0, 0, -(-sqrt(5)+1)/(sqrt(5)+1), 1/2-(1/10)*sqrt(5), 0, 0, 2/(5+sqrt(5)), 0, 0, 3/2-(1/2)*sqrt(5), -2+sqrt(5), 0, 0, 0, 3/2-(1/2)*sqrt(5), (1/2)*sqrt(5)-1/2, -(25-11*sqrt(5))/(-15+5*sqrt(5)), 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 2/(sqrt(5)+1), 0, -(3*sqrt(5)-5)/(sqrt(5)-5), 0, -2/(sqrt(5)-5), 0, 0, 0, 0, 0, 0, 0, 0, 0, -(-3-sqrt(5))/(5+3*sqrt(5)), 2*sqrt(5)/(5+3*sqrt(5)), 0, 0, -(3*sqrt(5)-5)/(-15+5*sqrt(5)), 0, -2*sqrt(5)/(sqrt(5)-5), 1, 0, 2/(5+sqrt(5)), (1/2)*sqrt(5)+1/2, 1/2+(1/10)*sqrt(5), 0}, {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2/(sqrt(5)-5), 0, -(3*sqrt(5)-5)/(sqrt(5)-5), 0, 0, 0, 0, 2*sqrt(5)/(5+3*sqrt(5)), 0, -(-3-sqrt(5))/(5+3*sqrt(5)), 0, 0, 0, 0, 0, 0, -(-3+sqrt(5))/(-4+2*sqrt(5)), 0, 0, -(3*sqrt(5)-5)/(-15+5*sqrt(5)), 0, 0, 0, (1/10)*(sqrt(5)-1)*sqrt(5)}, {0, 1, 0, 0, 0, 0, 0, 0, 1/2+(1/10)*sqrt(5), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2*sqrt(5)/(5+3*sqrt(5)), 1, 0, 0, 0, 0, -(3*sqrt(5)-5)/(-15+5*sqrt(5)), 2/(5+sqrt(5)), 0, 0, -(-sqrt(5)-1)/(5+sqrt(5))}, {0, 0, 1, 0, 0, 1/2+(1/10)*sqrt(5), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2*sqrt(5)/(5+3*sqrt(5)), 0, 1, 0, 0, 0, 0, -(3*sqrt(5)-5)/(-15+5*sqrt(5)), 0, 0, 0, 0, -(-sqrt(5)-1)/(5+sqrt(5)), 1, 1/2+(1/10)*sqrt(5), 2/(5+sqrt(5))}, {1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (1/2)*sqrt(5)-1/2, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, (1/2)*sqrt(5)+1/2, (1/5)*sqrt(5), 0}, {0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, -(sqrt(5)-5)/(3*sqrt(5)-5), 1, -(3*sqrt(5)-5)/(sqrt(5)-5), 0, 0, 1, 0, 0}, {0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1}}) ) else if name == "perles2" then ( print("dimension", 8); matrix(RR, {{(2836152*sqrt(5) + 5360256)/1459855, (493812*sqrt(5) + 1217700)/187409, (41517828*sqrt(5) + 224340732)/31766699, 0, 0, 0, (35478108*sqrt(5) + 85655952)/16407589, 0, 0, 0, 0, 0, 0, 0, (47784*sqrt(5) + 298320)/50299, 0, 0, 0, 0, 0, 0, 0, 0, 0, (342936*sqrt(5) + 2756160)/579041, 0, 0, 0, 0, 0}, {0, (114312*sqrt(5) + 233904)/187409, (-14207292*sqrt(5) + 78892044)/31766699, 0, 0, (414*sqrt(5) + 906)/311, (-12243186*sqrt(5) + 45046182)/16407589, 0, (-20875068*sqrt(5) + 51719196)/26102989, 0, (2596572*sqrt(5) + 1703064)/1777939, 0, 0, 0, 0, 0, 0, 0, 0, (-7333884*sqrt(5) + 48832152)/20501549, 0, 0, (1584*sqrt(5) + 36696)/22621, 0, (-185328*sqrt(5) + 981816)/579041, (74052*sqrt(5) + 116556)/122321, (-9067770*sqrt(5) + 58107066)/27082049, 0, 0, (411048*sqrt(5) + 8496048)/6199429}, {(-71676*sqrt(5) + 387000)/291971, (-94248*sqrt(5) + 270756)/187409, (-2267892*sqrt(5) + 34746984)/31766699, 0, (1043856*sqrt(5) + 9865908)/12542879, 0, 0, 0, 0, (-198*sqrt(5) + 1494)/779, (1648548*sqrt(5) + 2211966)/1777939, (-1174206*sqrt(5) + 3080622)/1549411, (-70818*sqrt(5) + 577446)/293921, (754776*sqrt(5) + 4718316)/3599671, (-24948*sqrt(5) + 117696)/50299, (-886380*sqrt(5) + 22796112)/19623371, 0, (151056*sqrt(5) + 253332)/193699, (-1983*sqrt(5) + 9921)/4282, 0, (17496*sqrt(5) + 9100)/6589, (-244848*sqrt(5) + 787572)/401599, (-4140*sqrt(5) + 39816)/22621, (-19698*sqrt(5) + 72126)/29431, (-234972*sqrt(5) + 1096344)/579041, (-46278*sqrt(5) + 280386)/122321, 0, (244056*sqrt(5) + 374148)/242429, (-4140*sqrt(5) + 11112)/6061, (-934344*sqrt(5) + 9212364)/6199429}, {0, 0, (25042644*sqrt(5) + 43220628)/31766699, (21*sqrt(5) + 93)/25, 0, 0, (-13526046*sqrt(5) + 43141662)/16407589, 0, (-9275724*sqrt(5) + 86404788)/26102989, 0, (1857834*sqrt(5) + 4060782)/1777939, (2372172*sqrt(5) + 2346036)/1549411, 0, 0, 0, 0, (1770*sqrt(5) + 30294)/10571, 0, 0, (-2679462*sqrt(5) + 48241458)/20501549, 0, 0, 0, 0, 0, 0, (-3876372*sqrt(5) + 57319560)/27082049, 0, 0, 0}, {0, 0, 0, 0, (12359556*sqrt(5) + 40587228)/12542879, (414*sqrt(5) + 2826)/311, 0, 0, 0, 0, 0, 0, (857868*sqrt(5) + 1091244)/293921, (7538388*sqrt(5) + 19558572)/3599671, 0, (7552908*sqrt(5) + 91871076)/19623371, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, (-9708876*sqrt(5) + 23047272)/16407589, (522*sqrt(5) + 234)/109, (2621556*sqrt(5) + 49068828)/26102989, 0, 0, 0, 0, 0, 0, (2065404*sqrt(5) + 28835004)/19623371, (-5442*sqrt(5) + 41490)/10571, 0, 0, (-16181928*sqrt(5) + 39426588)/20501549, (6956*sqrt(5) - 1076)/599, 0, 0, 0, 0, 0, (-14181876*sqrt(5) + 80028576)/27082049, (37284*sqrt(5) + 39564)/22039, 0, (-279972*sqrt(5) + 11557260)/6199429}, {0, 0, 0, 0, 0, 0, 0, 0, (27529236*sqrt(5) + 126043056)/26102989, (594*sqrt(5) + 23562)/3895, (2387286*sqrt(5) + 13359456)/1777939, (5652702*sqrt(5) + 8874426)/1549411, (1048674*sqrt(5) + 868890)/293921, 0, 0, 0, 0, 0, (4389*sqrt(5) + 13101)/4282, 0, 0, 0, 0, (330*sqrt(5) + 144342)/29431, 0, (365310*sqrt(5) + 461142)/122321, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (4454736*sqrt(5) + 4291848)/1549411, (261624*sqrt(5) + 989472)/293921, (10835352*sqrt(5) + 8912112)/3599671, (-22836*sqrt(5) + 187572)/50299, (-8731932*sqrt(5) + 91978260)/19623371, (3672*sqrt(5) + 55068)/10571, 0, (3201*sqrt(5) + 4257)/2141, 0, (10412*sqrt(5) - 580)/599, (45492*sqrt(5) + 84900)/36509, 0, (60324*sqrt(5) + 31548)/29431, 0, 0, 0, (115092*sqrt(5) + 34116)/22039, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (1101456*sqrt(5) + 1110888)/193699, (1998*sqrt(5) + 9924)/2141, (26195274*sqrt(5) + 109518390)/20501549, (208544*sqrt(5) + 88184)/6589, (277584*sqrt(5) + 2554536)/401599, (2556*sqrt(5) + 194940)/22621, 0, 0, 0, 0, 0, 0, 0}, {(-1786752*sqrt(5) + 6201624)/1459855, (285252*sqrt(5) + 526548)/187409, 0, 0, (-4938516*sqrt(5) + 49879500)/12542879, 0, 0, (522*sqrt(5) + 1074)/109, 0, (396*sqrt(5) + 15708)/3895, 0, 0, 0, 0, 0, 0, 0, (53604*sqrt(5) + 40596)/17609, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (79692*sqrt(5) + 105156)/29431, (77364*sqrt(5) + 2114172)/579041, (337536*sqrt(5) + 609768)/122321, (27126018*sqrt(5) + 129529386)/27082049, (1920192*sqrt(5) + 1724520)/242429, (13512*sqrt(5) + 38784)/6061, (803268*sqrt(5) + 45127476)/6199429}, {(-138204*sqrt(5) + 804276)/291971, 0, 0, (-21*sqrt(5) + 207)/25, (-8464896*sqrt(5) + 50181912)/12542879, 0, 0, 0, 0, 0, 0, 0, 0, (2542188*sqrt(5) + 10007052)/3599671, 0, 0, 0, (32796*sqrt(5) + 46692)/17609, 0, 0, 0, (48468*sqrt(5) + 49380)/36509, 0, 0, 0, 0, 0, 0, (-852*sqrt(5) + 2076)/551, 0}}) ) else if name == "barnette" then ( print("dimension", 4); matrix(RR, {{1, 0, 0, 0, 1, 1, 0}, {1, 0, 0, 0, 0, 1, 1}, {1, 0, 0, 1, 0, 0, 1}, {1, 0, 0, 1, 1, 0, 0}, {1, 0, 1, 0, 0, 0, 0}, {0, 1, 0, 0, 1, 1, 0}, {0, 1, 0, 0, 0, 1, 1}, {0, 1, 0, 1, 0, 0, 1}, {0, 1, 0, 1, 1, 0, 0}, {0, 1, 1, 0, 0, 0, 0}}) ) else if name == "toric-non-graphic" then ( print("dimension", 5); matrix(RR, {{0, 1, 1, 0, 0, 0, 0, 1}, {1, 1, 1, 0, 0, 0, 0, 0}, {0, 0, 1, 1, 0, 0, 0, 0}, {0, 1, 0, 0, 0, 1, 0, 0}, {1, 0, 1, 0, 0, 0, 1, 0}, {0, 0, 1, 0, 0, 0, 1, 1}, {0, 0, 0, 0, 0, 1, 1, 0}, {1, 1, 0, 0, 1, 0, 0, 0}, {0, 1, 0, 0, 1, 0, 0, 1}, {0, 0, 0, 1, 1, 0, 0, 0}, {0, 0, 0, 0, 1, 0, 1, 1}, {1, 0, 0, 0, 1, 0, 1, 0}}) ) else if name == "pu-non-mcmullen" then ( print("dimension", 5); matrix(RR, {{0, 0, 1, 0, 0, 0, 1, 1, 0, 0}, {1, 1, 1, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 1, 1, 0, 1, 0, 0, 0}, {0, 1, 0, 1, 0, 0, 0, 0, 0, 1}, {0, 1, 1, 1, 0, 0, 0, 0, 1, 0}, {1, 0, 0, 0, 1, 1, 0, 0, 0, 0}, {0, 0, 1, 0, 0, 1, 0, 1, 1, 0}, {0, 0, 0, 0, 0, 1, 0, 1, 0, 1}, {0, 0, 0, 1, 1, 1, 0, 0, 1, 0}}) ) else if name == "fano-matroid" then ( print("dimension", 2); matrix(ZZ/2, {{1, 0, 1, 0, 0, 1, 1}, {0, 0, 1, 1, 1, 1, 0}, {0, 1, 1, 0, 1, 0, 1}, {1, 1, 1, 1, 0, 0, 0}, {1, 0, 0, 1, 1, 0, 1}, {1, 1, 0, 0, 1, 1, 0}, {0, 1, 0, 1, 0, 1, 1}}) ) else if name == "complex-matroid" then ( print("dimension", 2); matrix(R/ideal(a^2-a+1), {{0, a, 1, 1, 0, 1, 0, a-1, -a+1, a, 1, 0}, {-a, 0, 1, a, 0, 0, 1, -1, 1, -1, 0, -a+1}, {1, 0, a, 0, -a+1, a, 0, -a, 1, 0, 1, 1}, {1, a, a, 0, 0, 1, a-1, 0, 0, 1, 1, a}, {a, 0, 0, -a+1, -a+1, a, -a, 0, -a+1, a, 1, 0}, {0, 1, 0, 0, a, -a, a, 1, a-1, -a+1, 0, a}, {0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1}, {a, 1, 0, -a+1, 1, 0, 0, 1, 0, 1, 1, a}}) ) else if name == "nonfano-matroid" then ( print("dimension", 2); matrix(RR, {{1, 0, 1, 0, 0, 1, 1, 1, 1}, {0, 0, 1, 1, -1, 1, 2, 0, 0}, {0, 1, -1, 0, 1, 0, -1, -1, 1}, {-1, 1, -1, 1, 0, 0, 0, -2, 0}, {1, 0, 0, -1, 1, 0, -1, 1, 1}, {1, 1, 0, 0, 1, 1, 0, 0, 2}, {0, 1, 0, 1, 0, 1, 1, -1, 1}}) ) else if name == "perles-matroid" then ( print("dimension", 2); matrix(RR, {{0, 1, 3/2-sqrt(5)/2-3, 3-3/2-sqrt(5)/2, 0, 3-3/2-sqrt(5)/2, 0, -1, 1, 3-3/2-sqrt(5)/2, 1, 3/2-sqrt(5)/2-2, 2-3/2-sqrt(5)/2, 2-3/2-sqrt(5)/2, 0}, {2*(3/2-sqrt(5)/2)-5, 1, 0, 0, 3-3/2-sqrt(5)/2, 3-3/2-sqrt(5)/2, 0, 2-3/2-sqrt(5)/2, 3-3/2-sqrt(5)/2, 3/2-sqrt(5)/2-2, 0, 3/2-sqrt(5)/2-2, 0, 2-3/2-sqrt(5)/2, 5-2*(3/2-sqrt(5)/2)}, {1, 3/2-sqrt(5)/2, 1, 0, 3/2-sqrt(5)/2, 3/2-sqrt(5)/2-1, 1, 0, 0, 3/2-sqrt(5)/2, 1-3/2-sqrt(5)/2, 1, 3/2-sqrt(5)/2, 0, 0}, {1, 0, 3/2-sqrt(5)/2-1, 1-3/2-sqrt(5)/2, 3/2-sqrt(5)/2-1, 0, 0, 3/2-sqrt(5)/2-1, -3/2-sqrt(5)/2, 1, 1-2*(3/2-sqrt(5)/2), 0, 3/2-sqrt(5)/2, 0, -1}, {2-3/2-sqrt(5)/2, 0, 2-3/2-sqrt(5)/2, 3/2-sqrt(5)/2-1, 0, 3/2-sqrt(5)/2-2, 1, 0, 3/2-sqrt(5)/2-1, 0, 3/2-sqrt(5)/2, 2-3/2-sqrt(5)/2, 0, 3/2-sqrt(5)/2-1, 3/2-sqrt(5)/2-1}, {2-3/2-sqrt(5)/2, 1-3/2-sqrt(5)/2, 0, 1, 0, 0, 1, 3/2-sqrt(5)/2-1, 0, 2-3/2-sqrt(5)/2, 1, 1-3/2-sqrt(5)/2, 1, 3/2-sqrt(5)/2, 3/2-sqrt(5)/2-1}, {0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1}, {0, 0, 3-3/2-sqrt(5)/2, 3/2-sqrt(5)/2-2, 1, 3/2-sqrt(5)/2-2, 1, 1, 0, 3/2-sqrt(5)/2-2, 0, 2-3/2-sqrt(5)/2, 3/2-sqrt(5)/2-1, 3/2-sqrt(5)/2-1, 1}, {0, 3/2-sqrt(5)/2+1, 1, 0, 1, 0, 1, 3/2-sqrt(5)/2, 1-3/2-sqrt(5)/2, 0, 1-3/2-sqrt(5)/2, 1-3/2-sqrt(5)/2, 3/2-sqrt(5)/2, 3/2-sqrt(5)/2, 1}}) ) else if name == "perles-matroid-QQ" then ( print("dimension", 2); matrix(R/ideal(a^2-3*a+1), {{0, 1, a-3, 3-a, 0, 3-a, 0, -1, 1, 3-a, 1, a-2, 2-a, 2-a, 0}, {2*a-5, 1, 0, 0, 3-a, 3-a, 0, 2-a, 3-a, a-2, 0, a-2, 0, 2-a, 5-2*a}, {1, a, 1, 0, a, a-1, 1, 0, 0, a, 1-a, 1, a, 0, 0}, {1, 0, a-1, 1-a, a-1, 0, 0, a-1, -a, 1, 1-2*a, 0, a, 0, -1}, {2-a, 0, 2-a, a-1, 0, a-2, 1, 0, a-1, 0, a, 2-a, 0, a-1, a-1}, {2-a, 1-a, 0, 1, 0, 0, 1, a-1, 0, 2-a, 1, 1-a, 1, a, a-1}, {0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1}, {0, 0, 3-a, a-2, 1, a-2, 1, 1, 0, a-2, 0, 2-a, a-1, a-1, 1}, {0, a+1, 1, 0, 1, 0, 1, a, 1-a, 0, 1-a, 1-a, a, a, 1}}) ) else error "Please choose one of the specified objects" ) symbolicSlackMatrix = method(Options => {Object => "polytope", CoefficientRing => QQ, Vars => {}}) symbolicSlackMatrix Matrix := Matrix => opts -> S -> ( -- INPUT: S = slack matrix -- OUTPUT: the symbolic slack matrix with support given by S -- also helper function for other symbolicSlackMatrix instances nvar := nonzeroEntries(S); a := numgens target S; b := numgens source S; F := opts.CoefficientRing; R := F(monoid[VariableBaseName => "x", Variables => nvar]); -- check if a set of appropriate variables is given as an option var := opts.Vars; if (#var > 0 and #var < nvar) then ( print("-- warning: not enough variables given. Creating new ring."); ) else if #var > 0 then ( R = F[var]; ); N := mutableMatrix(R, a, b); -- replace nonzero entries in order by rows with variables ind := 0; for i in (0..a-1) do ( for j in (0..b-1) do ( if (S_(i, j) != 0) then ( N_(i, j) = R_ind; ind = ind + 1; ); ); ); matrix(N) ) symbolicSlackMatrix Matroid := Matrix => opts -> M -> ( -- INPUT: matroid M -- OUTPUT: the (vertex-hyperplane) symbolic slack matrix of M n := #M.groundSet; H := hyperplanes M; h := #H; supp := for i from 0 to n-1 list for j from 0 to h-1 list if member(i, H_j) then 0 else 1; symbolicSlackMatrix(matrix supp, CoefficientRing => opts.CoefficientRing, Vars => opts.Vars) ) symbolicSlackMatrix List := Matrix => opts -> V -> ( -- INPUT: V = a list of vertex coordinates, matroid vectors, facet labels, or cone generators -- OUTPUT: the symbolic slack matrix of conv(V), or of matroid M[V] if Object => matroid is given -- or of the abstract polytope with facets V if Object => abstractPolytope is given -- or of cone(V) if Object => cone is given if (opts.Object == "polytope" or opts.Object == "cone") then ( S := slackMatrix(V, Object => opts.Object); symbolicSlackMatrix(S, CoefficientRing => opts.CoefficientRing, Vars => opts.Vars) ) else if opts.Object == "matroid" then ( V1 := for i to #V-1 list {1} | V_i; M := matroid(transpose matrix V1); symbolicSlackMatrix(M, CoefficientRing => opts.CoefficientRing, Vars => opts.Vars) ) else if opts.Object == "abstractPolytope" then ( -- extract ground set elements from V VV := sort(unique flatten V); supp := for i in VV list for F in V list if member(i, F) then 0 else 1; symbolicSlackMatrix(matrix supp, CoefficientRing => opts.CoefficientRing, Vars => opts.Vars) ) else error "Please choose a valid object" ) symbolicSlackMatrix Polyhedron := Matrix => opts -> P -> ( -- INPUT: polytope P -- OUTPUT: the (vertex-facet) symbolic slack matrix of P S := slackMatrix P; symbolicSlackMatrix(S, CoefficientRing => opts.CoefficientRing, Vars => opts.Vars) ) symbolicSlackMatrix Cone := Matrix => opts -> C -> ( -- INPUT: convex cone C -- OUTPUT: the (extreme ray-facet) symbolic slack matrix of C S := slackMatrix C; symbolicSlackMatrix(S, CoefficientRing => opts.CoefficientRing, Vars => opts.Vars) ) symbolicSlackOfPlucker = method(Options => {Object => "polytope", CoefficientRing => QQ}) symbolicSlackOfPlucker (ZZ, List) := Matrix => opts -> (v, B) -> ( -- INPUT: number v of polytope vertices, cone generators, or matroid vectors; a set B of hyperplane spanning set indices -- OUTPUT: slack matrix filled with Plücker variables -- CAVEAT: does not adjust for simplex orientation in B d := #(B_0); F := opts.CoefficientRing; R := F[gens ring Grassmannian(d, v-1)]; inds := subsets(toList(0..v-1), d+1); M := for i from 0 to v-1 list for b in B list {sgn(b, {i}), sort(join(b, {i}))}; matrix apply(M, r -> apply(r, e -> if member(e_1, inds) then (e_0)*R_(position(inds, j -> j==e_1)) else 0)) ) symbolicSlackOfPlucker (List, List) := Matrix => opts -> (V, B) -> ( -- INPUT: list of coordinates V for polytope vertices, cone generators, or matroid vectors; a set B of hyperplane spanning set indices -- OUTPUT: slack matrix filled with Plücker variables -- CAVEAT: does not check if B makes sense for given V symbolicSlackOfPlucker(#V, B, CoefficientRing => opts.CoefficientRing) ) symbolicSlackOfPlucker List := Matrix => opts -> V -> ( -- INPUT: list of coordinates V for polytope vertices, cone generators, or matroid vectors -- OUTPUT: slack matrix filled with Plücker variables (newV, B) := getFacetBases(V, Object => opts.Object); if opts.Object == "polytope" or opts.Object == "cone" then ( << "\nInput has been reordered to" << endl << newV << endl; ); symbolicSlackOfPlucker(#V, B, CoefficientRing => opts.CoefficientRing) ) symbolicSlackOfPlucker (Matrix, List) := Matrix => opts -> (S, B) -> ( -- INPUT: (symbolic) slack matrix S; a set B of hyperplane spanning set indices -- OUTPUT: slack matrix filled with Plücker variables -- CAVEAT: does not check if B makes sense for given S symbolicSlackOfPlucker(numgens target S, B, CoefficientRing => opts.CoefficientRing) ) symbolicSlackOfPlucker Matrix := Matrix => opts -> S -> ( -- INPUT: slack matrix S -- OUTPUT: slack matrix filled with Plücker variables if instance(ring S, PolynomialRing) and (flatten entries S != flatten entries substitute(S, coefficientRing ring S)) then ( error "Please give an actual slack matrix or a list of facet bases" ); (newV, B) := getFacetBases S; symbolicSlackOfPlucker(numgens target S, B, CoefficientRing => opts.CoefficientRing) ) symbolicSlackOfPlucker Polyhedron := Matrix => opts -> P -> ( -- INPUT: polytope P -- OUTPUT: slack matrix filled with Plücker variables (newV,B) := getFacetBases P; symbolicSlackOfPlucker(nVertices P, B, CoefficientRing => opts.CoefficientRing) ) symbolicSlackOfPlucker Matroid := Matrix => opts -> M -> ( -- INPUT: polytope P -- OUTPUT: slack matrix filled with Plücker variables (newV,B) := getFacetBases M; symbolicSlackOfPlucker(#(M_*), B, CoefficientRing => opts.CoefficientRing) ) slackIdeal = method(Options => {Object => "polytope", Strategy => Eliminate, CoefficientRing => QQ, Vars => {}, Saturate => "all"}) slackIdeal (ZZ, List) := Ideal => opts -> (d, V) -> ( -- INPUT: list of points in d-space, optional: object type, saturation strategy, ring and variables -- OUTPUT: slack ideal of conv(V), M[1 V] if Object => matroid, or abstract polytope with facets indexed by V -- if vectors are given check they span correct dimensional space if opts.Object == "polytope" or opts.Object == "matroid" or opts.Object == "cone" then ( M := slackMatrix(V, Object => opts.Object); D := rank M; if D != d+1 then ( print(" -- warning: Object is not of the correct dimension"); ); ); S := symbolicSlackMatrix(V, Object => opts.Object, CoefficientRing => opts.CoefficientRing, Vars => opts.Vars); J := minors(d+2, S); if opts.Saturate == "all" then ( saturate(J, product gens ring S, Strategy => opts.Strategy) ) else if opts.Saturate == "each" then ( I := J; for i in gens ring S do I = saturate(I, i, Strategy => opts.Strategy); I ) else error "Please choose a valid saturation mode" ) slackIdeal Matroid := Ideal => opts -> M -> ( -- INPUT: matroid M -- OUTPUT: slack ideal of M d := (rank M)-1; S := symbolicSlackMatrix(M, CoefficientRing => opts.CoefficientRing, Vars => opts.Vars); J := minors(d+2, S); if opts.Saturate == "all" then ( saturate(J, product gens ring S, Strategy => opts.Strategy) ) else if opts.Saturate == "each" then ( I := J; for i in gens ring S do I = saturate(I, i, Strategy => opts.Strategy); I ) else error "Please choose a valid saturation mode" ) slackIdeal Polyhedron := Ideal => opts -> P -> ( -- INPUT: polytope P -- OUTPUT: slack ideal of P d := dim P; S := symbolicSlackMatrix(P, CoefficientRing => opts.CoefficientRing, Vars => opts.Vars); J := minors(d+2, S); if opts.Saturate == "all" then ( saturate(J, product gens ring S, Strategy => opts.Strategy) ) else if opts.Saturate == "each" then ( I := J; for i in gens ring S do I = saturate(I, i, Strategy => opts.Strategy); I ) else error "Please choose a valid saturation mode" ) slackIdeal Cone := Ideal => opts -> C -> ( -- INPUT: cone C -- OUTPUT: slack ideal of C d := dim(C)-1; S := symbolicSlackMatrix(C, CoefficientRing => opts.CoefficientRing, Vars => opts.Vars); J := minors(d+2, S); if opts.Saturate == "all" then ( saturate(J, product gens ring S, Strategy => opts.Strategy) ) else if opts.Saturate == "each" then ( I := J; for i in (gens ring S) do I = saturate(I, i, Strategy => opts.Strategy); I ) else error "Please choose a valid saturation mode" ) slackIdeal List := Ideal => opts -> V -> ( -- INPUT: list V of points, optional object type -- OUTPUT: slack ideal of conv(V), or M[1 V] if Object => matroid, or abstract polytope with facets V, or cone(V) if opts.Object == "polytope" then ( P := convexHull(transpose matrix V); slackIdeal(P, Strategy => opts.Strategy, CoefficientRing => opts.CoefficientRing, Vars => opts.Vars) ) else if opts.Object == "matroid" then ( V1 := for i to #V-1 list {1} | V_i; M := matroid(transpose matrix V1); slackIdeal(M, Strategy => opts.Strategy, CoefficientRing => opts.CoefficientRing, Vars => opts.Vars) ) else if opts.Object == "abstractPolytope" then ( slackIdeal(V, findAbstractDim(V), Object => "abstractPolytope", CoefficientRing => opts.CoefficientRing, Vars => opts.Vars) ) else if opts.Object == "cone" then ( C := coneFromVData(transpose matrix V); slackIdeal C ) else error "Please choose a valid object" ) slackIdeal (ZZ, Matrix) := Ideal => opts -> (d, S) -> ( -- INPUT: (symbolic) slack matrix S of d-polytope or rank d+1 matroid -- OUTPUT: slack ideal of S F := opts.CoefficientRing; M := S; R := F[gens ring S]; var := opts.Vars; -- check if S has variable entries, if not create symbolic version -- or create new symbolic version with correct variables if (numgens R == 0 or #var > 0) then ( M = symbolicSlackMatrix(S, CoefficientRing => F, Vars => var); R = ring M; ); J := substitute(minors(d+2, M), R); if opts.Saturate == "all" then ( saturate(J, product gens R, Strategy => opts.Strategy) ) else if opts.Saturate == "each" then ( I := J; for i in gens R do I = saturate(I, i, Strategy => opts.Strategy); I ) else error "Please choose a valid saturation mode" ) slackIdeal Matrix := Ideal => opts -> S -> ( -- INPUT: (symbolic) slack matrix S -- OUTPUT: slack ideal of S d := findAbstractDim apply(entries transpose S, r -> positions(r, e -> e==0_(ring S))); slackIdeal(d, S, CoefficientRing => opts.CoefficientRing, Vars => opts.Vars) ) grassmannSectionIdeal = method(Options => {Object => "polytope", CoefficientRing => QQ, Strategy => Eliminate, Saturate => "all"}) grassmannSectionIdeal (Matrix, List) := Ideal => opts -> (S, B) -> ( -- INPUT: a slack matrix S; a set B of hyperplane spanning set indices -- OUTPUT: the Grassmannian section ideal corresponding to choice B of the object with slack matrix S -- CAVEAT: does not check if B makes sense for given S d := findAbstractDim apply(entries transpose S, r -> positions(r, e -> e==0_(ring S))); v := numgens target S; if #(B_0) != d then error "Dimensions do not match."; G := Grassmannian(d, v-1); F := opts.CoefficientRing; R := F[gens ring G]; G = substitute(G, R); Spl := substitute(symbolicSlackOfPlucker(S, B, CoefficientRing => F), R); zeroPl := select(apply(flatten entries Spl, flatten entries S, (e, f) -> if f==0_(ring S) and e != 0_(ring Spl) then e else 0_(ring Spl)), j -> j != 0_(ring Spl)); -- entries of Spl may have negative signs which won't be recognized as generators, so include +/- all entries usedPl := delete(0_R, unique join(flatten entries Spl, -flatten entries Spl)); Z := ideal zeroPl; -- zeroPl may also contain -p_J elements which we need to change to p_J to eliminate G0 := eliminate(G + Z, flatten entries mingens Z); G0used := eliminate(G0, toList(gens R - set(usedPl))); if opts.Saturate == "all" then ( saturate(G0used, product usedPl, Strategy => opts.Strategy) ) else if opts.Saturate == "each" then ( G0usedSat := G0used; for i in usedPl do G0usedSat = saturate(G0usedSat, i, Strategy => opts.Strategy); G0usedSat ) else error "Please choose a valid saturation mode" ) grassmannSectionIdeal Matrix := Ideal => opts -> S -> ( -- INPUT: a slack matrix S -- OUTPUT: the Grassmannian section ideal corresponding to choice B of the object with slack matrix S (newV, B) := getFacetBases S; grassmannSectionIdeal(S, B, CoefficientRing => opts.CoefficientRing, Strategy => opts.Strategy) ) grassmannSectionIdeal (List, List) := Ideal => opts -> (V, B) -> ( -- INPUT: a list V of polytope vertex coordinates, cone generators, or matroid vectors; a set B of hyperplane spanning set indices -- OUTPUT: the Grassmannian section ideal corresponding to choice B for object V -- CAVEAT: does not check if B makes sense for given S S := slackMatrix(V, Object => opts.Object); grassmannSectionIdeal(S, B, CoefficientRing => opts.CoefficientRing, Strategy => opts.Strategy) ) grassmannSectionIdeal List := Ideal => opts -> V -> ( -- INPUT: a list V of polytope vertex coordinates, cone generators, or matroid vectors; a set B of hyperplane spanning set indices -- OUTPUT: the Grassmannian section ideal corresponding to choice B for object V S := symbolicSlackMatrix(V, Object => opts.Object); grassmannSectionIdeal(S, CoefficientRing => opts.CoefficientRing, Strategy => opts.Strategy) ) grassmannSectionIdeal Polyhedron := Ideal => opts -> P -> ( -- INPUT: polytope P -- OUTPUT: Grassmannian section ideal of P S := slackMatrix P; grassmannSectionIdeal(S, CoefficientRing => opts.CoefficientRing, Strategy => opts.Strategy) ) grassmannSectionIdeal Cone := Ideal => opts -> C -> ( -- INPUT: cone C -- OUTPUT: Grassmannian section ideal of C S := slackMatrix C; grassmannSectionIdeal(S, CoefficientRing => opts.CoefficientRing, Strategy => opts.Strategy) ) grassmannSectionIdeal Matroid := Ideal => opts -> M -> ( -- INPUT: matroid M -- OUTPUT: Grassmannian section ideal of M --(not technically defined, but should be fine, right??) S := slackMatrix M; grassmannSectionIdeal(S, CoefficientRing => opts.CoefficientRing, Strategy => opts.Strategy) ) toBin = method() toBin (List, List, Ring) := (b, ss, R) -> ( -- INPUT: integer vector b, list of nonzero slack matrix entries ss, ring R -- OUTPUT: binomial in ring ss corresponding to cycle b: x^b+ - \alpha_b x^b- r := #(gens R); if ss == {0} then ss = for i from 1 to r list 1; pos := 1_R; neg := 1_R; scan(#b, i-> if b_i>0 then (pos = pos*(R_i)^(b_i); neg = ss_i*neg;) else if b_i<0 then (neg = neg*(R_i)^(-b_i); pos = ss_i*pos;)); pos - neg ) toricIdeal = method(Options => {Strategy => Eliminate, CoefficientRing => QQ, Vars => {}, Saturate => "all"}) toricIdeal(Matrix, List) := Ideal => opts -> (A, ss) -> ( -- Helper function for cycleIdeal, graphicIdeal -- INPUT: A = matrix whose columns are some vector configuration -- OUTPUT: the toric ideal of the vector configuration defined by A n := numgens source A; F := opts.CoefficientRing; R := F(monoid[VariableBaseName => "y", Variables => n]); var := opts.Vars; if (#var >0 and #var < n) then ( print(" -- warning: Not enough variables given. Creating new ring."); ) else if #var > 0 then ( R = F[var]; ); B := transpose LLL syz A; -- generate list of coefficients for binomials try ss = apply(ss, i->substitute(i, R)) else ( print(" -- warning: Slack entries cannot be substituted into chosen ring. Coefficients will be set to 1."); ss = for i from 1 to (#gens R) list 1; ); J := ideal apply(entries B, b-> toBin(b, ss, R)); if opts.Saturate == "all" then ( saturate(J, product gens R, Strategy => opts.Strategy) ) else if opts.Saturate == "each" then ( I := J; for i in gens R do I = saturate(I, i, Strategy => opts.Strategy); I ) else error "Please choose a valid saturation mode" ) graphFromSlackMatrix = method() graphFromSlackMatrix Matrix := Matrix => S -> ( -- INPUT: S = (symbolic) slack matrix -- OUTPUT: the vertex-edge adjacency matrix of the bipartite graph with adjacency matrix given by support of S n := nonzeroEntries S; -- make new symbolic slack with consecutively numbered variables y := symbol y; -- don't need to change symbol assignment here because user never accesses this ring -- check if S has variable entries and create symbolic version coeff := try coefficientRing(ring S) else ring S; M := symbolicSlackMatrix(S, CoefficientRing => coeff, Vars => toList(y_1..y_n)); R := ring M; v := numgens target M; f := numgens source M; e := numgens R; N := mutableMatrix(ZZ, v+f, e); for i in (0..v-1) do ( for j in (0..f-1) do ( var := M_(i, j); if var != 0 then ( N_(i, index var) = 1; N_(j+v, index var) = 1; ); ); ); -- Display new (possibly relabeled) symbolic slack used to compute the graph << "Graph computed from symbolic adjacency matrix: " << M << endl; matrix N ) -- Graphic ideals are defined ONLY for polytopes: they are unscaled cycleIdeals graphicIdeal = method(Options => {Object => "polytope", Strategy => Eliminate, CoefficientRing => QQ, Vars => {}, Saturate => "all"}) graphicIdeal List := Ideal => opts -> V -> ( -- INPUT: list V of vertices or facet sets -- OUTPUT: the toric ideal of the non-incidence graph of conv(V), or of abstract type of V if Object => abstractPolytope given S := symbolicSlackMatrix(V, Object => opts.Object, CoefficientRing => opts.CoefficientRing, Vars => opts.Vars); A := graphFromSlackMatrix S; if (opts.Object == "polytope" or opts.Object == "abstractPolytope") then ( toricIdeal(A, {0}, Strategy => opts.Strategy, CoefficientRing => opts.CoefficientRing, Vars => opts.Vars, Saturate => opts.Saturate) ) else if (opts.Object == "matroid") then ( print("-- warning: Did you mean to find the cycleIdeal?"); toricIdeal(A, {0}, Strategy => opts.Strategy, CoefficientRing => opts.CoefficientRing, Vars => opts.Vars, Saturate => opts.Saturate) ) -- should be caught by symbolicSlackMatrix else error "Please choose a valid object." ) graphicIdeal Polyhedron := Ideal => opts -> P -> ( -- INPUT: polytope P -- OUTPUT: the toric ideal of the non-incidence graph of P S := symbolicSlackMatrix(P, CoefficientRing => opts.CoefficientRing, Vars => opts.Vars); A := graphFromSlackMatrix S; toricIdeal(A, {0}, Strategy => opts.Strategy, CoefficientRing => opts.CoefficientRing, Vars => opts.Vars, Saturate => opts.Saturate) ) graphicIdeal Matrix := Ideal => opts -> S -> ( -- INPUT: slack matrix S of a polytope -- OUTPUT: the ideal of the non-incidence graph (graph with support of S as its adjacency matrix) of the polytope A := graphFromSlackMatrix S; T := toricIdeal(A, {0}, Strategy => opts.Strategy, CoefficientRing => opts.CoefficientRing, Vars => opts.Vars, Saturate => opts.Saturate); -- Check for symbolic original matrix and substitute variables back if flatten entries S != flatten entries substitute(S, QQ) then T else ( R := ring T; substitute(T, for i from 1 to numgens R list R_(i-1) => (delete(0_(ring S), flatten entries S))_(i-1)) ) ) graphicIdeal Matroid := Ideal => opts -> M -> ( -- INPUT: matroid M -- OUTPUT: the toric ideal of the non-incidence graph of M print("-- warning: Did you mean to find the cycleIdeal?"); S := symbolicSlackMatrix(M, CoefficientRing => opts.CoefficientRing, Vars => opts.Vars); A := graphFromSlackMatrix S; toricIdeal(A, {0}, Strategy => opts.Strategy, CoefficientRing => opts.CoefficientRing, Vars => opts.Vars, Saturate => opts.Saturate) ) cycleIdeal = method(Options => {Object => "polytope", Strategy => Eliminate, CoefficientRing => QQ, Vars => {}, Saturate => "all"}) cycleIdeal List := Ideal => opts -> V -> ( -- INPUT: list of vertices of polytope, or of vectors realization of a matroid if Object => matroid, -- or of facets if Object => abstractPolytope -- OUTPUT: cycle ideal of the realization, or graphic ideal if Object => abstractPolytope B := {}; if opts.Object == "abstractPolytope" then ( print("-- warning: No realization given. Returning graphicIdeal instead."); B = symbolicSlackMatrix(V, Object => opts.Object, CoefficientRing => opts.CoefficientRing, Vars => opts.Vars); graphicIdeal(B, CoefficientRing => opts.CoefficientRing, Vars => opts.Vars) ) else ( B = slackMatrix(V, Object => opts.Object); ss := delete(0_(ring B), flatten entries B); A := graphFromSlackMatrix B; toricIdeal(A, ss, Strategy => opts.Strategy, CoefficientRing => opts.CoefficientRing, Vars => opts.Vars, Saturate => opts.Saturate) ) ) cycleIdeal Matroid := Ideal => opts -> M -> ( -- INPUT: matroid M with ground set given by vectors -- OUTPUT: cycle ideal of the realization -- graphicIdeal is returned if realization of vectors is not given Sym := symbolicSlackMatrix(M, CoefficientRing => opts.CoefficientRing, Vars => opts.Vars); A := graphFromSlackMatrix Sym; if instance((M_*)_0, Matrix) then ( -- get entries of slack matrix for binomial coefficients S := slackMatrix M; ss := delete(0_(ring S), flatten entries S); toricIdeal(A, ss, Strategy => opts.Strategy, CoefficientRing => opts.CoefficientRing, Vars => opts.Vars, Saturate => opts.Saturate) ) else ( print("-- warning: No realization given. Returning graphicIdeal instead."); toricIdeal(A, {0}, Strategy => opts.Strategy, CoefficientRing => opts.CoefficientRing, Vars => opts.Vars, Saturate => opts.Saturate) ) ) cycleIdeal Polyhedron := Ideal => opts -> P -> ( -- INPUT: polytope P -- OUTPUT: cycle ideal of P S := slackMatrix P; ss := delete(0_(ring S), flatten entries S); A := graphFromSlackMatrix S; toricIdeal(A, ss, Strategy => opts.Strategy, CoefficientRing => opts.CoefficientRing, Vars => opts.Vars, Saturate => opts.Saturate) ) cycleIdeal Matrix := Ideal => opts -> S -> ( -- INPUT: slack matrix S -- OUTPUT: cycle ideal of the realization S -- check that an actual realization is given if instance(ring S, PolynomialRing) and (flatten entries S != flatten entries substitute(S, coefficientRing(ring S))) then ( error "Please give the slack matrix of a realization." ); ss := delete(0_(ring S), flatten entries S); A := graphFromSlackMatrix S; toricIdeal(A, ss, Strategy => opts.Strategy, CoefficientRing => opts.CoefficientRing, Vars => opts.Vars, Saturate => opts.Saturate) ) -- the universal realization ideal is ONLY defined for matroids universalIdeal = method(Options => {CoefficientRing => QQ, Vars => {}}) universalIdeal Matroid := Ideal => opts -> M -> ( -- INPUT: matroid M -- OUTPUT: universal realization ideal of M F := opts.CoefficientRing; d := (rank M)-1; n := #M.groundSet; S := symbolicSlackMatrix(M, CoefficientRing => F, Vars => opts.Vars); G := Grassmannian(d, n-1, CoefficientRing => F); R := ring G; -- gets the index of the sets of non-bases in the list of subsets of {0..n-1} of size d+1 -- this gives the index of the correspond plucker variable in the list of gens R NBind := apply(nonbases M, NB -> position(subsets(toList(0..n-1), d+1), J -> (J==sort(toList NB)))); P := substitute(G, for i in NBind list R_i => 0); T := F[gens ring S, gens ring G]; U := substitute(P, T); H := hyperplanes M; for j from 0 to #H-1 do ( SS := slackToPluckerMatrix(toList(H_j), n, d, R); c1 := submatrix(S, sort(toList(set(0..n-1)-H_j)), {j}); mat := substitute(c1, T) | substitute(matrix SS, T); U = U + minors(2, mat); ); U ) universalIdeal List := Ideal => opts -> V -> ( -- INPUT: realization of a matroid M[1 V] -- OUTPUT: universal realization ideal of M V1 := for i to #V-1 list {1} | V_i; M := matroid(transpose matrix V1); universalIdeal(M, CoefficientRing => opts.CoefficientRing, Vars => opts.Vars) ) slackToPluckerMatrix = (H, n, d, R) -> ( -- INPUT: list of hyperplane elements H, number of elements of the matroid n, -- rank of matroid is d+1, ring of the Grassmannian of the matroid R -- OUTPUT: the substitution matrix M_H cols := subsets(H, d); rows := sort(toList(set(0..n-1)-H)); -- Plücker variable p_({r}|c) has to be retrieved as the generator of R having gets the -- index given by the position of {r}|c in the list of subsets of {0..n-1} of size d+1 for r in rows list for c in cols list sgn({r}, c)*R_(position(subsets(toList(0..n-1), d+1), J -> (J==sort(join({r}, c))))) ) fromBinomial = b -> ( -- INPUT: binomial b -- OUTPUT: kernel vector of exponents of b -- does not check binomiality, if b has >2 terms the exponent vector of the first two will be returned E := exponents(b); E_0 - E_1 ) toricPolytope = method() toricPolytope Ideal := Matrix => I -> ( -- INPUT: toric ideal I -- OUTPUT: matrix whose columns represent the vector configuration with toric ideal I K := for f in flatten entries gens I list fromBinomial(f); transpose LLL syz matrix K ) setOnesForest = method() setOnesForest Matrix := (Matrix, Graph) => X -> ( -- INPUT: symbolic slack matrix X, -- OUTPUT: symbolic slack matrix with spanning forest of variables replaced by 1s, spanning forest a := numgens target X; b := numgens source X; -- ring of variables representing nodes of the graph S := QQ(monoid[VariableBaseName => "y", Variables => a+b]); E := {}; -- add edges to the graph corresponding to variables in the slack matrix X for i in (0..a-1) do ( for j in (0..b-1) do ( if X_(i, j) != 0_(ring X) then ( E = E | {{S_(i), S_(j+a)}}; ); ); ); G := graph(S, E); T := spanningTree G; W := X; -- index of nodes in edges of tree give position in matrix to set to 1 for k in edges(T) do ( W = substitute(W, {X_(index(k_0), index(k_1)-a) => 1}); ); (W, T) ) varEntriesIndices = (M, ind, rc) ->( -- INPUT: matrix M, index of row or column ind, 'r' for row or 'c' for column -- OUTPUT: list of indices of variables in the specified row or column of the matrix M L := {}; if rc=="r" then ( L = flatten entries M^{ind} - set{0_(ring M), 1_(ring M)}; ) else ( L = flatten entries M_ind - set{0_(ring M), 1_(ring M)}; ); sort(apply(L, v->index(v)+1)) ) distVU = (G, v, u) -> ( -- INPUT: graph G, vertices v, u of G -- OUTPUT: distance from v to u in G if not member(v, vertices G) or not member(u, vertices G) then error "The given vertices are not vertices of G."; n := #vertices G; v = position(vertices G, i -> i == v); u = position(vertices G, i -> i == u); C := new MutableList from toList(#vertices G:infinity); Q := {v}; C#v = 0; while #Q != 0 do ( y := first Q; Q = drop(Q, 1); N := select(positions(first entries (adjacencyMatrix G)^{y}, j -> j != 0), x -> C#x == infinity); if any(N, x -> x == u) then ( C#u = C#y + 1; break; ); Q = Q | N; for z in N do C#z = C#y + 1; ); C#u ) rehomogenizePolynomial = method() rehomogenizePolynomial Matrix := X -> ( -- INPUT: symbolic slack matrix X -- OUTPUT: rehomogenization of a polynomial entered by the user, reversing the dehomogenization of the slack matrix (Y, T) := setOnesForest X; -- remVars is the list of variables that are not set to 1 remVars := flatten entries Y - set{0_(ring Y), 1_(ring Y)}; print("Write a polynomial in the variables", toString remVars); f := read " "; g := value f; while not isSubset(apply(support g, v->(ring X)_(index(v))), remVars) do ( print("Warning: polynomial in the wrong variables"); print("Write a polynomial in the variables", toString remVars); f = read " "; g = value f; ); Z := Y; a := numgens target Y; -- #rows of Y verticesT := vertices T; -- dist is a reverse sorted list of couples, where the 1st element is the distance between vertex v and vertex 1 and the 2nd element is vertex v connComp := connectedComponents(T); for C in connComp do ( verticesC := C; dist := rsort(apply(verticesC, v->{distVU(T, verticesC_0, v), v})); newVertices := {}; for c in (0..#dist-2) do ( newVert := index((dist_c)_1)+1; newVertices = newVertices | {newVert}; varsInd := {}; newIndex := -1; newVar := 0; variablesInd := {}; -- we identify the row or column containing exactly one 1 entry if newVert<=a then ( -- varsInd is the list of the indices of the variables in the row of index newVert-1 of Z varsInd = varEntriesIndices(Z, newVert-1, "r"); -- newIndex is the column index of the variable wrt which we want to homogenize g newIndex = (toList(apply(neighbors(T, verticesT_((newVert)-1)), w->index(w)+1)-set(newVertices)))_0-a-1; -- newVar is the variable wrt which we want homogenize g newVar = X_(newVert-1, newIndex); Z = mutableMatrix Z; Z_(newVert-1, newIndex) = X_(newVert-1, newIndex); ) else ( -- varsInd is the list of the indices of the variables in the row of index newVert-1 of Z varsInd = varEntriesIndices(Z, newVert-a-1, "c"); -- newIndex is the column index of the variable wrt which we want to homogenize g newIndex = (toList(apply(neighbors(T, verticesT_((newVert)-1)), w -> index(w)+1)-set(newVertices)))_0-1; -- newVar is the variable wrt which we want homogenize g newVar = X_(newIndex, newVert-a-1); Z = mutableMatrix Z; Z_(newIndex, newVert-a-1) = X_(newIndex, newVert-a-1); ); Z = matrix Z; -- newVarIndex is the index of the new variable that we add to the list varsInd newVarIndex := index(newVar)+1; variablesInd = sort(varsInd | {newVarIndex}); -- weights is the vector of the weights of the variables (we write 1 for the variables in varsInd, 0 otherwise) weights := {}; for i in (0..dim(ring X)-1) do ( if member(i+1, variablesInd) then weights = weights | {1} else weights = weights | {0}; ); g = homogenize(g, newVar, weights); ); ); g ) rehomogenizePolynomial (Matrix, Matrix, Graph, RingElement) := (X, Y, T, g) -> ( -- INPUT: symbolic slack matrix X, dehomogenized slack matrix Y, spanning forest T, polynomial g -- OUTPUT: rehomogenization of g reversing the dehomogenization of the slack matrix Z := Y; a := numgens target Y; -- #rows of Y verticesT := vertices T; connComp := connectedComponents(T); for C in connComp do ( verticesC := C; dist := rsort(apply(verticesC, v -> {distVU(T, verticesC_0, v), v})); newVertices := {}; for c in (0..#dist-2) do ( newVert := index((dist_c)_1)+1; newVertices = newVertices | {newVert}; varsInd := {}; newIndex := -1; newVar := 0; variablesInd := {}; if newVert<=a then ( varsInd = varEntriesIndices(Z, newVert-1, "r"); newIndex = (toList(apply(neighbors(T, verticesT_((newVert)-1)), w -> index(w)+1)-set(newVertices)))_0-a-1; newVar = X_(newVert-1, newIndex); Z = mutableMatrix Z; Z_(newVert-1, newIndex) = X_(newVert-1, newIndex); ) else ( varsInd = varEntriesIndices(Z, newVert-a-1, "c"); newIndex = (toList(apply(neighbors(T, verticesT_((newVert)-1)), w -> index(w)+1)-set(newVertices)))_0-1; newVar = X_(newIndex, newVert-a-1); Z = mutableMatrix Z; Z_(newIndex, newVert-a-1) = X_(newIndex, newVert-a-1); ); Z = matrix Z; newVarIndex := index(newVar)+1; variablesInd = sort(varsInd | {newVarIndex}); weights := {}; for i in (0..dim(ring Y)-1) do ( if member(i+1, variablesInd) then weights = weights | {1} else weights = weights | {0}; ); g = homogenize(g, newVar, weights); ); ); g ) rehomogenizeIdeal = method(Options => {Strategy => Eliminate, Saturate => "all"}) rehomogenizeIdeal (ZZ, Matrix) := Ideal => opts -> (d, X) -> ( -- INPUT: symbolic slack matrix X of d-polytope -- OUTPUT: rehomogenization of the dehomogenized slack ideal (Y, T) := setOnesForest(X); varsY := flatten entries Y - set{0_(ring Y), 1_(ring Y)}; J := minors(d+2, Y); dehomIdeal := J; if opts.Saturate == "all" then ( dehomIdeal = saturate(dehomIdeal, product(varsY), Strategy => opts.Strategy) ) else if opts.Saturate == "each" then ( for i in varsY do dehomIdeal = saturate(dehomIdeal, i, Strategy => opts.Strategy); ) else error "Please choose a valid saturation mode"; K := ideal(apply(flatten entries gens dehomIdeal, g -> rehomogenizePolynomial(X, Y, T, g))); satIdeal := K; for a in (gens ring X - set(varsY)) do satIdeal = saturate(satIdeal, a, Strategy => opts.Strategy); satIdeal ) rehomogenizeIdeal (ZZ, Matrix, Graph) := Ideal => opts -> (d, Y, T) -> ( -- INPUT: dehomogenized symbolic slack matrix Y of d-polytope, spanning forest T whose edges match the ones in Y -- OUTPUT: rehomogenization of the dehomogenized slack ideal a := numgens target Y; b := numgens source Y; ones := positions(flatten entries transpose Y, y -> y == 1); onesCoord := apply(ones, k -> {k%a, k//a + a}); indicesEdges := apply(edges T, e->{index e_0, index e_1}); if onesCoord != indicesEdges then error "The edges of the forest do not match the position of the ones in Y."; X := substitute(symbolicSlackMatrix Y, ring Y); varsY := flatten entries Y - set{0_(ring Y), 1_(ring Y)}; -- varsY := apply(flatten entries Y - set{0_(ring Y), 1_(ring Y)}, v -> (ring X)_(index v)); J := minors(d+2, Y); dehomIdeal := J; if opts.Saturate == "all" then ( dehomIdeal = saturate(dehomIdeal, product(varsY), Strategy => opts.Strategy) ) else if opts.Saturate == "each" then ( for i in varsY do dehomIdeal = saturate(dehomIdeal, i, Strategy => opts.Strategy); ) else error "Please choose a valid saturation mode"; K := ideal(apply(flatten entries gens dehomIdeal, g -> rehomogenizePolynomial(X, Y, T, g))); satIdeal := K; for a in (gens ring X - set(varsY)) do satIdeal = saturate(satIdeal, a, Strategy => opts.Strategy); satIdeal ) findFlag = method(Options => {Object => "polytope", FlagElement => 0}) findFlag Polyhedron := List => opts -> P -> ( -- INPUT: Polytope P -- OUTPUT: a list F of facet labels that make up a flag in P, through facet FlagElement if option given V := entries transpose Polyhedra$vertices P; -- get list of vertices that make up each facet facetList := Polyhedra$facesAsPolyhedra(1, P); facetList = apply(facetList, f -> entries transpose Polyhedra$vertices f); coatoms := apply(facetList, f -> apply(f, v -> position(V, e -> e==v))); << "\nOrder of vertices is " << endl << V << endl; << "Order of facets is " << endl << coatoms << endl; flagFromPosetCoatoms(opts.FlagElement, coatoms) ) findFlag Matroid := List => opts -> M -> ( -- INPUT: a matroid M -- OUTPUT: a list F of hyperplane labels that make up a flag in M through hyperplane FlagElement if option given H := apply(hyperplanes M, h -> sort(toList h)); << "\nOrder of hyperplanes is " << endl << H << endl; flagFromPosetCoatoms(opts.FlagElement, H) ) findFlag Matrix := List => opts -> S -> ( -- INPUT: (symbolic) slack matrix S, -- OUTPUT: a list F of column labels that make up a flag in S through column FlagElement if option given R := ring S; facetList := apply(entries transpose S, r -> positions(r, e -> e==0_R)); flagFromPosetCoatoms(opts.FlagElement, facetList) ) findFlag List := List => opts -> V -> ( -- INPUT: V = a list of vertex coordinates, matroid vectors, facet labels, or cone generators -- OUTPUT: a list F of labels that make up a flag in object given by V through FlagElement if option given obj := opts.Object; S := symbolicSlackMatrix(V, Object => obj); R := ring S; coatoms := apply(entries transpose S, r -> positions(r, e -> e==0_R)); if obj == "matroid" then ( << "\nOrder of hyperplanes is " << endl; ) else ( << "Order of facets is " << endl; ); << coatoms << endl; flagFromPosetCoatoms(opts.FlagElement, coatoms) ) containsFlag = method(Options => {Object => "polytope"}) containsFlag (List, Polyhedron) := Boolean => opts -> (fl, P) -> ( -- INPUT: list of facets fl, polytope P -- OUTPUT: true/false if fl contains a flag of facets for P S := slackMatrix P; d := dim P; if rank(S_fl) == d+1 then true else false ) containsFlag (List, Matroid) := Boolean => opts -> (fl, M) -> ( -- INPUT: list of facets fl, matroid M -- OUTPUT: true/false if fl contains a flag of facets for M S := slackMatrix M; d := (rank M) - 1; if rank(S_fl) == d+1 then true else false ) containsFlag (List, Matrix) := Boolean => opts -> (fl, S) -> ( -- INPUT: list of facets fl, (symbolic) slack matrix S -- OUTPUT: true/false if fl contains a flag of facets for S d := findAbstractDim apply(entries transpose S, r -> positions(r, e -> e==0_(ring S))); D := findAbstractDim apply(entries transpose S_fl, r -> positions(r, e -> e==0_(ring S))); if D == d then true else false ) containsFlag (List, List) := Boolean => opts -> (fl, V) -> ( -- INPUT: list of facets fl, V = a list of vertex coordinates, matroid vectors, facet labels, or cone generators -- OUTPUT: true/false if fl contains a flag of facets for object represented by V S := symbolicSlackMatrix(V, Object=>opts.Object); containsFlag(fl, S) ) simplicialColExtend := (S, fl, fa) -> ( -- helper function for reconstructSlackMatrix -- INPUT: S a (column) reduced slack matrix, fl a flag of columns, fa the vertices in a simplicial facet column we want to refill -- OUTPUT: The column of facet fa as a matrix -- check facet is really simplicial if #fl != (#fa + 1) then error "Facet is not simplicial"; v := numgens target S; newC := for i from 0 to v-1 list det submatrix(S, join(fa, {i}), fl); if positions(newC, e->e==0) != fa then error "Cannot extend matrix"; transpose matrix {newC} ) smallColExtend := (S, fl, fa, R, kvars) -> ( -- helper function for reconstructSlackMatrix -- INPUT: S a (column) reduced slack matrix, fl a flag of columns, fa the vertices in a column with less than a simplicial facet many (d) zeros, R ring in which to construct new column with extra free variables kvars -- OUTPUT: the column of facet fa as a matrix -- check for correct number of elements in facet if #fa >= #fl then error "Facet has too many elements"; K := kernel(submatrix(S, fa, fl)); M := substitute(K.generators, R); -- get a symbolic element of the kernel of the submatrix of S -- corresponding to the elements of column to fill v := M*substitute(matrix(for i from 1 to numgens source M list {kvars_(i-1)}), R); newC := substitute(S, R)*v; if positions(flatten entries newC, e -> e==0_R) != fa then error "Cannot extend matrix"; newC ) reconstructSlackMatrix = method(Options => {CoefficientRing => QQ, Vars => {}}) reconstructSlackMatrix (Matrix, List, List) := Matrix => opts -> (S, fl, F) -> ( -- INPUT: S a (column) reduced slack matrix, fl a flag of columns, F list of facet columns we want to refill -- OUTPUT: S extended by the columns of F -- If Options are given, new slack matrix is built in ring CoefficientRing[Vars] if not containsFlag(fl, S) then error "Given columns don't contain a flag"; d := #fl-1; simpF := select(F, f -> #f==d); smallF := select(F, f -> not member(f, simpF)); -- check smallF is really small facets scan(smallF, f -> if d-#f < 0 then error "Cannot reconstruct nonsimplicial facets"); nVars := sum apply(smallF, f -> d-#f); oVars := nonzeroEntries S; -- make ring for output matrix newR := ring S; newS := S; -- get coefficient ring of the ring of S, or ring itself if not symbolic coeff := try coefficientRing S else ring S; -- if Option Vars are given then assume symbolic matrix to be constructed X := monoid[VariableBaseName => "x", Variables => oVars]; -- reduced slack matrix variables Y := monoid[VariableBaseName => "y", Variables => nVars]; -- free kernel variables if #(opts.Vars) > 0 then ( newR = opts.CoefficientRing[opts.Vars]; -- override options if not enough variables are given if #(opts.Vars) < nVars+oVars then ( <<"\nNot enough variables given. Making new ring for reconstructed matrix" << endl; newR = coeff(X**Y); ); newS = symbolicSlackMatrix(S, CoefficientRing => coefficientRing newR, Vars => gens newR); ) else if nVars > 0 then ( --even if no variables are given, create ones for underdetermined columns X = monoid[gens ring S]; newR = coeff(X**Y); oVars = #gens(ring S); ); newS = substitute(newS, newR); newCols := for f in F list if member(f, simpF) then simplicialColExtend(newS, fl, f) else smallColExtend(newS, fl, f, newR, drop(gens newR, oVars)); scan(newCols, c->(newS = newS | c)); matrix(for i in (0..numgens target newS-1) list(flatten entries newS^{i})) ) reconstructSlackMatrix (Matrix, List) := Matrix => opts -> (S, F) -> ( -- INPUT: S a (column) reduced slack matrix, F list of facet columns we want to refill -- OUTPUT: S extended by the columns of F -- If Options are given, new slack matrix is built in ring CoefficientRing[Vars] fl := findFlag S; reconstructSlackMatrix(S, fl, F, CoefficientRing => opts.CoefficientRing, Vars => opts.Vars) ) reducedSlackMatrix = method(Options => {Object => "polytope", CoefficientRing => QQ, Vars => {}, FlagIndices => {}}) reducedSlackMatrix (ZZ, Matrix) := Matrix => opts -> (d, S) -> ( -- INPUT: (symbolic) slack matrix S of rank d+1 -- OUTPUT: reduced slack matrix -- find nonsimplicial facet columns fl := opts.FlagIndices; v := numgens target S; nonSimpF := positions(entries transpose S, r -> (v - nonzeroEntries(matrix {r}) > d)); i := 0; -- check if non-simplicial facets contain a flag and the optional given flag if containsFlag(nonSimpF, S) then ( if not isSubset(fl, nonSimpF) then ( print("-- warning: You've chosen a flag containing simplicial facets"); ) else ( if #opts.Vars > 0 then ( return symbolicSlackMatrix(S_nonSimpF, CoefficientRing => opts.CoefficientRing, Vars => opts.Vars); ) else return S_nonSimpF; ); ); -- find flag through some nonSimplicial facet if it exists if #nonSimpF > 0 then i = nonSimpF_0; nsFl := findFlag(S, FlagElement => i); -- check for optional given flag if #fl > 0 then ( if not containsFlag(fl, S) then ( <<"-- warning: Given facets don't contain a flag. Using new flag" << endl << nsFl << endl; fl = nsFl; ); ) else fl = nsFl; if #fl != d+1 then ( print(" -- warning: Flag and matrix ranks don't match"); ); cols := sort(unique join(fl, nonSimpF)); -- put into new ring if Options are given if #opts.Vars > 0 then symbolicSlackMatrix(S_cols, CoefficientRing => opts.CoefficientRing, Vars => opts.Vars) else S_cols ) reducedSlackMatrix Matrix := Matrix => opts -> S -> ( -- INPUT: (symbolic) slack matrix S -- OUTPUT: reduced slack matrix fl := findFlag S; d := #fl - 1; reducedSlackMatrix(d, S, CoefficientRing => opts.CoefficientRing, Vars => opts.Vars, FlagIndices=>opts.FlagIndices) ) reducedSlackMatrix List := Matrix => opts -> V -> ( -- INPUT: V = a list of vertex coordinates, matroid vectors, facet labels, or cone generators -- OUTPUT: reduced slack matrix of object represented by V S := try slackMatrix(V, Object=>opts.Object) else symbolicSlackMatrix(V, Object=>opts.Object); d := findAbstractDim apply(entries transpose S, r -> positions(r, e -> e==0_(ring S))); reducedSlackMatrix(d, S, CoefficientRing => opts.CoefficientRing, Vars => opts.Vars, FlagIndices => opts.FlagIndices) ) beginDocumentation() doc /// Key SlackIdeals Headline a package for slack ideals of polytopes and matroids Description Text @{EM "SlackIdeals"}@ is a package which allows the user to create slack realizations and the slack ideal of a polytope or a matroid. Polytopes and matroids may be entered as a list of vertices of a specific realization or as a pre-created @{TT "Polyhedron"}@ or @{TT "Matroid"}@ object (using the packages @TO Polyhedra@ and @TO Matroids@). @{BOLD "References."}@ @UL { LI {"[GMTW19] ", EM "The slack realization space of a polytope, ", "(J. Gouveia, A. Macchia, R.R. Thomas, A. Wiebe, SIAM J. Discrete Math. 33 (2019), 3, 1637–1653.)"}, LI {"[BW19] ", EM "The slack realization space of a matroid, ", "(M. Brandt, A. Wiebe, Algebraic Combinatorics, 2 (2019), 4, 663–681, 2019.)"}, LI {"[BMTW20] ", EM "Projectively unique polytopes and toric slack ideals, ", "(J. Gouveia, A. Macchia, R.R. Thomas, A. Wiebe, J. Pure Appl. Algebra 224 (2020), 5, paper 106229.)"}, LI {"[BMW20] ", EM "Combining realization space models of polytopes, ", "(J. Gouveia, A. Macchia, A. Wiebe, preprint (2020), arXiv:2001.11999v1.)"}}@ /// doc /// Key slackMatrix (slackMatrix, List) (slackMatrix, Matroid) (slackMatrix, Polyhedron) (slackMatrix, Cone) Headline computes the slack matrix of a given realization Usage S = slackMatrix V S = slackMatrix M S = slackMatrix P S = slackMatrix C Inputs V:List a list of vertices of a polytope, or the vectors of a linear matroid M:Matroid a matroid P:Polyhedron a polytope C:Cone a cone Outputs S:Matrix a slack matrix of the realization Description Text A slack matrix depends on the given representation. Its rows are indexed by vertices/ground set elements and its columns are indexed by facets/hyperplanes. The @{TT "(i, j)"}@-entry is the @{TT "j"}@-th inequality evaluated on element @{TT "i"}@. Example V = {{0, 0}, {0, 1}, {1, 1}, {1, 0}}; SP = slackMatrix V SM = slackMatrix(V, Object => "matroid") Example C = posHull(matrix{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}); S = slackMatrix C Caveat When giving a @{TT "Matroid"}@ as input, the ground set must be a set of vectors giving a representation of the matroid. SeeAlso symbolicSlackMatrix Object /// doc /// Key getFacetBases (getFacetBases, Matrix) (getFacetBases, Polyhedron) (getFacetBases, Matroid) (getFacetBases, List) Headline get a list of d-spanning elements for each facet Usage (newV, B) = getFacetBases S (newV, B) = getFacetBases P (newV, B) = getFacetBases M (newV, B) = getFacetBases V Inputs S:Matrix a slack matrix S of rank d+1 P:Polyhedron a polytope M:Matroid a matroid V:List a list of vertices of d-polytope, vectors of a rank d+1 matroid, or (d+1)-cone generators Outputs newV:List a list of vertices (empty if a matrix is given as input) in the order corresponding to B B:List list of d spanning elements for each facet Description Text This function produces a list B of d spanning elements for each facet in a given d-polytope, rank d+1 matroid, or (d+1)-cone generators. If a slack matrix or a list of vertices is given as input, it also creates a sorted list of vertices (empty if a matrix is given as input) from which B is computed in the order corresponding to B. Example V = {{0, 0}, {1, 0}, {2, 1}, {1, 2}, {0, 1}}; (newV, B) = getFacetBases V Example V = {{0, 0}, {1, 0}, {1, 1}, {0, 1}}; S = slackMatrix V; (newV, B) = getFacetBases S SeeAlso slackFromPlucker symbolicSlackOfPlucker grassmannSectionIdeal /// doc /// Key slackFromPlucker (slackFromPlucker, List, List) (slackFromPlucker, List) (slackFromPlucker, Polyhedron) (slackFromPlucker, Matroid) Headline fill the slack matrix of a given polytope, cone or matroid with Plücker coordinates Usage fillPl = slackFromPlucker(V, B) fillPl = slackFromPlucker V fillPl = slackFromPlucker P fillPl = slackFromPlucker M Inputs V:List list of coordinates for polytope vertices, cone generators, or matroid vectors B:List set of hyperplane spanning set indices P:Polyhedron a polytope M:Matroid a matroid Outputs fillPl:Matrix slack matrix filled with Plücker coordinates Description Text Given a slack matrix or a list of vertices of d-polytope or a rank d+1 matroid, or (d+1)-cone generators, it fills the corresponding slack matrix with Plücker coordinates. Example V = {{0, 0, 0}, {1, 0, 0}, {0, 1, 0}, {0, 0, 1}, {1, 0, 1}, {1, 1, 0}}; B = {{1, 2, 4}, {0, 2, 3}, {0, 1, 4}, {3, 4, 5}, {0, 1, 2}}; fillPl = slackFromPlucker(V, B) Example V = {{0, 0, 0}, {1, 0, 0}, {0, 1, 0}, {0, 0, 1}, {1, 0, 1}, {1, 1, 0}}; fillPl = slackFromPlucker V Caveat Does not check if B actually spans for given V, does not check orientation of simplices in B, so that the resulting slack matrix may differ by signs of each column. SeeAlso getFacetBases /// doc /// Key slackFromGalePlucker (slackFromGalePlucker, List, List) (slackFromGalePlucker, List, Matrix) Headline fill the slack matrix with Plücker coordinates of the Gale transform Usage fillPl = slackFromGalePlucker(B, G) fillPl = slackFromGalePlucker(B, MG) Inputs B:List set of hyperplane spanning set indices G:List list of Gale vectors of a polytope MG:Matrix matrix of Gale vectors of a polytope Outputs fillPl:Matrix slack matrix filled with Plücker coordinates Description Text Given a set of vectors of a Gale transform or a matrix whose columns form a Gale transform of a polytope, it fills the slack matrix of the polytope with Plücker coordinates of the Gale transform. Example G = {{0, 1}, {1, 0}, {-1, -1}, {0, -1}, {-1, 0}, {1, 1}}; B = {{1, 2, 4}, {0, 2, 3}, {0, 1, 4}, {3, 4, 5}, {0, 1, 2}}; slackFromGalePlucker(B, G) Example MG = matrix(RR, {{0, 1, -1, 0, -1, 1}, {1, 0, -1, -1, 0, 1}}); B = {{1, 2, 4}, {0, 2, 3}, {0, 1, 4}, {3, 4, 5}, {0, 1, 2}}; slackFromGalePlucker(B, MG) Caveat Does not check if B actually spans for given V, does not check orientation of simplices in B, so that the resulting slack matrix may differ by signs of each column. SeeAlso getFacetBases slackFromPlucker /// doc /// Key slackFromGaleCircuits (slackFromGaleCircuits, Matrix) Headline computes the slack matrix of a polytope from a Gale transform of the polytope Usage M = slackFromGaleCircuits(G, Tolerance => 12) M = slackFromGaleCircuits G Inputs G:Matrix matrix of the form matrix(RR, {...}) whose columns are the vectors of a Gale transform Outputs SP:Matrix the slack matrix of the polytope whose Gale transform is G Description Text This function computes the slack matrix of a polytope starting from a matrix whose columns correspond to the vertices of a Gale transform of the polytope. The second argument Tolerance, which is optional, is a positive integer that expresses the tolerance used in the computations, i.e. if an entry of a matrix is less than 10^(-Tolerance), then it will be treated as zero. The default value for the tolerance is 14. Example -- Let G be the Gale transform of the triangular prism G = matrix(RR, {{0, 1, -1, 0, -1, 1}, {1, 0, -1, -1, 0, 1}}); M = slackFromGaleCircuits G Example -- Let G be the Gale transform of the octahedron G = matrix(RR, {{1, 1, -1, -1, 0, 0}, {1, 1, 0, 0, -1, -1}}); M = slackFromGaleCircuits G Example -- Let G be the Gale transform of the bipyramid over a square pyramid G = matrix(RR, {{1, 0, 1, 0, 2, -2, -2}, {0, 1, 0, 1, 2, -2, -2}}); M = slackFromGaleCircuits G Example -- Let G be the Gale transform of the cyclic polytope in R^3 with seven vertices G = matrix(RR, {{1, -4, 6, -4, 1, 0, 0}, {4, -15, 20, -10, 0, 1, 0}, {10, -36, 45, -20, 0, 0, 1}}); M = slackFromGaleCircuits G Example -- Let G be the Gale transform of the Perles polytope G = matrix(RR, {{-sqrt(10+2*sqrt(5))*(sqrt(5)+1)/(4*(sqrt(5)-1)), sqrt(10+2*sqrt(5))*(sqrt(5)+1)/(4*(sqrt(5)-1)), -4*sqrt(5)/(sqrt(10+2*sqrt(5))*(sqrt(5)+1)+(sqrt(5)-5)*sqrt(10-2*sqrt(5))), 4*sqrt(5)/(sqrt(10+2*sqrt(5))*(sqrt(5)+1)+(sqrt(5)-5)*sqrt(10-2*sqrt(5))), -sqrt(10-2*sqrt(5))/4, sqrt(10-2*sqrt(5))/4, -sqrt(10+2*sqrt(5))/4, sqrt(10+2*sqrt(5))/4, -sqrt(10-2*sqrt(5))/4, sqrt(10+2*sqrt(5))/4, -sqrt(10+2*sqrt(5))/4, 0}, {(sqrt(5)+1)/4, (sqrt(5)+1)/4, (-5-sqrt(5))/(6*sqrt(5)-10), (-5-sqrt(5))/(6*sqrt(5)-10), (sqrt(5)+1)/4, (sqrt(5)+1)/4, -(sqrt(5)-1)/4, -(sqrt(5)-1)/4, -(sqrt(5)+1)/4, (sqrt(5)-1)/4, (sqrt(5)-1)/4, 0}, {1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1}}); M = slackFromGaleCircuits G SeeAlso slackMatrix symbolicSlackMatrix /// doc /// Key specificSlackMatrix (specificSlackMatrix, String) Headline creates built-in slack matrices of some polytopes and matroids Usage specificSlackMatrix name Inputs name:String the name of the polytope or of matroids Outputs :Matrix Description Text Returns a slack matrix of one of the named polytopes and matroids below. Example peek specificSlackMatrix "perles1" peek specificSlackMatrix "perles2" peek specificSlackMatrix "barnette" peek specificSlackMatrix "toric-non-graphic" peek specificSlackMatrix "pu-non-mcmullen" peek specificSlackMatrix "fano-matroid" peek specificSlackMatrix "complex-matroid" peek specificSlackMatrix "nonfano-matroid" peek specificSlackMatrix "perles-matroid" peek specificSlackMatrix "perles-matroid-QQ" /// doc /// Key symbolicSlackMatrix (symbolicSlackMatrix, List) (symbolicSlackMatrix, Matrix) (symbolicSlackMatrix, Matroid) (symbolicSlackMatrix, Polyhedron) (symbolicSlackMatrix, Cone) Headline computes the symbolic slack matrix Usage S = symbolicSlackMatrix V S = symbolicSlackMatrix X S = symbolicSlackMatrix M S = symbolicSlackMatrix P S = symbolicSlackMatrix C Inputs V:List a list of points treated as the vertices of polytope; or vectors of a linear matroid if matroid is given as @{TO Object}@; or a list of indices comprising the facets of an abstract polytope if abstractPolytope is given as @{TO Object}@. X:Matrix a slack matrix M:Matroid a matroid P:Polyhedron a polytope C:Cone a cone Outputs S:Matrix the symbolic slack matrix with indexed variables in symbol x Description Text The symbolic slack matrix records the combinatorial structure of the given object. Its @{TT "(i, j)"}@-entry is 0 if element @{TT "i"}@ is in hyperplane @{TT "j"}@ and it is a variable otherwise. Variables are indexed left to right by rows. Example V = {{0, 0}, {0, 1}, {1, 1}, {1, 0}}; S = symbolicSlackMatrix V Example M = matroid({0, 1, 2, 3, 4, 5}, {{1, 2, 3}, {0, 2, 4}, {0, 3, 5}, {1, 4, 5}}, EntryMode => "nonbases"); S = symbolicSlackMatrix M Example V = {{1, 2, 3}, {4, 5, 6}, {1, 2, 4, 5}, {1, 3, 4, 6}, {2, 3, 5, 6}}; S = symbolicSlackMatrix(V, Object => "abstractPolytope") SeeAlso slackMatrix Object /// doc /// Key symbolicSlackOfPlucker (symbolicSlackOfPlucker, ZZ, List) (symbolicSlackOfPlucker, List, List) (symbolicSlackOfPlucker, List) (symbolicSlackOfPlucker, Matrix, List) (symbolicSlackOfPlucker, Matrix) (symbolicSlackOfPlucker, Polyhedron) (symbolicSlackOfPlucker, Matroid) Headline fill the slack matrix with Plücker variables Usage fillPl = symbolicSlackOfPlucker(v, B) fillPl = symbolicSlackOfPlucker(V, B) fillPl = symbolicSlackOfPlucker V fillPl = symbolicSlackOfPlucker(S, B) fillPl = symbolicSlackOfPlucker S fillPl = symbolicSlackOfPlucker P fillPl = symbolicSlackOfPlucker M Inputs v:ZZ number of polytope vertices, cone generators, or matroid vectors B:List set of hyperplane spanning set indices V:List list of coordinates for polytope vertices, cone generators, or matroid vectors S:Matrix (symbolic) slack matrix P:Polyhedron a polytope M:Matroid a matroid Outputs fillPl:Matrix slack matrix filled with Plücker variables Description Text Given the number of polytope vertices, cone generators, or matroid vectors, or a set of polytope vertices, cone generators, or matroid vectors, or a slack matrix and a set of set of hyperplane spanning set indices, it fills the slack matrix with Plücker variables. Example v = 6; B = {{1, 2, 4}, {0, 2, 3}, {0, 1, 4}, {3, 4, 5}, {0, 1, 2}}; fillPl = symbolicSlackOfPlucker(v, B) Example V = {{0, 0, 0}, {1, 0, 0}, {0, 1, 0}, {0, 0, 1}, {1, 0, 1}, {1, 1, 0}}; B = {{1, 2, 4}, {0, 2, 3}, {0, 1, 4}, {3, 4, 5}, {0, 1, 2}}; fillPl = symbolicSlackOfPlucker(V, B) Example V = {{0, 0, 0}, {1, 0, 0}, {0, 1, 0}, {0, 0, 1}, {1, 0, 1}, {1, 1, 0}}; fillPl = symbolicSlackOfPlucker V Example V = {{0, 0, 0}, {1, 0, 0}, {0, 1, 0}, {0, 0, 1}, {1, 0, 1}, {1, 1, 0}}; B = {{1, 2, 4}, {0, 2, 3}, {0, 1, 4}, {3, 4, 5}, {0, 1, 2}}; fillPl = symbolicSlackOfPlucker(slackMatrix V, B) Example V = {{0, 0, 0}, {1, 0, 0}, {0, 1, 0}, {0, 0, 1}, {1, 0, 1}, {1, 1, 0}}; fillPl = symbolicSlackOfPlucker(slackMatrix V) SeeAlso getFacetBases slackFromPlucker slackFromGalePlucker /// doc /// Key slackIdeal (slackIdeal, ZZ, List) (slackIdeal, Matroid) (slackIdeal, Polyhedron) (slackIdeal, Cone) (slackIdeal, List) (slackIdeal, ZZ, Matrix) (slackIdeal, Matrix) Headline computes the slack ideal Usage I = slackIdeal(d, V) I = slackIdeal M I = slackIdeal P I = slackIdeal C I = slackIdeal V I = slackIdeal(d, S) I = slackIdeal S Inputs d:ZZ the dimension of the polytope or 1 less than the rank of the matroid V:List a list of vertices of a polytope, the vectors of a linear matroid, or facet sets of an abstract polytope M:Matroid a matroid P:Polyhedron a polytope C:Cone a cone S:Matrix a (symbolic) slack matrix Outputs I:Ideal the slack ideal - the saturated ideal of (d+2)-minors of the symbolic slack matrix Description Text The slack ideal of a d-polytope or rank d+1 matroid is the ideal of (d+2)-minors of its symbolic slack matrix, saturated by the product of the variables in the matrix. Example V = {{0, 0}, {1, 0}, {1, 1}, {0, 1}}; I = slackIdeal V Text If a list of points is given it can be treated as the vertices of a polytope, the ground set of a matroid or the facets of an abstract polytope by specifying the option @TO{Object}@. The default is as a polytope. Example V = {{0, 0}, {1, 0}, {1, 1}, {0, 1}}; IP = slackIdeal V IM = slackIdeal(V, Object => "matroid") SeeAlso slackMatrix symbolicSlackMatrix /// doc /// Key grassmannSectionIdeal (grassmannSectionIdeal, Matrix, List) (grassmannSectionIdeal, Matrix) (grassmannSectionIdeal, List, List) (grassmannSectionIdeal, List) (grassmannSectionIdeal, Polyhedron) (grassmannSectionIdeal, Cone) (grassmannSectionIdeal, Matroid) Headline compute the Grassmannian section ideal corresponding to a slack matrix Usage I = grassmannSectionIdeal(S, B) I = grassmannSectionIdeal S I = grassmannSectionIdeal(V, B) I = grassmannSectionIdeal V I = grassmannSectionIdeal P I = grassmannSectionIdeal C I = grassmannSectionIdeal M Inputs S:Matrix slack matrix B:List set of hyperplane spanning set indices V:List list of polytope vertex coordinates, cone generators, or matroid vectors P:Polyhedron a polytope C:Cone a cone M:Matroid a matroid Outputs I:Ideal the Grassmannian section ideal corresponding to choice B of the object with slack matrix S Description Text Given a slack matrix of a polytope, a cone or a matroid, or a set of polytope vertices, cone generators, or matroid vectors, and a set of set of hyperplane spanning set indices, it computes the Grassmannian section ideal corresponding to choice B of the object with slack matrix S. Example V = {{0, 0}, {1, 0}, {2, 1}, {1, 2}, {0, 1}}; (VV, B) = getFacetBases V; I = grassmannSectionIdeal(VV, B) Example V = {{0, 0}, {1, 0}, {2, 1}, {1, 2}, {0, 1}}; (VV, B) = getFacetBases V; I = grassmannSectionIdeal(slackMatrix(VV), B) SeeAlso getFacetBases slackFromPlucker slackFromGalePlucker symbolicSlackOfPlucker /// doc /// Key graphFromSlackMatrix (graphFromSlackMatrix, Matrix) Headline creates the vertex-edge incidence matrix for the bipartite non-incidence graph with adjacency matrix the given slack matrix Usage A = graphFromSlackMatrix S Inputs S:Matrix a (symbolic) slack matrix Outputs A:Matrix 0-1 vertex-edge incidence matrix Description Text This function creates a matrix whose columns correspond to the edges of the non-incidence graph of a slack matrix. They are ordered by variable index. The first n rows correspond to rows of the slack matrix (vertices/ground set elements) and the remaining rows correspond to columns of the slack matrix (facets/hyperplanes). Example V = {{0, 0}, {1, 0}, {1, 1}, {0, 1}}; S = symbolicSlackMatrix V A = graphFromSlackMatrix S Caveat If S is not a symbolic slack matrix, the columns of A will be ordered assuming edges are listed in order by rows of S (as in @TO{symbolicSlackMatrix}@). SeeAlso graphicIdeal symbolicSlackMatrix /// doc /// Key graphicIdeal (graphicIdeal, List) (graphicIdeal, Polyhedron) (graphicIdeal, Matrix) (graphicIdeal, Matroid) Headline creates the toric ideal of the non-incidence graph of a polytope Usage T = graphicIdeal V T = graphicIdeal P T = graphicIdeal S T = graphicIdeal M Inputs V:List a list of vertices or of facet sets P:Polyhedron a polytope S:Matrix a (symbolic) slack matrix of a polytope M:Matroid a matroid Outputs T:Ideal the toric ideal of the non-incidence graph Description Text The graphic ideal associated to a polytope is the toric ideal of the vector configuration consisting of the columns of the vertex-edge incidence matrix of the non-incidence (of vertices and facets) graph of the polytope. Example P = convexHull(matrix{{0, 0, 1, 1}, {0, 1, 0, 1}}); T = graphicIdeal P Caveat If S is not a symbolic slack matrix, the ideal will have variables indexed as in @TO{symbolicSlackMatrix}@ (from left to right in order by rows of S). SeeAlso graphFromSlackMatrix cycleIdeal symbolicSlackMatrix /// doc /// Key cycleIdeal (cycleIdeal, List) (cycleIdeal, Matroid) (cycleIdeal, Polyhedron) (cycleIdeal, Matrix) Headline constructs the cycle ideal of a realization Usage C = cycleIdeal V C = cycleIdeal M C = cycleIdeal P C = cycleIdeal S Inputs V:List a list of points of a realization M:Matroid a matroid P:Polyhedron a polytope S:Matrix a slack matrix of some realization Outputs C:Ideal the cycle ideal with coefficients from given realization Description Text A cycle ideal is the toric ideal generated by the cycles of the bipartite non-incidence graph on vertices/elements and facets/hyperplanes. Each cycle binomial has coefficients coming from the entries of a slack matrix of a realization of the given object. This method computes the cycle ideal of the given realization of a polytope or matroid. Example V = {{0, 0}, {1, 0}, {1, 1}, {0, 1}}; C = cycleIdeal V Text You can create the cycle ideal of any matrix, even if it is not the realization of some matroid or polytope. Example M = matrix{{1, 1, 0}, {0, 1, 2}, {1, 0, 3}}; C = cycleIdeal M Caveat Variables in the cycle ideal C will be labelled according to the labeling assigned by @TO{symbolicSlackMatrix}@, which is in order by rows, so to test equality of C with some precomputed ideal care needs to be taken that variable labels match. If @TO{Object}@ => abstractPolytope is chosen, the graphic ideal will be returned instead. SeeAlso graphicIdeal slackMatrix /// doc /// Key universalIdeal (universalIdeal, Matroid) (universalIdeal, List) Headline computes the universal realization ideal of a matroid Usage U = universalIdeal M U = universalIdeal V Inputs M:Matroid a matroid V:List a list of points of a representation of a matroid Outputs U:Ideal the universal realization ideal in Plücker and slack variables Description Text The universal realization ideal defines a variety containing points (p, S) which are pairs of a Plücker vector and a slack matrix coming from the same realization of the matroid. Example M = matroid({0, 1, 2, 3, 4, 5}, {{1, 2, 3}, {0, 2, 4}, {0, 3, 5}, {1, 4, 5}}, EntryMode => "nonbases"); U = universalIdeal M Caveat A list of points representing a matroid are always assumed to be in affine space and are projectivized by appending 1 to vector of coordinates. SeeAlso slackMatrix /// doc /// Key toricPolytope (toricPolytope, Ideal) Headline computes the polytope whose toric ideal is the given ideal Usage Q = toricPolytope I Inputs I:Ideal a toric ideal Outputs Q:Matrix a matrix whose columns are the vectors of a configuration whose toric ideal is I Description Text Every toric ideal comes as the ideal of some vector configuration. This function gives one such vector configuration whose ideal is the given ideal. Example V = {{0, 0}, {0, 1}, {1, 1}, {1, 0}}; I = slackIdeal V Q = toricPolytope I Caveat This function does not test for binomiality. If it is given an ideal which is not toric, it will return the polytope of the ideal whose generators are the first two terms of each generator of the input ideal. If the input toric ideal is scaled (lattice ideal with not all coefficients one) the toric polytope of the unscaled ideal is returned. SeeAlso graphicIdeal cycleIdeal /// doc /// Key setOnesForest (setOnesForest, Matrix) Headline sets to 1 variables in a symbolic slack matrix which corresponding to edges of a spanning forest Usage (Y, F) = setOnesForest X Inputs X:Matrix a symbolic slack matrix Outputs Y:Matrix the matrix X with the variables corresponding to the edges of a spanning forest set to 1 F:Graph spanning forest of the bipartite (non-incidence) graph whose vertices are the vertices and facets of a polytope P, and whose edges are the vertex-facet pairs of P such that the vertex is not on the facet Description Text Since row and column scaling operations preserve the projective equivalence class of a slack matrix, it is sometimes advantageous to choose a certain equivalence class representative by setting some variables in a slack matrix to 1. This reduces the computational time of calculating the slack ideal, for example. This function automates the selection of a spanning forest in the bipartite graph corresponding to S and sets the associated variables to 1. Example V = {{0, 0}, {0, 1}, {1, 1}, {1, 0}}; X = symbolicSlackMatrix V (Y, F) = setOnesForest X SeeAlso graphFromSlackMatrix slackIdeal symbolicSlackMatrix /// doc /// Key rehomogenizePolynomial (rehomogenizePolynomial, Matrix) (rehomogenizePolynomial, Matrix, Matrix, Graph, RingElement) Headline rehomogenization of a polynomial reversing the dehomogenization of the slack matrix Usage h = rehomogenizePolynomial X h = rehomogenizePolynomial(X, Y, T, g) Inputs X:Matrix a symbolic slack matrix X Y:Matrix dehomogenized slack matrix Y T:Graph a spanning forest of the bipartite graph associated to X g:RingElement a polynomial Outputs h:RingElement the rehomogenization of g reversing the dehomogenization of the slack matrix Description Text Given the symbolic slack matrix X of a polytope, we may set to 1 the variables corresponding of a spanning forest of the bipartite graph associated with X. It can be useful to rehomogenize a polynomial in the variables that are left, reversing the dehomogenization process. This function produces the rehomogenization of a polynomial following the spanning forest backwards. It is useful in the computation of the rehomogenization of the generators of an ideal, for example of the slack ideal. Example R = QQ[x_1..x_12]; X = matrix {{0, x_1, 0, 0, x_2}, {x_3, 0, 0, 0, x_4}, {0, x_5, x_6, 0, 0}, {x_7, 0, x_8, 0, 0}, {0, x_9, 0, x_10, 0}, {x_11, 0, 0, x_12, 0}}; (Y, T) = setOnesForest X; remVars := flatten entries Y - set{0_(ring Y), 1_(ring Y)}; h = rehomogenizePolynomial(X, Y, T, remVars_0^2+remVars_0*remVars_1-1) SeeAlso setOnesForest slackIdeal symbolicSlackMatrix /// doc /// Key rehomogenizeIdeal (rehomogenizeIdeal, ZZ, Matrix) (rehomogenizeIdeal, ZZ, Matrix, Graph) Headline rehomogenization of a the dehomogenized slack ideal Usage H = rehomogenizeIdeal(d, X) H = rehomogenizeIdeal(d, Y, T) Inputs d:ZZ dimension of the polytope X:Matrix a symbolic slack matrix X of a d-polytope Y:Matrix dehomogenized symbolic slack matrix Y of d-polytope T:Graph spanning forest whose edges match the ones in Y Outputs H:Ideal the rehomogenization of the dehomogenized slack ideal Description Text It computes the rehomogenization of the dehomogenized slack ideal, applying the rehomogenize function to its generators. Example V = {{0, 0, 0}, {1, 0, 0}, {1, 1, 0}, {0, 1, 0}, {0, 0, 1}, {0, 1, 1}}; X = symbolicSlackMatrix V H = rehomogenizeIdeal(3, X) Example R = QQ[x_0..x_11]; Y = matrix {{0, 0, 1, 0, 1}, {1, 0, 1, 0, 0}, {0, x_4, 0, 0, 1}, {1, 1, 0, 0, 0}, {0, 0, 1, 1, 0}, {0, x_10, 0, 1, 0}}; T = graph(QQ[y_0, y_1, y_2, y_3, y_4, y_5, y_6, y_7, y_8, y_9, y_10], {{y_1, y_6}, {y_3, y_6}, {y_3, y_7}, {y_0, y_8}, {y_1, y_8}, {y_4, y_8}, {y_4, y_9}, {y_5, y_9}, {y_0, y_10}, {y_2, y_10}}); rehomogenizeIdeal(3, Y, T) SeeAlso rehomogenizePolynomial setOnesForest slackIdeal symbolicSlackMatrix /// doc /// Key findFlag (findFlag, Polyhedron) (findFlag, Matroid) (findFlag, Matrix) (findFlag, List) Headline computes a list of facet labels that make up a flag in a polytope Usage F = findFlag P F = findFlag M F = findFlag S F = findFlag V Inputs P:Polyhedron a polytope M:Matroid a matroid S:Matrix (symbolic) slack matrix V:List a list of vertex coordinates, matroid vectors, facet labels, or cone generators Outputs F:List a list of facet labels or hyperplanes or column labels or labels that make up a flag in the given polytope or matroid or matrix or object given by V Description Text Given a polytope, a matroid, a cone, it finds a flag of facets or hyperplanes or cone generators that can be given as input to obtain a reduced slack matrix. Example V = {{0, 0, 0}, {0, 0, 1}, {1, 0, 0}, {1, 0, 1}, {0, 1, 0}, {0, 1, 1}}; findFlag V findFlag(V, Object => "matroid") findFlag({{0, 2, 3, 5}, {0, 1, 3, 4}, {1, 2, 4, 5}, {0, 1, 2}, {3, 4, 5}}, Object => "abstractPolytope") SeeAlso reconstructSlackMatrix reducedSlackMatrix /// doc /// Key containsFlag (containsFlag, List, Polyhedron) (containsFlag, List, Matroid) (containsFlag, List, Matrix) (containsFlag, List, List) Headline establishes whether or not a list of facet labels contains a flag in a polytope or matroid Usage containsFlag(fl, P) containsFlag(fl, M) containsFlag(fl, S) containsFlag(fl, V) Inputs fl:List a list of facet labels P:Polyhedron a polytope M:Matroid a matroid S:Matrix (symbolic) slack matrix V:List a list of vertex coordinates, matroid vectors, facet labels, or cone generators Outputs :Boolean whether or not a list of facet labels contains a flag in a polytope or matroid Description Text Given a list of facet labels fl and a polytope, a matroid, a (symbolic) slack matrix or a list of vertex coordinates, matroid vectors, facet labels, establishes whether or not fl contains a flag in the given object. Example V = {{0, 0, 0}, {0, 0, 1}, {1, 0, 0}, {1, 0, 1}, {0, 1, 0}, {0, 1, 1}}; containsFlag({0, 1, 2, 4}, V) containsFlag({0, 1, 2, 8}, V, Object => "matroid") containsFlag({0, 1, 2, 3}, {{0, 2, 3, 5}, {0, 1, 3, 4}, {1, 2, 4, 5}, {0, 1, 2}, {3, 4, 5}}, Object => "abstractPolytope") SeeAlso findFlag reducedSlackMatrix /// doc /// Key reconstructSlackMatrix (reconstructSlackMatrix, Matrix, List, List) (reconstructSlackMatrix, Matrix, List) Headline a list of facet labels that make up a flag in a polytope Usage ExtS = reconstructSlackMatrix(S, fl, F) ExtS = reconstructSlackMatrix(S, F) Inputs S:Matrix a (column) reduced slack matrix fl:List a flag of columns F:List list of facet columns we want to refill Outputs ExtS:Matrix S extended by the columns of F Description Text Given a (column) reduced slack matrix S, a flag of columns and a list of facet columns F to refill, it extends S by the columns of F. Example V = {{0,0,0},{0,0,1},{1,0,0},{1,0,1},{0,1,0},{0,1,1}}; S = slackMatrix V; redS = reducedSlackMatrix(3, S); reconstructSlackMatrix(reducedSlackMatrix(S, Vars => {a,b,c,d,e,f,g,h,j,k,m,p}), {{0,1,2}}) reconstructSlackMatrix(redS, {{0,1,2}}) reconstructSlackMatrix(redS, {{0,1,2}}, Vars => {x}) SeeAlso findFlag reducedSlackMatrix /// doc /// Key reducedSlackMatrix (reducedSlackMatrix, ZZ, Matrix) (reducedSlackMatrix, Matrix) (reducedSlackMatrix, List) Headline a reduced slack matrix of a polytope Usage RedS = reducedSlackMatrix(d, S) RedS = reducedSlackMatrix S RedS = reducedSlackMatrix V Inputs d:ZZ the dimension of the polytope or 1 less than the rank of the matroid S:Matrix a (symbolic) slack matrix of a polytope or of a matroid V:List list of vertex coordinates, matroid vectors, facet labels, or cone generators Outputs RedS:Matrix a reduced slack matrix Description Text Given a (symbolic) slack matrix of a polytope or of a matroid, or a list of vertex coordinates, matroid vectors, facet labels, or cone generators, it reduces it by removing the columns corresponding to simplicial facets outside of a flag. Example -- Let P be a triangular prism V = {{0,0,0},{0,0,1},{1,0,0},{1,0,1},{0,1,0},{0,1,1}}; S = slackMatrix V; reducedSlackMatrix V reducedSlackMatrix(3, S) -- Let P be a 3-polytope with 8 vertices and facets {1357, 1458, 2367, 2468, 5678, 134, 234} R = QQ[x_1..x_30]; S = matrix {{0, 0, x_1, x_2, x_3, 0, x_4}, {x_5, x_6, 0, 0, x_7, x_8, 0}, {0, x_9, 0, x_10, x_11, 0, 0}, {x_12, 0, x_13, 0, x_14, 0, 0}, {0, 0, x_15, x_16, 0, x_17, x_18}, {x_19, x_20, 0, 0, 0, x_21, x_22}, {0, x_23, 0, x_24, 0, x_25, x_26}, {x_27, 0, x_28, 0, 0, x_29, x_30}}; redS = reducedSlackMatrix(3, S) SeeAlso findFlag reconstructSlackMatrix /// doc /// Key Object Headline select the combinatorial object which the input should be interpreted as Usage slackMatrix(V, Object => "matroid") slackIdeal(V, Object => "abstractPolytope") symbolicSlackMatrix(V, Object => "polytope") cycleIdeal(V, Object => "matroid") graphicIdeal(V, Object => "abstractPolytope") getFacetBases(V, Object => "cone") slackFromPlucker(V, Object => "polytope") symbolicSlackOfPlucker(V, Object => "matroid") grassmannSectionIdeal(V, Object => "cone") findFlag(V, Object => "matroid") containsFlag(fl, V, Object => "matroid") reducedSlackMatrix(V, Object => "polytope") Description Text The default value is polytope. SeeAlso slackMatrix slackIdeal symbolicSlackMatrix cycleIdeal graphicIdeal getFacetBases slackFromPlucker symbolicSlackOfPlucker grassmannSectionIdeal findFlag containsFlag reducedSlackMatrix /// doc /// Key [slackMatrix, Object] Headline specify combinatorial object Usage slackMatrix(..., Object => "polytope") slackMatrix(..., Object => "matroid") Description Text Indicates whether an input list should be treated as the vertices of a polytope or the ground set of a matroid. /// doc /// Key [graphicIdeal, Object] Headline specify combinatorial object Usage slackMatrix(..., Object => "polytope") slackMatrix(..., Object => "abstractPolytope") Description Text Indicates whether an input list should be treated as the vertices of a polytope or the facets of an abstract polytope. /// doc /// Key [slackIdeal, Object] Headline specify combinatorial object Usage slackIdeal(..., Object => "polytope") slackIdeal(..., Object => "matroid") slackIdeal(..., Object => "abstractPolytope") Description Text Indicates whether an input list should be treated as the vertices of a polytope, the ground set of a matroid or the facets of an abstract polytope. /// doc /// Key [symbolicSlackMatrix, Object] Headline specify combinatorial object Usage symbolicSlackMatrix(..., Object => "polytope") symbolicSlackMatrix(..., Object => "matroid") symbolicSlackMatrix(..., Object => "abstractPolytope") Description Text Indicates whether an input list should be treated as the vertices of a polytope, the ground set of a matroid or the facets of an abstract polytope. /// doc /// Key [symbolicSlackOfPlucker, Object] Headline specify combinatorial object Usage symbolicSlackOfPlucker(..., Object => "polytope") symbolicSlackOfPlucker(..., Object => "cone") symbolicSlackOfPlucker(..., Object => "matroid") Description Text Indicates whether an input list should be treated as the vertices of a polytope, the ground set of a matroid or the facets of an abstract polytope. /// doc /// Key [grassmannSectionIdeal, Object] Headline specify combinatorial object Usage grassmannSectionIdeal(..., Object => "cone") grassmannSectionIdeal(..., Object => "matroid") grassmannSectionIdeal(..., Object => "polytope") Description Text Indicates whether an input list should be treated as the vertices of a polytope, the ground set of a matroid or the facets of an abstract polytope. /// doc /// Key [cycleIdeal, Object] Headline specify combinatorial object Usage cycleIdeal(..., Object => "polytope") cycleIdeal(..., Object => "matroid") cycleIdeal(..., Object => "abstractPolytope") Description Text Indicates whether an input list should be treated as the vertices of a polytope, the ground set of a matroid or the facets of an abstract polytope. /// doc /// Key [getFacetBases, Object] Headline specify combinatorial object Usage getFacetBases(..., Object => "polytope") getFacetBases(..., Object => "cone") getFacetBases(..., Object => "matroid") Description Text Indicates whether an input list should be treated as the vertices of a polytope, the ground set of a matroid or the facets of an abstract polytope. /// doc /// Key [slackFromPlucker, Object] Headline specify combinatorial object Usage slackFromPlucker(..., Object => "cone") slackFromPlucker(..., Object => "abstractPolytope") slackFromPlucker(..., Object => "polytope") Description Text Indicates whether an input list should be treated as the vertices of a polytope, the ground set of a matroid or the facets of an abstract polytope. /// doc /// Key [findFlag, Object] Headline specify combinatorial object Usage findFlag(..., Object => "polytope") findFlag(..., Object => "matroid") findFlag(..., Object => "abstractPolytope") Description Text Indicates whether an input list should be treated as the vertices of a polytope, the ground set of a matroid or the facets of an abstract polytope. /// doc /// Key [containsFlag, Object] Headline specify combinatorial object Usage containsFlag(..., Object => "polytope") containsFlag(..., Object => "matroid") Description Text Indicates whether an input list should be treated as the vertices of a polytope, the ground set of a matroid or the facets of an abstract polytope. /// doc /// Key [reducedSlackMatrix, Object] Headline specify combinatorial object Usage reducedSlackMatrix(..., Object => "polytope") reducedSlackMatrix(..., Object => "matroid") Description Text Indicates whether an input list should be treated as the vertices of a polytope, the ground set of a matroid. /// doc /// Key [slackIdeal, Strategy] Headline specifies saturation strategy to be used Usage slackIdeal(..., Strategy => Iterate) slackIdeal(..., Strategy => Bayer) slackIdeal(..., Strategy => Linear) slackIdeal(..., Strategy => Eliminate) SeeAlso Strategy /// doc /// Key [grassmannSectionIdeal, Strategy] Headline specifies saturation strategy to be used Usage grassmannSectionIdeal(..., Strategy => Iterate) grassmannSectionIdeal(..., Strategy => Bayer) grassmannSectionIdeal(..., Strategy => Linear) grassmannSectionIdeal(..., Strategy => Eliminate) SeeAlso Strategy /// doc /// Key [cycleIdeal, Strategy] Headline specifies saturation strategy to be used Usage cycleIdeal(..., Strategy => Iterate) cycleIdeal(..., Strategy => Bayer) cycleIdeal(..., Strategy => Linear) cycleIdeal(..., Strategy => Eliminate) SeeAlso Strategy /// doc /// Key [graphicIdeal, Strategy] Headline specifies saturation strategy to be used Usage cycleIdeal(..., Strategy => Iterate) cycleIdeal(..., Strategy => Bayer) cycleIdeal(..., Strategy => Linear) cycleIdeal(..., Strategy => Eliminate) SeeAlso Strategy /// doc /// Key [rehomogenizeIdeal, Strategy] Headline specifies saturation strategy to be used Usage rehomogenizeIdeal(..., Strategy => Iterate) rehomogenizeIdeal(..., Strategy => Bayer) rehomogenizeIdeal(..., Strategy => Linear) rehomogenizeIdeal(..., Strategy => Eliminate) SeeAlso Strategy /// doc /// Key Saturate Headline choose whether to saturate with respect to the product of all variables at the same time or variable by variable. Usage slackIdeal(V, Saturate => "all") rehomogenizeIdeal(d, X, Saturate => "each") grassmannSectionIdeal(S, B, Saturate => "all") graphicIdeal(V, Saturate => "each") cycleIdeal(S, Saturate => "all") Description Text The default value is "all". SeeAlso Strategy slackIdeal rehomogenizeIdeal grassmannSectionIdeal graphicIdeal cycleIdeal /// doc /// Key [slackIdeal, Saturate] Headline specifies saturation strategy to be used Usage slackIdeal(..., Saturate => "all") slackIdeal(..., Saturate => "each") SeeAlso Strategy /// doc /// Key [rehomogenizeIdeal, Saturate] Headline specifies saturation strategy to be used Usage rehomogenizeIdeal(..., Saturate => "all") rehomogenizeIdeal(..., Saturate => "each") SeeAlso Strategy /// doc /// Key [grassmannSectionIdeal, Saturate] Headline specifies saturation strategy to be used Usage grassmannSectionIdeal(..., Saturate => "all") grassmannSectionIdeal(..., Saturate => "each") SeeAlso Strategy /// doc /// Key [graphicIdeal, Saturate] Headline specifies saturation strategy to be used Usage graphicIdeal(..., Saturate => "all") graphicIdeal(..., Saturate => "each") SeeAlso Strategy /// doc /// Key [cycleIdeal, Saturate] Headline specifies saturation strategy to be used Usage cycleIdeal(..., Saturate => "all") cycleIdeal(..., Saturate => "each") SeeAlso Strategy /// doc /// Key [symbolicSlackMatrix, CoefficientRing] Headline specifies the coefficient ring of the underlying ring of the matrix Usage symbolicSlackMatrix(..., CoefficientRing => QQ) symbolicSlackMatrix(..., CoefficientRing => ZZ/7) symbolicSlackMatrix(..., CoefficientRing => GF(9)) SeeAlso coefficientRing /// doc /// Key [symbolicSlackOfPlucker, CoefficientRing] Headline specifies the coefficient ring of the underlying ring of the matrix Usage symbolicSlackOfPlucker(..., CoefficientRing => QQ) symbolicSlackOfPlucker(..., CoefficientRing => ZZ/7) symbolicSlackOfPlucker(..., CoefficientRing => GF(9)) SeeAlso coefficientRing /// doc /// Key [slackIdeal, CoefficientRing] Headline specifies the coefficient ring of the underlying ring of the ideal Usage slackIdeal(..., CoefficientRing => QQ) slackIdeal(..., CoefficientRing => ZZ/7) slackIdeal(..., CoefficientRing => GF(9)) SeeAlso coefficientRing /// doc /// Key [grassmannSectionIdeal, CoefficientRing] Headline specifies the coefficient ring of the underlying ring of the ideal Usage grassmannSectionIdeal(..., CoefficientRing => QQ) grassmannSectionIdeal(..., CoefficientRing => ZZ/7) grassmannSectionIdeal(..., CoefficientRing => GF(9)) SeeAlso coefficientRing /// doc /// Key [cycleIdeal, CoefficientRing] Headline specifies the coefficient ring of the underlying ring of the ideal Usage cycleIdeal(..., CoefficientRing => QQ) cycleIdeal(..., CoefficientRing => ZZ/7) cycleIdeal(..., CoefficientRing => GF(9)) SeeAlso coefficientRing /// doc /// Key [graphicIdeal, CoefficientRing] Headline specifies the coefficient ring of the underlying ring of the ideal Usage graphicIdeal(..., CoefficientRing => QQ) graphicIdeal(..., CoefficientRing => ZZ/7) graphicIdeal(..., CoefficientRing => GF(9)) SeeAlso coefficientRing /// doc /// Key [universalIdeal, CoefficientRing] Headline specifies the coefficient ring of the underlying ring of the ideal Usage universalIdeal(..., CoefficientRing => QQ) universalIdeal(..., CoefficientRing => ZZ/7) universalIdeal(..., CoefficientRing => GF(9)) SeeAlso coefficientRing /// doc /// Key [reconstructSlackMatrix, CoefficientRing] Headline specifies the coefficient ring of the underlying ring of the ideal Usage reconstructSlackMatrix(..., CoefficientRing => QQ) reconstructSlackMatrix(..., CoefficientRing => ZZ/7) reconstructSlackMatrix(..., CoefficientRing => GF(9)) SeeAlso coefficientRing /// doc /// Key [reducedSlackMatrix, CoefficientRing] Headline specifies the coefficient ring of the underlying ring of the ideal Usage reducedSlackMatrix(..., CoefficientRing => QQ) reducedSlackMatrix(..., CoefficientRing => ZZ/7) reducedSlackMatrix(..., CoefficientRing => GF(9)) SeeAlso coefficientRing /// doc /// Key Vars Headline give a set of variables for the polynomial ring where the object created will live Usage symbolicSlackMatrix(S, Vars => {x_1..x_10}) slackIdeal(V, Vars => {a..z}) cycleIdeal(M, Vars => {A, B, S, T}) graphicIdeal(P, Vars => {y_(1, 1)..y_(5, 4)}) universalIdeal(M, Vars => vars{3, 5, 7}) reconstructSlackMatrix(S, {{0,1,2}}, Vars => {x}) reducedSlackMatrix(S, Vars => {a,b,c,d,e,f,g,h,j,k,m,p}) Description Text This option is useful if you want to compare the object you will create with one in an existing ring. The default value is @{TT "{}"}@ which means the method will create the necessary variables (in a new ring) for the constructed object. SeeAlso symbolicSlackMatrix slackIdeal cycleIdeal graphicIdeal universalIdeal reconstructSlackMatrix reducedSlackMatrix PolynomialRing vars /// doc /// Key [symbolicSlackMatrix, Vars] Headline specifies the variables to use to create the underlying ring of the matrix Usage symbolicSlackMatrix(..., Vars => {x_1..x_10}) symbolicSlackMatrix(..., Vars => {a..z}) symbolicSlackMatrix(..., Vars => {y_(1, 1)..y_(3, 4)}) SeeAlso PolynomialRing vars /// doc /// Key [slackIdeal, Vars] Headline specifies the variables to use to create the underlying ring of the ideal Usage slackIdeal(..., Vars => {a..r}) slackIdeal(..., Vars => {y_1..y_6}) slackIdeal(..., Vars => {A, B, S, T}) SeeAlso PolynomialRing vars /// doc /// Key [cycleIdeal, Vars] Headline specifies the variables to use to create the underlying ring of the ideal Usage cycleIdeal(..., Vars => vars(13..54)) cycleIdeal(..., Vars => {x_(1, 1)..x_(4, 5)}) cycleIdeal(..., Vars => {y_3..y_9}) SeeAlso PolynomialRing vars /// doc /// Key [graphicIdeal, Vars] Headline specifies the variables to use to create the underlying ring of the ideal Usage graphicIdeal(..., Vars => {x_0..x_19}) graphicIdeal(..., Vars => {y_(1, 1)..y_(3, 2)}) graphicIdeal(..., Vars => {a..k}) SeeAlso PolynomialRing vars /// doc /// Key [universalIdeal, Vars] Headline specifies the variables to use to create the underlying ring of the ideal Usage universalIdeal(..., Vars => {P, Q, R, S}) universalIdeal(..., Vars => {a_0..a_12}) universalIdeal(..., Vars => vars(-10..-3)) SeeAlso PolynomialRing vars /// doc /// Key [reconstructSlackMatrix, Vars] Headline specifies the variables to use to create the underlying ring of the ideal Usage reconstructSlackMatrix(..., Vars => {x}) reconstructSlackMatrix(..., Vars => {a,b,c,d,e,f,g,h,j}) SeeAlso PolynomialRing vars /// doc /// Key [reducedSlackMatrix, Vars] Headline specifies the variables to use to create the underlying ring of the ideal Usage reducedSlackMatrix(..., Vars => {x}) reducedSlackMatrix(..., Vars => {a,b,c,d,e,f,g,h,j,k,m,p}) SeeAlso PolynomialRing vars /// doc /// Key Tolerance Headline choose the tolerance to approximate computations over the field RR Usage slackFromGaleCircuits(G, Tolerance => 12) Description Text The default value is 14. SeeAlso Strategy slackFromGaleCircuits /// doc /// Key [slackFromGaleCircuits, Tolerance] Headline specifies the tolerance to compute the slack matrix of a polytope from a Gale transform of a polytope Usage slackFromGaleCircuits(..., Tolerance => 12) SeeAlso Strategy /// doc /// Key FlagElement Headline a facet label that will be contained in a flag of facets of given polytope or matroid Usage findFlag(V, FlagElement => 3) Description Text The default value is 0. SeeAlso Object findFlag /// doc /// Key [findFlag, FlagElement] Headline a facet label that will be contained in a flag of facets of given polytope or matroid Usage findFlag(..., FlagElement => 3) SeeAlso Object /// doc /// Key FlagIndices Headline a list of facet labels that form a flag of facets of given polytope or matroid Usage containsFlag(V, FlagIndices => {0, 1, 2, 3}) Description Text The default value is 0. SeeAlso Object findFlag /// doc /// Key [reducedSlackMatrix, FlagIndices] Headline a list of facet labels that form a flag of facets of given polytope or matroid Usage reducedSlackMatrix(..., FlagIndices => {0, 1, 2, 3}) SeeAlso Object /// ------ TESTS ------ TEST /// V = {{0, 0}, {0, 1}, {1, 1}, {1, 0}} assert(slackMatrix V == matrix(QQ, {{0, 1, 0, 1}, {1, 0, 0, 1}, {0, 1, 1, 0}, {1, 0, 1, 0}})) assert(slackMatrix(V, Object => "matroid") == matrix {{-1, -1, 0, -1, 0, 0}, {-1, 0, 1, 0, 1, 0}, {0, 1, 1, 0, 0, -1}, {0, 0, 0, -1, -1, -1}}) C = posHull(matrix{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}) assert(slackMatrix C == matrix {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}) /// TEST /// V = {{0, 0}, {1, 0}, {2, 1}, {1, 2}, {0, 1}} assert(getFacetBases V == ({{0, 0}, {1, 0}, {0, 1}, {2, 1}, {1, 2}}, {{0, 2}, {0, 1}, {1, 3}, {2, 4}, {3, 4}})) /// TEST /// V = {{0, 0, 0}, {1, 0, 0}, {0, 1, 0}, {0, 0, 1}, {1, 0, 1}, {1, 1, 0}} B = {{1, 2, 4}, {0, 2, 3}, {0, 1, 4}, {3, 4, 5}, {0, 1, 2}} assert(slackFromPlucker(V, B) == matrix {{-1, 0, 0, -1, 0}, {0, 1, 0, -1, 0}, {0, 0, -1, 0, 0}, {-1, 0, 0, 0, 1}, {0, 1, 0, 0, 1}, {1, 1, -1, 0, 0}}) /// TEST /// MG = matrix(RR, {{0, 1, -1, 0, -1, 1}, {1, 0, -1, -1, 0, 1}}) B = {{1, 2, 4}, {0, 2, 3}, {0, 1, 4}, {3, 4, 5}, {0, 1, 2}} assert(slackFromGalePlucker(B, MG) == matrix(RR, {{1, 0, 0, 1, 0}, {0, -1, 0, 1, 0}, {0, 0, 1, 1, 0}, {1, 0, 0, 0, -1}, {0, -1, 0, 0, -1}, {0, 0, 1, 0, -1}})) /// TEST /// G = matrix(RR, {{0, 1, -1, 0, -1, 1}, {1, 0, -1, -1, 0, 1}}) assert(slackFromGaleCircuits G == matrix(RR, {{1, 0, 0, 1, 0}, {0, 1, 0, 1, 0}, {0, 0, 1, 1, 0}, {1, 0, 0, 0, 1}, {0, 1, 0, 0, 1}, {0, 0, 1, 0, 1}})) /// TEST /// assert(specificSlackMatrix "barnette" == matrix(RR, {{1, 0, 0, 0, 1, 1, 0}, {1, 0, 0, 0, 0, 1, 1}, {1, 0, 0, 1, 0, 0, 1}, {1, 0, 0, 1, 1, 0, 0}, {1, 0, 1, 0, 0, 0, 0}, {0, 1, 0, 0, 1, 1, 0}, {0, 1, 0, 0, 0, 1, 1}, {0, 1, 0, 1, 0, 0, 1}, {0, 1, 0, 1, 1, 0, 0}, {0, 1, 1, 0, 0, 0, 0}})) /// TEST /// V = {{0, 0}, {0, 1}, {1, 1}, {1, 0}} R = QQ[x_0..x_11] assert(substitute(symbolicSlackMatrix V, R) == matrix {{0, x_0, 0, x_1}, {x_2, 0, 0, x_3}, {0, x_4, x_5, 0}, {x_6, 0, x_7, 0}}) assert(substitute(symbolicSlackMatrix(V, Object => "matroid"), R) == matrix {{x_0, x_1, 0, x_2, 0, 0}, {x_3, 0, x_4, 0, x_5, 0}, {0, x_6, x_7, 0, 0, x_8}, {0, 0, 0, x_9, x_10, x_11}}) V = {{1, 2, 3}, {4, 5, 6}, {1, 2, 4, 5}, {1, 3, 4, 6}, {2, 3, 5, 6}} assert(substitute(symbolicSlackMatrix(V, Object => "abstractPolytope"), R) == matrix {{0, x_0, 0, 0, x_1}, {0, x_2, 0, x_3, 0}, {0, x_4, x_5, 0, 0}, {x_6, 0, 0, 0, x_7}, {x_8, 0, 0, x_9, 0}, {x_10, 0, x_11, 0, 0}}) /// TEST /// V = {{0, 0, 0}, {1, 0, 0}, {0, 1, 0}, {0, 0, 1}, {1, 0, 1}, {1, 1, 0}} B = {{1, 2, 4}, {0, 2, 3}, {0, 1, 4}, {3, 4, 5}, {0, 1, 2}} assert(symbolicSlackOfPlucker(V, B) == matrix {{-p_(0,1,2,4), 0, 0, -p_(0,3,4,5), 0}, {0, p_(0,1,2,3), 0, -p_(1,3,4,5), 0}, {0, 0, -p_(0,1,2,4), -p_(2,3,4,5), 0}, {-p_(1,2,3,4), 0, -p_(0,1,3,4), 0, p_(0,1,2,3)}, {0, p_(0,2,3,4), 0, 0, p_(0,1,2,4)}, {p_(1,2,4,5), p_(0,2,3,5), p_(0,1,4,5), 0, p_(0,1,2,5)}}) /// TEST /// V = {{0, 0}, {1, 0}, {1, 1}, {0, 1}} R = QQ[x_0..x_11] assert(substitute(slackIdeal V, R) == ideal(x_0*x_3*x_5*x_6-x_1*x_2*x_4*x_7)) assert(substitute(slackIdeal(V, Object => "matroid"), R) == ideal(x_4*x_8*x_10+x_5*x_7*x_11, x_1*x_8*x_9+x_2*x_6*x_11, x_0*x_5*x_9+x_2*x_3*x_10, x_0*x_4*x_6+x_1*x_3*x_7, x_1*x_3*x_8*x_10-x_0*x_5*x_6*x_11, x_0*x_4*x_8*x_9-x_2*x_3*x_7*x_11, x_1*x_5*x_7*x_9-x_2*x_4*x_6*x_10)) /// TEST /// V = {{0, 0}, {1, 0}, {2, 1}, {1, 2}, {0, 1}} (VV, B) = getFacetBases V R = QQ[p_(0,1,2), p_(0,1,3), p_(0,2,3), p_(1,2,3), p_(0,1,4), p_(0,2,4), p_(1,2,4), p_(0,3,4), p_(1,3,4), p_(2,3,4)] assert(substitute(grassmannSectionIdeal(VV, B), R) == substitute(ideal(p_(1,2,4)*p_(0,3,4)-p_(0,2,4)*p_(1,3,4)+p_(0,1,4)*p_(2,3,4), p_(1,2,3)*p_(0,3,4)-p_(0,2,3)*p_(1,3,4)+p_(0,1,3)*p_(2,3,4), p_(1,2,3)*p_(0,2,4)-p_(0,2,3)*p_(1,2,4)+p_(0,1,2)*p_(2,3,4), p_(1,2,3)*p_(0,1,4)-p_(0,1,3)*p_(1,2,4)+p_(0,1,2)*p_(1,3,4), p_(0,2,3)*p_(0,1,4)-p_(0,1,3)*p_(0,2,4)+p_(0,1,2)*p_(0,3,4)), R)) /// TEST /// V = {{0, 0}, {1, 0}, {1, 1}, {0, 1}} assert(graphFromSlackMatrix(symbolicSlackMatrix V) == matrix {{1, 1, 0, 0, 0, 0, 0, 0}, {0, 0, 1, 1, 0, 0, 0, 0}, {0, 0, 0, 0, 1, 1, 0, 0}, {0, 0, 0, 0, 0, 0, 1, 1}, {0, 0, 1, 0, 0, 0, 1, 0}, {1, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 0, 0, 0, 1, 0, 1}, {0, 1, 0, 1, 0, 0, 0, 0}}) /// TEST /// P = convexHull(matrix{{0, 0, 1, 1}, {0, 1, 0, 1}}) R = QQ[y_0..y_7] assert(substitute(graphicIdeal P, R) == ideal(y_0*y_3*y_5*y_6-y_1*y_2*y_4*y_7)) /// TEST /// V = {{0, 0}, {1, 0}, {1, 1}, {0, 1}} R = QQ[y_0..y_11] assert(substitute(cycleIdeal V, R) == ideal(y_0*y_3*y_5*y_6-y_1*y_2*y_4*y_7)) assert(substitute(cycleIdeal(V, Object => "matroid"), R) == ideal(y_4*y_8*y_10+y_5*y_7*y_11, y_1*y_8*y_9+y_2*y_6*y_11, y_0*y_5*y_9+y_2*y_3*y_10, y_0*y_4*y_6+y_1*y_3*y_7, y_1*y_3*y_8*y_10-y_0*y_5*y_6*y_11, y_0*y_4*y_8*y_9-y_2*y_3*y_7*y_11, y_1*y_5*y_7*y_9-y_2*y_4*y_6*y_10)) S = matrix{{1, 1, 0}, {0, 1, 2}, {1, 0, 3}} assert(substitute(cycleIdeal S, R) == ideal(3*y_1*y_3*y_4-2*y_0*y_2*y_5)) /// TEST /// V = {{0, 0}, {0, 1}, {1, 1}, {1, 0}} assert(toricPolytope(slackIdeal V) == matrix {{1, 0, 0, 0, 1, 0, 0, 0}, {0, 1, 0, 0, 0, 1, 0, 0}, {0, 0, 0, 0, 1, 1, 0, 0}, {0, 0, 0, 0, 1, 0, 1, 0}, {0, 0, 1, 0, -1, 0, 0, 0}, {0, 0, 0, 0, 0, 1, 0, 1}, {0, 0, 0, 1, 0, -1, 0, 0}}) /// TEST /// R = QQ[x_1..x_12] X = matrix {{0, x_1, 0, 0, x_2}, {x_3, 0, 0, 0, x_4}, {0, x_5, x_6, 0, 0}, {x_7, 0, x_8, 0, 0}, {0, x_9, 0, x_10, 0}, {x_11, 0, 0, x_12, 0}} assert(rehomogenizePolynomial(X, matrix {{0, 1, 0, 0, 1}, {1, 0, 0, 0, x_4}, {0, 1, 1, 0, 0}, {1, 0, x_8, 0, 0}, {0, 1, 0, 1, 0}, {1, 0, 0, 1, 0}}, graph(QQ[y_1..y_11], {{y_2, y_7}, {y_4, y_7}, {y_6, y_7}, {y_1, y_8}, {y_3, y_8}, {y_5, y_8}, {y_3, y_9}, {y_5, y_10}, {y_6, y_10}, {y_1, y_11}}), x_4^2+x_4*x_8-1) == x_1^2*x_4^2*x_6*x_7*x_10^2*x_11^2 + x_1*x_2*x_3*x_4*x_5*x_8*x_10^2*x_11^2 - x_2^2*x_3^2*x_6*x_7*x_9^2*x_12^2) /// TEST /// V = {{0, 0, 0}, {1, 0, 0}, {1, 1, 0}, {0, 1, 0}, {0, 0, 1}, {0, 1, 1}} R = QQ[x_0..x_11] assert(substitute(rehomogenizeIdeal(3, symbolicSlackMatrix V), R) == ideal(x_3*x_6*x_9*x_10-x_2*x_7*x_8*x_11, x_0*x_5*x_9*x_10-x_1*x_4*x_8*x_11, x_1*x_3*x_4*x_6-x_0*x_2*x_5*x_7)) Y = matrix {{0, 0, 1, 0, 1}, {1, 0, 1, 0, 0}, {0, x_4, 0, 0, 1}, {1, 1, 0, 0, 0}, {0, 0, 1, 1, 0}, {0, x_10, 0, 1, 0}} T = graph(QQ[y_0, y_1, y_2, y_3, y_4, y_5, y_6, y_7, y_8, y_9, y_10], {{y_1, y_6}, {y_3, y_6}, {y_3, y_7}, {y_0, y_8}, {y_1, y_8}, {y_4, y_8}, {y_4, y_9}, {y_5, y_9}, {y_0, y_10}, {y_2, y_10}}) assert(rehomogenizeIdeal(3, Y, T) == ideal(x_3*x_6*x_9*x_10-x_2*x_7*x_8*x_11, x_0*x_5*x_9*x_10-x_1*x_4*x_8*x_11, x_1*x_3*x_4*x_6-x_0*x_2*x_5*x_7)) /// TEST /// V = {{0,0,0},{0,0,1},{1,0,0},{1,0,1},{0,1,0},{0,1,1}} S = slackMatrix V assert(findFlag S == {0, 1, 2, 4}) assert(findFlag(V, Object => "matroid") == {0, 1, 5, 7}) assert(findFlag({{0, 2, 3, 5}, {0, 1, 3, 4}, {1, 2, 4, 5}, {0, 1, 2}, {3, 4, 5}}, Object => "abstractPolytope") == {0, 1, 2, 4}) /// TEST /// V = {{0, 0, 0}, {0, 0, 1}, {1, 0, 0}, {1, 0, 1}, {0, 1, 0}, {0, 1, 1}}; assert(containsFlag({0, 1, 2, 4}, V) == true) assert(containsFlag({0, 1, 2, 8}, V, Object => "matroid") == true) assert(containsFlag({0, 1, 2, 8}, V, Object => "matroid") == true) assert(containsFlag({0, 1, 2, 3}, {{0, 2, 3, 5}, {0, 1, 3, 4}, {1, 2, 4, 5}, {0, 1, 2}, {3, 4, 5}}, Object => "abstractPolytope") == true) /// TEST /// V = {{0,0,0},{0,0,1},{1,0,0},{1,0,1},{0,1,0},{0,1,1}} S = slackMatrix V redS = reducedSlackMatrix(S,Vars => {a,b,c,d,e,f,g,h,j,k,m,p}) R = ring redS assert(reconstructSlackMatrix(redS, {{0,1,2}}) == substitute(matrix {{0, 0, a, b, 0}, {c, 0, 0, d, 0}, {0, e, 0, f, 0}, {0, 0, g, 0, -b*c*e*g}, {h, 0, 0, 0, -a*d*e*h}, {0, j, 0, 0, -a*c*f*j}}, R)) assert(reconstructSlackMatrix(reducedSlackMatrix(3, S), {{0,1,2}}) == matrix(QQ, {{0, 0, 1, 1, 0}, {1, 0, 0, 1, 0}, {0, 1, 0, 1, 0}, {0, 0, 1, 0, -1}, {1, 0, 0, 0, -1}, {0, 1, 0, 0, -1}})) redS1 = reducedSlackMatrix(3, S) extS1 = reconstructSlackMatrix(redS1, {{0,1,2}}, Vars => {x}) T = ring extS1 assert(extS1 == substitute(matrix {{0, 0, x_0, x_1, 0}, {x_2, 0, 0, x_3, 0}, {0, x_4, 0, x_5, 0}, {0, 0, x_6, 0, -x_1*x_2*x_4*x_6}, {x_7, 0, 0, 0, -x_0*x_3*x_4*x_7}, {0, x_8, 0, 0, -x_0*x_2*x_5*x_8}}, T)) /// TEST /// V = {{0,0,0},{0,0,1},{1,0,0},{1,0,1},{0,1,0},{0,1,1}} S = slackMatrix V assert(reducedSlackMatrix V == matrix(QQ, {{0, 0, 1, 1}, {1, 0, 0, 1}, {0, 1, 0, 1}, {0, 0, 1, 0}, {1, 0, 0, 0}, {0, 1, 0, 0}})) R = QQ[x_0..x_8] assert(substitute(reducedSlackMatrix(S, Vars => {x}), R) == matrix {{0, 0, x_0, x_1}, {x_2, 0, 0, x_3}, {0, x_4, 0, x_5}, {0, 0, x_6, 0}, {x_7, 0, 0, 0}, {0, x_8, 0, 0}}) /// end restart loadPackage("SlackIdeals", Reload => true) uninstallPackage "SlackIdeals" installPackage "SlackIdeals" installPackage("SlackIdeals", RemakeAllDocumentation => true) viewHelp "SlackIdeals" check "SlackIdeals"