Skip to content

Commit

Permalink
sagemathgh-37859: Implement the ladder idempotents of the symmetric g…
Browse files Browse the repository at this point in the history
…roup algebra

    
<!-- ^ Please provide a concise and informative title. -->
<!-- ^ Don't put issue numbers in the title, do this in the PR
description below. -->
<!-- ^ For example, instead of "Fixes sagemath#12345" use "Introduce new method
to calculate 1 + 2". -->
<!-- v Describe your changes below in detail. -->
<!-- v Why is this change required? What problem does it solve? -->
<!-- v If this PR resolves an open issue, please link to it here. For
example, "Fixes sagemath#12345". -->

We implement the so-called ladder idempotents of the symmetric group
algebra $F[S_n]$, defined by Ryom-Hansen, which can be used to construct
the projective covers of simple modules when the field $F$ has positive
characteristic.

### 📝 Checklist

<!-- Put an `x` in all the boxes that apply. -->

- [x] The title is concise and informative.
- [x] The description explains in detail what this PR is about.
- [x] I have linked a relevant issue or discussion.
- [x] I have created tests covering the changes.
- [x] I have updated the documentation and checked the documentation
preview.

### ⌛ Dependencies

<!-- List all open PRs that this PR logically depends on. For example,
-->
<!-- - sagemath#12345: short description why this is a dependency -->
<!-- - sagemath#34567: ... -->
    
URL: sagemath#37859
Reported by: Travis Scrimshaw
Reviewer(s): Andrew Mathas
  • Loading branch information
Release Manager committed May 12, 2024
2 parents 08be24c + 5754976 commit 6fa34e7
Show file tree
Hide file tree
Showing 3 changed files with 201 additions and 0 deletions.
3 changes: 3 additions & 0 deletions src/doc/en/reference/references/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6174,6 +6174,9 @@ REFERENCES:
:doi: `10.1017/fms.2022.38`.
:arxiv:`2106.11141`.
.. [Ryom2015] Steen Ryom-Hansen. *Projective modules for the symmetric group and
Young's seminormal form*. J. Algebra **439** (2015) pp. 515-541.
.. [SV1970] \H. Schneider and M. Vidyasagar. Cross-positive matrices. SIAM
Journal on Numerical Analysis, 7:508-519, 1970.
Expand Down
104 changes: 104 additions & 0 deletions src/sage/combinat/partition.py
Original file line number Diff line number Diff line change
Expand Up @@ -2945,6 +2945,110 @@ def top_garnir_tableau(self,e,cell):
t[row+1][col-b+1:col+1] = [m+a+col-b+1+i for i in range(b)]
return tableau.StandardTableau(t)

def ladder_tableau(self, e, ladder_lengths=False):
r"""
Return the ladder tableau of shape ``self``.
The `e`-*ladder tableau* is the standard Young tableau obtained
by reading the *ladders*, the set of cells `(i, j)` that differ
from `(i+e-1, j-1)`, of the partition `\lambda` from left-to-right.
INPUT:
- ``e`` -- a nonnegative integer; ``0`` is considered as `\infty`
(analogous to the characteristic of a ring)
- ``ladder_sizes`` -- (default: ``False``) if ``True``, also return
the sizes of the ladders
.. SEEALSO::
:meth:`ladders`
EXAMPLES::
sage: la = Partition([6, 5, 3, 1])
sage: ascii_art(la.ladder_tableau(3))
1 2 3 5 7 10
4 6 8 11 13
9 12 14
15
sage: la.ladder_tableau(3, ladder_lengths=True)[1]
[1, 1, 2, 2, 3, 3, 3]
sage: ascii_art(la.ladder_tableau(0))
1 2 3 4 5 6
7 8 9 10 11
12 13 14
15
sage: all(ll == 1 for ll in la.ladder_tableau(0, ladder_lengths=True)[1])
True
"""
Tlad = [[None] * val for val in self]
counter = 0
start = 0
n = sum(self)
sizes = []
e = e - 1 if e > 0 else n # change to the slope
while counter < n:
cur = start
size = 0
for i, val in enumerate(self):
if cur < 0:
break
if cur < val:
counter += 1
Tlad[i][cur] = counter
size += 1
cur -= e
if ladder_lengths and size:
sizes.append(size)
start += 1
ret = tableau.StandardTableaux(self)(Tlad)
if ladder_lengths:
return (ret, sizes)
return ret

