Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Addition of new presentations to Chow rings of matroids #39359

Open
wants to merge 25 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
5c4c89d
Updated new commits and added new presentations
25shriya Jan 21, 2025
1aabf83
Added presentation in chow_ring.py
25shriya Jan 21, 2025
7545335
Added doctests for atom-free presentation
25shriya Jan 21, 2025
af68b64
Added doctests for simplicial presentation and updated references
25shriya Jan 24, 2025
0eb7ec9
Debgged presetatios
25shriya Jan 27, 2025
78f067b
Debugged normal_basis() for simplicial presentation
25shriya Feb 1, 2025
b3dbeb2
Refactored poly_define()
25shriya Feb 1, 2025
c6960a1
Edited doctests for atom-free presentation of non augmented Chow ring…
25shriya Feb 2, 2025
80eded6
Edited doctests for chow_ring_ideal()
25shriya Feb 2, 2025
b687fe7
Corrected linting errors
25shriya Feb 2, 2025
86021da
Edited doctests for chow_ring.py
25shriya Feb 2, 2025
2026053
Corrected linting errors for chow_ring_ideal.py
25shriya Feb 2, 2025
b1fda09
Edited doctests in matroid.pyx
25shriya Feb 2, 2025
0a573cf
Added graded_character() method
25shriya Feb 2, 2025
03847c4
Debugged atom-free presentation
25shriya Feb 3, 2025
0b4a5be
Edited _acted_upon() doctest
25shriya Feb 3, 2025
78762f2
Merge branch 'sagemath:develop' into new_presentations
25shriya Feb 16, 2025
aa1111d
Added Hasse Diagram vertex removal for optimization
25shriya Feb 17, 2025
7b8266f
edited comments
25shriya Feb 17, 2025
ea89219
Resolved github issues
25shriya Feb 20, 2025
17d2cc7
Edited repr() tests
25shriya Feb 20, 2025
7f86b1b
Corrected doctests
25shriya Feb 20, 2025
9ac07c7
Corrected doctests
25shriya Feb 20, 2025
71256c7
Corrected doctests
25shriya Feb 20, 2025
6d69988
Added conftest.py
25shriya Feb 21, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/doc/en/reference/references/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,9 @@ REFERENCES:
.. [BeBo2009] Olivier Bernardi and Nicolas Bonichon, *Intervals in Catalan
lattices and realizers of triangulations*, JCTA 116 (2009)

.. [BES2024] Spencer Backman, Christopher Eur, and Connor Simpson. *Simplicial generation
of Chow rings of matroids*, 2024. :arxiv:`1905.07114`

.. [Best2021] Alex J. Best: Tools and Techniques for Rational Points on Curves.
PhD Thesis, Boston University, 2021.

Expand Down
200 changes: 139 additions & 61 deletions src/sage/matroids/chow_ring.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,46 @@
# https://www.gnu.org/licenses/
# ****************************************************************************

from sage.matroids.chow_ring_ideal import ChowRingIdeal_nonaug, AugmentedChowRingIdeal_fy, AugmentedChowRingIdeal_atom_free
from sage.matroids.chow_ring_ideal import ChowRingIdeal_nonaug_fy, ChowRingIdeal_nonaug_af, ChowRingIdeal_nonaug_sp, AugmentedChowRingIdeal_fy, AugmentedChowRingIdeal_atom_free
from sage.rings.quotient_ring import QuotientRing_generic
from sage.categories.kahler_algebras import KahlerAlgebras
from sage.categories.commutative_rings import CommutativeRings
from sage.misc.cachefunc import cached_method
from sage.modules.with_basis.representation import Representation_abstract


