Skip to content
This repository has been archived by the owner on Jan 30, 2023. It is now read-only.

Commit

Permalink
Changing Coxeter groups to use _default_side.
Browse files Browse the repository at this point in the history
  • Loading branch information
Travis Scrimshaw committed Jul 9, 2017
1 parent 7de256c commit 1fbee1b
Show file tree
Hide file tree
Showing 9 changed files with 114 additions and 62 deletions.
Expand Up @@ -140,6 +140,8 @@ def Irreducible(self):
return self._with_axiom('Irreducible')

class ParentMethods:
_default_side = "right"

@abstract_method
def index_set(self):
r"""
Expand Down Expand Up @@ -910,7 +912,7 @@ def apply_simple_reflection_right(self, i):
s = self.parent().simple_reflections()
return self * s[i]

def apply_simple_reflection(self, i, side='right'):
def apply_simple_reflection(self, i, side=None):
"""
Return ``self`` multiplied by the simple reflection ``s[i]``.
Expand Down Expand Up @@ -942,7 +944,8 @@ def apply_simple_reflection(self, i, side='right'):
sage: w.apply_simple_reflection(2, side = "right")
(1, 2, 0, 3)
By default, ``side`` is ``"right"``::
The ``side`` is the preferred side of the Coxeter group
implementation, in this case it is on the right::
sage: w.apply_simple_reflection(0)
(2, 1, 3, 0)
Expand Down Expand Up @@ -973,21 +976,22 @@ def apply_simple_reflection(self, i, side='right'):
sage: w.apply_simple_reflection_right.__module__
'sage.categories.complex_reflection_or_generalized_coxeter_groups'
"""
if side is None:
side = self.parent()._default_side
if side == 'right':
return self.apply_simple_reflection_right(i)
else:
return self.apply_simple_reflection_left(i)

def apply_simple_reflections(self, word, side='right', type='simple'):
def apply_simple_reflections(self, word, side=None, type='simple'):
r"""
Return the result of the (left/right) multiplication of
``self`` by ``word``.
INPUT:
- ``word`` -- a sequence of indices of simple reflections
- ``side`` -- (default: ``'right'``) indicates multiplying
from left or right
- ``side`` -- indicates multiplying from left or right (optional)
This is a specialized implementation of
:meth:`apply_reflections` for the simple reflections. The
Expand Down Expand Up @@ -1015,16 +1019,15 @@ def apply_simple_reflections(self, word, side='right', type='simple'):
self = self.apply_simple_reflection(i, side)
return self

def apply_reflections(self, word, side='right', word_type='all'):
def apply_reflections(self, word, side=None, word_type='all'):
r"""
Return the result of the (left/right) multiplication of
``self`` by ``word``.
INPUT:
- ``word`` -- a sequence of indices of reflections
- ``side`` -- (default: ``'right'``) indicates multiplying
from left or right
- ``side`` -- indicates multiplying from left or right (optional)
- ``word_type`` -- (optional, default: ``'all'``):
either ``'simple'``, ``'distinguished'``, or ``'all'``
Expand Down Expand Up @@ -1071,6 +1074,8 @@ def apply_reflections(self, word, side='right', word_type='all'):
reflections = self.parent().distinguished_reflections()
else:
reflections = self.parent().reflections()
if side is None:
side = self.parent()._default_side
if side == 'left':
for i in word:
self = reflections[i] * self
Expand Down
78 changes: 42 additions & 36 deletions src/sage/categories/coxeter_groups.py
Expand Up @@ -160,15 +160,15 @@ def __iter__(self):
"""
return iter(self.weak_order_ideal(predicate = ConstantFunction(True)))

def weak_order_ideal(self, predicate, side ="right", category = None):
def weak_order_ideal(self, predicate, side=None, category=None):
"""
Returns a weak order ideal defined by a predicate
INPUT:
- ``predicate``: a predicate on the elements of ``self`` defining an
weak order ideal in ``self``
- ``side``: "left" or "right" (default: "right")
- ``side`` -- ``"left"`` or ``"right"`` (optional)
OUTPUT: an enumerated set
Expand Down Expand Up @@ -332,14 +332,14 @@ class is not unique and we only obtain one such class.
from sage.combinat.permutation import Permutations
return set(self.from_reduced_word(w) for w in Permutations(self._index_set))

def grassmannian_elements(self, side="right"):
def grassmannian_elements(self, side=None):
"""
Return the left or right Grassmannian elements of ``self``
as an enumerated set.
INPUT:
- ``side`` -- (default: ``"right"``) ``"left"`` or ``"right"``
- ``side`` -- ``"left"`` or ``"right"`` (optional)
EXAMPLES::
Expand Down Expand Up @@ -380,7 +380,7 @@ def _test_reduced_word(self, **options):
tester.assertEquals(self.from_reduced_word(red), x)
tester.assertEquals(self.prod((s[i] for i in red)), x)

