Skip to content

Commit b28c9f4

Browse files
committed
Implement matrix Schubert variety ideals.
1 parent 7ef5433 commit b28c9f4

File tree

3 files changed

+132
-8
lines changed

3 files changed

+132
-8
lines changed

src/doc/en/reference/references/index.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2812,6 +2812,9 @@ REFERENCES:
28122812
.. [Ful1989] \W. Fulton. Algebraic curves: an introduction to algebraic geometry. Addison-Wesley,
28132813
Redwood City CA (1989).
28142814
2815+
.. [Ful1992] \W. Fulton. *Flags, Schubert polynomials, degeneracy loci, and
2816+
determinantal formulas*. Duke Math. J. **65** (1992), no. 3, 381-420.
2817+
28152818
.. [Ful1993] Wiliam Fulton, *Introduction to Toric Varieties*,
28162819
Princeton University Press, 1993.
28172820

src/sage/combinat/diagram.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
from sage.combinat.skew_partition import SkewPartition
3333
from sage.combinat.skew_tableau import SkewTableaux
3434
from sage.combinat.tableau import Tableau
35+
from sage.misc.cachefunc import cached_method
3536
from sage.misc.inherit_comparison import InheritComparisonClasscallMetaclass
3637
from sage.misc.lazy_import import lazy_import
3738
from sage.structure.element import Matrix
@@ -534,6 +535,28 @@ def specht_module_dimension(self, base_ring=None):
534535
from sage.combinat.specht_module import specht_module_rank
535536
return specht_module_rank(self, base_ring)
536537

538+
@cached_method
539+
def essential_set(self):
540+
r"""
541+
Return the essential set of ``self`` as defined by Fulton.
542+
543+
Let `D` be a diagram. Then the *essential set* of `D` are the
544+
cells `(i, j) \in D` such that `(i+1, j) \notin D` and
545+
`(i, j+1) \notin D`; that is, the maximally southwest elements
546+
in each connected component of `D`.
547+
548+
EXAMPLES::
549+
550+
sage: w = Permutation([2, 1, 5, 4, 3])
551+
sage: D = w.rothe_diagram()
552+
sage: D.essential_set()
553+
((0, 0), (2, 3), (3, 2))
554+
"""
555+
ret = [c for c in self._cells if (c[0]+1, c[1]) not in self._cells
556+
and (c[0], c[1]+1) not in self._cells]
557+
ret.sort()
558+
return tuple(ret)
559+
537560

538561
class Diagrams(UniqueRepresentation, Parent):
539562
r"""

src/sage/combinat/permutation.py

Lines changed: 106 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3155,6 +3155,24 @@ def reduced_word_lexmin(self):
31553155

31563156
return rw
31573157

3158+
def number_of_reduced_words(self):
3159+
r"""
3160+
Return the number of reduced words of ``self`` without explicitly
3161+
computing them all.
3162+
3163+
EXAMPLES::
3164+
3165+
sage: p = Permutation([6,4,2,5,1,8,3,7])
3166+
sage: len(p.reduced_words()) == p.number_of_reduced_words() # needs sage.combinat
3167+
True
3168+
"""
3169+
Tx = self.rothe_diagram().peelable_tableaux()
3170+
return sum(map(_tableau_contribution, Tx))
3171+
3172+
##################
3173+
# Rothe diagrams #
3174+
##################
3175+
31583176
def rothe_diagram(self):
31593177
r"""
31603178
Return the Rothe diagram of ``self``.
@@ -3173,20 +3191,100 @@ def rothe_diagram(self):
31733191
from sage.combinat.diagram import RotheDiagram
31743192
return RotheDiagram(self)
31753193

