Skip to content

Commit

Permalink
Merge branch 'master' into min-size-downset
Browse files Browse the repository at this point in the history
  • Loading branch information
engenmt authored Nov 6, 2023
2 parents ec06b42 + 7eba9f5 commit ae161ca
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 31 deletions.
7 changes: 0 additions & 7 deletions .github/workflows/ci-cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,6 @@ jobs:
--extra-index-url https://pypi.org/simple \
permpy
- name: Test install from TestPyPI
run: |
pip install \
--index-url https://test.pypi.org/simple/ \
--extra-index-url https://pypi.org/simple \
pycounts
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ profile = "black"

[tool.poetry]
name = "permpy"
version = "0.2.5"
version = "0.2.10"
description = "A package for analyzing permutation patterns."
authors = ["Michael Engen", "Cheyne Homberger", "Jay Pantone"]
license = "MIT"
Expand Down
2 changes: 1 addition & 1 deletion src/permpy/deprecated/permsetdeprecated.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ def layer_down(self, verbose=0):

@deprecated
def all_syms(self):
return self.symmetries()
return self.all_symmetries()

@deprecated
def extensions(self, test):
Expand Down
17 changes: 10 additions & 7 deletions src/permpy/permset.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,13 +92,16 @@ def minimal_elements(self):

return shortest_perms + S.minimal_elements()

def symmetries(self):
"""Return the PermSet of all symmetries of all permutations in `self`."""
S = set(self)
S.update([p.reverse() for p in S])
S.update([p.complement() for p in S])
S.update([p.inverse() for p in S])
return PermSet(S)
def all_symmetries(self):
"""Return the list of PermSets that are symmetries of self."""
symmetries = Permutation.symmetries()
return [PermSet(symmetry(p) for p in self) for symmetry in symmetries]

def is_representative(self):
representative = sorted(
self.all_symmetries(), key=lambda S: sorted(tuple(p) for p in S)
)[0]
return self == representative

def covers(self):
"""Return those permutations that `self` covers."""
Expand Down
46 changes: 31 additions & 15 deletions src/permpy/permutation.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,20 @@ def ind_to_perm(cls, k, n):
p = cls(result, clean=True)
return p

@classmethod
def symmetries(self):
"""Return the list of all symmetries of a permutation as functions."""
return [
lambda p: p,
lambda p: p.reverse(),
lambda p: p.complement(),
lambda p: p.inverse(),
lambda p: p.inverse().reverse(),
lambda p: p.inverse().complement(),
lambda p: p.complement().reverse(),
lambda p: p.complement().reverse().inverse(),
]

# overloaded built in functions:
def __new__(cls, p=None, n=None, clean=False):
"""Create a new permutation object. Supports a variety of creation
Expand Down Expand Up @@ -581,14 +595,18 @@ def noninversions(self):

def breadth(self):
"""Return the minimum taxicab distance among pairs of entries in the permutation."""

min_dist = len(self)
for i, j in itertools.combinations(range(len(self)), 2):
h_dist = abs(i - j)
v_dist = abs(self[i] - self[j])
dist = h_dist + v_dist
if dist < min_dist:
min_dist = dist
for idx_west, val_west in enumerate(self):
for delta_x, val_east in enumerate(
self[idx_west + 1 : idx_west + min_dist - 1], start=1
):
dist = delta_x + abs(val_west - val_east)
if dist < min_dist:
# The minimum breadth attained by a permutation is 2,
# so no smaller breadth will be found.
if dist == 2:
return dist
min_dist = dist
return min_dist

def bonds(self):
Expand Down Expand Up @@ -1063,17 +1081,15 @@ def downset_profile(self, min_length=0):

return profile[::-1]

def symmetries(self):
"""Return the set of all symmetries of `self`."""
S = set([self])
S.update([P.reverse() for P in S])
S.update([P.complement() for P in S])
S.update([P.inverse() for P in S])
return S
def all_symmetries(self):
"""Return the set of all symmetries of self."""
return set([symmetry(self) for symmetry in Permutation.symmetries()])

def is_representative(self):
"""Check if `self` is the (lexicographically) least element of its symmetry class."""
return self == sorted(self.symmetries())[0]
return (
self == sorted(self.all_symmetries(), key=tuple)[0]
) # Use tuple sorting as __lt__ is for containment

def copies(self, other):
"""Return the list of (values corresponding to) copies of `other` in `self`."""
Expand Down
15 changes: 15 additions & 0 deletions tests/test_permutation.py
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,21 @@ def test_pattern_counts():
)


def test_downset():
p = Perm(2413)
expected = [
{Perm()},
{Perm(1)},
{Perm(12), Perm(21)},
{Perm(312), Perm(132), Perm(213), Perm(231)},
{Perm(2413)},
]
result = p.downset()
assert result == expected, (
f"Perm({p}).downset() returned {result}," f" but it should return {expected}."
)


def test_avoids():
cases = [
(Perm(123456), 231, True),
Expand Down

0 comments on commit ae161ca

Please sign in to comment.