class ChowRing(QuotientRing_generic):
class ChowRing(QuotientRing_generic, Representation_abstract):
r"""
The Chow ring of a matroid.

The *Chow ring of the matroid* `M` is defined as the quotient ring
The *Chow ring of the matroid* `M` has three different presentations.

The *Feitchner-Yuzvinsky presentation* is the quotient ring

.. MATH::

A^*(M)_R := R[x_{F_1}, \ldots, x_{F_k}] / (I_M + J_M),

where `(I_M + J_M)` is the :class:`Chow ring ideal
<sage.matroids.chow_ring_ideal.ChowRingIdeal_nonaug_fy>` of matroid `M`.

The *atom-free presentation* is the quotient ring

.. MATH::

A^*(M)_R := R[x_{F_1}, \ldots, x_{F_k}] / (I_M + J_M + K_M),

where `(I_M + J_M + K_M)` is the :class:`Chow ring ideal
<sage.matroids.chow_ring_ideal.ChowRingIdeal_nonaug_af>` of matroid `M`.

The *simplicial presentation* is the quotient ring

.. MATH::

A^*(M)_R := R[x_{F_1}, \ldots, x_{F_k}] / (I_M + J_M),

where `(I_M + J_M)` is the :class:`Chow ring ideal
<sage.matroids.chow_ring_ideal.ChowRingIdeal_nonaug>` of matroid `M`.
<sage.matroids.chow_ring_ideal.ChowRingIdeal_nonaug_sp>` of matroid `M`.

The *augmented Chow ring of matroid* `M` has two different presentations
as quotient rings:
Expand Down Expand Up @@ -74,10 +95,10 @@
- ``augmented`` -- boolean; when ``True``, this is the augmented
Chow ring and if ``False``, this is the non-augmented Chow ring
- ``presentation`` -- string (default: ``None``); one of the following
(ignored if ``augmented=False``)

* ``"fy"`` - the Feitchner-Yuzvinsky presentation
* ``"atom-free"`` - the atom-free presentation
* ``"simplicial"`` - the simplicial presentation

REFERENCES:

Expand All @@ -87,53 +108,61 @@
EXAMPLES::

sage: M1 = matroids.catalog.P8pp()
sage: ch = M1.chow_ring(QQ, False)
sage: ch = M1.chow_ring(QQ, False, 'fy')
sage: ch
Chow ring of P8'': Matroid of rank 4 on 8 elements with 8 nonspanning circuits
over Rational Field
Chow ring of P8'': Matroid of rank 4 on 8 elements with 8 nonspanning
circuits in Feitchner-Yuzvinsky presentation over Rational Field
"""
def __init__(self, R, M, augmented, presentation=None):
r"""
Initialize ``self``.

EXAMPLES::

sage: ch = matroids.Wheel(3).chow_ring(QQ, False)
sage: ch = matroids.Wheel(3).chow_ring(QQ, False, 'fy')
sage: TestSuite(ch).run()
"""
self._matroid = M
self._augmented = augmented
self._presentation = presentation
if augmented is True:
if augmented:
if presentation == 'fy':
self._ideal = AugmentedChowRingIdeal_fy(M, R)
elif presentation == 'atom-free':
self._ideal = AugmentedChowRingIdeal_atom_free(M, R)
else:
self._ideal = ChowRingIdeal_nonaug(M, R)
if presentation == 'fy':
self._ideal = ChowRingIdeal_nonaug_fy(M, R)
if presentation == 'atom-free':
self._ideal = ChowRingIdeal_nonaug_af(M, R)
if presentation == 'simplicial':
self._ideal = ChowRingIdeal_nonaug_sp(M, R)
C = CommutativeRings().Quotients() & KahlerAlgebras(R)
QuotientRing_generic.__init__(self, R=self._ideal.ring(),
I=self._ideal,
names=self._ideal.ring().variable_names(),
category=C)
Representation_abstract.__init__(self, semigroup=M.automorphism_group(), side="left")