3176-
def number_of_reduced_words(self):
3194+
def rank_matrix(self):
31773195
r"""
3178-
Return the number of reduced words of ``self`` without explicitly
3179-
computing them all.
3196+
Return the rank matrix of ``self``.
3197+
3198+
Let `P = [P_{ij}]_{i, j=1}^n` be the permutation matrix of `w \in S_n`.
3199+
The rank matrix is the `n \times n` matrix with entries
3200+
3201+
.. MATH::
3202+
3203+
r_w(i, j) = \sum_{a=1}^i \sum_{b=1}^j P_{ij}.
31803204
31813205
EXAMPLES::
31823206
3183-
sage: p = Permutation([6,4,2,5,1,8,3,7])
3184-
sage: len(p.reduced_words()) == p.number_of_reduced_words() # needs sage.combinat
3185-
True
3207+
sage: w = Permutation([2, 1, 5, 4, 3])
3208+
sage: w.to_matrix()
3209+
[0 1 0 0 0]
3210+
[1 0 0 0 0]
3211+
[0 0 0 0 1]
3212+
[0 0 0 1 0]
3213+
[0 0 1 0 0]
3214+
sage: w.rank_matrix()
3215+
[0 1 1 1 1]
3216+
[1 2 2 2 2]
3217+
[1 2 2 2 3]
3218+
[1 2 2 3 4]
3219+
[1 2 3 4 5]
31863220
"""
3187-
Tx = self.rothe_diagram().peelable_tableaux()
3221+
ret = self.to_matrix()
3222+
n = ret.nrows()
3223+
for j in range(1, n):
3224+
ret[0, j] += ret[0, j-1]
3225+
for i in range(1, n):
3226+
ret[i, 0] += ret[i-1, 0]
3227+
for j in range(1, n):
3228+
# Compute by inclusion-exclusion
3229+
ret[i, j] += ret[i-1, j] + ret[i, j-1] - ret[i-1, j-1]
3230+
return ret
31883231

3189-
return sum(map(_tableau_contribution, Tx))
3232+
def schubert_determinant_ideal(self):
3233+
r"""
3234+
Return the Schubert determinant ideal of ``self``.
3235+
3236+
From Lemma 3.10 [Ful1992]_, the matrix Schubert variety of
3237+
a permutation `w \in S_n` is defined by the ideal
3238+
3239+
.. MATH::
3240+
3241+
I_w = \sum_{(i, j)} I_{r_w(i, j)+1}(i, j),
3242+
3243+
where the sum is over the :meth:`essential set
3244+
<sage.combinat.diagram.Diagram.essential_set>`, `[r_w(i, j)]_{i, j}`
3245+
is the :meth:`rank_matrix` of `w`, and `I_k(i, j)` is the ideal
3246+
generated by the the `k \times k` minors of the `i \times j`
3247+
matrix `[z_{ab}]_{a, b}`.
3248+
3249+
These ideals are known to be prime of codimension equal to `\ell(w)`
3250+
(the length of `w`) such that `R / I_w` is Cohen-Macaulay, where `R`
3251+
is the polynomial ring `\QQ[z_{ab} | 1 \leq a, b \leq n]` from
3252+
Prop. 3.10 of [Ful1992]_.
3253+
3254+
EXAMPLES::
3255+
3256+
sage: w = Permutation([3, 1, 4, 2])
3257+
sage: Iw = w.schubert_determinant_ideal()
3258+
sage: Iw.gens()
3259+
[z00, z01, -z01*z10 + z00*z11, -z01*z20 + z00*z21, -z11*z20 + z10*z21]
3260+
sage: Iw.dimension()
3261+
13
3262+
sage: Iw.dimension() + w.length()
3263+
16
3264+
sage: Iw.is_prime()
3265+
True
3266+
3267+
sage: w = Permutation([2, 1, 5, 4, 3])
3268+
sage: Iw = w.schubert_determinant_ideal()
3269+
sage: Iw.dimension()
3270+
21
3271+
sage: w.length() + Iw.dimension()
3272+
25
3273+
sage: Iw.is_prime()
3274+
True
3275+
"""
3276+
from sage.rings.rational_field import QQ
3277+
from sage.matrix.constructor import matrix
3278+
n = len(self)
3279+
PR = PolynomialRing(QQ, n, var_array='z')
3280+
z = PR.gens()
3281+
Z = matrix(PR, [[z[r*n+c] for c in range(n)] for r in range(n)])
3282+
rk = self.rank_matrix()
3283+
gens = []
3284+
for i, j in self.rothe_diagram().essential_set():
3285+
# we apply the transpose to the rank matrix to match conventions
3286+
gens.extend(Z.submatrix(0, 0, i+1, j+1).minors(rk[j, i] + 1))
3287+
return PR.ideal(gens)
31903288

31913289
################
31923290
# Fixed Points #

0 commit comments

Comments
 (0)