Spaces:
Sleeping
Sleeping
from sympy.combinatorics.group_constructs import DirectProduct | |
from sympy.combinatorics.perm_groups import PermutationGroup | |
from sympy.combinatorics.permutations import Permutation | |
_af_new = Permutation._af_new | |
def AbelianGroup(*cyclic_orders): | |
""" | |
Returns the direct product of cyclic groups with the given orders. | |
Explanation | |
=========== | |
According to the structure theorem for finite abelian groups ([1]), | |
every finite abelian group can be written as the direct product of | |
finitely many cyclic groups. | |
Examples | |
======== | |
>>> from sympy.combinatorics.named_groups import AbelianGroup | |
>>> AbelianGroup(3, 4) | |
PermutationGroup([ | |
(6)(0 1 2), | |
(3 4 5 6)]) | |
>>> _.is_group | |
True | |
See Also | |
======== | |
DirectProduct | |
References | |
========== | |
.. [1] https://groupprops.subwiki.org/wiki/Structure_theorem_for_finitely_generated_abelian_groups | |
""" | |
groups = [] | |
degree = 0 | |
order = 1 | |
for size in cyclic_orders: | |
degree += size | |
order *= size | |
groups.append(CyclicGroup(size)) | |
G = DirectProduct(*groups) | |
G._is_abelian = True | |
G._degree = degree | |
G._order = order | |
return G | |
def AlternatingGroup(n): | |
""" | |
Generates the alternating group on ``n`` elements as a permutation group. | |
Explanation | |
=========== | |
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) | |
set_alternating_group_properties(G, n, n) | |
G._is_alt = True | |
return G | |
def set_alternating_group_properties(G, n, degree): | |
"""Set known properties of an alternating group. """ | |
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 = degree | |
G._is_transitive = True | |
G._is_dihedral = False | |
def CyclicGroup(n): | |
""" | |
Generates the cyclic group of order ``n`` as a permutation group. | |
Explanation | |
=========== | |
The generator taken is the ``n``-cycle ``(0 1 2 ... n-1)`` | |
(in cycle notation). After the group is generated, some of its basic | |
properties are set. | |
Examples | |
======== | |
>>> from sympy.combinatorics.named_groups import CyclicGroup | |
>>> G = CyclicGroup(6) | |
>>> G.is_group | |
True | |
>>> G.order() | |
6 | |
>>> list(G.generate_schreier_sims(af=True)) | |
[[0, 1, 2, 3, 4, 5], [1, 2, 3, 4, 5, 0], [2, 3, 4, 5, 0, 1], | |
[3, 4, 5, 0, 1, 2], [4, 5, 0, 1, 2, 3], [5, 0, 1, 2, 3, 4]] | |
See Also | |
======== | |
SymmetricGroup, DihedralGroup, AlternatingGroup | |
""" | |
a = list(range(1, n)) | |
a.append(0) | |
gen = _af_new(a) | |
G = PermutationGroup([gen]) | |
G._is_abelian = True | |
G._is_nilpotent = True | |
G._is_solvable = True | |
G._degree = n | |
G._is_transitive = True | |
G._order = n | |
G._is_dihedral = (n == 2) | |
return G | |
def DihedralGroup(n): | |
r""" | |
Generates the dihedral group `D_n` as a permutation group. | |
Explanation | |
=========== | |
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_dihedral = True | |
G._is_abelian = False | |
G._is_solvable = True | |
G._degree = n | |
G._is_transitive = True | |
G._order = 2*n | |
return G | |
def SymmetricGroup(n): | |
""" | |
Generates the symmetric group on ``n`` elements as a permutation group. | |
Explanation | |
=========== | |
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]) | |
set_symmetric_group_properties(G, n, n) | |
G._is_sym = True | |
return G | |
def set_symmetric_group_properties(G, n, degree): | |
"""Set known properties of a symmetric group. """ | |
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 = degree | |
G._is_transitive = True | |
G._is_dihedral = (n in [2, 3]) # cf Landau's func and Stirling's approx | |
def RubikGroup(n): | |
"""Return a group of Rubik's cube generators | |
>>> from sympy.combinatorics.named_groups import RubikGroup | |
>>> RubikGroup(2).is_group | |
True | |
""" | |
from sympy.combinatorics.generators import rubik | |
if n <= 1: | |
raise ValueError("Invalid cube. n has to be greater than 1") | |
return PermutationGroup(rubik(n)) | |