def _repr_(self):
r"""
EXAMPLES::

sage: M1 = matroids.catalog.Fano()
sage: ch = M1.chow_ring(QQ, False)
sage: ch = M1.chow_ring(QQ, False, 'fy')
sage: ch
Chow ring of Fano: Binary matroid of rank 3 on 7 elements, type (3, 0)
over Rational Field
Chow ring of Fano: Binary matroid of rank 3 on 7 elements,
type (3, 0) in Feitchner-Yuzvinsky presentation over Rational Field
"""
output = "Chow ring of {}".format(self._matroid)
if self._augmented is True:
if self._augmented:
output = "Augmented " + output
if self._presentation == 'fy':
output += " in Feitchner-Yuzvinsky presentation"
elif self._presentation == 'atom-free':
output += " in atom-free presentation"
if self._presentation == 'fy':
output += " in Feitchner-Yuzvinsky presentation"
elif self._presentation == 'atom-free':
output += " in atom-free presentation"
elif self._presentation == 'simplicial':
output += " in simplicial presentation"
return output + " over " + repr(self.base_ring())

def _latex_(self):
Expand All @@ -143,7 +172,7 @@
EXAMPLES::

sage: M1 = matroids.Uniform(2, 5)
sage: ch = M1.chow_ring(QQ, False)
sage: ch = M1.chow_ring(QQ, False, 'fy')
sage: ch._latex_()
'A(\\begin{array}{l}\n\\text{\\texttt{U(2,{ }5):{ }Matroid{ }of{ }rank{ }2{ }on{ }5{ }elements{ }with{ }circuit{-}closures}}\\\\\n\\text{\\texttt{{\\char`\\{}2:{ }{\\char`\\{}{\\char`\\{}0,{ }1,{ }2,{ }3,{ }4{\\char`\\}}{\\char`\\}}{\\char`\\}}}}\n\\end{array})_{\\Bold{Q}}'
"""
Expand Down Expand Up @@ -172,7 +201,7 @@

TESTS::

sage: ch = matroids.Wheel(3).chow_ring(QQ, False)
sage: ch = matroids.Wheel(3).chow_ring(QQ, False, 'atom-free')
sage: ch._coerce_map_from_base_ring() is None
True
"""
Expand All @@ -186,14 +215,14 @@

sage: ch = matroids.Uniform(3, 6).chow_ring(QQ, True, 'fy')
sage: ch.basis()
Family (1, B1, B1*B012345, B0, B0*B012345, B01, B01^2, B2,
B2*B012345, B02, B02^2, B12, B12^2, B3, B3*B012345, B03, B03^2,
B13, B13^2, B23, B23^2, B4, B4*B012345, B04, B04^2, B14, B14^2,
B24, B24^2, B34, B34^2, B5, B5*B012345, B05, B05^2, B15, B15^2,
B25, B25^2, B35, B35^2, B45, B45^2, B012345, B012345^2, B012345^3)
Family (1, B02, B02*A5, B01, B01*A5, B13, B13^2, B03, B03*A5, B14,
B14^2, B25, B25^2, B04, B04*A5, B15, B15^2, B34, B34^2, B012345,
B012345^2, B05, B05*A5, B23, B23^2, B35, B35^2, A0, A0^2, A2, A2^2,
B12, B12*A5, B24, B24^2, B45, B45^2, A1, A1^2, A3, A3^2, A4, A4^2,
A5, A5^2, A5^3)
sage: set(ch.defining_ideal().normal_basis()) == set(ch.basis())
True
sage: ch = matroids.catalog.Fano().chow_ring(QQ, False)
sage: ch = matroids.catalog.Fano().chow_ring(QQ, False, 'fy')
sage: ch.basis()
Family (1, Abcd, Aace, Aabf, Adef, Aadg, Abeg, Acfg, Aabcdefg,
Aabcdefg^2)
Expand All @@ -219,7 +248,7 @@

EXAMPLES::

sage: ch = matroids.catalog.P8pp().chow_ring(QQ, False)
sage: ch = matroids.catalog.P8pp().chow_ring(QQ, False, 'fy')
sage: ch.lefschetz_element()
-2*Aab - 2*Aac - 2*Aad - 2*Aae - 2*Aaf - 2*Aag - 2*Aah - 2*Abc
- 2*Abd - 2*Abe - 2*Abf - 2*Abg - 2*Abh - 2*Acd - 2*Ace - 2*Acf
Expand All @@ -236,7 +265,7 @@
It is then multiplied with the elements of FY-monomial bases of
different degrees::

