schubmult 5.2.0b1: Schubert calculus rings for Sage (double / quantum / Grothendieck, polynomial bases) -- beta testers wanted

36 views
Skip to first unread message

Matthew J. Samuel

unread,
Sep 26, 2026, 8:17:19 PMSep 26
to sage-...@googlegroups.com

Hi all,

I'm the author of schubmult, a Python package for Schubert calculus computations (structure constants for Schubert, double Schubert, quantum, quantum double and Grothendieck polynomials). The 5.2.0 pre-release adds a Sage layer, schubmult.sage, and I'd be grateful if people who work with Schubert polynomials or any related polynomials (slide, key, glide, forest, grove, Lascoux) in Sage would try it and tell me where it breaks or where the conventions surprise them.

Install into a Sage environment with

    sage: %pip install --pre schubmult

(the --pre is needed; plain pip install stays on 5.1.1). Sage is not a dependency of schubmult and nothing changes for non-Sage users; schubmult.sage is only importable inside Sage.

What it provides, all built on the Sage framework (CombinatorialFreeModule parents, coercion, WithRealizations, TestSuite passes, doctests run under sage.doctest):

- DoubleSchubertPolynomialRing(R): double Schubert polynomials S_w(x; y) over R[y, z] with products and coercion between alphabets;
- QuantumSchubertPolynomialRing(R, parabolic=...), QuantumDoubleSchubertPolynomialRing(R, parabolic=...): quantum and equivariant quantum Schubert polynomials, with parabolic block sizes for partial flag varieties (Peterson-Woodward);
- GrothendieckPolynomialRing(R), DoubleGrothendieckPolynomialRing(R): beta-Grothendieck polynomials and their double versions, beta kept as a variable; the double structure constants are rational functions in beta and y and come out reduced;
- PolynomialAlgebra(R) (and PolynomialAlgebra(R, n) in n variables): the polynomial ring with its combinatorial bases as realizations, SymmetricFunctions-style -- Schubert and Grothendieck indexed by permutations, monomial / key / fundamental and monomial slide / forest / glide / Lascoux / grove indexed by weak compositions, and in n variables the basis of (not-quite-standard) elementary monomials. All bases coerce into one another.
- Coercions with Sage's SchubertPolynomialRing and KeyPolynomials, and from_symmetric_function / to_symmetric_function for the Grassmannian case.

A taste:

    sage: from schubmult.sage import *
    sage: X = DoubleSchubertPolynomialRing(QQ)
    sage: X([3, 1, 2]) * X([2, 1])
    (y_2-y_0)*X_y[3, 1, 2] + X_y[4, 1, 2, 3]

    sage: A = PolynomialAlgebra(QQ); S = A.schubert(); k = A.key()
    sage: k(S[3, 1, 2])
    k[2]
    sage: A.fundamental_slide()(KeyPolynomials(QQ)([1, 0, 2]))
    F[1, 0, 2] + F[2, 0, 1]
    sage: k([2,0,0,3])*k([0,3,2])
    k[2, 3, 2, 3] + k[2, 3, 4, 1] + k[2, 3, 5] + k[2, 4, 2, 2] + k[2, 5, 2, 1] + k[2, 6, 2] + k[3, 3, 1, 3] + k[3, 3, 4] + k[3, 4, 1, 2] + k[3, 5, 1, 1] + k[3, 5, 2] + k[3, 6, 1] + k[4, 1, 2, 3] + k[4, 1, 4, 1] + k[4, 1, 5] + k[4, 2, 4] + k[4, 3, 0, 3] - k[4, 3, 2, 1] - k[4, 3, 3] + k[4, 4, 0, 2] - k[4, 4, 2] + k[4, 5, 0, 1] + k[4, 6] + k[5, 0, 2, 3] + k[5, 0, 4, 1] + k[5, 0, 5] + k[5, 1, 2, 2] + k[5, 1, 3, 1] - k[5, 2, 2, 1] + k[5, 3, 0, 2] - k[5, 3, 1, 1] - 2*k[5, 3, 2] - k[5, 4, 1] + k[6, 0, 2, 2] + k[6, 0, 3, 1] + k[6, 0, 4] - k[6, 2, 2] - k[6, 3, 1] - k[6, 4]

Equivariant quantum cohomology of Gr(2,5), Example 2.5 in Buch's two-step puzzle paper: [X^{(2,1)}] * [X^{(3,1)}] is

    sage: QD = QuantumDoubleSchubertPolynomialRing(QQ, parabolic=(2, 3))
    sage: (QD([2, 4, 1, 3]) * QD([2, 5, 1, 3, 4])).project(5)

which reproduces the seven terms of the paper (project(5) drops the classes that vanish in Gr(2,5)).

Conventions to know before comparing with your own computations: variables are 0-indexed (x0, y_0, q_0), so y_i here is y_{i+1} in most papers; the K-theoretic bases of PolynomialAlgebra (Grothendieck, glide, Lascoux, grove) are at beta = -1, while the Grothendieck rings keep beta symbolic; double Grothendieck polynomials use x (+) y = x + y + beta*x*y; and in the parabolic quantum rings the last block is implicit and unbounded, so some products carry extra descents until you project.

On performance: single and double Schubert / quantum products are fast (the kernels are schubmult's own). Double Grothendieck structure constants are rational functions and get large quickly -- a triple product of S_4 groths takes a few seconds. In schubmult itself without Sage, polynomial coefficients are kept factored, and having these expanded is where most of the time is spent in the Sage version.

What I'd most like to hear:

1. Which Sage versions it works on. I developed against Sage 10.9 from conda-forge; it imports sage.combinat.key_polynomial, so it will need a Sage recent enough to have KeyPolynomials. If it fails to import on some supported version, the traceback is exactly what I need.
2. Mathematical spot checks against computations you trust, especially anything equivariant, quantum, or K-theoretic where conventions bite.
3. Anything un-Sage-like in the API.

The test suite runs with ` pytest tests/sage` from a checkout; issues (of which there are none at this time) and pull requests at https://github.com/matthematics/schubmult. Full details in the README on the "redevelop" branch ("Using with SageMath") and CHANGELOG.

Thanks,
Matt Samuel
Reply all
Reply to author
Forward
0 new messages