Skip to content

Commit

Permalink
gh-37830: Implement the Schur functors applied to semigroup represent…
Browse files Browse the repository at this point in the history
…ations

    
<!-- ^ 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 #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 #12345". -->

The Schur functor is an important part of the representation theory of
$GL_n$, but it can be defined generically for any representation of a
semigroup (well, really for any vector space, but the utility is for
representation theory). We provide an implementation, realizing the
natural representation structure. To help with examples, we also
implement the natural representation of any matrix (semi)group.

Along the way, we clean up some stuff with the sign representations.

### 📝 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,
-->
<!-- - #12345: short description why this is a dependency -->
<!-- - #34567: ... -->

- #37871 - Uses the `Subrepresentation` class implemented here.
    
URL: #37830
Reported by: Travis Scrimshaw
Reviewer(s): Matthias Köppe
  • Loading branch information
Release Manager committed Jun 16, 2024
2 parents 8f6b1e5 + ee80187 commit 19a6233
Show file tree
Hide file tree
Showing 5 changed files with 461 additions and 21 deletions.
17 changes: 11 additions & 6 deletions src/sage/categories/coxeter_groups.py
Original file line number Diff line number Diff line change
Expand Up @@ -937,22 +937,27 @@ def simple_projections(self, side='right', length_increasing=True):
from sage.sets.family import Family
return Family(self.index_set(), lambda i: self.simple_projection(i, side=side, length_increasing=length_increasing))

def sign_representation(self, base_ring=None, side="twosided"):
def sign_representation(self, base_ring=None):
r"""
Return the sign representation of ``self`` over ``base_ring``.
INPUT:
- ``base_ring`` -- (optional) the base ring; the default is `\ZZ`
- ``side`` -- ignored
EXAMPLES::
sage: W = WeylGroup(["A", 1, 1]) # needs sage.combinat sage.groups
sage: W.sign_representation() # needs sage.combinat sage.groups
sage: W = WeylGroup(['D', 4]) # needs sage.combinat sage.groups
sage: W.sign_representation(QQ) # needs sage.combinat sage.groups
Sign representation of
Weyl Group of type ['A', 1, 1] (as a matrix group acting on the root space)
over Integer Ring
Weyl Group of type ['D', 4] (as a matrix group acting on the ambient space)
over Rational Field
sage: # optional - gap3
sage: W = CoxeterGroup(['B',3], implementation="coxeter3")
sage: W.sign_representation()
Sign representation of Coxeter group of type ['B', 3]
implemented by Coxeter3 over Integer Ring
"""
if base_ring is None:
from sage.rings.integer_ring import ZZ
Expand Down
66 changes: 66 additions & 0 deletions src/sage/combinat/symmetric_group_algebra.py
Original file line number Diff line number Diff line change
Expand Up @@ -2367,6 +2367,72 @@ def _row_stabilizer(self, la):
G = self.group()
return self.sum_of_monomials(G(list(w.tuple())) for w in la.young_subgroup())

@cached_method
def _column_antistabilizer(self, la):
"""
Return the column antistabilizer element of a canonical standard tableau
of shape ``la``.
EXAMPLES::
sage: SGA = SymmetricGroupAlgebra(QQ, 3)
sage: for la in Partitions(3):
....: print(la, SGA._column_antistabilizer(la))
[3] [1, 2, 3]
[2, 1] [1, 2, 3] - [3, 2, 1]
[1, 1, 1] [1, 2, 3] - [1, 3, 2] - [2, 1, 3] + [2, 3, 1] + [3, 1, 2] - [3, 2, 1]
"""
T = []
total = 1 # make it 1-based
for r in la:
T.append(list(range(total, total+r)))
total += r
T = Tableau(T)
G = self.group()
R = self.base_ring()
return self._from_dict({G(list(w.tuple())): R(w.sign()) for w in T.column_stabilizer()},
remove_zeros=False)

@cached_method
def _young_symmetrizer(self, la):
"""
Return the Young symmetrizer of shape ``la`` of ``self``.
EXAMPLES::
sage: SGA = SymmetricGroupAlgebra(QQ, 3)
sage: for la in Partitions(3):
....: print(la, SGA._young_symmetrizer(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] - [3, 1, 2] - [3, 2, 1]
[1, 1, 1] [1, 2, 3] - [1, 3, 2] - [2, 1, 3] + [2, 3, 1] + [3, 1, 2] - [3, 2, 1]
"""
return self._column_antistabilizer(la) * self._row_stabilizer(la)

