From 9487473aed473cbe2f30c1c125258694811a7e48 Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Thu, 30 Nov 2023 11:46:13 +0900 Subject: [PATCH 1/4] Initial implementation of the Murphy basis of the SGA. --- src/sage/algebras/cellular_basis.py | 21 +-- src/sage/combinat/symmetric_group_algebra.py | 144 ++++++++++++++++++- 2 files changed, 155 insertions(+), 10 deletions(-) diff --git a/src/sage/algebras/cellular_basis.py b/src/sage/algebras/cellular_basis.py index c80eee401ff..8c474420378 100644 --- a/src/sage/algebras/cellular_basis.py +++ b/src/sage/algebras/cellular_basis.py @@ -164,7 +164,7 @@ class CellularBasis(CombinatorialFreeModule): - C([2, 1], [[1, 3], [2]], [[1, 3], [2]]) + C([3], [[1, 2, 3]], [[1, 2, 3]]) """ - def __init__(self, A): + def __init__(self, A, to_algebra=None, from_algebra=None, **kwargs): r""" Initialize ``self``. @@ -181,21 +181,26 @@ def __init__(self, A): # TODO: Use instead A.category().Realizations() so # operations are defined by coercion? + prefix = kwargs.pop('prefix', 'C') cat = Algebras(A.category().base_ring()).FiniteDimensional().WithBasis().Cellular() CombinatorialFreeModule.__init__(self, A.base_ring(), I, - prefix='C', bracket=False, - category=cat) + prefix=prefix, bracket=False, + category=cat, **kwargs) # Register coercions - if A._to_cellular_element is not NotImplemented: - to_cellular = A.module_morphism(A._to_cellular_element, codomain=self, + if from_algebra is None: + from_algebra = A._to_cellular_element + if to_algebra is None: + to_algebra = A._from_cellular_index + if from_algebra is not NotImplemented: + to_cellular = A.module_morphism(from_algebra, codomain=self, category=cat) - if A._from_cellular_index is NotImplemented: + if to_algebra is NotImplemented: from_cellular = ~to_cellular else: - from_cellular = self.module_morphism(A._from_cellular_index, codomain=A, + from_cellular = self.module_morphism(to_algebra, codomain=A, category=cat) - if A._to_cellular_element is NotImplemented: + if from_algebra is NotImplemented: to_cellular = ~from_cellular to_cellular.register_as_coercion() from_cellular.register_as_coercion() diff --git a/src/sage/combinat/symmetric_group_algebra.py b/src/sage/combinat/symmetric_group_algebra.py index 7672c8c7649..7fad5258aa8 100644 --- a/src/sage/combinat/symmetric_group_algebra.py +++ b/src/sage/combinat/symmetric_group_algebra.py @@ -19,6 +19,7 @@ from sage.combinat.partition import _Partitions, Partitions_n from sage.combinat.tableau import Tableau, StandardTableaux_size, StandardTableaux_shape, StandardTableaux from sage.algebras.group_algebra import GroupAlgebra_class +from sage.algebras.cellular_basis import CellularBasis from sage.categories.weyl_groups import WeylGroups from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.rings.rational_field import QQ @@ -688,8 +689,7 @@ def cell_poset(self): Finite poset containing 5 elements """ from sage.combinat.posets.posets import Poset - from sage.combinat.partition import Partitions - return Poset([Partitions(self.n), lambda x, y: y.dominates(x)]) + return Poset([Partitions_n(self.n), lambda x, y: y.dominates(x)]) def cell_module_indices(self, la): r""" @@ -2083,6 +2083,36 @@ def epsilon_ik(self, itab, ktab, star=0, mult='l2r'): else: return z.map_support(lambda x: x.inverse()) + def murphy_basis(self): + r""" + Return the Murphy basis of ``self``. + """ + return MurphyBasis(self) + + def murphy_basis_element(self, S, T): + r""" + Return the Murphy basis element indexed by ``S`` and ``T``. + """ + la = S.shape() + if la != T.shape(): + raise ValueError("S and T must have the same shape") + if sum(la) != self.n: + raise ValueError(f"the shape must be a partition of size {self.n}") + + G = self.group() + ds = G(list(sum((row for row in S), ()))) + dt = G(list(sum((row for row in T), ()))) + return self.monomial(~ds) * self._row_stabilizer(la) * self.monomial(dt) + + @cached_method + def _row_stabilizer(self, la): + """ + Return the row stabilizer element of a canonical standard tableau + of shape ``la``. + """ + G = self.group() + return self.sum_of_monomials(G(list(w.tuple())) for w in la.young_subgroup()) + epsilon_ik_cache = {} @@ -2634,6 +2664,116 @@ def seminormal_test(n): raise ValueError("3.1.20 - %s, %s" % (tab, tab2)) return True + +####################### + + +class MurphyBasis(CellularBasis): + """ + The Murphy basis of a symmetric group algebra. + + Let `R` be a commutative ring, and let `A = R[S_n]` denote the group + algebra (over `R`) of `S_n`. The *Murphy basis* is the basis of `A` + defined as follows. Let `S, T` be standard tableaux of shape `\lambda`. + Define `T^{\lambda}` as the standard tableau of shape `\lambda` with + the first row filled with `1, \ldots, \lambda_1`, the second row + `\lambda_1+1, \ldots, \lambda_1+\lambda_2`, and so on. Let `d(S)` be + the unique permutation such that `S = T^{\lambda} d(S)` under the natural + action. Then the Murphy basis element indexed by `S` and `T` is + + .. MATH:: + + M_{ST} = d(S)^{-1} R_{\lambda} d(T). + + The Murphy basis is a :class:`cellular basis + ` of `A`. + + EXAMPLES:: + + sage: SGA = SymmetricGroupAlgebra(GF(3), 5) + sage: M = SGA.murphy_basis() + sage: for la in M.simple_module_parameterization(): + ....: CM = M.cell_module(la) + ....: print(la, CM.dimension(), CM.simple_module().dimension()) + [3, 2] 5 4 + [3, 1, 1] 6 6 + [2, 2, 1] 5 1 + [2, 1, 1, 1] 4 4 + [1, 1, 1, 1, 1] 1 1 + """ + def __init__(self, SGA): + """ + Initialize ``self``. + + EXAMPLES:: + + sage: SGA = SymmetricGroupAlgebra(GF(3), 3) + sage: M = SGA.murphy_basis() + sage: TestSuite(M).run() + """ + self._algebra = SGA + I = [(S, T) for la in Partitions_n(SGA.n) + for S in la.standard_tableaux() for T in la.standard_tableaux()] + CellularBasis.__init__(self, SGA, self._to_sga) + + def _to_sga(self, ind): + r""" + Return the element in the symmetric group algebra indexed by ``ind``. + + EXAMPLES:: + + sage: SGA = SymmetricGroupAlgebra(GF(3), 3) + sage: M = SGA.murphy_basis() + sage: for ind in M.basis().keys(): + ....: print(ind, M._to_sga(ind)) + ([3], [[1, 2, 3]], [[1, 2, 3]]) [1, 2, 3] + [1, 3, 2] + [2, 1, 3] + [2, 3, 1] + [3, 1, 2] + [3, 2, 1] + ([2, 1], [[1, 3], [2]], [[1, 3], [2]]) [1, 2, 3] + [3, 2, 1] + ([2, 1], [[1, 3], [2]], [[1, 2], [3]]) [1, 3, 2] + [2, 3, 1] + ([2, 1], [[1, 2], [3]], [[1, 3], [2]]) [1, 3, 2] + [3, 1, 2] + ([2, 1], [[1, 2], [3]], [[1, 2], [3]]) [1, 2, 3] + [2, 1, 3] + ([1, 1, 1], [[1], [2], [3]], [[1], [2], [3]]) [1, 2, 3] + """ + return self._algebra.murphy_basis_element(ind[1], ind[2]) + + def _repr_(self): + r""" + Return a string representation of ``self``. + + EXAMPLES:: + + sage: SGA = SymmetricGroupAlgebra(GF(3), 4) + sage: SGA.murphy_basis() + Murphy basis of Symmetric group algebra of order 4 over Finite Field of size 3 + """ + return "Murphy basis of {}".format(self._algebra) + + @cached_method + def one_basis(self): + """ + Return the index of the basis element for the multiplicative identity. + + EXAMPLES:: + + sage: SGA = SymmetricGroupAlgebra(GF(3), 4) + sage: M = SGA.murphy_basis() + sage: M.one_basis() + """ + col = _Partitions([1]*self._algebra.n).standard_tableaux()[0] + return (col, col) + + @cached_method + def one(self): + """ + Return the element `1` in ``self``. + + EXAMPLES:: + + sage: SGA = SymmetricGroupAlgebra(GF(3), 4) + sage: M = SGA.murphy_basis() + sage: M.one() + """ + return self.monomial(self.one_basis()) + ####################### From e632044de64582e5008398f2dd4d65c2e47df1b9 Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Thu, 30 Nov 2023 17:49:41 +0900 Subject: [PATCH 2/4] Add additional cellular bases for the symmetric group algebra. --- src/doc/en/reference/references/index.rst | 4 + src/sage/combinat/symmetric_group_algebra.py | 311 +++++++++++++------ 2 files changed, 228 insertions(+), 87 deletions(-) diff --git a/src/doc/en/reference/references/index.rst b/src/doc/en/reference/references/index.rst index fd3963ab275..20d2349f0e5 100644 --- a/src/doc/en/reference/references/index.rst +++ b/src/doc/en/reference/references/index.rst @@ -4515,6 +4515,10 @@ REFERENCES: .. [Mat2002] Jiří Matousek, "Lectures on Discrete Geometry", Springer, 2002 +.. [Mathas2004] Andrew Mathas. + *Matrix units and generic degrees for the Ariki-Koike algebras*. + J. Algebra. **281** (2004) pp. 695-730. + .. [Mas1995] Mason, Geoffrey. *The quantum double of a finite group and its role in conformal field theory*. Groups '93 Galway/St. Andrews, Vol. 2, 405-417, London Math. Soc. Lecture Note Ser., 212, Cambridge, 1995. diff --git a/src/sage/combinat/symmetric_group_algebra.py b/src/sage/combinat/symmetric_group_algebra.py index 7fad5258aa8..d5a230abc50 100644 --- a/src/sage/combinat/symmetric_group_algebra.py +++ b/src/sage/combinat/symmetric_group_algebra.py @@ -732,40 +732,14 @@ def _from_cellular_index(self, x): sage: [S._from_cellular_index(i) for i in C.basis().keys()] [[1, 2, 3] + [1, 3, 2] + [2, 1, 3] + [2, 3, 1] + [3, 1, 2] + [3, 2, 1], [1, 2, 3] + [2, 1, 3], - [1, 2, 3] + [1, 3, 2] + [2, 1, 3] + [3, 1, 2], - [1, 2, 3] + [1, 3, 2] + [2, 1, 3] + [2, 3, 1], - [1, 2, 3] + [1, 3, 2], + [1, 3, 2] + [3, 1, 2], + [1, 3, 2] + [2, 3, 1], + [1, 2, 3] + [3, 2, 1], [1, 2, 3]] sage: TestSuite(C).run() """ if ~factorial(self.n) not in self.base_ring(): - from sage.combinat.rsk import RSK_inverse - from sage.sets.recursively_enumerated_set import RecursivelyEnumeratedSet - G = self.basis().keys() - R = self.base_ring() - one = R.one() - # check if the KL polynomials can be computed using ``coxeter3`` - try: - from sage.libs.coxeter3.coxeter_group import CoxeterGroup as Coxeter3Group - except ImportError: - # Falback to using the KL polynomial - from sage.combinat.kazhdan_lusztig import KazhdanLusztigPolynomial - from sage.groups.perm_gps.permgroup_named import SymmetricGroup - q = PolynomialRing(R, 'q').gen() - KLG = SymmetricGroup(self.n) - self._cellular_KL = KazhdanLusztigPolynomial(KLG, q) - polyfunc = self._cellular_KL.P - else: - self._cellular_KL = Coxeter3Group(['A', self.n+1]) - KLG = self._cellular_KL - polyfunc = self._cellular_KL.kazhdan_lusztig_polynomial - - def func(S, T, mult=None): - w = KLG.from_reduced_word(RSK_inverse(T, S, output="permutation").reduced_word()) - bruhat = RecursivelyEnumeratedSet([w], lambda u: u.bruhat_lower_covers(), structure='graded') - return self.element_class(self, {G.from_reduced_word(v.reduced_word()): R(c(q=one)) - for v in bruhat if (c := polyfunc(v, w))}) - + func = self.murphy_basis_element else: func = self.epsilon_ik @@ -2085,14 +2059,46 @@ def epsilon_ik(self, itab, ktab, star=0, mult='l2r'): def murphy_basis(self): r""" - Return the Murphy basis of ``self``. + Return the :class:`Murphy basis + ` of ``self``. + + EXAMPLES:: + + sage: SGA = SymmetricGroupAlgebra(QQ, 3) + sage: M = SGA.murphy_basis() + sage: M(SGA.an_element()) + -C([1, 1, 1], [[1], [2], [3]], [[1], [2], [3]]) + + C([2, 1], [[1, 2], [3]], [[1, 2], [3]]) + + C([2, 1], [[1, 2], [3]], [[1, 3], [2]]) + + 2*C([2, 1], [[1, 3], [2]], [[1, 2], [3]]) + + 4*C([2, 1], [[1, 3], [2]], [[1, 3], [2]]) + - 3*C([3], [[1, 2, 3]], [[1, 2, 3]]) """ return MurphyBasis(self) + @cached_method def murphy_basis_element(self, S, T): r""" Return the Murphy basis element indexed by ``S`` and ``T``. + + .. SEEALSO:: + + :class:`~sage.combinat.symmetric_group_algebra.MurphyBasis` + + EXAMPLES:: + + sage: import itertools + sage: SGA = SymmetricGroupAlgebra(QQ, 3) + sage: for S, T in itertools.product(StandardTableaux([2,1]), repeat=2): + ....: print(S, T, SGA.murphy_basis_element(S, T)) + [[1, 3], [2]] [[1, 3], [2]] [1, 2, 3] + [2, 1, 3] + [[1, 3], [2]] [[1, 2], [3]] [1, 3, 2] + [3, 1, 2] + [[1, 2], [3]] [[1, 3], [2]] [1, 3, 2] + [2, 3, 1] + [[1, 2], [3]] [[1, 2], [3]] [1, 2, 3] + [3, 2, 1] """ + S = S.conjugate() + T = T.conjugate() + la = S.shape() if la != T.shape(): raise ValueError("S and T must have the same shape") @@ -2109,10 +2115,79 @@ def _row_stabilizer(self, la): """ Return the row stabilizer element of a canonical standard tableau of shape ``la``. + + EXAMPLES:: + + sage: SGA = SymmetricGroupAlgebra(QQ, 3) + sage: for la in Partitions(3): + ....: print(la, SGA._row_stabilizer(la)) + [3] [1, 2, 3] + [1, 3, 2] + [2, 1, 3] + [2, 3, 1] + [3, 1, 2] + [3, 2, 1] + [2, 1] [1, 2, 3] + [2, 1, 3] + [1, 1, 1] [1, 2, 3] """ G = self.group() return self.sum_of_monomials(G(list(w.tuple())) for w in la.young_subgroup()) + def kazhdan_lusztig_cellular_basis(self): + r""" + Return the Kazhdan-Lusztig basis (at `q = 1`) of ``self`` + as a cellular basis. + + EXAMPLES:: + + sage: SGA = SymmetricGroupAlgebra(QQ, 3) + sage: KL = SGA.kazhdan_lusztig_cellular_basis() + sage: KL(SGA.an_element()) + C([2, 1], [[1, 2], [3]], [[1, 2], [3]]) + + C([2, 1], [[1, 3], [2]], [[1, 2], [3]]) + + 2*C([2, 1], [[1, 3], [2]], [[1, 3], [2]]) + - 3*C([3], [[1, 2, 3]], [[1, 2, 3]]) + """ + return KLCellularBasis(self) + + @cached_method + def kazhdan_lusztig_basis_element(self, w): + r""" + Return the Kazhdan-Lusztig `C'_w` basis element at `q = 1`. + + EXAMPLES:: + + sage: SGA = SymmetricGroupAlgebra(QQ, 3) + sage: for w in SGA.group(): + ....: print(w, SGA.kazhdan_lusztig_basis_element(w)) + [1, 2, 3] [1, 2, 3] + [1, 3, 2] [1, 2, 3] + [1, 3, 2] + [2, 1, 3] [1, 2, 3] + [2, 1, 3] + [2, 3, 1] [1, 2, 3] + [1, 3, 2] + [2, 1, 3] + [2, 3, 1] + [3, 1, 2] [1, 2, 3] + [1, 3, 2] + [2, 1, 3] + [3, 1, 2] + [3, 2, 1] [1, 2, 3] + [1, 3, 2] + [2, 1, 3] + [2, 3, 1] + [3, 1, 2] + [3, 2, 1] + """ + from sage.sets.recursively_enumerated_set import RecursivelyEnumeratedSet + G = self.basis().keys() + R = self.base_ring() + one = R.one() + # check if the KL polynomials can be computed using ``coxeter3`` + try: + from sage.libs.coxeter3.coxeter_group import CoxeterGroup as Coxeter3Group + except ImportError: + # Falback to using the KL polynomial + from sage.combinat.kazhdan_lusztig import KazhdanLusztigPolynomial + from sage.groups.perm_gps.permgroup_named import SymmetricGroup + q = PolynomialRing(R, 'q').gen() + self._KLG = SymmetricGroup(self.n) + self._cellular_KL = KazhdanLusztigPolynomial(KLG, q) + polyfunc = self._cellular_KL.P + else: + self._cellular_KL = Coxeter3Group(['A', self.n+1]) + self._KLG = self._cellular_KL + polyfunc = self._cellular_KL.kazhdan_lusztig_polynomial + + if w.parent() is not self._KLG: + w = self._KLG.from_reduced_word(w.reduced_word()) + bruhat = RecursivelyEnumeratedSet([w], lambda u: u.bruhat_lower_covers(), structure='graded') + return self.element_class(self, {G.from_reduced_word(v.reduced_word()): R(c(q=one)) + for v in bruhat if (c := polyfunc(v, w))}) + epsilon_ik_cache = {} @@ -2668,8 +2743,71 @@ def seminormal_test(n): ####################### -class MurphyBasis(CellularBasis): +class SGACellularBasis(CellularBasis): + r""" + A cellular basis of the symmetric group algebra. """ + def __init__(self, SGA): + r""" + Initialize ``self``. + + EXAMPLES:: + + sage: SGA = SymmetricGroupAlgebra(GF(3), 3) + sage: M = SGA.murphy_basis() + sage: TestSuite(M).run() + sage: KL = SGA.kazhdan_lusztig_cellular_basis() + sage: TestSuite(KL).run() + """ + CellularBasis.__init__(self, SGA, self._to_sga) + + def _repr_(self): + r""" + Return a string representation of ``self``. + + EXAMPLES:: + + sage: SGA = SymmetricGroupAlgebra(GF(3), 4) + sage: SGA.murphy_basis() + Murphy basis of Symmetric group algebra of order 4 over Finite Field of size 3 + sage: SGA.kazhdan_lusztig_cellular_basis() + Kazhdan-Lusztig basis of Symmetric group algebra of order 4 over Finite Field of size 3 + """ + return self._name + " basis of {}".format(self._algebra) + + @cached_method + def one_basis(self): + r""" + Return the index of the basis element for the multiplicative identity. + + EXAMPLES:: + + sage: SGA = SymmetricGroupAlgebra(GF(3), 4) + sage: M = SGA.murphy_basis() + sage: M.one_basis() + ([4], [[1, 2, 3, 4]], [[1, 2, 3, 4]]) + """ + la = _Partitions([self._algebra.n]) + col = la.standard_tableaux()[0] + return (la, col, col) + + @cached_method + def one(self): + r""" + Return the element `1` in ``self``. + + EXAMPLES:: + + sage: SGA = SymmetricGroupAlgebra(GF(3), 4) + sage: M = SGA.murphy_basis() + sage: M.one() + C([4], [[1, 2, 3, 4]], [[1, 2, 3, 4]]) + """ + return self.monomial(self.one_basis()) + + +class MurphyBasis(SGACellularBasis): + r""" The Murphy basis of a symmetric group algebra. Let `R` be a commutative ring, and let `A = R[S_n]` denote the group @@ -2683,8 +2821,9 @@ class MurphyBasis(CellularBasis): .. MATH:: - M_{ST} = d(S)^{-1} R_{\lambda} d(T). + M_{S'T'} = d(S)^{-1} R_{\lambda} d(T), + where `S'` denotes the conjugate tableau. The Murphy basis is a :class:`cellular basis ` of `A`. @@ -2695,26 +2834,18 @@ class MurphyBasis(CellularBasis): sage: for la in M.simple_module_parameterization(): ....: CM = M.cell_module(la) ....: print(la, CM.dimension(), CM.simple_module().dimension()) - [3, 2] 5 4 + [2, 2, 1] 5 4 [3, 1, 1] 6 6 - [2, 2, 1] 5 1 - [2, 1, 1, 1] 4 4 - [1, 1, 1, 1, 1] 1 1 - """ - def __init__(self, SGA): - """ - Initialize ``self``. + [3, 2] 5 1 + [4, 1] 4 4 + [5] 1 1 - EXAMPLES:: + REFERENCES: - sage: SGA = SymmetricGroupAlgebra(GF(3), 3) - sage: M = SGA.murphy_basis() - sage: TestSuite(M).run() - """ - self._algebra = SGA - I = [(S, T) for la in Partitions_n(SGA.n) - for S in la.standard_tableaux() for T in la.standard_tableaux()] - CellularBasis.__init__(self, SGA, self._to_sga) + - [DJM1998]_ + - [Mathas2004]_ + """ + _name = "Murphy" def _to_sga(self, ind): r""" @@ -2726,53 +2857,59 @@ def _to_sga(self, ind): sage: M = SGA.murphy_basis() sage: for ind in M.basis().keys(): ....: print(ind, M._to_sga(ind)) - ([3], [[1, 2, 3]], [[1, 2, 3]]) [1, 2, 3] + [1, 3, 2] + [2, 1, 3] + [2, 3, 1] + [3, 1, 2] + [3, 2, 1] - ([2, 1], [[1, 3], [2]], [[1, 3], [2]]) [1, 2, 3] + [3, 2, 1] - ([2, 1], [[1, 3], [2]], [[1, 2], [3]]) [1, 3, 2] + [2, 3, 1] - ([2, 1], [[1, 2], [3]], [[1, 3], [2]]) [1, 3, 2] + [3, 1, 2] - ([2, 1], [[1, 2], [3]], [[1, 2], [3]]) [1, 2, 3] + [2, 1, 3] - ([1, 1, 1], [[1], [2], [3]], [[1], [2], [3]]) [1, 2, 3] + ([1, 1, 1], [[1], [2], [3]], [[1], [2], [3]]) [1, 2, 3] + [1, 3, 2] + [2, 1, 3] + [2, 3, 1] + [3, 1, 2] + [3, 2, 1] + ([2, 1], [[1, 3], [2]], [[1, 3], [2]]) [1, 2, 3] + [2, 1, 3] + ([2, 1], [[1, 3], [2]], [[1, 2], [3]]) [1, 3, 2] + [3, 1, 2] + ([2, 1], [[1, 2], [3]], [[1, 3], [2]]) [1, 3, 2] + [2, 3, 1] + ([2, 1], [[1, 2], [3]], [[1, 2], [3]]) [1, 2, 3] + [3, 2, 1] + ([3], [[1, 2, 3]], [[1, 2, 3]]) [1, 2, 3] """ return self._algebra.murphy_basis_element(ind[1], ind[2]) - def _repr_(self): - r""" - Return a string representation of ``self``. - - EXAMPLES:: - - sage: SGA = SymmetricGroupAlgebra(GF(3), 4) - sage: SGA.murphy_basis() - Murphy basis of Symmetric group algebra of order 4 over Finite Field of size 3 - """ - return "Murphy basis of {}".format(self._algebra) - @cached_method - def one_basis(self): - """ - Return the index of the basis element for the multiplicative identity. +class KLCellularBasis(SGACellularBasis): + """ + The Kazhdan-Lusztig `C'` basis (at `q = 1`) of the symmetric group + algebra realized as a cellular basis. - EXAMPLES:: + EXAMPLES:: - sage: SGA = SymmetricGroupAlgebra(GF(3), 4) - sage: M = SGA.murphy_basis() - sage: M.one_basis() - """ - col = _Partitions([1]*self._algebra.n).standard_tableaux()[0] - return (col, col) + sage: SGA = SymmetricGroupAlgebra(GF(3), 5) + sage: KL = SGA.kazhdan_lusztig_cellular_basis() + sage: for la in KL.simple_module_parameterization(): + ....: CM = KL.cell_module(la) + ....: print(la, CM.dimension(), CM.simple_module().dimension()) + [2, 2, 1] 5 4 + [3, 1, 1] 6 6 + [3, 2] 5 1 + [4, 1] 4 4 + [5] 1 1 + """ + _name = "Kazhdan-Lusztig" - @cached_method - def one(self): - """ - Return the element `1` in ``self``. + def _to_sga(self, ind): + r""" + Return the element in the symmetric group algebra indexed by ``ind``. EXAMPLES:: - sage: SGA = SymmetricGroupAlgebra(GF(3), 4) - sage: M = SGA.murphy_basis() - sage: M.one() - """ - return self.monomial(self.one_basis()) + sage: SGA = SymmetricGroupAlgebra(GF(3), 3) + sage: KL = SGA.kazhdan_lusztig_cellular_basis() + sage: for ind in KL.basis().keys(): + ....: print(ind, KL._to_sga(ind)) + ([1, 1, 1], [[1], [2], [3]], [[1], [2], [3]]) [1, 2, 3] + [1, 3, 2] + [2, 1, 3] + [2, 3, 1] + [3, 1, 2] + [3, 2, 1] + ([2, 1], [[1, 3], [2]], [[1, 3], [2]]) [1, 2, 3] + [2, 1, 3] + ([2, 1], [[1, 3], [2]], [[1, 2], [3]]) [1, 2, 3] + [1, 3, 2] + [2, 1, 3] + [3, 1, 2] + ([2, 1], [[1, 2], [3]], [[1, 3], [2]]) [1, 2, 3] + [1, 3, 2] + [2, 1, 3] + [2, 3, 1] + ([2, 1], [[1, 2], [3]], [[1, 2], [3]]) [1, 2, 3] + [1, 3, 2] + ([3], [[1, 2, 3]], [[1, 2, 3]]) [1, 2, 3] + """ + from sage.combinat.rsk import RSK_inverse + S = ind[1] + T = ind[2] + w = RSK_inverse(T, S, output="permutation") + return self._algebra.kazhdan_lusztig_basis_element(w) + ####################### From ff616a8bd2bd163b28a99afa79c70e38701c3f50 Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Tue, 12 Dec 2023 10:04:48 +0900 Subject: [PATCH 3/4] Some last little details. --- src/sage/combinat/symmetric_group_algebra.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/sage/combinat/symmetric_group_algebra.py b/src/sage/combinat/symmetric_group_algebra.py index d5a230abc50..abfc017591d 100644 --- a/src/sage/combinat/symmetric_group_algebra.py +++ b/src/sage/combinat/symmetric_group_algebra.py @@ -2175,7 +2175,7 @@ def kazhdan_lusztig_basis_element(self, w): from sage.groups.perm_gps.permgroup_named import SymmetricGroup q = PolynomialRing(R, 'q').gen() self._KLG = SymmetricGroup(self.n) - self._cellular_KL = KazhdanLusztigPolynomial(KLG, q) + self._cellular_KL = KazhdanLusztigPolynomial(self._KLG, q) polyfunc = self._cellular_KL.P else: self._cellular_KL = Coxeter3Group(['A', self.n+1]) @@ -2870,7 +2870,8 @@ def _to_sga(self, ind): class KLCellularBasis(SGACellularBasis): """ The Kazhdan-Lusztig `C'` basis (at `q = 1`) of the symmetric group - algebra realized as a cellular basis. + algebra realized as a :class:`cellular basis + ` EXAMPLES:: From e1f1a463efaf1c54b3ca0a3d5397ba968d100697 Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Mon, 18 Dec 2023 10:07:14 +0900 Subject: [PATCH 4/4] Addressing reviewer comments. --- src/sage/combinat/symmetric_group_algebra.py | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/sage/combinat/symmetric_group_algebra.py b/src/sage/combinat/symmetric_group_algebra.py index abfc017591d..031940f5283 100644 --- a/src/sage/combinat/symmetric_group_algebra.py +++ b/src/sage/combinat/symmetric_group_algebra.py @@ -2076,7 +2076,7 @@ def murphy_basis(self): """ return MurphyBasis(self) - @cached_method + @cached_method(key=lambda s, X, Y: (StandardTableaux()(X), StandardTableaux()(Y))) def murphy_basis_element(self, S, T): r""" Return the Murphy basis element indexed by ``S`` and ``T``. @@ -2095,15 +2095,28 @@ def murphy_basis_element(self, S, T): [[1, 3], [2]] [[1, 2], [3]] [1, 3, 2] + [3, 1, 2] [[1, 2], [3]] [[1, 3], [2]] [1, 3, 2] + [2, 3, 1] [[1, 2], [3]] [[1, 2], [3]] [1, 2, 3] + [3, 2, 1] + + TESTS:: + + sage: SGA = SymmetricGroupAlgebra(QQ, 3) + sage: SGA.murphy_basis_element([[1,2,3,4]], [[1,2],[3,4]]) + Traceback (most recent call last): + ... + ValueError: [[1, 2, 3, 4]] is not an element of Standard tableaux of size 3 + sage: SGA.murphy_basis_element([[1,2,3]], [[1,2],[3]]) + Traceback (most recent call last): + ... + ValueError: S and T must have the same shape """ + std_tab = StandardTableaux(self.n) + S = std_tab(S) + T = std_tab(T) S = S.conjugate() T = T.conjugate() la = S.shape() if la != T.shape(): raise ValueError("S and T must have the same shape") - if sum(la) != self.n: - raise ValueError(f"the shape must be a partition of size {self.n}") G = self.group() ds = G(list(sum((row for row in S), ())))