def simple_projection(self, i, side = 'right', length_increasing = True):
def simple_projection(self, i, side=None, length_increasing=True):
r"""
INPUT:
Expand Down Expand Up @@ -424,14 +424,14 @@ def simple_projection(self, i, side = 'right', length_increasing = True):
return lambda x: x.apply_simple_projection(i, side = side, length_increasing = length_increasing)

@cached_method
def simple_projections(self, side = 'right', length_increasing = True):
def simple_projections(self, side=None, length_increasing=True):
r"""
Returns the family of simple projections, also known as 0-Hecke or Demazure operators.
INPUT:
- ``self`` - a Coxeter group `W`
- ``side`` - 'left' or 'right' (default: 'right')
- ``side`` -- ``'left'`` or ``'right'`` (optional)
- ``length_increasing`` - a boolean (default: True) specifying
whether the operator increases or decreases length
Expand Down Expand Up @@ -837,7 +837,7 @@ def _test_descents(self, **options):
tester.assertNotIn(i, si.descents(positive=True, side='right'))

class ElementMethods:
def has_descent(self, i, side = 'right', positive=False):
def has_descent(self, i, side=None, positive=False):
"""
Returns whether i is a (left/right) descent of self.
Expand All @@ -862,6 +862,8 @@ def has_descent(self, i, side = 'right', positive=False):
"""
if not isinstance(positive, bool):
raise TypeError("%s is not a boolean"%(bool))
if side is None:
side = self.parent()._default_side
if side == 'right':
return self.has_right_descent(i) != positive
if side != 'left':
Expand Down Expand Up @@ -915,7 +917,7 @@ def has_left_descent(self, i):
"""
return (~self).has_right_descent(i)

def first_descent(self, side = 'right', index_set=None, positive=False):
def first_descent(self, side=None, index_set=None, positive=False):
"""
Returns the first left (resp. right) descent of self, as
ane element of ``index_set``, or ``None`` if there is none.
Expand All @@ -939,17 +941,17 @@ def first_descent(self, side = 'right', index_set=None, positive=False):
if index_set is None:
index_set = self.parent().index_set()
for i in index_set:
if self.has_descent(i, side = side, positive = positive):
if self.has_descent(i, side=side, positive=positive):
return i
return None

def descents(self, side = 'right', index_set=None, positive=False):
def descents(self, side=None, index_set=None, positive=False):
"""
INPUT:
- ``index_set`` - a subset (as a list or iterable) of the nodes of the Dynkin diagram;
(default: all of them)
- ``side`` - 'left' or 'right' (default: 'right')
- ``side`` -- ``'left'`` or ``'right'`` (optional)
- ``positive`` - a boolean (default: ``False``)
Returns the descents of self, as a list of elements of the
Expand Down Expand Up @@ -981,14 +983,14 @@ def descents(self, side = 'right', index_set=None, positive=False):
TODO: side, index_set, positive
"""
if index_set is None:
index_set=self.parent().index_set()
return [ i for i in index_set if self.has_descent(i, side = side, positive = positive) ]
index_set = self.parent().index_set()
return [i for i in index_set if self.has_descent(i, side=side, positive=positive)]

def is_grassmannian(self, side = "right"):
def is_grassmannian(self, side=None):
"""
INPUT:
- ``side`` - "left" or "right" (default: "right")
- ``side`` -- ``"left"`` or ``"right"``
Tests whether ``self`` is Grassmannian, i.e. it has at
most one descent on the right (resp. on the left).
Expand Down Expand Up @@ -1414,12 +1416,12 @@ def canonical_matrix(self):
G = self.parent().canonical_representation()
return G.prod(G.simple_reflection(i) for i in self.reduced_word()).matrix()

def coset_representative(self, index_set, side = 'right'):
def coset_representative(self, index_set, side=None):
r"""
INPUT:
- ``index_set`` - a subset (or iterable) of the nodes of the Dynkin diagram
- ``side`` - 'left' or 'right'
- ``side`` -- ``'left'`` or ``'right'`` (optional)
Returns the unique shortest element of the Coxeter group
$W$ which is in the same left (resp. right) coset as
Expand Down Expand Up @@ -1462,12 +1464,12 @@ def coset_representative(self, index_set, side = 'right'):
return self
self = self.apply_simple_reflection(i, side = side)

