def test_composition_series(): a = Permutation(1, 2, 3) b = Permutation(1, 2) G = PermutationGroup([a, b]) comp_series = G.composition_series() assert comp_series == G.derived_series() # The first group in the composition series is always the group itself and # the last group in the series is the trivial group. S = SymmetricGroup(4) assert S.composition_series()[0] == S assert len(S.composition_series()) == 5 A = AlternatingGroup(4) assert A.composition_series()[0] == A assert len(A.composition_series()) == 4 # the composition series for C_8 is C_8 > C_4 > C_2 > triv G = CyclicGroup(8) series = G.composition_series() assert is_isomorphic(series[1], CyclicGroup(4)) assert is_isomorphic(series[2], CyclicGroup(2)) assert series[3].is_trivial
def test_eq(): a = [[1, 2, 0, 3, 4, 5], [1, 0, 2, 3, 4, 5], [2, 1, 0, 3, 4, 5], [1, 2, 0, 3, 4, 5]] a = [Permutation(p) for p in a + [[1, 2, 3, 4, 5, 0]]] g = Permutation([1, 2, 3, 4, 5, 0]) G1, G2, G3 = [PermutationGroup(x) for x in [a[:2], a[2:4], [g, g ** 2]]] assert G1.order() == G2.order() == G3.order() == 6 assert G1.is_subgroup(G2) assert not G1.is_subgroup(G3) G4 = PermutationGroup([Permutation([0, 1])]) assert not G1.is_subgroup(G4) assert G4.is_subgroup(G1, 0) assert PermutationGroup(g, g).is_subgroup(PermutationGroup(g)) assert SymmetricGroup(3).is_subgroup(SymmetricGroup(4), 0) assert SymmetricGroup(3).is_subgroup(SymmetricGroup(3) * CyclicGroup(5), 0) assert not CyclicGroup(5).is_subgroup(SymmetricGroup(3) * CyclicGroup(5), 0) assert CyclicGroup(3).is_subgroup(SymmetricGroup(3) * CyclicGroup(5), 0)
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 orbit_homomorphism(group, omega): ''' Return the homomorphism induced by the action of the permutation group `group` on the set `omega` that is closed under the action. ''' from sympy.combinatorics import Permutation from sympy.combinatorics.named_groups import SymmetricGroup codomain = SymmetricGroup(len(omega)) identity = codomain.identity omega = list(omega) images = { g: identity * Permutation([omega.index(o ^ g) for o in omega]) for g in group.generators } group._schreier_sims(base=omega) H = GroupHomomorphism(group, codomain, images) if len(group.basic_stabilizers) > len(omega): H._kernel = group.basic_stabilizers[len(omega)] else: H._kernel = PermutationGroup([group.identity]) return H
def block_homomorphism(group, blocks): ''' Return the homomorphism induced by the action of the permutation group `group` on the block system `blocks`. The latter should be of the same form as returned by the `minimal_block` method for permutation groups, namely a list of length `group.degree` where the i-th entry is a representative of the block i belongs to. ''' from sympy.combinatorics import Permutation from sympy.combinatorics.named_groups import SymmetricGroup n = len(blocks) # number the blocks; m is the total number, # b is such that b[i] is the number of the block i belongs to, # p is the list of length m such that p[i] is the representative # of the i-th block m = 0 p = [] b = [None] * n for i in range(n): if blocks[i] == i: p.append(i) b[i] = m m += 1 for i in range(n): b[i] = b[blocks[i]] codomain = SymmetricGroup(m) # the list corresponding to the identity permutation in codomain identity = range(m) images = { g: Permutation([b[p[i] ^ g] for i in identity]) for g in group.generators } H = GroupHomomorphism(group, codomain, images) return H
def test_presentation(): def _test(P): G = P.presentation() return G.order() == P.order() def _strong_test(P): G = P.strong_presentation() chk = len(G.generators) == len(P.strong_gens) return chk and G.order() == P.order() P = PermutationGroup( Permutation(0, 1, 5, 2)(3, 7, 4, 6), Permutation(0, 3, 5, 4)(1, 6, 2, 7)) assert _test(P) P = AlternatingGroup(5) assert _test(P) P = SymmetricGroup(5) assert _test(P) P = PermutationGroup([ Permutation(0, 3, 1, 2), Permutation(3)(0, 1), Permutation(0, 1)(2, 3) ]) G = P.strong_presentation() assert _strong_test(P) P = DihedralGroup(6) G = P.strong_presentation() assert _strong_test(P) a = Permutation(0, 1)(2, 3) b = Permutation(0, 2)(3, 1) c = Permutation(4, 5) P = PermutationGroup(c, a, b) assert _strong_test(P)
def test_schreier_sims_incremental(): identity = Permutation([0, 1, 2, 3, 4]) TrivialGroup = PermutationGroup([identity]) base, strong_gens = TrivialGroup.schreier_sims_incremental(base=[0, 1, 2]) assert _verify_bsgs(TrivialGroup, base, strong_gens) is True S = SymmetricGroup(5) base, strong_gens = S.schreier_sims_incremental(base=[0, 1, 2]) assert _verify_bsgs(S, base, strong_gens) is True D = DihedralGroup(2) base, strong_gens = D.schreier_sims_incremental(base=[1]) assert _verify_bsgs(D, base, strong_gens) is True A = AlternatingGroup(7) gens = A.generators[:] gen0 = gens[0] gen1 = gens[1] gen1 = rmul(gen1, ~gen0) gen0 = rmul(gen0, gen1) gen1 = rmul(gen0, gen1) base, strong_gens = A.schreier_sims_incremental(base=[0, 1], gens=gens) assert _verify_bsgs(A, base, strong_gens) is True C = CyclicGroup(11) gen = C.generators[0] base, strong_gens = C.schreier_sims_incremental(gens=[gen**3]) assert _verify_bsgs(C, base, strong_gens) is True
def test_is_group(): assert PermutationGroup(Permutation(1, 2), Permutation(2, 4)).is_group == True assert SymmetricGroup(4).is_group == True
def test_is_primitive(): S = SymmetricGroup(5) assert S.is_primitive() is True C = CyclicGroup(7) assert C.is_primitive() is True
def test_max_div(): S = SymmetricGroup(10) assert S.max_div == 5
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_naive_list_centralizer(): # verified by GAP S = SymmetricGroup(3) A = AlternatingGroup(3) assert _naive_list_centralizer(S, S) == [Permutation([0, 1, 2])] assert PermutationGroup(_naive_list_centralizer(S, A)).is_subgroup(A)
def test_cmp_perm_lists(): S = SymmetricGroup(4) els = list(S.generate_dimino()) other = els[:] shuffle(other) assert _cmp_perm_lists(els, other) is True
def test_sylow_subgroup(): P = PermutationGroup( Permutation(1, 5)(2, 4), Permutation(0, 1, 2, 3, 4, 5)) S = P.sylow_subgroup(2) assert S.order() == 4 P = DihedralGroup(12) S = P.sylow_subgroup(3) assert S.order() == 3 P = PermutationGroup( Permutation(1, 5)(2, 4), Permutation(0, 1, 2, 3, 4, 5), Permutation(0, 2)) S = P.sylow_subgroup(3) assert S.order() == 9 S = P.sylow_subgroup(2) assert S.order() == 8 P = SymmetricGroup(10) S = P.sylow_subgroup(2) assert S.order() == 256 S = P.sylow_subgroup(3) assert S.order() == 81 S = P.sylow_subgroup(5) assert S.order() == 25 # the length of the lower central series # of a p-Sylow subgroup of Sym(n) grows with # the highest exponent exp of p such # that n >= p**exp exp = 1 length = 0 for i in range(2, 9): P = SymmetricGroup(i) S = P.sylow_subgroup(2) ls = S.lower_central_series() if i // 2**exp > 0: # length increases with exponent assert len(ls) > length length = len(ls) exp += 1 else: assert len(ls) == length G = SymmetricGroup(100) S = G.sylow_subgroup(3) assert G.order() % S.order() == 0 assert G.order() / S.order() % 3 > 0 G = AlternatingGroup(100) S = G.sylow_subgroup(2) assert G.order() % S.order() == 0 assert G.order() / S.order() % 2 > 0 G = DihedralGroup(18) S = G.sylow_subgroup(p=2) assert S.order() == 4 G = DihedralGroup(50) S = G.sylow_subgroup(p=2) assert S.order() == 4
from sympy.combinatorics import Permutation, Cycle from sympy.combinatorics.named_groups import SymmetricGroup S5 = SymmetricGroup(5) S5_elems = list(S5.generate_schreier_sims()) IDENTITY = Permutation(4) ALPHA = Permutation(Cycle(0, 1, 2, 3, 4)) BETA = Permutation(Cycle(0, 2, 4, 3, 1)) ALPHA_INV = (~ALPHA) BETA_INV = (~BETA) COMMUTATOR = ALPHA * BETA * ALPHA_INV * BETA_INV ELEMENTS = [ALPHA, ALPHA_INV, BETA, BETA_INV, COMMUTATOR] CONJUGATORS = {e: {} for e in ELEMENTS} for e1 in ELEMENTS: for e2 in ELEMENTS: for gamma in S5_elems: if gamma * e1 * (~gamma) == e2: CONJUGATORS[e1][e2] = (gamma, ~gamma) break class GroupInstruction(object): def __init__(self, index, g0, g1): self.index = index self.g0 = g0 self.g1 = g1 def __str__(self): return str(self.index).ljust(4) + str(self.g0).ljust(15) + str( self.g1).ljust(13)