sage: ch = matroids.Uniform(4, 5).chow_ring(QQ, False)
sage: ch = matroids.Uniform(4, 5).chow_ring(QQ, False, 'fy')
sage: basis_deg = {}
sage: for b in ch.basis():
....: deg = b.homogeneous_degree()
Expand Down Expand Up @@ -325,14 +354,36 @@
new_el += hom_components1[i] * hom_components2[r - i]
return new_el.degree()

def graded_character(self, G=None):
r"""
Return the graded character of ``self`` as a representation of the
automorphism group of the defining matroid.

EXAMPLES::

sage: ch = matroids.Z(3).chow_ring(QQ, False, 'simplicial')
sage: gchi = ch.graded_character(); gchi
(q^2 + 8*q + 1, q^2 + 8*q + 1, q^2 + 8*q + 1, q^2 + 8*q + 1,
q^2 + 8*q + 1, q^2 + 8*q + 1)
"""
if G is None:
G = self._matroid.automorphism_group()
from sage.rings.rational_field import QQ
q = QQ['q'].gen()
B = self.basis()
from sage.modules.free_module_element import vector
return vector([sum(q**b.degree() * (g * b).lift().monomial_coefficient(b.lift()) for b in B)
for g in G.conjugacy_classes_representatives()],
immutable=True)

