Skip to content

Commit

Permalink
Fixing issues with the Tor computation.
Browse files Browse the repository at this point in the history
  • Loading branch information
tscrim committed Jan 24, 2025
1 parent 0e736da commit f1733e9
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 25 deletions.
61 changes: 46 additions & 15 deletions src/sage/matroids/tor_algebra.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,14 @@ def __init__(self, R, M):

self._matroid = M
E = tuple(M.groundset())
ordering = {e: i for i, e in enumerate(E)} # used in case E has incomparable elements
n = E[-1]
bases = M.bases()

# get the squarefree basis elements
# we can skip the full groundset (which necessarily has full rank)
sf_basis = [X for k in range(len(E)) for X in combinations(E, k) if not any(B.issubset(frozenset(X)) for B in bases)]
#max_comp = []
#print(sf_basis)
sf_basis = [X for k in range(len(E)) for X in combinations(E, k)
if not any(B.issubset(frozenset(X)) for B in bases)]
lin_basis = []
comp_max = []
for i, X in enumerate(sf_basis):
Expand All @@ -70,38 +70,69 @@ def __init__(self, R, M):
comp_max.append(comp.pop())
lin_basis.append(tuple(comp))

#print(comp_max)
#print(lin_basis)

# construct the Kozsul complex
diffs = {}
cur_basis = {(X, ()): i for i,X in enumerate(sf_basis)}
for k in range(1, len(E)):
print(cur_basis)
prev_basis = cur_basis
cur_basis = {}
rows = []
for X, L, comp in zip(sf_basis, lin_basis, comp_max):
for Y in combinations(L, k):
cur_basis[X,Y] = len(cur_basis)
row = [0] * len(prev_basis)

for j in range(k):
# compute multipliciation by x_i from (x_i - x_{\ell_+})
assert Y[j] not in X
Yp = Y[:j] + Y[j+1:]
Xp = tuple(sorted(X + (Y[j],)))
try:
row[prev_basis[Xp,Yp]] -= (-1) ** j
except KeyError:
#print("bad first term")
pass
Xp = tuple(sorted(X + (comp,)))
Xp = tuple(sorted(X + (Y[j],), key=ordering.__getitem__))
try:
row[prev_basis[Xp,Yp]] += (-1) ** j
except KeyError:
#print("bad second term")
# Xp goes to 0, nothing more to do for this term
pass

# Compute the multiplication by all x_{\ell_+} from the entire
# wedge product. We need to do this separately since
# we need to combine the factors in different ways.
# If new_comp in Y, then this will be (-1)^deg (Y \ new_comp)
# Otherwise we use the following fact:
# d[(a1 - an) ^ (a2 - an) ^ ... ^ (ak - an)] = d[a1 ^ a2 ^ ... ^ ak]
# For example:
# sage: E.<a,b,c,d,e> = ExteriorAlgebra(QQ)
# sage: (b+e)*(c+e) - (a+e)*(c+e) + (a+e)*(b+e)
# a*b - a*c + b*c
# sage: (b+e)*(c+e)*(d+e) - (a+e)*(c+e)*(d+e) + (a+e)*(b+e)*(d+e) - (a+e)*(b+e)*(c+e)
# -a*b*c + a*b*d - a*c*d + b*c*d
# sage: e - (a+e)
# -a
# sage: (b+e)*e - (a+e)*e + (a+e)*(b+e)
# a*b
# sage: (b+e)*(c+e)*e - (a+e)*(c+e)*e + (a+e)*(b+e)*e - (a+e)*(b+e)*(c+e)
# -a*b*c

Xp = tuple(sorted(X + (comp,), key=ordering.__getitem__))
try:
ind = sf_basis.index(Xp)
except ValueError:
# Xp goes to 0, nothing more to do
rows.append(row)
continue
new_comp = comp_max[ind]
assert ordering[new_comp] < ordering[comp], (new_comp, comp, X, Y)
if new_comp in Y:
assert Y[-1] == new_comp
Yp = Y[:-1]
row[prev_basis[Xp,Yp]] -= (-1) ** len(Yp)
else:
for j in range(k):
Yp = Y[:j] + Y[j+1:]
row[prev_basis[Xp,Yp]] -= (-1) ** j