def ladders(self, e):
r"""
Return a dictionary containing the ladders in the diagram of ``self``.
For `e > 0`, a node `(i, j)` in a partition belongs to the `l`-th
`e`-ladder if `l = (e - 1) r + c`.
INPUT:
- ``e`` -- a nonnegative integer; if ``0``, then we
set ``e = self.size() + 1``
EXAMPLES::
sage: Partition([3, 2]).ladders(3)
{0: [(0, 0)], 1: [(0, 1)], 2: [(0, 2), (1, 0)], 3: [(1, 1)]}
When ``e`` is ``0``, the cells are in bijection with the ladders,
but the index of the ladder depends on the size of the partition::
sage: Partition([3, 2]).ladders(0)
{0: [(0, 0)], 1: [(0, 1)], 2: [(0, 2)], 5: [(1, 0)], 6: [(1, 1)]}
sage: Partition([3, 2, 1]).ladders(0)
{0: [(0, 0)], 1: [(0, 1)], 2: [(0, 2)], 6: [(1, 0)], 7: [(1, 1)],
12: [(2, 0)]}
sage: Partition([3, 1, 1]).ladders(0)
{0: [(0, 0)], 1: [(0, 1)], 2: [(0, 2)], 5: [(1, 0)], 10: [(2, 0)]}
sage: Partition([1, 1, 1]).ladders(0)
{0: [(0, 0)], 3: [(1, 0)], 6: [(2, 0)]}
"""
if e == 0:
e = sum(self) + 1
ladders = {}
for row, val in enumerate(self):
for col in range(val):
ell = col + row * (e - 1)
if ell not in ladders:
ladders[ell] = []
ladders[ell].append((row, col))
return ladders

