Skip to content

Commit

Permalink
[FEATURE] Implement exceedences method (#77)
Browse files Browse the repository at this point in the history
  • Loading branch information
VascoSch92 authored May 31, 2024
1 parent 39a422b commit 66670e0
Show file tree
Hide file tree
Showing 11 changed files with 200 additions and 162 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ FEATURE:
- `symmetria.CyclePermutation`: add `ascents` method
- `symmetria.Permutation`: add `descents` method
- `symmetria.CyclePermutation`: add `descents` method
- `symmetria.Permutation`: add `exceedances` method
- `symmetria.CyclePermutation`: add `exceedances` method


## \[0.0.4\] - 2024-05-28
Expand Down
5 changes: 5 additions & 0 deletions docs/source/pages/API_reference/elements/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ Here, **P** denotes the class ``Permutation``, **C** the class ``Cycle``, and **
- ✅
- ❌
- ✅
* - ``exceedances``
- Return the positions of the permutation exceedances
- ✅
- ❌
- ✅
* - ``inverse``
- Compute the inverse of the permutation
- ✅
Expand Down
11 changes: 3 additions & 8 deletions symmetria/elements/_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,6 @@ def __str__(self) -> str:
"""Implement method `str()`."""
raise NotImplementedError

# TODO: decide if we want to implement this method also for the classes Cycle and CycleDecomposition
# @staticmethod
# @abstractmethod
# def from_dict(permutation: Dict) -> "Element":
# raise NotImplementedError

@abstractmethod
def cycle_decomposition(self) -> "CycleDecomposition":
"""Return the cycle decomposition of the element."""
Expand Down Expand Up @@ -117,9 +111,10 @@ def map(self) -> Dict[int, int]:
"""Return a dictionary representing the map defined the element."""
raise NotImplementedError

def name(self) -> str:
@staticmethod
def name() -> str:
"""Shortcut for the class name. Used for the tests."""
return self.__class__.__name__
return __class__.__name__

@abstractmethod
def orbit(self, item: Any) -> List[Any]:
Expand Down
29 changes: 29 additions & 0 deletions symmetria/elements/cycle_decomposition.py
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,35 @@ def equivalent(self, other: Any) -> bool:
return symmetria.elements.permutation.Permutation.from_cycle_decomposition(self) == other
return False

def exceedances(self, weakly: bool = False) -> List[int]:
r"""Return the exceedances of the cycle decomposition.
Recall that an exceedance of a permutation :math:`\sigma \in S_n`, where :math:`n \in \mathbb{N}`, is any
position :math:`i \in \{ 1, ..., n\}` where :math:`\sigma(i) > i`. An exceedance is called weakly if
:math:`\sigma(i) \geq i`.
:param weakly: `True` to return the weakly exceedances of the cycle decomposition. Default `False`.
:type weakly: bool
:return: The exceedances of the cycle decomposition.
:rtype: List[int]
:example:
>>> from symmetria import Cycle, CycleDecomposition
...
>>> CycleDecomposition(Cycle(1, 2), Cycle(3)).exceedances()
[1]
>>> CycleDecomposition(Cycle(1, 2), Cycle(3)).exceedances(weakly=True)
[1, 3]
>>> CycleDecomposition(Cycle(2, 3), Cycle(4, 5, 1)).exceedances()
[1, 2, 4]
>>> CycleDecomposition(Cycle(1), Cycle(2), Cycle(3)).exceedances()
[]
>>> CycleDecomposition(Cycle(1), Cycle(2), Cycle(3)).exceedances(weakly=True)
[1, 2, 3]
"""
return symmetria.Permutation.from_cycle_decomposition(self).exceedances(weakly=weakly)

def inverse(self) -> "CycleDecomposition":
r"""Return the inverse of the cycle decomposition.
Expand Down
31 changes: 31 additions & 0 deletions symmetria/elements/permutation.py
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,37 @@ def equivalent(self, other: Any) -> bool:
return self == Permutation.from_cycle_decomposition(other)
return False

def exceedances(self, weakly: bool = False) -> List[int]:
r"""Return the exceedances of the permutation.
Recall that an exceedance of a permutation :math:`\sigma \in S_n`, where :math:`n \in \mathbb{N}`, is any
position :math:`i \in \{ 1, ..., n\}` where :math:`\sigma(i) > i`. An exceedance is called weakly if
:math:`\sigma(i) \geq i`.
:param weakly: `True` to return the weakly exceedances of the permutation. Default `False`.
:type weakly: bool
co
:return: The exceedances of the permutation.
:rtype: List[int]
:example:
>>> from symmetria import Permutation
...
>>> Permutation(1, 2, 3).exceedances()
[]
>>> Permutation(1, 2, 3).exceedances(weakly=True)
[1, 2, 3]
>>> Permutation(4, 3, 2, 1).exceedances()
[1, 2]
>>> Permutation(3, 4, 5, 2, 1, 6, 7).exceedances()
[1, 2, 3]
>>> Permutation(3, 4, 5, 2, 1, 6, 7).exceedances(weakly=True)
[1, 2, 3, 6, 7]
"""
if weakly:
return [i for i, p in enumerate(self.image, 1) if p >= i]
return [i for i, p in enumerate(self.image, 1) if p > i]

@classmethod
def from_cycle(cls, cycle: "Cycle") -> "Permutation":
"""Return a permutation from a cycle.
Expand Down
Loading

0 comments on commit 66670e0

Please sign in to comment.