def young_symmetrizer(self, la):
"""
Return the Young symmetrizer of shape ``la`` of ``self``.
EXAMPLES::
sage: SGA = SymmetricGroupAlgebra(QQ, SymmetricGroup(3))
sage: SGA.young_symmetrizer([2,1])
() + (1,2) - (1,3,2) - (1,3)
sage: SGA = SymmetricGroupAlgebra(QQ, 4)
sage: SGA.young_symmetrizer([2,1,1])
[1, 2, 3, 4] - [1, 2, 4, 3] + [2, 1, 3, 4] - [2, 1, 4, 3]
- [3, 1, 2, 4] + [3, 1, 4, 2] - [3, 2, 1, 4] + [3, 2, 4, 1]
+ [4, 1, 2, 3] - [4, 1, 3, 2] + [4, 2, 1, 3] - [4, 2, 3, 1]
sage: SGA.young_symmetrizer([5,1,1])
Traceback (most recent call last):
...
ValueError: the partition [5, 1, 1] is not of size 4
"""
la = _Partitions(la)
if la.size() != self.n:
raise ValueError("the partition {} is not of size {}".format(la, self.n))
return self._young_symmetrizer(la)

def kazhdan_lusztig_cellular_basis(self):
r"""
Return the Kazhdan-Lusztig basis (at `q = 1`) of ``self``
Expand Down
62 changes: 50 additions & 12 deletions src/sage/groups/matrix_gps/matrix_group.py
Original file line number Diff line number Diff line change
Expand Up @@ -345,19 +345,14 @@ def _latex_(self):
gens = ', '.join(latex(x) for x in self.gens())
return '\\left\\langle %s \\right\\rangle' % gens

def sign_representation(self, base_ring=None, side="twosided"):
def sign_representation(self, base_ring=None):
r"""
Return the sign representation of ``self`` over ``base_ring``.
.. WARNING::
Assumes ``self`` is a matrix group over a field which has
embedding over real numbers.
INPUT:
- ``base_ring`` -- (optional) the base ring; the default is `\ZZ`
- ``side`` -- ignored
- ``base_ring`` -- (optional) the base ring; the default is the base
ring of ``self``
EXAMPLES::
Expand All @@ -367,22 +362,65 @@ def sign_representation(self, base_ring=None, side="twosided"):
sage: e
[1 0]
[0 1]
sage: V._default_sign(e)
1
sage: m2 = V.an_element()
sage: m2
2*B['v']
sage: m2*e
2*B['v']
sage: m2*e*e
2*B['v']
sage: W = WeylGroup(["A", 1, 1])
sage: W.sign_representation()
Sign representation of
Weyl Group of type ['A', 1, 1] (as a matrix group acting on the root space)
over Rational Field
sage: G = GL(4, 2)
sage: G.sign_representation() == G.trivial_representation()
True
"""
if base_ring is None:
from sage.rings.integer_ring import ZZ
base_ring = ZZ
base_ring = self.base_ring()
if base_ring.characteristic() == 2: # characteristic 2
return self.trivial_representation()
from sage.modules.with_basis.representation import SignRepresentationMatrixGroup
return SignRepresentationMatrixGroup(self, base_ring)

def natural_representation(self, base_ring=None):
r"""
Return the natural representation of ``self`` over ``base_ring``.
INPUT:
- ``base_ring`` -- (optional) the base ring; the default is the base
ring of ``self``
EXAMPLES::
sage: G = groups.matrix.SL(6, 3)
sage: V = G.natural_representation()
sage: V
Natural representation of Special Linear Group of degree 6
over Finite Field of size 3
sage: e = prod(G.gens())
sage: e
[2 0 0 0 0 1]
[2 0 0 0 0 0]
[0 2 0 0 0 0]
[0 0 2 0 0 0]
[0 0 0 2 0 0]
[0 0 0 0 2 0]
sage: v = V.an_element()
sage: v
2*e[0] + 2*e[1]
sage: e * v
e[0] + e[1] + e[2]
"""
from sage.modules.with_basis.representation import NaturalMatrixRepresentation
return NaturalMatrixRepresentation(self, base_ring)


###################################################################
#
# Matrix group over a generic ring
Expand Down
3 changes: 1 addition & 2 deletions src/sage/groups/perm_gps/permgroup.py
Original file line number Diff line number Diff line change
Expand Up @@ -4943,14 +4943,13 @@ def upper_central_series(self):

from sage.groups.generic import structure_description

def sign_representation(self, base_ring=None, side="twosided"):
def sign_representation(self, base_ring=None):
r"""
Return the sign representation of ``self`` over ``base_ring``.
INPUT:
- ``base_ring`` -- (optional) the base ring; the default is `\ZZ`
- ``side`` -- ignored
EXAMPLES::
Expand Down
Loading

0 comments on commit 19a6233

Please sign in to comment.