def _print_Permutation(self, expr): from sympy.combinatorics.permutations import Permutation, Cycle if Permutation.print_cyclic: if not expr.size: return '()' # before taking Cycle notation, see if the last element is # a singleton and move it to the head of the string s = Cycle(expr)(expr.size - 1).__repr__()[len('Cycle'):] last = s.rfind('(') if not last == 0 and ',' not in s[last:]: s = s[last:] + s[:last] s = s.replace(',', '') return s else: s = expr.support() if not s: if expr.size < 5: return 'Permutation(%s)' % self._print(expr.array_form) return 'Permutation([], size=%s)' % self._print(expr.size) trim = self._print( expr.array_form[:s[-1] + 1]) + ', size=%s' % self._print(expr.size) use = full = self._print(expr.array_form) if len(trim) < len(full): use = trim return 'Permutation(%s)' % use
def _print_Permutation(self, expr): from sympy.combinatorics.permutations import Permutation, Cycle from sympy.utilities.exceptions import SymPyDeprecationWarning perm_cyclic = Permutation.print_cyclic if perm_cyclic is not None: SymPyDeprecationWarning( feature="Permutation.print_cyclic = {}".format(perm_cyclic), useinstead="init_printing(perm_cyclic={})".format(perm_cyclic), issue=15201, deprecated_since_version="1.6").warn() else: perm_cyclic = self._settings.get("perm_cyclic", True) if perm_cyclic: if not expr.size: return 'Permutation()' # before taking Cycle notation, see if the last element is # a singleton and move it to the head of the string s = Cycle(expr)(expr.size - 1).__repr__()[len('Cycle'):] last = s.rfind('(') if not last == 0 and ',' not in s[last:]: s = s[last:] + s[:last] return 'Permutation%s' % s else: s = expr.support() if not s: if expr.size < 5: return 'Permutation(%s)' % str(expr.array_form) return 'Permutation([], size=%s)' % expr.size trim = str(expr.array_form[:s[-1] + 1]) + ', size=%s' % expr.size use = full = str(expr.array_form) if len(trim) < len(full): use = trim return 'Permutation(%s)' % use
def _print_Permutation(self, expr): from sympy.combinatorics.permutations import Permutation, Cycle if Permutation.print_cyclic: if not expr.size: return "()" # before taking Cycle notation, see if the last element is # a singleton and move it to the head of the string s = Cycle(expr)(expr.size - 1).__repr__()[len("Cycle") :] last = s.rfind("(") if not last == 0 and "," not in s[last:]: s = s[last:] + s[:last] s = s.replace(",", "") return s else: s = expr.support() if not s: if expr.size < 5: return "Permutation(%s)" % str(expr.array_form) return "Permutation([], size=%s)" % expr.size trim = str(expr.array_form[: s[-1] + 1]) + ", size=%s" % expr.size use = full = str(expr.array_form) if len(trim) < len(full): use = trim return "Permutation(%s)" % use
def _print_Permutation(self, expr): from sympy.combinatorics.permutations import Permutation, Cycle from sympy.utilities.exceptions import sympy_deprecation_warning perm_cyclic = Permutation.print_cyclic if perm_cyclic is not None: sympy_deprecation_warning( f""" Setting Permutation.print_cyclic is deprecated. Instead use init_printing(perm_cyclic={perm_cyclic}). """, deprecated_since_version="1.6", active_deprecations_target= "deprecated-permutation-print_cyclic", stacklevel=7, ) else: perm_cyclic = self._settings.get("perm_cyclic", True) if perm_cyclic: if not expr.size: return '()' # before taking Cycle notation, see if the last element is # a singleton and move it to the head of the string s = Cycle(expr)(expr.size - 1).__repr__()[len('Cycle'):] last = s.rfind('(') if not last == 0 and ',' not in s[last:]: s = s[last:] + s[:last] s = s.replace(',', '') return s else: s = expr.support() if not s: if expr.size < 5: return 'Permutation(%s)' % self._print(expr.array_form) return 'Permutation([], size=%s)' % self._print(expr.size) trim = self._print( expr.array_form[:s[-1] + 1]) + ', size=%s' % self._print(expr.size) use = full = self._print(expr.array_form) if len(trim) < len(full): use = trim return 'Permutation(%s)' % use
def _print_Permutation(self, expr): from sympy.combinatorics.permutations import Permutation, Cycle if Permutation.print_cyclic: if not expr.size: return 'Permutation()' # before taking Cycle notation, see if the last element is # a singleton and move it to the head of the string s = Cycle(expr)(expr.size - 1).__repr__()[len('Cycle'):] last = s.rfind('(') if not last == 0 and ',' not in s[last:]: s = s[last:] + s[:last] return 'Permutation%s' % s else: s = expr.support() if not s: if expr.size < 5: return 'Permutation(%s)' % str(expr.array_form) return 'Permutation([], size=%s)' % expr.size trim = str(expr.array_form[:s[-1] + 1]) + ', size=%s' % expr.size use = full = str(expr.array_form) if len(trim) < len(full): use = trim return 'Permutation(%s)' % use
def test_issue_17661(): c1 = Cycle(1, 2) c2 = Cycle(1, 2) assert c1 == c2 assert repr(c1) == 'Cycle(1, 2)' assert c1 == c2
def test_Cycle(): assert str(Cycle()) == '()' assert Cycle(Cycle(1, 2)) == Cycle(1, 2) assert Cycle(1, 2).copy() == Cycle(1, 2) assert list(Cycle(1, 3, 2)) == [0, 3, 1, 2] assert Cycle(1, 2)(2, 3) == Cycle(1, 3, 2) assert Cycle(1, 2)(2, 3)(4, 5) == Cycle(1, 3, 2)(4, 5) assert Permutation(Cycle(1, 2)(2, 1, 0, 3)).cyclic_form, Cycle(0, 2, 1) raises(ValueError, lambda: Cycle().list()) assert Cycle(1, 2).list() == [0, 2, 1] assert Cycle(1, 2).list(4) == [0, 2, 1, 3] assert Cycle(3).list(2) == [0, 1] assert Cycle(3).list(6) == [0, 1, 2, 3, 4, 5] assert Permutation(Cycle(1, 2), size=4) == \ Permutation([0, 2, 1, 3]) assert str(Cycle(1, 2)(4, 5)) == '(1 2)(4 5)' assert str(Cycle(1, 2)) == '(1 2)' assert Cycle(Permutation(list(range(3)))) == Cycle() assert Cycle(1, 2).list() == [0, 2, 1] assert Cycle(1, 2).list(4) == [0, 2, 1, 3] assert Cycle().size == 0 raises(ValueError, lambda: Cycle((1, 2))) raises(ValueError, lambda: Cycle(1, 2, 1)) raises(TypeError, lambda: Cycle(1, 2) * {}) raises(ValueError, lambda: Cycle(4)[a]) raises(ValueError, lambda: Cycle(2, -4, 3)) # check round-trip p = Permutation([[1, 2], [4, 3]], size=5) assert Permutation(Cycle(p)) == p
def test_Permutation(): # don't auto fill 0 raises(ValueError, lambda: Permutation([1])) p = Permutation([0, 1, 2, 3]) # call as bijective assert [p(i) for i in range(p.size)] == list(p) # call as operator assert p(list(range(p.size))) == list(p) # call as function assert list(p(1, 2)) == [0, 2, 1, 3] raises(TypeError, lambda: p(-1)) raises(TypeError, lambda: p(5)) # conversion to list assert list(p) == list(range(4)) assert Permutation(size=4) == Permutation(3) assert Permutation(Permutation(3), size=5) == Permutation(4) # cycle form with size assert Permutation([[1, 2]], size=4) == Permutation([[1, 2], [0], [3]]) # random generation assert Permutation.random(2) in (Permutation([1, 0]), Permutation([0, 1])) p = Permutation([2, 5, 1, 6, 3, 0, 4]) q = Permutation([[1], [0, 3, 5, 6, 2, 4]]) assert len({p, p}) == 1 r = Permutation([1, 3, 2, 0, 4, 6, 5]) ans = Permutation(_af_rmuln(*[w.array_form for w in (p, q, r)])).array_form assert rmul(p, q, r).array_form == ans # make sure no other permutation of p, q, r could have given # that answer for a, b, c in permutations((p, q, r)): if (a, b, c) == (p, q, r): continue assert rmul(a, b, c).array_form != ans assert p.support() == list(range(7)) assert q.support() == [0, 2, 3, 4, 5, 6] assert Permutation(p.cyclic_form).array_form == p.array_form assert p.cardinality == 5040 assert q.cardinality == 5040 assert q.cycles == 2 assert rmul(q, p) == Permutation([4, 6, 1, 2, 5, 3, 0]) assert rmul(p, q) == Permutation([6, 5, 3, 0, 2, 4, 1]) assert _af_rmul(p.array_form, q.array_form) == \ [6, 5, 3, 0, 2, 4, 1] assert rmul(Permutation([[1, 2, 3], [0, 4]]), Permutation([[1, 2, 4], [0], [3]])).cyclic_form == \ [[0, 4, 2], [1, 3]] assert q.array_form == [3, 1, 4, 5, 0, 6, 2] assert q.cyclic_form == [[0, 3, 5, 6, 2, 4]] assert q.full_cyclic_form == [[0, 3, 5, 6, 2, 4], [1]] assert p.cyclic_form == [[0, 2, 1, 5], [3, 6, 4]] t = p.transpositions() assert t == [(0, 5), (0, 1), (0, 2), (3, 4), (3, 6)] assert Permutation.rmul(*[Permutation(Cycle(*ti)) for ti in (t)]) assert Permutation([1, 0]).transpositions() == [(0, 1)] assert p**13 == p assert q**0 == Permutation(list(range(q.size))) assert q**-2 == ~q**2 assert q**2 == Permutation([5, 1, 0, 6, 3, 2, 4]) assert q**3 == q**2 * q assert q**4 == q**2 * q**2 a = Permutation(1, 3) b = Permutation(2, 0, 3) I = Permutation(3) assert ~a == a**-1 assert a * ~a == I assert a * b**-1 == a * ~b ans = Permutation(0, 5, 3, 1, 6)(2, 4) assert (p + q.rank()).rank() == ans.rank() assert (p + q.rank())._rank == ans.rank() assert (q + p.rank()).rank() == ans.rank() raises(TypeError, lambda: p + Permutation(list(range(10)))) assert (p - q.rank()).rank() == Permutation(0, 6, 3, 1, 2, 5, 4).rank() assert p.rank() - q.rank() < 0 # for coverage: make sure mod is used assert (q - p.rank()).rank() == Permutation(1, 4, 6, 2)(3, 5).rank() assert p * q == Permutation(_af_rmuln(*[list(w) for w in (q, p)])) assert p * Permutation([]) == p assert Permutation([]) * p == p assert p * Permutation([[0, 1]]) == Permutation([2, 5, 0, 6, 3, 1, 4]) assert Permutation([[0, 1]]) * p == Permutation([5, 2, 1, 6, 3, 0, 4]) pq = p ^ q assert pq == Permutation([5, 6, 0, 4, 1, 2, 3]) assert pq == rmul(q, p, ~q) qp = q ^ p assert qp == Permutation([4, 3, 6, 2, 1, 5, 0]) assert qp == rmul(p, q, ~p) raises(ValueError, lambda: p ^ Permutation([])) assert p.commutator(q) == Permutation(0, 1, 3, 4, 6, 5, 2) assert q.commutator(p) == Permutation(0, 2, 5, 6, 4, 3, 1) assert p.commutator(q) == ~q.commutator(p) raises(ValueError, lambda: p.commutator(Permutation([]))) assert len(p.atoms()) == 7 assert q.atoms() == {0, 1, 2, 3, 4, 5, 6} assert p.inversion_vector() == [2, 4, 1, 3, 1, 0] assert q.inversion_vector() == [3, 1, 2, 2, 0, 1] assert Permutation.from_inversion_vector(p.inversion_vector()) == p assert Permutation.from_inversion_vector(q.inversion_vector()).array_form\ == q.array_form raises(ValueError, lambda: Permutation.from_inversion_vector([0, 2])) assert Permutation([i for i in range(500, -1, -1)]).inversions() == 125250 s = Permutation([0, 4, 1, 3, 2]) assert s.parity() == 0 _ = s.cyclic_form # needed to create a value for _cyclic_form assert len(s._cyclic_form) != s.size and s.parity() == 0 assert not s.is_odd assert s.is_even assert Permutation([0, 1, 4, 3, 2]).parity() == 1 assert _af_parity([0, 4, 1, 3, 2]) == 0 assert _af_parity([0, 1, 4, 3, 2]) == 1 s = Permutation([0]) assert s.is_Singleton assert Permutation([]).is_Empty r = Permutation([3, 2, 1, 0]) assert (r**2).is_Identity assert rmul(~p, p).is_Identity assert (~p)**13 == Permutation([5, 2, 0, 4, 6, 1, 3]) assert ~(r**2).is_Identity assert p.max() == 6 assert p.min() == 0 q = Permutation([[6], [5], [0, 1, 2, 3, 4]]) assert q.max() == 4 assert q.min() == 0 p = Permutation([1, 5, 2, 0, 3, 6, 4]) q = Permutation([[1, 2, 3, 5, 6], [0, 4]]) assert p.ascents() == [0, 3, 4] assert q.ascents() == [1, 2, 4] assert r.ascents() == [] assert p.descents() == [1, 2, 5] assert q.descents() == [0, 3, 5] assert Permutation(r.descents()).is_Identity assert p.inversions() == 7 # test the merge-sort with a longer permutation big = list(p) + list(range(p.max() + 1, p.max() + 130)) assert Permutation(big).inversions() == 7 assert p.signature() == -1 assert q.inversions() == 11 assert q.signature() == -1 assert rmul(p, ~p).inversions() == 0 assert rmul(p, ~p).signature() == 1 assert p.order() == 6 assert q.order() == 10 assert (p**(p.order())).is_Identity assert p.length() == 6 assert q.length() == 7 assert r.length() == 4 assert p.runs() == [[1, 5], [2], [0, 3, 6], [4]] assert q.runs() == [[4], [2, 3, 5], [0, 6], [1]] assert r.runs() == [[3], [2], [1], [0]] assert p.index() == 8 assert q.index() == 8 assert r.index() == 3 assert p.get_precedence_distance(q) == q.get_precedence_distance(p) assert p.get_adjacency_distance(q) == p.get_adjacency_distance(q) assert p.get_positional_distance(q) == p.get_positional_distance(q) p = Permutation([0, 1, 2, 3]) q = Permutation([3, 2, 1, 0]) assert p.get_precedence_distance(q) == 6 assert p.get_adjacency_distance(q) == 3 assert p.get_positional_distance(q) == 8 p = Permutation([0, 3, 1, 2, 4]) q = Permutation.josephus(4, 5, 2) assert p.get_adjacency_distance(q) == 3 raises(ValueError, lambda: p.get_adjacency_distance(Permutation([]))) raises(ValueError, lambda: p.get_positional_distance(Permutation([]))) raises(ValueError, lambda: p.get_precedence_distance(Permutation([]))) a = [Permutation.unrank_nonlex(4, i) for i in range(5)] iden = Permutation([0, 1, 2, 3]) for i in range(5): for j in range(i + 1, 5): assert a[i].commutes_with(a[j]) == \ (rmul(a[i], a[j]) == rmul(a[j], a[i])) if a[i].commutes_with(a[j]): assert a[i].commutator(a[j]) == iden assert a[j].commutator(a[i]) == iden a = Permutation(3) b = Permutation(0, 6, 3)(1, 2) assert a.cycle_structure == {1: 4} assert b.cycle_structure == {2: 1, 3: 1, 1: 2} # issue 11130 raises(ValueError, lambda: Permutation(3, size=3)) raises(ValueError, lambda: Permutation([1, 2, 0, 3], size=3))
def test_Cycle(): assert Cycle(1, 2)(2, 3) == Cycle(1, 3, 2) assert Cycle(1, 2)(2, 3)(4, 5) == Cycle(1, 3, 2)(4, 5) assert Permutation(Cycle(1, 2)(2, 1, 0, 3)).cyclic_form, Cycle(0, 2, 1) raises(ValueError, lambda: Cycle().list()) assert Cycle(1, 2).list() == [0, 2, 1] assert Cycle(1, 2).list(4) == [0, 2, 1, 3] assert Permutation(Cycle(1, 2), size=4) == \ Permutation([0, 2, 1, 3]) assert str(Cycle(1, 2)(4, 5)) == 'Cycle(1, 2)(4, 5)' assert str(Cycle(1, 2)) == 'Cycle(1, 2)' assert Cycle(Permutation(range(3))) == Cycle() assert Cycle(1, 2).list() == [0, 2, 1] assert Cycle(1, 2).list(4) == [0, 2, 1, 3] raises(TypeError, lambda: Cycle((1, 2))) raises(ValueError, lambda: Cycle(1, 2, 1)) raises(TypeError, lambda: Cycle(1, 2) * {}) # check round-trip p = Permutation([[1, 2], [4, 3]], size=5) assert Permutation(Cycle(p)) == p