@cached_method
def young_subgroup(self):
r"""
Expand Down
94 changes: 94 additions & 0 deletions src/sage/combinat/symmetric_group_algebra.py
Original file line number Diff line number Diff line change
Expand Up @@ -1244,6 +1244,100 @@ def _blocks_dictionary(self):
blocks[c] = [la]
return blocks

def ladder_idemponent(self, la):
r"""
Return the ladder idempontent of ``self``.
Let `F` be a field of characteristic `p`. The *ladder idempotent*
of shape `\lambda` is the idempotent of `F[S_n]` defined as follows.
Let `T` be the :meth:`ladder tableau
<sage.combinat.partition.Partition.ladder_tableau>` of shape `\lambda`.
Let `[T]` be the set of standard tableaux whose residue sequence
is the same as for `T`. Let `\alpha` be the sizes of the ladders
of `\lambda`. Then the ladder idempontent is constructed as
.. MATH::
\widetilde{e}_{\lambda} := \frac{1}{\alpha!}
\left( \sum_{\sigma \in S_{\alpha}} \sigma \right)
\left( \overline{\sum_{U \in [T]} E_U} \right),
where `E_{UU}` is the :meth:`seminormal_basis` element over `\QQ`
and we project the sum to `F`, `S_{\alpha}` is the Young subgroup
corresponding to `\alpha`, and `\alpha! = \alpha_1! \cdots \alpha_k!`.
EXAMPLES::
sage: SGA = SymmetricGroupAlgebra(GF(3), 4)
sage: for la in Partitions(SGA.n):
....: idem = SGA.ladder_idemponent(la)
....: print(la)
....: print(idem)
....: assert idem^2 == idem
[4]
2*[1, 2, 3, 4] + 2*[1, 2, 4, 3] + 2*[2, 1, 3, 4] + 2*[2, 1, 4, 3]
+ 2*[3, 4, 1, 2] + 2*[3, 4, 2, 1] + 2*[4, 3, 1, 2] + 2*[4, 3, 2, 1]
[3, 1]
2*[1, 2, 3, 4] + 2*[1, 2, 4, 3] + 2*[2, 1, 3, 4] + 2*[2, 1, 4, 3]
+ [3, 4, 1, 2] + [3, 4, 2, 1] + [4, 3, 1, 2] + [4, 3, 2, 1]
[2, 2]
2*[1, 2, 3, 4] + 2*[1, 2, 4, 3] + 2*[2, 1, 3, 4] + 2*[2, 1, 4, 3]
+ 2*[3, 4, 1, 2] + 2*[3, 4, 2, 1] + 2*[4, 3, 1, 2] + 2*[4, 3, 2, 1]
[2, 1, 1]
2*[1, 2, 3, 4] + [1, 2, 4, 3] + 2*[1, 3, 2, 4] + [1, 3, 4, 2]
+ [1, 4, 2, 3] + 2*[1, 4, 3, 2] + 2*[2, 1, 3, 4] + [2, 1, 4, 3]
+ 2*[2, 3, 1, 4] + [2, 3, 4, 1] + [2, 4, 1, 3] + 2*[2, 4, 3, 1]
+ 2*[3, 1, 2, 4] + [3, 1, 4, 2] + 2*[3, 2, 1, 4] + [3, 2, 4, 1]
+ [4, 1, 2, 3] + 2*[4, 1, 3, 2] + [4, 2, 1, 3] + 2*[4, 2, 3, 1]
[1, 1, 1, 1]
2*[1, 2, 3, 4] + [1, 2, 4, 3] + [2, 1, 3, 4] + 2*[2, 1, 4, 3]
+ 2*[3, 4, 1, 2] + [3, 4, 2, 1] + [4, 3, 1, 2] + 2*[4, 3, 2, 1]
When `p = 0`, these idempotents will generate all of the simple
modules (which are the :meth:`Specht modules <specht_module>`
and also projective modules)::
sage: SGA = SymmetricGroupAlgebra(QQ, 5)
sage: for la in Partitions(SGA.n):
....: idem = SGA.ladder_idemponent(la)
....: assert idem^2 == idem
....: print(la, SGA.principal_ideal(idem).dimension())
[5] 1
[4, 1] 4
[3, 2] 5
[3, 1, 1] 6
[2, 2, 1] 5
[2, 1, 1, 1] 4
[1, 1, 1, 1, 1] 1
sage: [StandardTableaux(la).cardinality() for la in Partitions(SGA.n)]
[1, 4, 5, 6, 5, 4, 1]
REFERENCES:
- [Ryom2015]_
"""
R = self.base_ring()
p = R.characteristic()
n = self.n
if not p:
p = n + 1
la = _Partitions(la)
if sum(la) != n:
raise ValueError(f"{la} is not a partition of {n}")
Tlad, alpha = la.ladder_tableau(p, ladder_lengths=True)
if not all(val < p for val in alpha):
raise ValueError(f"{la} is not {p}-ladder restricted")
Tclass = Tlad.residue_sequence(p).standard_tableaux()
Elad = sum(epsilon_ik(T, T) for T in Tclass)
Elad = self.element_class(self, {sigma: R(c) for sigma, c in Elad._monomial_coefficients.items()})
from sage.groups.perm_gps.permgroup_named import SymmetricGroup
YG = SymmetricGroup(n).young_subgroup(alpha)
coeff = ~R.prod(factorial(val) for val in alpha)
G = self.group()
eprod = self.element_class(self, {G(list(elt.tuple())): coeff
for elt in YG})
return Elad * eprod

@cached_method
def algebra_generators(self):
r"""
Expand Down

0 comments on commit 6fa34e7

Please sign in to comment.