Skip to content

Commit

Permalink
[FEATURE] Add method records (#82)
Browse files Browse the repository at this point in the history
  • Loading branch information
VascoSch92 authored Jun 1, 2024
1 parent 8083291 commit 0694992
Show file tree
Hide file tree
Showing 8 changed files with 122 additions and 23 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ FEATURE:
- `symmetria.CyclePermutation`: add `descents` method
- `symmetria.Permutation`: add `exceedances` method
- `symmetria.CyclePermutation`: add `exceedances` method
- `symmetria.Permutation`: add `records` method
- `symmetria.CyclePermutation`: add `records` method

MAINTENANCE:
- `tests`: Refactor. Now the code is more concise, and it is easier to add a new test.
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 @@ -125,6 +125,11 @@ Here, **P** denotes the class ``Permutation``, **C** the class ``Cycle``, and **
- ✅
- ✅
- ✅
* - ``records``
- Return the positions of the permutation records
- ✅
- ❌
- ✅
* - ``sgn``
- Return the sign of the permutation
- ✅
Expand Down
25 changes: 25 additions & 0 deletions symmetria/elements/cycle_decomposition.py
Original file line number Diff line number Diff line change
Expand Up @@ -775,6 +775,31 @@ def order(self) -> int:
"""
return lcm(*[len(cycle) for cycle in self])

def records(self) -> List[int]:
r"""Return the records of the cycle decomposition.
Recall that a record of a permutation :math:`\sigma \in S_n`, where :math:`n \in \mathbb{N}`, is a position
:math:`i \in \{1, ..., n\}` such that is either :math:`i=1` or :math:`\sigma(j) < \sigma(i)`
for all :math:`j<i`.
.. note:: There are definitions of records in the literature where the first index is not considered as a
record.
:return: The records of the cycle decomposition.
:rtype: List[int]
:example:
>>> from symmetria import Cycle, CycleDecomposition
...
>>> CycleDecomposition(Cycle(1)).records()
[1]
>>> CycleDecomposition(Cycle(1, 2), Cycle(3)).records()
[1, 3]
>>> CycleDecomposition(Cycle(1), Cycle(2, 4, 7, 6), Cycle(3, 5)).records()
[1, 2, 3, 4]
"""
return symmetria.Permutation.from_cycle_decomposition(self).records()

def sgn(self) -> int:
r"""Return the sign of the cycle decomposition.
Expand Down
77 changes: 54 additions & 23 deletions symmetria/elements/permutation.py
Original file line number Diff line number Diff line change
Expand Up @@ -518,29 +518,29 @@ def equivalent(self, other: Any) -> bool:
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]
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
: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]
Expand Down Expand Up @@ -910,6 +910,37 @@ def order(self) -> int:
"""
return self.cycle_decomposition().order()

def records(self) -> List[int]:
r"""Return the records of the permutation.
Recall that a record of a permutation :math:`\sigma \in S_n`, where :math:`n \in \mathbb{N}`, is a position
:math:`i \in \{1, ..., n\}` such that is either :math:`i=1` or :math:`\sigma(j) < \sigma(i)`
for all :math:`j<i`.
.. note:: There are definitions of records in the literature where the first index is not considered as a
record.
:return: The records of the permutation.
:rtype: List[int]
:example:
>>> from symmetria import Permutation
...
>>> Permutation(1, 2, 3).records()
[1, 2, 3]
>>> Permutation(3, 1, 2).records()
[1]
>>> Permutation(1, 3, 4, 5, 2, 6).records()
[1, 2, 3, 4, 6]
"""
records = [1]
tmp_max = self[1]
for i in self.domain:
if self[i] > tmp_max:
records.append(i)
tmp_max = self[i]
return records

def sgn(self) -> int:
r"""Return the sign of the permutation.
Expand Down
5 changes: 5 additions & 0 deletions tests/tests_cycle_decomposition/test_cases.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,11 @@
(CycleDecomposition(Cycle(1), Cycle(2, 4, 7, 6), Cycle(3, 5)), 4),
(CycleDecomposition(Cycle(1, 6, 2, 4, 7), Cycle(3, 5)), 10),
]
TEST_RECORDS = [
(CycleDecomposition(Cycle(1)), [1]),
(CycleDecomposition(Cycle(1, 2), Cycle(3)), [1, 3]),
(CycleDecomposition(Cycle(1), Cycle(2, 4, 7, 6), Cycle(3, 5)), [1, 2, 3, 4]),
]
TEST_SUPPORT = [
(CycleDecomposition(Cycle(1)), set()),
(CycleDecomposition(Cycle(1), Cycle(2, 4, 7, 6), Cycle(3, 5)), {2, 4, 7, 6, 3, 5}),
Expand Down
15 changes: 15 additions & 0 deletions tests/tests_cycle_decomposition/test_generic_methods.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
TEST_ASCENTS,
TEST_INVERSE,
TEST_IS_EVEN,
TEST_RECORDS,
TEST_SUPPORT,
TEST_DESCENTS,
TEST_CYCLE_TYPE,
Expand Down Expand Up @@ -268,6 +269,20 @@ def test_order(cycle_decomposition, expected_value) -> None:
)


@pytest.mark.parametrize(
argnames="cycle_decomposition, expected_value",
argvalues=TEST_RECORDS,
ids=[f"{p}.records()={o}" for p, o in TEST_RECORDS],
)
def test_records(cycle_decomposition, expected_value) -> None:
"""Tests for the method `records()`."""
_check_values(
expression=f"{cycle_decomposition.rep()}.records()",
evaluation=cycle_decomposition.records(),
expected=expected_value,
)


@pytest.mark.parametrize(
argnames="cycle_decomposition, expected_value",
argvalues=TEST_SGN,
Expand Down
5 changes: 5 additions & 0 deletions tests/tests_permutation/test_cases.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,11 @@
(Permutation(1, 3, 2), {1: 1, 2: 3, 3: 2}),
(Permutation(1, 4, 3, 2), {1: 1, 2: 4, 3: 3, 4: 2}),
]
TEST_RECORDS = [
(Permutation(1, 2, 3), [1, 2, 3]),
(Permutation(3, 1, 2), [1]),
(Permutation(1, 3, 4, 5, 2, 6), [1, 2, 3, 4, 6]),
]
TEST_SUPPORT = [
(Permutation(1), set()),
(Permutation(2, 1), {1, 2}),
Expand Down
11 changes: 11 additions & 0 deletions tests/tests_permutation/test_generic_methods.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
TEST_ASCENTS,
TEST_INVERSE,
TEST_IS_EVEN,
TEST_RECORDS,
TEST_SUPPORT,
TEST_DESCENTS,
TEST_CYCLE_TYPE,
Expand Down Expand Up @@ -241,6 +242,16 @@ def test_map(permutation, expected_value) -> None:
_check_values(expression=f"{permutation.rep()}.map()", evaluation=permutation.map, expected=expected_value)


@pytest.mark.parametrize(
argnames="permutation, expected_value",
argvalues=TEST_RECORDS,
ids=[f"{p.rep()}.records()={s}" for p, s in TEST_RECORDS],
)
def test_records(permutation, expected_value) -> None:
"""Tests for the method `records()`."""
_check_values(expression=f"{permutation.rep()}.records()", evaluation=permutation.records(), expected=expected_value)


@pytest.mark.parametrize(
argnames="permutation, expected_value",
argvalues=TEST_SUPPORT,
Expand Down

0 comments on commit 0694992

Please sign in to comment.