def test_coset_factor(): a = Permutation([0, 2, 1]) G = PermutationGroup([a]) c = Permutation([2, 1, 0]) assert not G.coset_factor(c) assert G.coset_rank(c) is None a = Permutation([2, 0, 1, 3, 4, 5]) b = Permutation([2, 1, 3, 4, 5, 0]) g = PermutationGroup([a, b]) assert g.order() == 360 d = Permutation([1, 0, 2, 3, 4, 5]) assert not g.coset_factor(d.array_form) assert not g.contains(d) assert Permutation(2) in G c = Permutation([1, 0, 2, 3, 5, 4]) v = g.coset_factor(c, True) tr = g.basic_transversals p = Permutation.rmul(*[tr[i][v[i]] for i in range(len(g.base))]) assert p == c v = g.coset_factor(c) p = Permutation.rmul(*v) assert p == c assert g.contains(c) G = PermutationGroup([Permutation([2, 1, 0])]) p = Permutation([1, 0, 2]) assert G.coset_factor(p) == []
def test_unrank_lex(): assert Permutation.unrank_lex(5, 10).rank == 10 assert Permutation.unrank_lex(15, 225).rank == 225 assert Permutation.unrank_lex(10, 0).is_Identity p = Permutation.unrank_lex(4, 23) assert p.rank == 23 assert p.array_form == [3, 2, 1, 0]
def test_muln(): n = 6 m = 8 a = [Permutation.unrank_nonlex(n, i).array_form for i in range(m)] h = range(n) for i in range(m): h = perm_af_mul(h, a[i]) h2 = perm_af_muln(*a[:i+1]) assert h == h2
def test_mul(): a, b = [0, 2, 1, 3], [0, 1, 3, 2] assert _af_rmul(a, b) == [0, 2, 3, 1] assert _af_rmuln(a, b, range(4)) == [0, 2, 3, 1] assert rmul(Permutation(a), Permutation(b)).array_form == [0, 2, 3, 1] a = Permutation([0, 2, 1, 3]) b = (0, 1, 3, 2) c = (3, 1, 2, 0) assert Permutation.rmul(a, b, c) == Permutation([1, 2, 3, 0]) assert Permutation.rmul(a, c) == Permutation([3, 2, 1, 0]) raises(TypeError, lambda: Permutation.rmul(b, c)) n = 6 m = 8 a = [Permutation.unrank_nonlex(n, i).array_form for i in range(m)] h = range(n) for i in range(m): h = _af_rmul(h, a[i]) h2 = _af_rmuln(*a[:i + 1]) assert h == h2
def test_ranking(): assert Permutation.unrank_lex(5, 10).rank() == 10 p = Permutation.unrank_lex(15, 225) assert p.rank() == 225 p1 = p.next_lex() assert p1.rank() == 226 assert Permutation.unrank_lex(15, 225).rank() == 225 assert Permutation.unrank_lex(10, 0).is_Identity p = Permutation.unrank_lex(4, 23) assert p.rank() == 23 assert p.array_form == [3, 2, 1, 0] assert p.next_lex() is None p = Permutation([1, 5, 2, 0, 3, 6, 4]) q = Permutation([[1, 2, 3, 5, 6], [0, 4]]) a = [Permutation.unrank_trotterjohnson(4, i).array_form for i in range(5)] assert a == [[0, 1, 2, 3], [0, 1, 3, 2], [0, 3, 1, 2], [3, 0, 1, 2], [3, 0, 2, 1] ] assert [Permutation(pa).rank_trotterjohnson() for pa in a] == range(5) assert Permutation([0, 1, 2, 3]).next_trotterjohnson() == \ Permutation([0, 1, 3, 2]) assert q.rank_trotterjohnson() == 2283 assert p.rank_trotterjohnson() == 3389 assert Permutation([1, 0]).rank_trotterjohnson() == 1 a = Permutation(range(3)) b = a l = [] tj = [] for i in range(6): l.append(a) tj.append(b) a = a.next_lex() b = b.next_trotterjohnson() assert a == b is None assert set([tuple(a) for a in l]) == set([tuple(a) for a in tj]) p = Permutation([2, 5, 1, 6, 3, 0, 4]) q = Permutation([[6], [5], [0, 1, 2, 3, 4]]) assert p.rank() == 1964 assert q.rank() == 870 assert Permutation([]).rank_nonlex() == 0 prank = p.rank_nonlex() assert prank == 1600 assert Permutation.unrank_nonlex(7, 1600) == p qrank = q.rank_nonlex() assert qrank == 41 assert Permutation.unrank_nonlex(7, 41) == Permutation(q.array_form) a = [Permutation.unrank_nonlex(4, i).array_form for i in range(24)] assert a == [ [1, 2, 3, 0], [3, 2, 0, 1], [1, 3, 0, 2], [1, 2, 0, 3], [2, 3, 1, 0], [2, 0, 3, 1], [3, 0, 1, 2], [2, 0, 1, 3], [1, 3, 2, 0], [3, 0, 2, 1], [1, 0, 3, 2], [1, 0, 2, 3], [2, 1, 3, 0], [2, 3, 0, 1], [3, 1, 0, 2], [2, 1, 0, 3], [3, 2, 1, 0], [0, 2, 3, 1], [0, 3, 1, 2], [0, 2, 1, 3], [3, 1, 2, 0], [0, 3, 2, 1], [0, 1, 3, 2], [0, 1, 2, 3]] ok = [] p = Permutation([1, 0]) for i in range(3): ok.append(p.array_form) p = p.next_nonlex() if p is None: ok.append(None) break assert ok == [[1, 0], [0, 1], None] assert Permutation([3, 2, 0, 1]).next_nonlex() == Permutation([1, 3, 0, 2]) assert [Permutation(pa).rank_nonlex() for pa in a] == range(24)
def test_Permutation(): p = Permutation([2, 5, 1, 6, 3, 0, 4]) q = Permutation([[1], [0, 3, 5, 6, 2, 4]]) assert Permutation(p.cyclic_form).array_form == p.array_form assert p.cardinality == 5040 assert q.cardinality == 5040 assert q.cycles == 2 assert q*p == Permutation([4, 6, 1, 2, 5, 3, 0]) assert p*q == Permutation([6, 5, 3, 0, 2, 4, 1]) assert (Permutation([[1,2,3],[0,4]])*Permutation([[1,2,4],[0],[3]])).cyclic_form == \ [[1, 3], [0, 4, 2]] assert q.array_form == [3, 1, 4, 5, 0, 6, 2] assert p.cyclic_form == [[3, 6, 4], [0, 2, 1, 5]] assert p**13 == p assert q**2 == Permutation([5, 1, 0, 6, 3, 2, 4]) assert p+q == Permutation([5, 6, 3, 1, 2, 4, 0]) assert q+p == p+q assert p-q == Permutation([6, 3, 5, 1, 2, 4, 0]) assert q-p == Permutation([1, 4, 2, 6, 5, 3, 0]) a = p-q b = q-p assert (a+b).is_Identity assert len(p.atoms()) == 7 assert q.atoms() == set([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 assert Permutation([0, 4, 1, 3, 2]).parity() == 0 assert Permutation([0, 1, 4, 3, 2]).parity() == 1 s = Permutation([0]) assert s.is_Singleton r = Permutation([3, 2, 1, 0]) assert (r**2).is_Identity assert (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 assert Permutation([]).rank_nonlex() == 0 prank = p.rank_nonlex() assert prank == 1600 assert Permutation.unrank_nonlex(7, 1600) == p qrank = q.rank_nonlex() assert qrank == 41 assert Permutation.unrank_nonlex(7, 41) == Permutation(q.array_form) a = [Permutation.unrank_nonlex(4, i).array_form for i in range(24)] assert a == \ [[1, 2, 3, 0], [3, 2, 0, 1], [1, 3, 0, 2], [1, 2, 0, 3], [2, 3, 1, 0], \ [2, 0, 3, 1], [3, 0, 1, 2], [2, 0, 1, 3], [1, 3, 2, 0], [3, 0, 2, 1], \ [1, 0, 3, 2], [1, 0, 2, 3], [2, 1, 3, 0], [2, 3, 0, 1], [3, 1, 0, 2], \ [2, 1, 0, 3], [3, 2, 1, 0], [0, 2, 3, 1], [0, 3, 1, 2], [0, 2, 1, 3], \ [3, 1, 2, 0], [0, 3, 2, 1], [0, 1, 3, 2], [0, 1, 2, 3]] assert [Permutation(pa).rank_nonlex() for pa in a] == range(24) assert q.rank() == 870 assert p.rank() == 1964 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 assert p.signature() == -1 assert q.inversions() == 11 assert q.signature() == -1 assert (p*(~p)).inversions() == 0 assert (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 not p.is_Positive() assert p.is_Negative() assert not q.is_Positive() assert q.is_Negative() assert r.is_Positive() assert not r.is_Negative() 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 a = [Permutation.unrank_trotterjohnson(4, i).array_form for i in range(5)] assert a == [[0,1,2,3], [0,1,3,2], [0,3,1,2], [3,0,1,2], [3,0,2,1] ] assert [Permutation(pa).rank_trotterjohnson() for pa in a] == range(5) assert q.rank_trotterjohnson() == 2283 assert p.rank_trotterjohnson() == 3389 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
def test_polyhedron(): raises(ValueError, lambda: Polyhedron(list('ab'), pgroup=[Permutation([0])])) pgroup = [Permutation([[0,7,2,5],[6,1,4,3]]),\ Permutation([[0,7,1,6],[5,2,4,3]]),\ Permutation([[3,6,0,5],[4,1,7,2]]),\ Permutation([[7,4,5],[1,3,0],[2],[6]]),\ Permutation([[1,3,2],[7,6,5],[4],[0]]),\ Permutation([[4,7,6],[2,0,3],[1],[5]]),\ Permutation([[1,2,0],[4,5,6],[3],[7]]),\ Permutation([[4,2],[0,6],[3,7],[1,5]]),\ Permutation([[3,5],[7,1],[2,6],[0,4]]),\ Permutation([[2,5],[1,6],[0,4],[3,7]]),\ Permutation([[4,3],[7,0],[5,1],[6,2]]),\ Permutation([[4,1],[0,5],[6,2],[7,3]]),\ Permutation([[7,2],[3,6],[0,4],[1,5]]),\ Permutation([0,1,2,3,4,5,6,7])] corners = tuple(symbols('A:H')) faces = cube_faces cube = Polyhedron(corners, faces, pgroup) assert cube.edges == FiniteSet(*((0, 1), (6, 7), (1, 2), (5, 6), (0, 3), (2, 3), (4, 7), (4, 5), (3, 7), (1, 5), (0, 4), (2, 6))) for i in xrange(3): # add 180 degree face rotations cube.rotate(cube.pgroup[i]**2) assert cube.corners == corners for i in range(3, 7): # add 240 degree axial corner rotations cube.rotate(cube.pgroup[i]**2) assert cube.corners == corners cube.rotate(1) raises(ValueError, lambda: cube.rotate(Permutation([0, 1]))) assert cube.corners != corners assert cube.array_form == [7, 6, 4, 5, 3, 2, 0, 1] assert cube.cyclic_form == [[0, 7, 1, 6], [2, 4, 3, 5]] cube.reset() assert cube.corners == corners def check(h, size, rpt, target): assert len(h.faces) + len(h.vertices) - len(h.edges) == 2 assert h.size == size got = set() for p in h.pgroup: # make sure it restores original P = h.copy() hit = P.corners for i in range(rpt): P.rotate(p) if P.corners == hit: break else: print 'error in permutation', p.array_form for i in range(rpt): P.rotate(p) got.add(tuple(P.corners)) c = P.corners f = [[c[i] for i in f] for f in P.faces] assert h.faces == Polyhedron(c, f).faces assert len(got) == target assert PermutationGroup([Permutation(g) for g in got]).is_group() for h, size, rpt, target in zip( (tetrahedron, square, octahedron, dodecahedron, icosahedron), (4, 8, 6, 20, 12), (3, 4, 4, 5, 5), (12, 24, 24, 60, 60)): check(h, size, rpt, target)
def test_is_alt_sym(): G = DihedralGroup(10) assert G.is_alt_sym() is False S = SymmetricGroup(10) N_eps = 10 _random_prec = { 'N_eps': N_eps, 0: Permutation([[2], [1, 4], [0, 6, 7, 8, 9, 3, 5]]), 1: Permutation([[1, 8, 7, 6, 3, 5, 2, 9], [0, 4]]), 2: Permutation([[5, 8], [4, 7], [0, 1, 2, 3, 6, 9]]), 3: Permutation([[3], [0, 8, 2, 7, 4, 1, 6, 9, 5]]), 4: Permutation([[8], [4, 7, 9], [3, 6], [0, 5, 1, 2]]), 5: Permutation([[6], [0, 2, 4, 5, 1, 8, 3, 9, 7]]), 6: Permutation([[6, 9, 8], [4, 5], [1, 3, 7], [0, 2]]), 7: Permutation([[4], [0, 2, 9, 1, 3, 8, 6, 5, 7]]), 8: Permutation([[1, 5, 6, 3], [0, 2, 7, 8, 4, 9]]), 9: Permutation([[8], [6, 7], [2, 3, 4, 5], [0, 1, 9]]) } assert S.is_alt_sym(_random_prec=_random_prec) is True A = AlternatingGroup(10) _random_prec = { 'N_eps': N_eps, 0: Permutation([[1, 6, 4, 2, 7, 8, 5, 9, 3], [0]]), 1: Permutation([[1], [0, 5, 8, 4, 9, 2, 3, 6, 7]]), 2: Permutation([[1, 9, 8, 3, 2, 5], [0, 6, 7, 4]]), 3: Permutation([[6, 8, 9], [4, 5], [1, 3, 7, 2], [0]]), 4: Permutation([[8], [5], [4], [2, 6, 9, 3], [1], [0, 7]]), 5: Permutation([[3, 6], [0, 8, 1, 7, 5, 9, 4, 2]]), 6: Permutation([[5], [2, 9], [1, 8, 3], [0, 4, 7, 6]]), 7: Permutation([[1, 8, 4, 7, 2, 3], [0, 6, 9, 5]]), 8: Permutation([[5, 8, 7], [3], [1, 4, 2, 6], [0, 9]]), 9: Permutation([[4, 9, 6], [3, 8], [1, 2], [0, 5, 7]]) } assert A.is_alt_sym(_random_prec=_random_prec) is False
def test_is_trivial(): for i in range(5): triv = PermutationGroup([Permutation(list(range(i)))]) assert triv.is_trivial
def test_orbit_rep(): G = DihedralGroup(6) assert G.orbit_rep(1,3) in [Permutation([2, 3, 4, 5, 0, 1]),\ Permutation([4, 3, 2, 1, 0, 5])] H = CyclicGroup(4)*G assert H.orbit_rep(1, 5) == False
def SymmetricGroup(n): """ Generates the symmetric group on ``n`` elements as a permutation group. The generators taken are the ``n``-cycle ``(0 1 2 ... n-1)`` and the transposition ``(0 1)`` (in cycle notation). (See [1]). After the group is generated, some of its basic properties are set. Examples ======== >>> from sympy.combinatorics.named_groups import SymmetricGroup >>> G = SymmetricGroup(4) >>> G.is_group True >>> G.order() 24 >>> list(G.generate_schreier_sims(af=True)) [[0, 1, 2, 3], [1, 2, 3, 0], [2, 3, 0, 1], [3, 1, 2, 0], [0, 2, 3, 1], [1, 3, 0, 2], [2, 0, 1, 3], [3, 2, 0, 1], [0, 3, 1, 2], [1, 0, 2, 3], [2, 1, 3, 0], [3, 0, 1, 2], [0, 1, 3, 2], [1, 2, 0, 3], [2, 3, 1, 0], [3, 1, 0, 2], [0, 2, 1, 3], [1, 3, 2, 0], [2, 0, 3, 1], [3, 2, 1, 0], [0, 3, 2, 1], [1, 0, 3, 2], [2, 1, 0, 3], [3, 0, 2, 1]] See Also ======== CyclicGroup, DihedralGroup, AlternatingGroup References ========== .. [1] https://en.wikipedia.org/wiki/Symmetric_group#Generators_and_relations """ if n == 1: G = PermutationGroup([Permutation([0])]) elif n == 2: G = PermutationGroup([Permutation([1, 0])]) else: a = list(range(1, n)) a.append(0) gen1 = _af_new(a) a = list(range(n)) a[0], a[1] = a[1], a[0] gen2 = _af_new(a) G = PermutationGroup([gen1, gen2]) if n < 3: G._is_abelian = True G._is_nilpotent = True else: G._is_abelian = False G._is_nilpotent = False if n < 5: G._is_solvable = True else: G._is_solvable = False G._degree = n G._is_transitive = True G._is_sym = True return G
def AlternatingGroup(n): """ Generates the alternating group on ``n`` elements as a permutation group. For ``n > 2``, the generators taken are ``(0 1 2), (0 1 2 ... n-1)`` for ``n`` odd and ``(0 1 2), (1 2 ... n-1)`` for ``n`` even (See [1], p.31, ex.6.9.). After the group is generated, some of its basic properties are set. The cases ``n = 1, 2`` are handled separately. Examples ======== >>> from sympy.combinatorics.named_groups import AlternatingGroup >>> G = AlternatingGroup(4) >>> G.is_group True >>> a = list(G.generate_dimino()) >>> len(a) 12 >>> all(perm.is_even for perm in a) True See Also ======== SymmetricGroup, CyclicGroup, DihedralGroup References ========== [1] Armstrong, M. "Groups and Symmetry" """ # small cases are special if n in (1, 2): return PermutationGroup([Permutation([0])]) a = list(range(n)) a[0], a[1], a[2] = a[1], a[2], a[0] gen1 = a if n % 2: a = list(range(1, n)) a.append(0) gen2 = a else: a = list(range(2, n)) a.append(1) a.insert(0, 0) gen2 = a gens = [gen1, gen2] if gen1 == gen2: gens = gens[:1] G = PermutationGroup([_af_new(a) for a in gens], dups=False) if n < 4: G._is_abelian = True G._is_nilpotent = True else: G._is_abelian = False G._is_nilpotent = False if n < 5: G._is_solvable = True else: G._is_solvable = False G._degree = n G._is_transitive = True G._is_alt = True return G
def test_PermutationGroup(): assert PermutationGroup() == PermutationGroup(Permutation()) assert (PermutationGroup() == 0) is False
def DihedralGroup(n): r""" Generates the dihedral group `D_n` as a permutation group. The dihedral group `D_n` is the group of symmetries of the regular ``n``-gon. The generators taken are the ``n``-cycle ``a = (0 1 2 ... n-1)`` (a rotation of the ``n``-gon) and ``b = (0 n-1)(1 n-2)...`` (a reflection of the ``n``-gon) in cycle rotation. It is easy to see that these satisfy ``a**n = b**2 = 1`` and ``bab = ~a`` so they indeed generate `D_n` (See [1]). After the group is generated, some of its basic properties are set. Examples ======== >>> from sympy.combinatorics.named_groups import DihedralGroup >>> G = DihedralGroup(5) >>> G.is_group True >>> a = list(G.generate_dimino()) >>> [perm.cyclic_form for perm in a] [[], [[0, 1, 2, 3, 4]], [[0, 2, 4, 1, 3]], [[0, 3, 1, 4, 2]], [[0, 4, 3, 2, 1]], [[0, 4], [1, 3]], [[1, 4], [2, 3]], [[0, 1], [2, 4]], [[0, 2], [3, 4]], [[0, 3], [1, 2]]] See Also ======== SymmetricGroup, CyclicGroup, AlternatingGroup References ========== [1] https://en.wikipedia.org/wiki/Dihedral_group """ # small cases are special if n == 1: return PermutationGroup([Permutation([1, 0])]) if n == 2: return PermutationGroup([Permutation([1, 0, 3, 2]), Permutation([2, 3, 0, 1]), Permutation([3, 2, 1, 0])]) a = list(range(1, n)) a.append(0) gen1 = _af_new(a) a = list(range(n)) a.reverse() gen2 = _af_new(a) G = PermutationGroup([gen1, gen2]) # if n is a power of 2, group is nilpotent if n & (n-1) == 0: G._is_nilpotent = True else: G._is_nilpotent = False G._is_abelian = False G._is_solvable = True G._degree = n G._is_transitive = True G._order = 2*n return G
def test_is_alt_sym(): G = DihedralGroup(10) assert G.is_alt_sym() is False assert G._eval_is_alt_sym_naive() is False assert G._eval_is_alt_sym_naive(only_alt=True) is False assert G._eval_is_alt_sym_naive(only_sym=True) is False S = SymmetricGroup(10) assert S._eval_is_alt_sym_naive() is True assert S._eval_is_alt_sym_naive(only_alt=True) is False assert S._eval_is_alt_sym_naive(only_sym=True) is True N_eps = 10 _random_prec = { 'N_eps': N_eps, 0: Permutation([[2], [1, 4], [0, 6, 7, 8, 9, 3, 5]]), 1: Permutation([[1, 8, 7, 6, 3, 5, 2, 9], [0, 4]]), 2: Permutation([[5, 8], [4, 7], [0, 1, 2, 3, 6, 9]]), 3: Permutation([[3], [0, 8, 2, 7, 4, 1, 6, 9, 5]]), 4: Permutation([[8], [4, 7, 9], [3, 6], [0, 5, 1, 2]]), 5: Permutation([[6], [0, 2, 4, 5, 1, 8, 3, 9, 7]]), 6: Permutation([[6, 9, 8], [4, 5], [1, 3, 7], [0, 2]]), 7: Permutation([[4], [0, 2, 9, 1, 3, 8, 6, 5, 7]]), 8: Permutation([[1, 5, 6, 3], [0, 2, 7, 8, 4, 9]]), 9: Permutation([[8], [6, 7], [2, 3, 4, 5], [0, 1, 9]]) } assert S.is_alt_sym(_random_prec=_random_prec) is True A = AlternatingGroup(10) assert A._eval_is_alt_sym_naive() is True assert A._eval_is_alt_sym_naive(only_alt=True) is True assert A._eval_is_alt_sym_naive(only_sym=True) is False _random_prec = { 'N_eps': N_eps, 0: Permutation([[1, 6, 4, 2, 7, 8, 5, 9, 3], [0]]), 1: Permutation([[1], [0, 5, 8, 4, 9, 2, 3, 6, 7]]), 2: Permutation([[1, 9, 8, 3, 2, 5], [0, 6, 7, 4]]), 3: Permutation([[6, 8, 9], [4, 5], [1, 3, 7, 2], [0]]), 4: Permutation([[8], [5], [4], [2, 6, 9, 3], [1], [0, 7]]), 5: Permutation([[3, 6], [0, 8, 1, 7, 5, 9, 4, 2]]), 6: Permutation([[5], [2, 9], [1, 8, 3], [0, 4, 7, 6]]), 7: Permutation([[1, 8, 4, 7, 2, 3], [0, 6, 9, 5]]), 8: Permutation([[5, 8, 7], [3], [1, 4, 2, 6], [0, 9]]), 9: Permutation([[4, 9, 6], [3, 8], [1, 2], [0, 5, 7]]) } assert A.is_alt_sym(_random_prec=_random_prec) is False G = PermutationGroup( Permutation(1, 3, size=8)(0, 2, 4, 6), Permutation(5, 7, size=8)(0, 2, 4, 6)) assert G.is_alt_sym() is False # Tests for monte-carlo c_n parameter setting, and which guarantees # to give False. G = DihedralGroup(10) assert G._eval_is_alt_sym_monte_carlo() is False G = DihedralGroup(20) assert G._eval_is_alt_sym_monte_carlo() is False # A dry-running test to check if it looks up for the updated cache. G = DihedralGroup(6) G.is_alt_sym() assert G.is_alt_sym() == False
def test_cyclic(): G = SymmetricGroup(2) assert G.is_cyclic G = AbelianGroup(3, 7) assert G.is_cyclic G = AbelianGroup(7, 7) assert not G.is_cyclic G = AlternatingGroup(3) assert G.is_cyclic G = AlternatingGroup(4) assert not G.is_cyclic # Order less than 6 G = PermutationGroup(Permutation(0, 1, 2), Permutation(0, 2, 1)) assert G.is_cyclic G = PermutationGroup(Permutation(0, 1, 2, 3), Permutation(0, 2)(1, 3)) assert G.is_cyclic G = PermutationGroup(Permutation(3), Permutation(0, 1)(2, 3), Permutation(0, 2)(1, 3), Permutation(0, 3)(1, 2)) assert G.is_cyclic is False # Order 15 G = PermutationGroup( Permutation(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14), Permutation(0, 2, 4, 6, 8, 10, 12, 14, 1, 3, 5, 7, 9, 11, 13)) assert G.is_cyclic # Distinct prime orders assert PermutationGroup._distinct_primes_lemma([3, 5]) is True assert PermutationGroup._distinct_primes_lemma([5, 7]) is True assert PermutationGroup._distinct_primes_lemma([2, 3]) is None assert PermutationGroup._distinct_primes_lemma([3, 5, 7]) is None assert PermutationGroup._distinct_primes_lemma([5, 7, 13]) is True G = PermutationGroup(Permutation(0, 1, 2, 3), Permutation(0, 2)(1, 3)) assert G.is_cyclic assert G._is_abelian
def test_index(): G = PermutationGroup(Permutation(0, 1, 2), Permutation(0, 2, 3)) H = G.subgroup([Permutation(0, 1, 3)]) assert G.index(H) == 4
def test_from_sequence(): assert Permutation.from_sequence('SymPy') == Permutation(4)(0, 1, 3) assert Permutation.from_sequence('SymPy', key=lambda x: x.lower()) == \ Permutation(4)(0, 2)(1, 3)
def test_orbits(): a = Permutation([2, 0, 1]) b = Permutation([2, 1, 0]) g = PermutationGroup([a, b]) assert g.orbit(0) == {0, 1, 2} assert g.orbits() == [{0, 1, 2}] assert g.is_transitive() and g.is_transitive(strict=False) assert g.orbit_transversal(0) == \ [Permutation( [0, 1, 2]), Permutation([2, 0, 1]), Permutation([1, 2, 0])] assert g.orbit_transversal(0, True) == \ [(0, Permutation([0, 1, 2])), (2, Permutation([2, 0, 1])), (1, Permutation([1, 2, 0]))] a = Permutation(list(range(1, 100)) + [0]) G = PermutationGroup([a]) assert [min(o) for o in G.orbits()] == [0] G = PermutationGroup(rubik_cube_generators()) assert [min(o) for o in G.orbits()] == [0, 1] assert not G.is_transitive() and not G.is_transitive(strict=False) G = PermutationGroup([Permutation(0, 1, 3), Permutation(3)(0, 1)]) assert not G.is_transitive() and G.is_transitive(strict=False) assert PermutationGroup( Permutation(3)).is_transitive(strict=False) is False
def test_ranking(): assert Permutation.unrank_lex(5, 10).rank() == 10 p = Permutation.unrank_lex(15, 225) assert p.rank() == 225 p1 = p.next_lex() assert p1.rank() == 226 assert Permutation.unrank_lex(15, 225).rank() == 225 assert Permutation.unrank_lex(10, 0).is_Identity p = Permutation.unrank_lex(4, 23) assert p.rank() == 23 assert p.array_form == [3, 2, 1, 0] assert p.next_lex() is None p = Permutation([1, 5, 2, 0, 3, 6, 4]) q = Permutation([[1, 2, 3, 5, 6], [0, 4]]) a = [Permutation.unrank_trotterjohnson(4, i).array_form for i in range(5)] assert a == [[0, 1, 2, 3], [0, 1, 3, 2], [0, 3, 1, 2], [3, 0, 1, 2], [3, 0, 2, 1]] assert [Permutation(pa).rank_trotterjohnson() for pa in a] == list(range(5)) assert Permutation([0, 1, 2, 3]).next_trotterjohnson() == \ Permutation([0, 1, 3, 2]) assert q.rank_trotterjohnson() == 2283 assert p.rank_trotterjohnson() == 3389 assert Permutation([1, 0]).rank_trotterjohnson() == 1 a = Permutation(list(range(3))) b = a l = [] tj = [] for i in range(6): l.append(a) tj.append(b) a = a.next_lex() b = b.next_trotterjohnson() assert a == b is None assert {tuple(a) for a in l} == {tuple(a) for a in tj} p = Permutation([2, 5, 1, 6, 3, 0, 4]) q = Permutation([[6], [5], [0, 1, 2, 3, 4]]) assert p.rank() == 1964 assert q.rank() == 870 assert Permutation([]).rank_nonlex() == 0 prank = p.rank_nonlex() assert prank == 1600 assert Permutation.unrank_nonlex(7, 1600) == p qrank = q.rank_nonlex() assert qrank == 41 assert Permutation.unrank_nonlex(7, 41) == Permutation(q.array_form) a = [Permutation.unrank_nonlex(4, i).array_form for i in range(24)] assert a == [[1, 2, 3, 0], [3, 2, 0, 1], [1, 3, 0, 2], [1, 2, 0, 3], [2, 3, 1, 0], [2, 0, 3, 1], [3, 0, 1, 2], [2, 0, 1, 3], [1, 3, 2, 0], [3, 0, 2, 1], [1, 0, 3, 2], [1, 0, 2, 3], [2, 1, 3, 0], [2, 3, 0, 1], [3, 1, 0, 2], [2, 1, 0, 3], [3, 2, 1, 0], [0, 2, 3, 1], [0, 3, 1, 2], [0, 2, 1, 3], [3, 1, 2, 0], [0, 3, 2, 1], [0, 1, 3, 2], [0, 1, 2, 3]] N = 10 p1 = Permutation(a[0]) for i in range(1, N + 1): p1 = p1 * Permutation(a[i]) p2 = Permutation.rmul_with_af(*[Permutation(h) for h in a[N::-1]]) assert p1 == p2 ok = [] p = Permutation([1, 0]) for i in range(3): ok.append(p.array_form) p = p.next_nonlex() if p is None: ok.append(None) break assert ok == [[1, 0], [0, 1], None] assert Permutation([3, 2, 0, 1]).next_nonlex() == Permutation([1, 3, 0, 2]) assert [Permutation(pa).rank_nonlex() for pa in a] == list(range(24))
def test_elements(): p = Permutation(2, 3) assert PermutationGroup(p).elements == {Permutation(3), Permutation(2, 3)}
def test_coset_repr(): a = Permutation([0, 2, 1]) b = Permutation([1, 0, 2]) G = PermutationGroup([a, b]) assert G.coset_repr() == [[[0,1,2], [1,0,2], [2,0,1]], [[0,1,2], [0,2,1]]] assert G.stabilizers_gens() == [[0, 2, 1]]
def test_is_group(): assert PermutationGroup(Permutation(1,2), Permutation(2,4)).is_group == True assert SymmetricGroup(4).is_group == True
def test_orbits(): a = Permutation([2, 0, 1]) b = Permutation([2, 1, 0]) g = PermutationGroup([a, b]) assert g.orbit(0) == {0, 1, 2} assert g.orbits() == [{0, 1, 2}] assert g.is_transitive() and g.is_transitive(strict=False) assert g.orbit_transversal(0) == \ [Permutation( [0, 1, 2]), Permutation([2, 0, 1]), Permutation([1, 2, 0])] assert g.orbit_transversal(0, True) == \ [(0, Permutation([0, 1, 2])), (2, Permutation([2, 0, 1])), (1, Permutation([1, 2, 0]))] G = DihedralGroup(6) transversal, slps = _orbit_transversal(G.degree, G.generators, 0, True, slp=True) for i, t in transversal: slp = slps[i] w = G.identity for s in slp: w = G.generators[s] * w assert w == t a = Permutation(list(range(1, 100)) + [0]) G = PermutationGroup([a]) assert [min(o) for o in G.orbits()] == [0] G = PermutationGroup(rubik_cube_generators()) assert [min(o) for o in G.orbits()] == [0, 1] assert not G.is_transitive() and not G.is_transitive(strict=False) G = PermutationGroup([Permutation(0, 1, 3), Permutation(3)(0, 1)]) assert not G.is_transitive() and G.is_transitive(strict=False) assert PermutationGroup( Permutation(3)).is_transitive(strict=False) is False
def test_Permutation(): p = Permutation([2,5,1,6,3,0,4]) q = Permutation([[1,4,5],[2,0,6],[3]]) assert q.cycles == 3 assert p*q == Permutation([4, 6, 1, 2, 5, 3, 0]) assert q*p == Permutation([6, 5, 3, 0, 2, 4, 1]) assert q.array_form == [3, 1, 4, 5, 0, 6, 2] assert p.cyclic_form == [[3, 6, 4], [0, 2, 1, 5]] assert p**13 == p assert q**2 == Permutation([5, 1, 0, 6, 3, 2, 4]) assert p+q == Permutation([5, 6, 3, 1, 2, 4, 0]) assert q+p == p+q assert p-q == Permutation([6, 3, 5, 1, 2, 4, 0]) assert q-p == Permutation([1, 4, 2, 6, 5, 3, 0]) a = p-q b = q-p assert (a+b).is_Identity assert len(p.atoms()) == 7 assert q.atoms() == set([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 s = Permutation([0]) assert s.is_Singleton r = Permutation([3,2,1,0]) assert (r**2).is_Identity assert (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([[4,1,2,3],[0,5,6]]) assert q.max == 4 assert q.min == 0 assert p.rank_nonlex() == 14830 assert q.rank_nonlex() == 8441 assert Permutation.unrank_nonlex(7, 41) == Permutation([4, 2, 3, 5, 1, 0, 6]) assert q.rank == 870 assert p.rank == 1964 p = Permutation([1,5,2,0,3,6,4]) q = Permutation([[2,3,5],[1,0,6],[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 assert p.signature == -1 assert q.inversions == 11 assert q.signature == -1 assert (p*(~p)).inversions == 0 assert (p*(~p)).signature == 1 assert p.order == 6 assert q.order == 3 assert (p**(p.order)).is_Identity assert p.length == 6 assert q.length == 7 assert r.length == 4 assert not p.is_Positive assert p.is_Negative assert not q.is_Positive assert q.is_Negative assert r.is_Positive assert not r.is_Negative 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 q.rank_trotterjohnson == 259 assert p.rank_trotterjohnson == 1087 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
def test_order(): a = Permutation([2, 0, 1, 3, 4, 5, 6, 7, 8, 9]) b = Permutation([2, 1, 3, 4, 5, 6, 7, 8, 9, 0]) g = PermutationGroup([a, b]) assert g.order() == 1814400 assert PermutationGroup().order() == 1
def test_make_perm(): assert cube.pgroup.make_perm(5, seed=list(range(5))) == \ Permutation([4, 7, 6, 5, 0, 3, 2, 1]) assert cube.pgroup.make_perm(7, seed=list(range(7))) == \ Permutation([6, 7, 3, 2, 5, 4, 0, 1])
def test_args(): p = Permutation([(0, 3, 1, 2), (4, 5)]) assert p._cyclic_form is None assert Permutation(p) == p assert p.cyclic_form == [[0, 3, 1, 2], [4, 5]] assert p._array_form == [3, 2, 0, 1, 5, 4] p = Permutation((0, 3, 1, 2)) assert p._cyclic_form is None assert p._array_form == [0, 3, 1, 2] assert Permutation([0]) == Permutation((0, )) assert Permutation([[0], [1]]) == Permutation(((0, ), (1, ))) == \ Permutation(((0, ), [1])) assert Permutation([[1, 2]]) == Permutation([0, 2, 1]) assert Permutation([[1], [4, 2]]) == Permutation([0, 1, 4, 3, 2]) assert Permutation([[1], [4, 2]], size=1) == Permutation([0, 1, 4, 3, 2]) assert Permutation([[1], [4, 2]], size=6) == Permutation([0, 1, 4, 3, 2, 5]) assert Permutation([], size=3) == Permutation([0, 1, 2]) assert Permutation(3).list(5) == [0, 1, 2, 3, 4] assert Permutation(3).list(-1) == [] assert Permutation(5)(1, 2).list(-1) == [0, 2, 1] assert Permutation(5)(1, 2).list() == [0, 2, 1, 3, 4, 5] raises(ValueError, lambda: Permutation([1, 2], [0])) # enclosing brackets needed raises(ValueError, lambda: Permutation([[1, 2], 0])) # enclosing brackets needed on 0 raises(ValueError, lambda: Permutation([1, 1, 0])) raises(ValueError, lambda: Permutation([[1], [1, 2]])) raises(ValueError, lambda: Permutation([4, 5], size=10)) # where are 0-3? # but this is ok because cycles imply that only those listed moved assert Permutation(4, 5) == Permutation([0, 1, 2, 3, 5, 4])
def test_PermutationGroup(): assert PermutationGroup() == PermutationGroup(Permutation())
def test_sympy__combinatorics__permutations__Permutation(): from sympy.combinatorics.permutations import Permutation assert _test_args(Permutation([0, 1, 2, 3]))
def test_ranking(): assert Permutation.unrank_lex(5, 10).rank() == 10 p = Permutation.unrank_lex(15, 225) assert p.rank() == 225 p1 = p.next_lex() assert p1.rank() == 226 assert Permutation.unrank_lex(15, 225).rank() == 225 assert Permutation.unrank_lex(10, 0).is_Identity p = Permutation.unrank_lex(4, 23) assert p.rank() == 23 assert p.array_form == [3, 2, 1, 0] assert p.next_lex() == None p = Permutation([1, 5, 2, 0, 3, 6, 4]) q = Permutation([[1, 2, 3, 5, 6], [0, 4]]) a = [Permutation.unrank_trotterjohnson(4, i).array_form for i in range(5)] assert a == [[0,1,2,3], [0,1,3,2], [0,3,1,2], [3,0,1,2], [3,0,2,1] ] assert [Permutation(pa).rank_trotterjohnson() for pa in a] == range(5) assert Permutation([0,1,2,3]).next_trotterjohnson() == \ Permutation([0,1,3,2]) assert q.rank_trotterjohnson() == 2283 assert p.rank_trotterjohnson() == 3389 p = Permutation([2, 5, 1, 6, 3, 0, 4]) q = Permutation([[6], [5], [0, 1, 2, 3, 4]]) assert p.rank() == 1964 assert q.rank() == 870 assert Permutation([]).rank_nonlex() == 0 prank = p.rank_nonlex() assert prank == 1600 assert Permutation.unrank_nonlex(7, 1600) == p qrank = q.rank_nonlex() assert qrank == 41 assert Permutation.unrank_nonlex(7, 41) == Permutation(q.array_form) a = [Permutation.unrank_nonlex(4, i).array_form for i in range(24)] assert a == \ [[1, 2, 3, 0], [3, 2, 0, 1], [1, 3, 0, 2], [1, 2, 0, 3], [2, 3, 1, 0], \ [2, 0, 3, 1], [3, 0, 1, 2], [2, 0, 1, 3], [1, 3, 2, 0], [3, 0, 2, 1], \ [1, 0, 3, 2], [1, 0, 2, 3], [2, 1, 3, 0], [2, 3, 0, 1], [3, 1, 0, 2], \ [2, 1, 0, 3], [3, 2, 1, 0], [0, 2, 3, 1], [0, 3, 1, 2], [0, 2, 1, 3], \ [3, 1, 2, 0], [0, 3, 2, 1], [0, 1, 3, 2], [0, 1, 2, 3]] assert Permutation([3, 2, 0, 1]).next_nonlex() == Permutation([1, 3, 0, 2]) assert [Permutation(pa).rank_nonlex() for pa in a] == range(24)
def test_coset_transvesal(): G = AlternatingGroup(5) H = PermutationGroup(Permutation(0,1,2),Permutation(1,2)(3,4)) assert G.coset_transversal(H) == \ [Permutation(4), Permutation(2, 3, 4), Permutation(2, 4, 3), Permutation(1, 2, 4), Permutation(4)(1, 2, 3), Permutation(1, 3)(2, 4), Permutation(0, 1, 2, 3, 4), Permutation(0, 1, 2, 4, 3), Permutation(0, 1, 3, 2, 4), Permutation(0, 2, 4, 1, 3)]
def test_Permutation(): p = Permutation([2, 5, 1, 6, 3, 0, 4]) q = Permutation([[1], [0, 3, 5, 6, 2, 4]]) assert Permutation(p.cyclic_form).array_form == p.array_form assert p.cardinality == 5040 assert q.cardinality == 5040 assert q.cycles == 2 assert q*p == Permutation([4, 6, 1, 2, 5, 3, 0]) assert p*q == Permutation([6, 5, 3, 0, 2, 4, 1]) assert perm_af_mul([2, 5, 1, 6, 3, 0, 4], [3, 1, 4, 5, 0, 6, 2]) == \ [6, 5, 3, 0, 2, 4, 1] assert cyclic([(2,3,5)], 5) == [[1, 2, 4], [0], [3]] assert (Permutation([[1,2,3],[0,4]])*Permutation([[1,2,4],[0],[3]])).cyclic_form == \ [[1, 3], [0, 4, 2]] assert q.array_form == [3, 1, 4, 5, 0, 6, 2] assert p.cyclic_form == [[3, 6, 4], [0, 2, 1, 5]] assert p.transpositions() == [(3, 4), (3, 6), (0, 5), (0, 1), (0, 2)] assert p**13 == p assert q**2 == Permutation([5, 1, 0, 6, 3, 2, 4]) assert p+q == Permutation([5, 6, 3, 1, 2, 4, 0]) assert q+p == p+q assert p-q == Permutation([6, 3, 5, 1, 2, 4, 0]) assert q-p == Permutation([1, 4, 2, 6, 5, 3, 0]) a = p-q b = q-p assert (a+b).is_Identity assert p.conjugate(q) == Permutation([5, 3, 0, 4, 6, 2, 1]) assert p.conjugate(q) == ~q*p*q == p**q assert q.conjugate(p) == Permutation([6, 3, 2, 0, 1, 4, 5]) assert q.conjugate(p) == ~p*q*p == q**p assert p.commutator(q) == Permutation([1, 4, 5, 6, 3, 0, 2]) assert q.commutator(p) == Permutation([5, 0, 6, 4, 1, 2, 3]) assert p.commutator(q) == ~ q.commutator(p) assert len(p.atoms()) == 7 assert q.atoms() == set([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 assert Permutation([i for i in range(500,-1,-1)]).inversions() == 125250 assert Permutation([0, 4, 1, 3, 2]).parity() == 0 assert Permutation([0, 1, 4, 3, 2]).parity() == 1 assert perm_af_parity([0, 4, 1, 3, 2]) == 0 assert perm_af_parity([0, 1, 4, 3, 2]) == 1 s = Permutation([0]) assert s.is_Singleton r = Permutation([3, 2, 1, 0]) assert (r**2).is_Identity assert (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 assert p.signature() == -1 assert q.inversions() == 11 assert q.signature() == -1 assert (p*(~p)).inversions() == 0 assert (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 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]) == (a[i]*a[j] == 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
def test_subgroup(): G = PermutationGroup(Permutation(0,1,2), Permutation(0,2,3)) H = G.subgroup([Permutation(0,1,3)]) assert H.is_subgroup(G)
def test_josephus(): assert Permutation.josephus(4, 6, 1) == Permutation([3, 1, 0, 2, 5, 4]) assert Permutation.josephus(1, 5, 1).is_Identity
def test_nC_nP_nT(): from sympy.utilities.iterables import (multiset_permutations, multiset_combinations, multiset_partitions, partitions, subsets, permutations) from sympy.functions.combinatorial.numbers import (nP, nC, nT, stirling, _stirling1, _stirling2, _multiset_histogram, _AOP_product) from sympy.combinatorics.permutations import Permutation from random import choice c = string.ascii_lowercase for i in range(100): s = ''.join(choice(c) for i in range(7)) u = len(s) == len(set(s)) try: tot = 0 for i in range(8): check = nP(s, i) tot += check assert len(list(multiset_permutations(s, i))) == check if u: assert nP(len(s), i) == check assert nP(s) == tot except AssertionError: print(s, i, 'failed perm test') raise ValueError() for i in range(100): s = ''.join(choice(c) for i in range(7)) u = len(s) == len(set(s)) try: tot = 0 for i in range(8): check = nC(s, i) tot += check assert len(list(multiset_combinations(s, i))) == check if u: assert nC(len(s), i) == check assert nC(s) == tot if u: assert nC(len(s)) == tot except AssertionError: print(s, i, 'failed combo test') raise ValueError() for i in range(1, 10): tot = 0 for j in range(1, i + 2): check = nT(i, j) assert check.is_Integer tot += check assert sum(1 for p in partitions(i, j, size=True) if p[0] == j) == check assert nT(i) == tot for i in range(1, 10): tot = 0 for j in range(1, i + 2): check = nT(range(i), j) tot += check assert len(list(multiset_partitions(list(range(i)), j))) == check assert nT(range(i)) == tot for i in range(100): s = ''.join(choice(c) for i in range(7)) u = len(s) == len(set(s)) try: tot = 0 for i in range(1, 8): check = nT(s, i) tot += check assert len(list(multiset_partitions(s, i))) == check if u: assert nT(range(len(s)), i) == check if u: assert nT(range(len(s))) == tot assert nT(s) == tot except AssertionError: print(s, i, 'failed partition test') raise ValueError() # tests for Stirling numbers of the first kind that are not tested in the # above assert [stirling(9, i, kind=1) for i in range(11) ] == [0, 40320, 109584, 118124, 67284, 22449, 4536, 546, 36, 1, 0] perms = list(permutations(range(4))) assert [ sum(1 for p in perms if Permutation(p).cycles == i) for i in range(5) ] == [0, 6, 11, 6, 1] == [stirling(4, i, kind=1) for i in range(5)] # http://oeis.org/A008275 assert [ stirling(n, k, signed=1) for n in range(10) for k in range(1, n + 1) ] == [ 1, -1, 1, 2, -3, 1, -6, 11, -6, 1, 24, -50, 35, -10, 1, -120, 274, -225, 85, -15, 1, 720, -1764, 1624, -735, 175, -21, 1, -5040, 13068, -13132, 6769, -1960, 322, -28, 1, 40320, -109584, 118124, -67284, 22449, -4536, 546, -36, 1 ] # https://en.wikipedia.org/wiki/Stirling_numbers_of_the_first_kind assert [stirling(n, k, kind=1) for n in range(10) for k in range(n + 1)] == [ 1, 0, 1, 0, 1, 1, 0, 2, 3, 1, 0, 6, 11, 6, 1, 0, 24, 50, 35, 10, 1, 0, 120, 274, 225, 85, 15, 1, 0, 720, 1764, 1624, 735, 175, 21, 1, 0, 5040, 13068, 13132, 6769, 1960, 322, 28, 1, 0, 40320, 109584, 118124, 67284, 22449, 4536, 546, 36, 1 ] # https://en.wikipedia.org/wiki/Stirling_numbers_of_the_second_kind assert [stirling(n, k, kind=2) for n in range(10) for k in range(n + 1)] == [ 1, 0, 1, 0, 1, 1, 0, 1, 3, 1, 0, 1, 7, 6, 1, 0, 1, 15, 25, 10, 1, 0, 1, 31, 90, 65, 15, 1, 0, 1, 63, 301, 350, 140, 21, 1, 0, 1, 127, 966, 1701, 1050, 266, 28, 1, 0, 1, 255, 3025, 7770, 6951, 2646, 462, 36, 1 ] assert stirling(3, 4, kind=1) == stirling(3, 4, kind=1) == 0 raises(ValueError, lambda: stirling(-2, 2)) # Assertion that the return type is SymPy Integer. assert isinstance(_stirling1(6, 3), Integer) assert isinstance(_stirling2(6, 3), Integer) def delta(p): if len(p) == 1: return oo return min(abs(i[0] - i[1]) for i in subsets(p, 2)) parts = multiset_partitions(range(5), 3) d = 2 assert (sum(1 for p in parts if all(delta(i) >= d for i in p)) == stirling(5, 3, d=d) == 7) # other coverage tests assert nC('abb', 2) == nC('aab', 2) == 2 assert nP(3, 3, replacement=True) == nP('aabc', 3, replacement=True) == 27 assert nP(3, 4) == 0 assert nP('aabc', 5) == 0 assert nC(4, 2, replacement=True) == nC('abcdd', 2, replacement=True) == \ len(list(multiset_combinations('aabbccdd', 2))) == 10 assert nC('abcdd') == sum(nC('abcdd', i) for i in range(6)) == 24 assert nC(list('abcdd'), 4) == 4 assert nT('aaaa') == nT(4) == len(list(partitions(4))) == 5 assert nT('aaab') == len(list(multiset_partitions('aaab'))) == 7 assert nC('aabb' * 3, 3) == 4 # aaa, bbb, abb, baa assert dict(_AOP_product((4, 1, 1, 1))) == { 0: 1, 1: 4, 2: 7, 3: 8, 4: 8, 5: 7, 6: 4, 7: 1 } # the following was the first t that showed a problem in a previous form of # the function, so it's not as random as it may appear t = (3, 9, 4, 6, 6, 5, 5, 2, 10, 4) assert sum(_AOP_product(t)[i] for i in range(55)) == 58212000 raises(ValueError, lambda: _multiset_histogram({1: 'a'}))
def mult(permutation_a, permutation_b): return Permutation( [permutation_a[j] for i, j in enumerate(permutation_b.array_forms)])
def test1(): a = Permutation([2, 0, 1, 3, 4, 5]) b = Permutation([0, 2, 1, 3, 4]) g = PermutationGroup([a, b])
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(range(p.size)) == list(p) # call as function assert list(p(1, 2)) == [0, 2, 1, 3] # conversion to list assert list(p) == range(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(set([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() == 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(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(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() == set([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}