From 72d63d78475f22865119b0ec2c67d8ccd5665d63 Mon Sep 17 00:00:00 2001 From: Chris Smith Date: Wed, 12 Sep 2012 15:28:28 +0545 Subject: [PATCH] permutations: make cycle_structure a property; return dict --- sympy/combinatorics/permutations.py | 44 +++++++++---------- .../combinatorics/tests/test_permutations.py | 8 ++-- 2 files changed, 25 insertions(+), 27 deletions(-) diff --git a/sympy/combinatorics/permutations.py b/sympy/combinatorics/permutations.py index de188d233ffd..2aa8131451e2 100644 --- a/sympy/combinatorics/permutations.py +++ b/sympy/combinatorics/permutations.py @@ -1,4 +1,5 @@ import random +from collections import defaultdict from sympy.core import Basic, S, FiniteSet, Tuple from sympy.core.compatibility import is_sequence @@ -709,6 +710,7 @@ class Permutation(Basic): _array_form = None _cyclic_form = None + _cycle_structure = None _size = None _rank = None @@ -2095,35 +2097,33 @@ def length(self): return len(self.support()) - def cycle_structure(self, other=None): - """Return the cycle structure (default) or a boolean indicating - whether self and other have the same cycle structure. - - The cycle structure returned is a tuple giving the size of the - permutation and the sorted lengths of cycles in the permutation. + @property + def cycle_structure(self): + """Return the cycle structure of the permutation as a dictionary + indicating the multiplicity of each cycle length. Examples ======== >>> from sympy.combinatorics import Permutation >>> Permutation.print_cyclic = True - >>> a = Permutation(3); a.cycle_structure() - (4,) - >>> b = Permutation(0, 4, 3)(1, 2)(5, 6); b.cycle_structure() - (7, 2, 2, 3) - - >>> a.cycle_structure(Permutation(2)) - False - >>> b.cycle_structure(Permutation(0, 3)(1, 2, 4)(5, 6)) - True + >>> Permutation(3).cycle_structure + {1: 4} + >>> Permutation(0, 4, 3)(1, 2)(5, 6).cycle_structure + {2: 2, 3: 1} """ - rv = [self.size] - rv.extend(list(sorted([len(c) for c in self.cyclic_form]))) - if other: - o = [other.size] - o.extend(list(sorted([len(c) for c in other.cyclic_form]))) - return rv == o - return tuple(rv) + if self._cycle_structure: + rv = self._cycle_structure + else: + rv = defaultdict(int) + singletons = self.size + for c in self.cyclic_form: + rv[len(c)] += 1 + singletons -= len(c) + if singletons: + rv[1] = singletons + self._cycle_structure = rv + return dict(rv) # make a copy @property def cycles(self): diff --git a/sympy/combinatorics/tests/test_permutations.py b/sympy/combinatorics/tests/test_permutations.py index 0a049a01acd6..9721fcf5d53c 100644 --- a/sympy/combinatorics/tests/test_permutations.py +++ b/sympy/combinatorics/tests/test_permutations.py @@ -206,11 +206,9 @@ def test_Permutation(): assert a[j].commutator(a[i]) == iden a = Permutation(3) - b = Permutation(0, 4, 3)(1, 2)(5, 6) - assert a.cycle_structure() == (4,) - assert b.cycle_structure() == (7, 2, 2, 3) - assert a.cycle_structure(Permutation(2)) is False - assert b.cycle_structure(Permutation(0, 3)(1, 2, 4)(5, 6)) is True + b = Permutation(0, 6, 3)(1, 2) + assert a.cycle_structure == {1: 4} + assert b.cycle_structure == {2: 1, 3: 1, 1: 2} def test_josephus(): assert Permutation.josephus(4, 6, 1) == Permutation([3, 1, 0, 2, 5, 4])