class Element(QuotientRing_generic.Element):
def to_vector(self, order=None):
r"""
Return ``self`` as a (dense) free module vector.

EXAMPLES::

sage: ch = matroids.Uniform(3, 6).chow_ring(QQ, False)
sage: ch = matroids.Uniform(3, 6).chow_ring(QQ, False, 'fy')
sage: v = ch.an_element(); v
-A01 - A02 - A03 - A04 - A05 - A012345
sage: v.to_vector()
Expand Down Expand Up @@ -372,7 +423,7 @@

EXAMPLES::

sage: ch = matroids.Uniform(3, 6).chow_ring(QQ, False)
sage: ch = matroids.Uniform(3, 6).chow_ring(QQ, False, 'fy')
sage: for b in ch.basis():
....: print(b, b.degree())
1 0
Expand Down Expand Up @@ -407,46 +458,45 @@
EXAMPLES::

sage: ch = matroids.catalog.Fano().chow_ring(QQ, True, 'fy')
sage: for b in ch.basis():

Check failure on line 461 in src/sage/matroids/chow_ring.py

View workflow job for this annotation

GitHub Actions / test-new

Failed example:

Failed example:: Got: 1 0 Babf 1 Babf*Ae 2 Bace 1 Bace*Ae 2 Badg 1 Badg*Ae 2 Bbcd 1 Bbcd*Ae 2 Ab 1 Ab^2 2 Bbeg 1 Bbeg*Ae 2 Ag 1 Ag^2 2 Bcfg 1 Bcfg*Ae 2 Babcdefg 1 Babcdefg^2 2 Ad 1 Ad^2 2 Bdef 1 Bdef*Ae 2 Aa 1 Aa^2 2 Ac 1 Ac^2 2 Af 1 Af^2 2 Ae 1 Ae^2 2 Ae^3 3
....: print(b, b.homogeneous_degree())
1 0
Ba 1
Ba*Babcdefg 2
Bb 1
Bb*Babcdefg 2
Bc 1
Bc*Babcdefg 2
Bd 1
Bd*Babcdefg 2
Bbcd 1
Bbcd^2 2
Be 1
Be*Babcdefg 2
Bace 1
Bace^2 2
Bf 1
Bf*Babcdefg 2
Babf 1
Babf^2 2
Bdef 1
Bdef^2 2
Bg 1
Bg*Babcdefg 2
Babf*Ae 2
Bace 1
Bace*Ae 2
Badg 1
Badg^2 2
Badg*Ae 2
Bbcd 1
Bbcd*Ae 2
Aa 1
Aa^2 2
Bbeg 1
Bbeg^2 2
Bbeg*Ae 2
Ac 1
Ac^2 2
Bcfg 1
Bcfg^2 2
Bcfg*Ae 2
Babcdefg 1
Babcdefg^2 2
Babcdefg^3 3
Af 1
Af^2 2
Bdef 1
Bdef*Ae 2
Ad 1
Ad^2 2
Ag 1
Ag^2 2
Ab 1
Ab^2 2
Ae 1
Ae^2 2
Ae^3 3
sage: v = sum(ch.basis()); v

Check failure on line 495 in src/sage/matroids/chow_ring.py

View workflow job for this annotation

GitHub Actions / test-new

Failed example:

Failed example:: Got: Ae^3 + Babcdefg^2 + Ag^2 + Aa^2 + Ab^2 + Ac^2 + Af^2 + Ad^2 + Babf*Ae + Bace*Ae + Badg*Ae + Bbcd*Ae + Bbeg*Ae + Bcfg*Ae + Bdef*Ae + Ae^2 + Babf + Bace + Badg + Bbcd + Bbeg + Bcfg + Bdef + Babcdefg + Ag + Aa + Ab + Ac + Af + Ad + Ae + 1
Babcdefg^3 + Babf^2 + Bace^2 + Badg^2 + Bbcd^2 + Bbeg^2 +
Bcfg^2 + Bdef^2 + Ba*Babcdefg + Bb*Babcdefg + Bc*Babcdefg +
Bd*Babcdefg + Be*Babcdefg + Bf*Babcdefg + Bg*Babcdefg +
Babcdefg^2 + Ba + Bb + Bc + Bd + Be + Bf + Bg + Babf + Bace +
Badg + Bbcd + Bbeg + Bcfg + Bdef + Babcdefg + 1
Ae^3 + Babcdefg^2 + Ac^2 + Ad^2 + Aa^2 + Ag^2 + Ab^2 + Af^2 +
Babf*Ae + Bace*Ae + Badg*Ae + Bbcd*Ae + Bbeg*Ae + Bcfg*Ae +
Bdef*Ae + Ae^2 + Babf + Bace + Badg + Bbcd + Bbeg + Bcfg +
Bdef + Babcdefg + Ac + Ad + Aa + Ag + Ab + Af + Ae + 1
sage: v.homogeneous_degree()
Traceback (most recent call last):
...
Expand All @@ -466,3 +516,31 @@
if not f.is_homogeneous():
raise ValueError("element is not homogeneous")
return f.degree()

def _acted_upon_(self, scalar, self_on_left=True):
r"""
Return the action of ``scalar`` on ``self``.

EXAMPLES::

sage: ch = matroids.catalog.P8pp().chow_ring(QQ, False, 'atom-free')
sage: y = ch.an_element(); y
Aab
sage: semigroup = ch.semigroup()
sage: x = semigroup.an_element(); x

Check failure on line 530 in src/sage/matroids/chow_ring.py

View workflow job for this annotation

GitHub Actions / test-new

Failed example:

Failed example:: Got: ('g','b')('a','h')('c','f')('d','e')
('c','h','d','e','a','f','b','g')
sage: x * y # indirect doctest
Aab
"""
P = self.parent()
if scalar in P.base_ring():
return super()._acted_upon_(scalar, self_on_left)
if scalar in P._matroid.automorphism_group():
gens = P.ambient().gens()
return P.retract(self.lift().subs({g: gens[scalar(i+1)-1] for i, g in enumerate(gens)}))
if not self_on_left and scalar in P._matroid.automorphism_group():
scalar = P._semigroup_algebra(scalar)
gens = P.ambient().gens()
return P.sum(c * P.retract(self.lift().subs({g: gens[sigma(i+1)-1] for i, g in enumerate(gens)}))
for sigma, c in scalar.monomial_coefficients(copy=False).items())
return super()._acted_upon_(scalar, self_on_left)
Loading
Loading