From 7545335ee11998a3bf7026b2452c1e0c790835a3 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Tue, 21 Jan 2025 16:35:35 +0530 Subject: [PATCH] Added doctests for atom-free presentation --- src/sage/matroids/chow_ring.py | 2 +- src/sage/matroids/chow_ring_ideal.py | 155 +++++++++++++++++++++++++-- 2 files changed, 150 insertions(+), 7 deletions(-) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index 53f008f5a8a..23db567168e 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -92,7 +92,7 @@ class ChowRing(QuotientRing_generic): Chow ring of P8'': Matroid of rank 4 on 8 elements with 8 nonspanning circuits over Rational Field """ - def __init__(self, R, M, augmented, presentation=None): + def __init__(self, R, M, augmented, presentation='fy'): r""" Initialize ``self``. diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index 75b20e76146..9472d9e4ffa 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -137,14 +137,14 @@ class ChowRingIdeal_nonaug_fy(ChowRingIdeal): Chow ring ideal of uniform matroid of rank 3 on 6 elements:: - sage: ch = matroids.Uniform(3, 6).chow_ring(QQ, False) + sage: ch = matroids.Uniform(3, 6).chow_ring(QQ, False, 'fy') sage: ch.defining_ideal() Chow ring ideal of U(3, 6): Matroid of rank 3 on 6 elements with circuit-closures {3: {{0, 1, 2, 3, 4, 5}}} - non augmented - sage: ch = matroids.catalog.Fano().chow_ring(QQ, False) + sage: ch = matroids.catalog.Fano().chow_ring(QQ, False, 'fy') sage: ch.defining_ideal() Chow ring ideal of Fano: Binary matroid of rank 3 on 7 elements, - type (3, 0) - non augmented + type (3, 0) - non augmented in Feitchner-Yuzvinsky presentation """ def __init__(self, M, R): r""" @@ -152,7 +152,7 @@ def __init__(self, M, R): EXAMPLES:: - sage: I = matroids.catalog.Fano().chow_ring(QQ, False).defining_ideal() + sage: I = matroids.catalog.Fano().chow_ring(QQ, False, 'fy').defining_ideal() sage: TestSuite(I).run(skip="_test_category") """ self._matroid = M @@ -342,7 +342,69 @@ def normal_basis(self, algorithm='', *args, **kwargs): return PolynomialSequence(R, [monomial_basis]) class ChowRingIdeal_nonaug_af(ChowRingIdeal): + r""" + The Chow ring ideal of a matroid `M` in atom-free presentation. + + The *Chow ring ideal* for a matroid `M` in atom-free presentation + is defined as the ideal `(I_M + J_M + K_M)` of the polynomial ring + + .. MATH:: + + R[x_{F_1}, \ldots, x_{F_k}], + + where + + - `F_1, \ldots, F_k` are flats of `M` of at least rank 2, + - `I_M` is the ideal generated by products `x_{F_i} x_{F_j}` for + incomparable flats `F_i` and `F_j`, + - `J_M` is the ideal generated by all linear forms + + .. MATH:: + + x_F \sum_{F' \superseteq F \vee i} x_{F'} + + for all flats `F` and `i` in `E - F`, where `E` is the groundset of + the matroid, and + - `K_M` is the ideal generated by all quadratic forms + + .. MATH:: + + \sum_{F \superseteq i \vee j} x_F^2 + \sum_{F' \superset F \superseteq i \vee j} 2 x_F x_{F'} + + for all elements `i, j` in `E`, such that `i \neq j`. + + INPUT: + + - ``M`` -- matroid + - ``R`` -- commutative ring + + REFERENCES: + + - [MM2022]_ + + EXAMPLES: + + Chow ring ideal of uniform matroid of rank 3 on 6 elements:: + + sage: ch = matroids.Uniform(3, 6).chow_ring(QQ, False, 'atom-free') + sage: ch.defining_ideal() + Chow ring ideal of U(3, 6): Matroid of rank 3 on 6 elements with + circuit-closures {3: {{0, 1, 2, 3, 4, 5}}} - non augmented in the + atom-free presentation + sage: ch = matroids.catalog.Fano().chow_ring(QQ, False) + sage: ch.defining_ideal() + Chow ring ideal of Fano: Binary matroid of rank 3 on 7 elements, + type (3, 0) - non augmented in the atom-free presentation + """ def __init__(self, M, R): + r""" + Initialize ``self``. + + EXAMPLES:: + + sage: I = matroids.catalog.Fano().chow_ring(QQ, False, 'atom-free').defining_ideal() + sage: TestSuite(I).run(skip="_test_category") + """ self._matroid = M flats = [X for i in range(2, self._matroid.rank() + 1) for X in self._matroid.flats(i)] @@ -356,6 +418,45 @@ def __init__(self, M, R): MPolynomialIdeal.__init__(self, poly_ring, self._gens_constructor(poly_ring)) def _gens_constructor(self, poly_ring): + r""" + Return the generators of ``self``. + + EXAMPLES:: + + sage: ch = matroids.catalog.NonFano().chow_ring(QQ, False) + sage: sorted(ch.defining_ideal()._gens_constructor(ch.defining_ideal().ring())) + [0, Adef*Aabcdefg, Adef*Aabcdefg, Adef*Aabcdefg, 4*Adef*Aabcdefg, + Acfg*Aabcdefg, Acfg*Aabcdefg, Acfg*Aabcdefg, 4*Acfg*Aabcdefg, + Abeg*Aabcdefg, Abeg*Aabcdefg, Abeg*Aabcdefg, 4*Abeg*Aabcdefg, + Abcd*Aabcdefg, Abcd*Aabcdefg, Abcd*Aabcdefg, 4*Abcd*Aabcdefg, + Aadg*Aabcdefg, Aadg*Aabcdefg, Aadg*Aabcdefg, + Aadg*Aabcdefg + Abeg*Aabcdefg + Acfg*Aabcdefg, + Aadg*Aabcdefg + Abcd*Aabcdefg + Adef*Aabcdefg, + 4*Aadg*Aabcdefg, Aace*Aabcdefg, Aace*Aabcdefg, Aace*Aabcdefg, + Aace*Aabcdefg + Abeg*Aabcdefg + Adef*Aabcdefg, + Aace*Aabcdefg + Abcd*Aabcdefg + Acfg*Aabcdefg, + 4*Aace*Aabcdefg, Aabf*Aabcdefg, Aabf*Aabcdefg, Aabf*Aabcdefg, + Aabf*Aabcdefg + Acfg*Aabcdefg + Adef*Aabcdefg, + Aabf*Aabcdefg + Abcd*Aabcdefg + Abeg*Aabcdefg, + Aabf*Aabcdefg + Aace*Aabcdefg + Aadg*Aabcdefg, 4*Aabf*Aabcdefg, + Adef^2 + Aabcdefg^2, Adef^2 + Aabcdefg^2, Adef^2 + Aabcdefg^2, + Acfg*Adef, Abeg*Adef, Abcd*Adef, Aadg*Adef, Aace*Adef, Aabf*Adef, + Acfg^2 + Aabcdefg^2, Acfg^2 + Aabcdefg^2, Acfg^2 + Aabcdefg^2, + Abeg*Acfg, Abcd*Acfg, Aadg*Acfg, Aace*Acfg, Aabf*Acfg, + Abeg^2 + Aabcdefg^2, Abeg^2 + Aabcdefg^2, Abeg^2 + Aabcdefg^2, + Abcd*Abeg, Aadg*Abeg, Aace*Abeg, Aabf*Abeg, Abcd^2 + Aabcdefg^2, + Abcd^2 + Aabcdefg^2, Abcd^2 + Aabcdefg^2, Aadg*Abcd, Aace*Abcd, + Aabf*Abcd, Aadg^2 + Aabcdefg^2, Aadg^2 + Aabcdefg^2, + Aadg^2 + Aabcdefg^2, Aadg^2 + Abeg^2 + Acfg^2 + Aabcdefg^2, + Aadg^2 + Abcd^2 + Adef^2 + Aabcdefg^2, Aace*Aadg, Aabf*Aadg, + Aace^2 + Aabcdefg^2, Aace^2 + Aabcdefg^2, Aace^2 + Aabcdefg^2, + Aace^2 + Abeg^2 + Adef^2 + Aabcdefg^2, + Aace^2 + Abcd^2 + Acfg^2 + Aabcdefg^2, Aabf*Aace, + Aabf^2 + Aabcdefg^2, Aabf^2 + Aabcdefg^2, + Aabf^2 + Aabcdefg^2, Aabf^2 + Acfg^2 + Adef^2 + Aabcdefg^2, + Aabf^2 + Abcd^2 + Abeg^2 + Aabcdefg^2, + Aabf^2 + Aace^2 + Aadg^2 + Aabcdefg^2] + """ E = list(self._matroid.groundset()) flats = list(self._flats_generator) lattice_flats = Poset((flats, lambda x, y: x <= y)) @@ -387,13 +488,57 @@ def _gens_constructor(self, poly_ring): return I + J + K def _repr_(self): + r""" + Return a string representation of ``self``. + + EXAMPLES:: + + sage: ch = matroids.catalog.Fano().chow_ring(QQ, False, 'atom-free') + sage: ch.defining_ideal() + Chow ring ideal of Fano: Binary matroid of rank 3 on 7 elements, + type (3, 0) - non augmented in the atom-free presentation + """ return "Chow ring ideal of {} - non augmented in the atom-free presentation".format(self._matroid) def _latex_(self): + r""" + Return a LaTeX representation of ``self``. + + EXAMPLES:: + + sage: M1 = Matroid(groundset='abcd', bases=['ab','ad', 'bc']) + sage: ch = M1.chow_ring(QQ, False, 'atom-free') + sage: ch.defining_ideal()._latex_() + '(I_{\\text{\\texttt{Matroid{ }of{ }rank{ }2{ }on{ }4{ }elements{ }with{ }3{ }bases}}} + J_{\\text{\\texttt{Matroid{ }of{ }rank{ }2{ }on{ }4{ }elements{ }with{ }3{ }bases}}} + K_{\\text{\\texttt{Matroid{ }of{ }rank{ }2{ }on{ }4{ }elements{ }with{ }3{ }bases}}}' + """ from sage.misc.latex import latex return '(I_{{{M}}} + J_{{{M}}} + K_{{{M}}}'.format(M=latex(self._matroid)) def groebner_basis(self, algorithm = '', *args, **kwargs): + r""" + Return a Groebner basis of ``self``. + + EXAMPLES:: + + sage: ch = matroids.catalog.Fano().chow_ring(QQ, False, 'atom-free') + sage: ch.defining_ideal().groebner_basis() + Polynomial Sequence with 36 Polynomials in 8 Variables + sage: ch.defining_ideal().groebner_basis().is_groebner() + True + sage: ch.defining_ideal().hilbert_series() == ch.defining_ideal().gens().ideal().hilbert_series() + True + + Another example would be the Groebner basis of the Chow ring ideal of + the matroid of the length 3 cycle graph:: + + sage: ch = Matroid(graphs.CycleGraph(3)).chow_ring(QQ, False, 'atom-free') + sage: ch.defining_ideal().groebner_basis() + [A^2] + sage: ch.defining_ideal().groebner_basis().is_groebner() + True + sage: ch.defining_ideal().hilbert_series() == ch.defining_ideal().gens().ideal().hilbert_series() + True + """ if algorithm == '': algorithm = 'constructed' if algorithm != 'constructed': @@ -412,7 +557,6 @@ def groebner_basis(self, algorithm = '', *args, **kwargs): term = poly_ring.zero() for F in lattice_flats.order_filter([subset[1]]): term += flats_gen[F] - print(subset) gb.append(flats_gen[subset[0]] * (term ** (ranks[subset[1]] - ranks[subset[0]]))) for F in flats: term = poly_ring.zero() @@ -449,7 +593,6 @@ def normal_basis(self, algorithm = '', *args, **kwargs): expression = R.one() for val, c in zip(subset, combination): expression *= flats_gen[val] ** c - print(subset, expression, combination) monomial_basis.append(expression) return PolynomialSequence(R, [monomial_basis])