rows.append(row)
diffs[k] = matrix(R, rows).transpose()

self._kozsul_complex = ChainComplex(diffs, degree_of_differential=-1)
self._cohomology = self._kozsul_complex.homology()

Expand Down
42 changes: 32 additions & 10 deletions src/sage/topology/simplicial_complex.py
Original file line number Diff line number Diff line change
Expand Up @@ -3526,18 +3526,44 @@ def _stanley_reisner_base_ring(self, base_ring=ZZ):
EXAMPLES::
sage: X = SimplicialComplex([[1,2], [0], [3]])
sage: X._stanley_reisner_base_ring()
sage: X._stanley_reisner_base_ring()[0]
Multivariate Polynomial Ring in x0, x1, x2, x3 over Integer Ring
sage: Y = SimplicialComplex([['a', 'b', 'c']])
sage: Y._stanley_reisner_base_ring(base_ring=QQ)
sage: Y._stanley_reisner_base_ring(base_ring=QQ)[0]
Multivariate Polynomial Ring in a, b, c over Rational Field
sage: Fano = matroids.catalog.Fano()
sage: Z = Fano.lattice_of_flats().order_complex()
sage: Z._stanley_reisner_base_ring(base_ring=QQ)[0]
Multivariate Polynomial Ring in x0, x1, x2, x3, x4, x5, x6, x7, x8,
x9, x10, x11, x12, x13, x14, x15 over Rational Field
sage: Z._stanley_reisner_base_ring(base_ring=QQ)[1]
{frozenset(): 0,
frozenset({'d', 'e', 'f'}): 1,
frozenset({'a', 'c', 'e'}): 2,
frozenset({'b'}): 3,
frozenset({'c'}): 4,
frozenset({'g'}): 5,
frozenset({'a', 'b', 'f'}): 6,
frozenset({'b', 'c', 'd'}): 7,
frozenset({'f'}): 8,
frozenset({'a', 'd', 'g'}): 9,
frozenset({'c', 'f', 'g'}): 10,
frozenset({'e'}): 11,
frozenset({'b', 'e', 'g'}): 12,
frozenset({'a'}): 13,
frozenset({'d'}): 14,
frozenset({'a', 'b', 'c', 'd', 'e', 'f', 'g'}): 15}
"""
verts = self._gen_dict.values()
try:
verts = sorted(verts)
except TypeError:
verts = sorted(verts, key=str)
return PolynomialRing(base_ring, verts)
mapping = {v: i for i, v in enumerate(verts)}
try:
return PolynomialRing(base_ring, verts), mapping
except ValueError: # non alphanumeric variable names
return PolynomialRing(base_ring, 'x', len(verts)), mapping

def stanley_reisner_ring(self, base_ring=ZZ):
"""
Expand Down Expand Up @@ -3583,13 +3609,9 @@ def stanley_reisner_ring(self, base_ring=ZZ):
sage: Y.stanley_reisner_ring(base_ring=QQ)
Multivariate Polynomial Ring in x0, x1, x2, x3, x4 over Rational Field
"""
R = self._stanley_reisner_base_ring(base_ring)
products = []
for f in self.minimal_nonfaces():
prod = 1
for v in f:
prod *= R(self._gen_dict[v])
products.append(prod)
R, mapping = self._stanley_reisner_base_ring(base_ring)
products = [R.prod(R.gen(mapping[self._gen_dict[v]]) for v in f)
for f in self.minimal_nonfaces()]
return R.quotient(products)

def alexander_dual(self, is_mutable=True):
Expand Down

0 comments on commit f1733e9

Please sign in to comment.