From bad504bc6ff97510f90529063cff215d2ee3496f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 20 May 2026 20:35:11 +0000 Subject: [PATCH 1/3] Initial plan From ce20788ef1f50439f1299549b750e25fab798cd8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 20 May 2026 20:57:28 +0000 Subject: [PATCH 2/3] Add affine Schubert polynomial support Agent-Logs-Url: https://github.com/ghseeli/combinatorialpolynomials/sessions/79368070-cceb-4b52-b735-4f771f3879fd Co-authored-by: ghseeli <3360068+ghseeli@users.noreply.github.com> --- README.org | 1 + schubert_polynomials.py | 67 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/README.org b/README.org index 91f2bed..9a0b834 100644 --- a/README.org +++ b/README.org @@ -9,6 +9,7 @@ Certain functions may also be implemented in SageMath, but I have chosen to rewr + Double Schubert polynomials + Grothendieck polynomials + Quantum Schubert polynomials ++ Affine Schubert polynomials + Quantum Grothendieck polynomials + Key polynomials / Type A Demazure characters + Demazure atom polynomials diff --git a/schubert_polynomials.py b/schubert_polynomials.py index 4190906..e3fde4e 100755 --- a/schubert_polynomials.py +++ b/schubert_polynomials.py @@ -5,7 +5,7 @@ # https://www.gnu.org/licenses/ # *************************************************************************** -from sage.all import Permutation, Permutations, QQ, Frac, parent, SchubertPolynomialRing, prod, SymmetricFunctions, Sequence, Subsets, cached_function, block_matrix, zero_matrix, binomial, IntegerVectors, CombinatorialFreeModule, SR +from sage.all import Permutation, Permutations, QQ, ZZ, Frac, parent, SchubertPolynomialRing, prod, SymmetricFunctions, Sequence, Subsets, cached_function, block_matrix, zero_matrix, binomial, IntegerVectors, CombinatorialFreeModule, SR from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence from functools import reduce from math import prod @@ -420,6 +420,71 @@ def reduced_factorization_pairs(w): pairs.append((u,v)) return list(set(pairs)) +def additive_affine_length_decomposition(w): + r""" + Given an affine permutation ``w`` in type `\widetilde{A}_{n-1}`, return all pairs `(w_1, w_2)` such that + `w_1 \in \widetilde{S}_n`, `w_2 \in S_n`, `w = w_1 w_2`, and `\ell(w_1)+\ell(w_2)=\ell(w)`. + + EXAMPLES:: + + sage: W = WeylGroup(['A',2,1], prefix='s') + sage: w = W.from_reduced_word([0,1]) + sage: [(str(w1), list(w2)) for (w1,w2) in additive_affine_length_decomposition(w)] + [('s0*s1', [1, 2, 3]), ('s0', [2, 1, 3])] + """ + if not hasattr(w, "parent"): + raise TypeError("input must be an affine permutation element") + W = w.parent() + if not hasattr(W, "cartan_type"): + raise TypeError("input must belong to an affine Weyl group of type A") + cartan_type = W.cartan_type() + if not (cartan_type.is_affine() and cartan_type[0] == 'A'): + raise ValueError("input must belong to an affine Weyl group of type A") + n = cartan_type[1] + 1 + pairs = [] + lw = w.length() + for v in Permutations(n): + v = Permutation(v) + v_aff = W.from_reduced_word(v.reduced_word()) + w1 = w * v_aff.inverse() + if w1.length() + v.length() == lw: + pairs.append((w1, v)) + return pairs + +def affine_Schubert(w, base_ring=ZZ, x_pref='x', sf_basis='s'): + r""" + Return the affine Schubert polynomial associated to ``w`` using + `\sum_{w = w_1 w_2,\ \ell(w_1)+\ell(w_2)=\ell(w)} F_{w_1}\mathfrak{S}_{w_2}`. + + The output is a symmetric function over `R = \text{base\_ring}[x_1,\ldots,x_n]`. + + EXAMPLES:: + + sage: W = WeylGroup(['A',2,1], prefix='s') + sage: affine_Schubert(W.one()) + s[] + sage: affine_Schubert(W.from_reduced_word([0,1])) + x1*s[1] + s[1, 1] + sage: affine_Schubert(W.from_reduced_word([0,2]), sf_basis='m') + (x1+x2)*m[1] + m[1, 1] + m[2] + """ + cartan_type = w.parent().cartan_type() + if not (cartan_type.is_affine() and cartan_type[0] == 'A'): + raise ValueError("input must belong to an affine Weyl group of type A") + n = cartan_type[1] + 1 + poly_ring = generate_polynomial_ring(base_ring, n, x_pref=x_pref) + symmetric_functions = SymmetricFunctions(poly_ring) + if not hasattr(symmetric_functions, sf_basis): + raise ValueError("invalid symmetric function basis {}".format(sf_basis)) + m = symmetric_functions.m() + output_basis = getattr(symmetric_functions, sf_basis)() + X = SchubertPolynomialRing(base_ring) + res = m.zero() + for (w1, w2) in additive_affine_length_decomposition(w): + stanley = sum(poly_ring(coeff)*m(pa) for (pa, coeff) in w1.stanley_symmetric_function()) + res += poly_ring(X(w2).expand())*stanley + return output_basis(res) + ## Grothendieck polynomials def pi_divided_difference(i, poly, alphabet='x'): From d444f845c418d1d9638ccc0c9c17320d5857fa8c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 20 May 2026 21:00:08 +0000 Subject: [PATCH 3/3] Polish affine Schubert docs and naming clarity Agent-Logs-Url: https://github.com/ghseeli/combinatorialpolynomials/sessions/79368070-cceb-4b52-b735-4f771f3879fd Co-authored-by: ghseeli <3360068+ghseeli@users.noreply.github.com> --- schubert_polynomials.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/schubert_polynomials.py b/schubert_polynomials.py index e3fde4e..0b9b48e 100755 --- a/schubert_polynomials.py +++ b/schubert_polynomials.py @@ -423,7 +423,7 @@ def reduced_factorization_pairs(w): def additive_affine_length_decomposition(w): r""" Given an affine permutation ``w`` in type `\widetilde{A}_{n-1}`, return all pairs `(w_1, w_2)` such that - `w_1 \in \widetilde{S}_n`, `w_2 \in S_n`, `w = w_1 w_2`, and `\ell(w_1)+\ell(w_2)=\ell(w)`. + `w_1 \in \widetilde{A}_{n-1}`, `w_2 \in S_n`, `w = w_1 w_2`, and `\ell(w_1)+\ell(w_2)=\ell(w)`. EXAMPLES:: @@ -454,7 +454,9 @@ def additive_affine_length_decomposition(w): def affine_Schubert(w, base_ring=ZZ, x_pref='x', sf_basis='s'): r""" Return the affine Schubert polynomial associated to ``w`` using - `\sum_{w = w_1 w_2,\ \ell(w_1)+\ell(w_2)=\ell(w)} F_{w_1}\mathfrak{S}_{w_2}`. + `\sum_{w = w_1 w_2,\ \ell(w_1)+\ell(w_2)=\ell(w)} F_{w_1}\mathfrak{S}_{w_2}`, + where `F_{w_1}` is the affine Stanley symmetric function and `\mathfrak{S}_{w_2}` is + the ordinary Schubert polynomial. The output is a symmetric function over `R = \text{base\_ring}[x_1,\ldots,x_n]`. @@ -478,11 +480,11 @@ def affine_Schubert(w, base_ring=ZZ, x_pref='x', sf_basis='s'): raise ValueError("invalid symmetric function basis {}".format(sf_basis)) m = symmetric_functions.m() output_basis = getattr(symmetric_functions, sf_basis)() - X = SchubertPolynomialRing(base_ring) + schubert_ring = SchubertPolynomialRing(base_ring) res = m.zero() for (w1, w2) in additive_affine_length_decomposition(w): - stanley = sum(poly_ring(coeff)*m(pa) for (pa, coeff) in w1.stanley_symmetric_function()) - res += poly_ring(X(w2).expand())*stanley + stanley = sum(poly_ring(coeff)*m(partition) for (partition, coeff) in w1.stanley_symmetric_function()) + res += poly_ring(schubert_ring(w2).expand())*stanley return output_basis(res) ## Grothendieck polynomials