def apply_simple_projection(self, i, side = 'right', length_increasing = True):
def apply_simple_projection(self, i, side=None, length_increasing=True):
r"""
INPUT:
- ``i`` - an element of the index set of the Coxeter group
- ``side`` - 'left' or 'right' (default: 'right')
- ``side`` -- ``'left'`` or ``'right'`` (optional)
- ``length_increasing`` - a boolean (default: True) specifying
the direction of the projection
Expand Down Expand Up @@ -1670,7 +1672,7 @@ def bruhat_lower_covers_reflections(self):
wi = self.apply_simple_reflection(i)
return [(u.apply_simple_reflection(i),r.apply_conjugation_by_simple_reflection(i)) for u,r in wi.bruhat_lower_covers_reflections() if not u.has_descent(i)] + [(wi, self.parent().simple_reflection(i))]

def lower_cover_reflections(self, side = 'right'):
def lower_cover_reflections(self, side=None):
r"""
Returns the reflections ``t`` such that ``self`` covers ``self`` ``t``.
Expand All @@ -1686,7 +1688,8 @@ def lower_cover_reflections(self, side = 'right'):
[s2*s3*s2, s3, s1]
"""

if side is None:
side = self.parent()._default_side
if side == 'left':
self = self.inverse()
return [x[1] for x in self.bruhat_lower_covers_reflections()]
Expand Down Expand Up @@ -1718,7 +1721,7 @@ def bruhat_upper_covers_reflections(self):
Covers += [(wi,self.parent().simple_reflection(i))]
return uniq(Covers)

def cover_reflections(self, side = 'right'):
def cover_reflections(self, side=None):
r"""
Returns the set of reflections ``t`` such that ``self`` ``t`` covers ``self``.
Expand All @@ -1734,7 +1737,8 @@ def cover_reflections(self, side = 'right'):
[s4, s2, s1*s2*s1, s3*s4*s3]
"""

if side is None:
side = self.parent()._default_side
if side == 'left':
self = self.inverse()
return [x[1] for x in self.bruhat_upper_covers_reflections()]
Expand Down Expand Up @@ -1811,14 +1815,14 @@ def bruhat_le(self, other):
else:
return self == other

def weak_le(self, other, side = 'right'):
def weak_le(self, other, side=None):
"""
comparison in weak order
INPUT:
- other - an element of the same Coxeter group
- side - 'left' or 'right' (default: 'right')
- ``side`` -- ``"left"`` or ``"right"`` (optional)
OUTPUT: a boolean
Expand Down Expand Up @@ -1881,13 +1885,13 @@ def weak_le(self, other, side = 'right'):
self = self.apply_simple_reflection(desc, side = prefix_side)
other = other.apply_simple_reflection(desc, side = prefix_side)

def weak_covers(self, side = 'right', index_set = None, positive = False):
def weak_covers(self, side=None, index_set=None, positive=False):
"""
Returns all elements that ``self`` covers in weak order.
INPUT:
- side - 'left' or 'right' (default: 'right')
- ``side`` -- ``'left'`` or ``'right'`` (optional)
- positive - a boolean (default: False)
- index_set - a list of indices or None
Expand Down Expand Up @@ -2028,7 +2032,7 @@ def is_coxeter_sortable(self,c,sorting_word=None):
i = 0
return True

def apply_demazure_product(self, element, side = 'right', length_increasing = True):
def apply_demazure_product(self, element, side=None, length_increasing=True):
r"""
Returns the Demazure or 0-Hecke product of ``self`` with another Coxeter group element.
Expand All @@ -2041,10 +2045,10 @@ def apply_demazure_product(self, element, side = 'right', length_increasing = Tr
reduced word) of elements from the index set of the
Coxeter group.
- ``side`` -- 'left' or 'right' (default: 'right'); the
- ``side`` -- ``'left'`` or ``'right'`` (optional); the
side of ``self`` on which the element should be
applied. If ``side`` is 'left' then the operation is
applied on the left.
applied; if ``side`` is ``'left'`` then the operation
is applied on the left
- ``length_increasing`` -- a boolean (default True)
whether to act length increasingly or decreasingly
Expand Down Expand Up @@ -2079,6 +2083,8 @@ def apply_demazure_product(self, element, side = 'right', length_increasing = Tr
# the copy is so that if we need to reverse the list, the original will not
# get reversed
the_word = copy(element)
if side is None:
side = self.parent()._default_side
if side == 'left':
the_word.reverse()
for i in the_word:
Expand Down Expand Up @@ -2287,13 +2293,13 @@ def left_inversions_as_reflections(self):

return self.inverse().inversions_as_reflections()

def lower_covers(self, side = 'right', index_set = None):
def lower_covers(self, side=None, index_set=None):
"""
Returns all elements that ``self`` covers in weak order.
INPUT:
- side - 'left' or 'right' (default: 'right')
- ``side`` -- ``'left'`` or ``'right'`` (optional)
- index_set - a list of indices or None
OUTPUT: a list
Expand Down Expand Up @@ -2322,13 +2328,13 @@ def lower_covers(self, side = 'right', index_set = None):
"""
return self.weak_covers(side = side, index_set = index_set, positive = False)

def upper_covers(self, side = 'right', index_set = None):
def upper_covers(self, side=None, index_set=None):
"""
Returns all elements that cover ``self`` in weak order.
INPUT:
- side - 'left' or 'right' (default: 'right')
- ``side`` -- ``'left'`` or ``'right'`` (optional)
- index_set - a list of indices or None
OUTPUT: a list
Expand Down
3 changes: 2 additions & 1 deletion src/sage/categories/finite_coxeter_groups.py
Expand Up @@ -213,7 +213,8 @@ def bruhat_poset(self, facade=False):
covers = tuple([u, v] for v in self for u in v.bruhat_lower_covers() )
return Poset((self, covers), cover_relations=True, facade=facade)

def shard_poset(self, side='right'):
# FIXME: side is not used in this code
def shard_poset(self, side=None):
"""
Return the shard intersection order attached to `W`.
Expand Down

0 comments on commit 1fbee1b

Please sign in to comment.