test_perm_groups.py 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243
  1. from sympy.core.containers import Tuple
  2. from sympy.combinatorics.generators import rubik_cube_generators
  3. from sympy.combinatorics.homomorphisms import is_isomorphic
  4. from sympy.combinatorics.named_groups import SymmetricGroup, CyclicGroup,\
  5. DihedralGroup, AlternatingGroup, AbelianGroup, RubikGroup
  6. from sympy.combinatorics.perm_groups import (PermutationGroup,
  7. _orbit_transversal, Coset, SymmetricPermutationGroup)
  8. from sympy.combinatorics.permutations import Permutation
  9. from sympy.combinatorics.polyhedron import tetrahedron as Tetra, cube
  10. from sympy.combinatorics.testutil import _verify_bsgs, _verify_centralizer,\
  11. _verify_normal_closure
  12. from sympy.testing.pytest import skip, XFAIL, slow
  13. rmul = Permutation.rmul
  14. def test_has():
  15. a = Permutation([1, 0])
  16. G = PermutationGroup([a])
  17. assert G.is_abelian
  18. a = Permutation([2, 0, 1])
  19. b = Permutation([2, 1, 0])
  20. G = PermutationGroup([a, b])
  21. assert not G.is_abelian
  22. G = PermutationGroup([a])
  23. assert G.has(a)
  24. assert not G.has(b)
  25. a = Permutation([2, 0, 1, 3, 4, 5])
  26. b = Permutation([0, 2, 1, 3, 4])
  27. assert PermutationGroup(a, b).degree == \
  28. PermutationGroup(a, b).degree == 6
  29. g = PermutationGroup(Permutation(0, 2, 1))
  30. assert Tuple(1, g).has(g)
  31. def test_generate():
  32. a = Permutation([1, 0])
  33. g = list(PermutationGroup([a]).generate())
  34. assert g == [Permutation([0, 1]), Permutation([1, 0])]
  35. assert len(list(PermutationGroup(Permutation((0, 1))).generate())) == 1
  36. g = PermutationGroup([a]).generate(method='dimino')
  37. assert list(g) == [Permutation([0, 1]), Permutation([1, 0])]
  38. a = Permutation([2, 0, 1])
  39. b = Permutation([2, 1, 0])
  40. G = PermutationGroup([a, b])
  41. g = G.generate()
  42. v1 = [p.array_form for p in list(g)]
  43. v1.sort()
  44. assert v1 == [[0, 1, 2], [0, 2, 1], [1, 0, 2], [1, 2, 0], [2, 0,
  45. 1], [2, 1, 0]]
  46. v2 = list(G.generate(method='dimino', af=True))
  47. assert v1 == sorted(v2)
  48. a = Permutation([2, 0, 1, 3, 4, 5])
  49. b = Permutation([2, 1, 3, 4, 5, 0])
  50. g = PermutationGroup([a, b]).generate(af=True)
  51. assert len(list(g)) == 360
  52. def test_order():
  53. a = Permutation([2, 0, 1, 3, 4, 5, 6, 7, 8, 9])
  54. b = Permutation([2, 1, 3, 4, 5, 6, 7, 8, 9, 0])
  55. g = PermutationGroup([a, b])
  56. assert g.order() == 1814400
  57. assert PermutationGroup().order() == 1
  58. def test_equality():
  59. p_1 = Permutation(0, 1, 3)
  60. p_2 = Permutation(0, 2, 3)
  61. p_3 = Permutation(0, 1, 2)
  62. p_4 = Permutation(0, 1, 3)
  63. g_1 = PermutationGroup(p_1, p_2)
  64. g_2 = PermutationGroup(p_3, p_4)
  65. g_3 = PermutationGroup(p_2, p_1)
  66. g_4 = PermutationGroup(p_1, p_2)
  67. assert g_1 != g_2
  68. assert g_1.generators != g_2.generators
  69. assert g_1.equals(g_2)
  70. assert g_1 != g_3
  71. assert g_1.equals(g_3)
  72. assert g_1 == g_4
  73. def test_stabilizer():
  74. S = SymmetricGroup(2)
  75. H = S.stabilizer(0)
  76. assert H.generators == [Permutation(1)]
  77. a = Permutation([2, 0, 1, 3, 4, 5])
  78. b = Permutation([2, 1, 3, 4, 5, 0])
  79. G = PermutationGroup([a, b])
  80. G0 = G.stabilizer(0)
  81. assert G0.order() == 60
  82. gens_cube = [[1, 3, 5, 7, 0, 2, 4, 6], [1, 3, 0, 2, 5, 7, 4, 6]]
  83. gens = [Permutation(p) for p in gens_cube]
  84. G = PermutationGroup(gens)
  85. G2 = G.stabilizer(2)
  86. assert G2.order() == 6
  87. G2_1 = G2.stabilizer(1)
  88. v = list(G2_1.generate(af=True))
  89. assert v == [[0, 1, 2, 3, 4, 5, 6, 7], [3, 1, 2, 0, 7, 5, 6, 4]]
  90. gens = (
  91. (1, 2, 0, 4, 5, 3, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19),
  92. (0, 1, 2, 3, 4, 5, 19, 6, 8, 9, 10, 11, 12, 13, 14,
  93. 15, 16, 7, 17, 18),
  94. (0, 1, 2, 3, 4, 5, 6, 7, 9, 18, 16, 11, 12, 13, 14, 15, 8, 17, 10, 19))
  95. gens = [Permutation(p) for p in gens]
  96. G = PermutationGroup(gens)
  97. G2 = G.stabilizer(2)
  98. assert G2.order() == 181440
  99. S = SymmetricGroup(3)
  100. assert [G.order() for G in S.basic_stabilizers] == [6, 2]
  101. def test_center():
  102. # the center of the dihedral group D_n is of order 2 for even n
  103. for i in (4, 6, 10):
  104. D = DihedralGroup(i)
  105. assert (D.center()).order() == 2
  106. # the center of the dihedral group D_n is of order 1 for odd n>2
  107. for i in (3, 5, 7):
  108. D = DihedralGroup(i)
  109. assert (D.center()).order() == 1
  110. # the center of an abelian group is the group itself
  111. for i in (2, 3, 5):
  112. for j in (1, 5, 7):
  113. for k in (1, 1, 11):
  114. G = AbelianGroup(i, j, k)
  115. assert G.center().is_subgroup(G)
  116. # the center of a nonabelian simple group is trivial
  117. for i in(1, 5, 9):
  118. A = AlternatingGroup(i)
  119. assert (A.center()).order() == 1
  120. # brute-force verifications
  121. D = DihedralGroup(5)
  122. A = AlternatingGroup(3)
  123. C = CyclicGroup(4)
  124. G.is_subgroup(D*A*C)
  125. assert _verify_centralizer(G, G)
  126. def test_centralizer():
  127. # the centralizer of the trivial group is the entire group
  128. S = SymmetricGroup(2)
  129. assert S.centralizer(Permutation(list(range(2)))).is_subgroup(S)
  130. A = AlternatingGroup(5)
  131. assert A.centralizer(Permutation(list(range(5)))).is_subgroup(A)
  132. # a centralizer in the trivial group is the trivial group itself
  133. triv = PermutationGroup([Permutation([0, 1, 2, 3])])
  134. D = DihedralGroup(4)
  135. assert triv.centralizer(D).is_subgroup(triv)
  136. # brute-force verifications for centralizers of groups
  137. for i in (4, 5, 6):
  138. S = SymmetricGroup(i)
  139. A = AlternatingGroup(i)
  140. C = CyclicGroup(i)
  141. D = DihedralGroup(i)
  142. for gp in (S, A, C, D):
  143. for gp2 in (S, A, C, D):
  144. if not gp2.is_subgroup(gp):
  145. assert _verify_centralizer(gp, gp2)
  146. # verify the centralizer for all elements of several groups
  147. S = SymmetricGroup(5)
  148. elements = list(S.generate_dimino())
  149. for element in elements:
  150. assert _verify_centralizer(S, element)
  151. A = AlternatingGroup(5)
  152. elements = list(A.generate_dimino())
  153. for element in elements:
  154. assert _verify_centralizer(A, element)
  155. D = DihedralGroup(7)
  156. elements = list(D.generate_dimino())
  157. for element in elements:
  158. assert _verify_centralizer(D, element)
  159. # verify centralizers of small groups within small groups
  160. small = []
  161. for i in (1, 2, 3):
  162. small.append(SymmetricGroup(i))
  163. small.append(AlternatingGroup(i))
  164. small.append(DihedralGroup(i))
  165. small.append(CyclicGroup(i))
  166. for gp in small:
  167. for gp2 in small:
  168. if gp.degree == gp2.degree:
  169. assert _verify_centralizer(gp, gp2)
  170. def test_coset_rank():
  171. gens_cube = [[1, 3, 5, 7, 0, 2, 4, 6], [1, 3, 0, 2, 5, 7, 4, 6]]
  172. gens = [Permutation(p) for p in gens_cube]
  173. G = PermutationGroup(gens)
  174. i = 0
  175. for h in G.generate(af=True):
  176. rk = G.coset_rank(h)
  177. assert rk == i
  178. h1 = G.coset_unrank(rk, af=True)
  179. assert h == h1
  180. i += 1
  181. assert G.coset_unrank(48) is None
  182. assert G.coset_unrank(G.coset_rank(gens[0])) == gens[0]
  183. def test_coset_factor():
  184. a = Permutation([0, 2, 1])
  185. G = PermutationGroup([a])
  186. c = Permutation([2, 1, 0])
  187. assert not G.coset_factor(c)
  188. assert G.coset_rank(c) is None
  189. a = Permutation([2, 0, 1, 3, 4, 5])
  190. b = Permutation([2, 1, 3, 4, 5, 0])
  191. g = PermutationGroup([a, b])
  192. assert g.order() == 360
  193. d = Permutation([1, 0, 2, 3, 4, 5])
  194. assert not g.coset_factor(d.array_form)
  195. assert not g.contains(d)
  196. assert Permutation(2) in G
  197. c = Permutation([1, 0, 2, 3, 5, 4])
  198. v = g.coset_factor(c, True)
  199. tr = g.basic_transversals
  200. p = Permutation.rmul(*[tr[i][v[i]] for i in range(len(g.base))])
  201. assert p == c
  202. v = g.coset_factor(c)
  203. p = Permutation.rmul(*v)
  204. assert p == c
  205. assert g.contains(c)
  206. G = PermutationGroup([Permutation([2, 1, 0])])
  207. p = Permutation([1, 0, 2])
  208. assert G.coset_factor(p) == []
  209. def test_orbits():
  210. a = Permutation([2, 0, 1])
  211. b = Permutation([2, 1, 0])
  212. g = PermutationGroup([a, b])
  213. assert g.orbit(0) == {0, 1, 2}
  214. assert g.orbits() == [{0, 1, 2}]
  215. assert g.is_transitive() and g.is_transitive(strict=False)
  216. assert g.orbit_transversal(0) == \
  217. [Permutation(
  218. [0, 1, 2]), Permutation([2, 0, 1]), Permutation([1, 2, 0])]
  219. assert g.orbit_transversal(0, True) == \
  220. [(0, Permutation([0, 1, 2])), (2, Permutation([2, 0, 1])),
  221. (1, Permutation([1, 2, 0]))]
  222. G = DihedralGroup(6)
  223. transversal, slps = _orbit_transversal(G.degree, G.generators, 0, True, slp=True)
  224. for i, t in transversal:
  225. slp = slps[i]
  226. w = G.identity
  227. for s in slp:
  228. w = G.generators[s]*w
  229. assert w == t
  230. a = Permutation(list(range(1, 100)) + [0])
  231. G = PermutationGroup([a])
  232. assert [min(o) for o in G.orbits()] == [0]
  233. G = PermutationGroup(rubik_cube_generators())
  234. assert [min(o) for o in G.orbits()] == [0, 1]
  235. assert not G.is_transitive() and not G.is_transitive(strict=False)
  236. G = PermutationGroup([Permutation(0, 1, 3), Permutation(3)(0, 1)])
  237. assert not G.is_transitive() and G.is_transitive(strict=False)
  238. assert PermutationGroup(
  239. Permutation(3)).is_transitive(strict=False) is False
  240. def test_is_normal():
  241. gens_s5 = [Permutation(p) for p in [[1, 2, 3, 4, 0], [2, 1, 4, 0, 3]]]
  242. G1 = PermutationGroup(gens_s5)
  243. assert G1.order() == 120
  244. gens_a5 = [Permutation(p) for p in [[1, 0, 3, 2, 4], [2, 1, 4, 3, 0]]]
  245. G2 = PermutationGroup(gens_a5)
  246. assert G2.order() == 60
  247. assert G2.is_normal(G1)
  248. gens3 = [Permutation(p) for p in [[2, 1, 3, 0, 4], [1, 2, 0, 3, 4]]]
  249. G3 = PermutationGroup(gens3)
  250. assert not G3.is_normal(G1)
  251. assert G3.order() == 12
  252. G4 = G1.normal_closure(G3.generators)
  253. assert G4.order() == 60
  254. gens5 = [Permutation(p) for p in [[1, 2, 3, 0, 4], [1, 2, 0, 3, 4]]]
  255. G5 = PermutationGroup(gens5)
  256. assert G5.order() == 24
  257. G6 = G1.normal_closure(G5.generators)
  258. assert G6.order() == 120
  259. assert G1.is_subgroup(G6)
  260. assert not G1.is_subgroup(G4)
  261. assert G2.is_subgroup(G4)
  262. I5 = PermutationGroup(Permutation(4))
  263. assert I5.is_normal(G5)
  264. assert I5.is_normal(G6, strict=False)
  265. p1 = Permutation([1, 0, 2, 3, 4])
  266. p2 = Permutation([0, 1, 2, 4, 3])
  267. p3 = Permutation([3, 4, 2, 1, 0])
  268. id_ = Permutation([0, 1, 2, 3, 4])
  269. H = PermutationGroup([p1, p3])
  270. H_n1 = PermutationGroup([p1, p2])
  271. H_n2_1 = PermutationGroup(p1)
  272. H_n2_2 = PermutationGroup(p2)
  273. H_id = PermutationGroup(id_)
  274. assert H_n1.is_normal(H)
  275. assert H_n2_1.is_normal(H_n1)
  276. assert H_n2_2.is_normal(H_n1)
  277. assert H_id.is_normal(H_n2_1)
  278. assert H_id.is_normal(H_n1)
  279. assert H_id.is_normal(H)
  280. assert not H_n2_1.is_normal(H)
  281. assert not H_n2_2.is_normal(H)
  282. def test_eq():
  283. a = [[1, 2, 0, 3, 4, 5], [1, 0, 2, 3, 4, 5], [2, 1, 0, 3, 4, 5], [
  284. 1, 2, 0, 3, 4, 5]]
  285. a = [Permutation(p) for p in a + [[1, 2, 3, 4, 5, 0]]]
  286. g = Permutation([1, 2, 3, 4, 5, 0])
  287. G1, G2, G3 = [PermutationGroup(x) for x in [a[:2], a[2:4], [g, g**2]]]
  288. assert G1.order() == G2.order() == G3.order() == 6
  289. assert G1.is_subgroup(G2)
  290. assert not G1.is_subgroup(G3)
  291. G4 = PermutationGroup([Permutation([0, 1])])
  292. assert not G1.is_subgroup(G4)
  293. assert G4.is_subgroup(G1, 0)
  294. assert PermutationGroup(g, g).is_subgroup(PermutationGroup(g))
  295. assert SymmetricGroup(3).is_subgroup(SymmetricGroup(4), 0)
  296. assert SymmetricGroup(3).is_subgroup(SymmetricGroup(3)*CyclicGroup(5), 0)
  297. assert not CyclicGroup(5).is_subgroup(SymmetricGroup(3)*CyclicGroup(5), 0)
  298. assert CyclicGroup(3).is_subgroup(SymmetricGroup(3)*CyclicGroup(5), 0)
  299. def test_derived_subgroup():
  300. a = Permutation([1, 0, 2, 4, 3])
  301. b = Permutation([0, 1, 3, 2, 4])
  302. G = PermutationGroup([a, b])
  303. C = G.derived_subgroup()
  304. assert C.order() == 3
  305. assert C.is_normal(G)
  306. assert C.is_subgroup(G, 0)
  307. assert not G.is_subgroup(C, 0)
  308. gens_cube = [[1, 3, 5, 7, 0, 2, 4, 6], [1, 3, 0, 2, 5, 7, 4, 6]]
  309. gens = [Permutation(p) for p in gens_cube]
  310. G = PermutationGroup(gens)
  311. C = G.derived_subgroup()
  312. assert C.order() == 12
  313. def test_is_solvable():
  314. a = Permutation([1, 2, 0])
  315. b = Permutation([1, 0, 2])
  316. G = PermutationGroup([a, b])
  317. assert G.is_solvable
  318. G = PermutationGroup([a])
  319. assert G.is_solvable
  320. a = Permutation([1, 2, 3, 4, 0])
  321. b = Permutation([1, 0, 2, 3, 4])
  322. G = PermutationGroup([a, b])
  323. assert not G.is_solvable
  324. P = SymmetricGroup(10)
  325. S = P.sylow_subgroup(3)
  326. assert S.is_solvable
  327. def test_rubik1():
  328. gens = rubik_cube_generators()
  329. gens1 = [gens[-1]] + [p**2 for p in gens[1:]]
  330. G1 = PermutationGroup(gens1)
  331. assert G1.order() == 19508428800
  332. gens2 = [p**2 for p in gens]
  333. G2 = PermutationGroup(gens2)
  334. assert G2.order() == 663552
  335. assert G2.is_subgroup(G1, 0)
  336. C1 = G1.derived_subgroup()
  337. assert C1.order() == 4877107200
  338. assert C1.is_subgroup(G1, 0)
  339. assert not G2.is_subgroup(C1, 0)
  340. G = RubikGroup(2)
  341. assert G.order() == 3674160
  342. @XFAIL
  343. def test_rubik():
  344. skip('takes too much time')
  345. G = PermutationGroup(rubik_cube_generators())
  346. assert G.order() == 43252003274489856000
  347. G1 = PermutationGroup(G[:3])
  348. assert G1.order() == 170659735142400
  349. assert not G1.is_normal(G)
  350. G2 = G.normal_closure(G1.generators)
  351. assert G2.is_subgroup(G)
  352. def test_direct_product():
  353. C = CyclicGroup(4)
  354. D = DihedralGroup(4)
  355. G = C*C*C
  356. assert G.order() == 64
  357. assert G.degree == 12
  358. assert len(G.orbits()) == 3
  359. assert G.is_abelian is True
  360. H = D*C
  361. assert H.order() == 32
  362. assert H.is_abelian is False
  363. def test_orbit_rep():
  364. G = DihedralGroup(6)
  365. assert G.orbit_rep(1, 3) in [Permutation([2, 3, 4, 5, 0, 1]),
  366. Permutation([4, 3, 2, 1, 0, 5])]
  367. H = CyclicGroup(4)*G
  368. assert H.orbit_rep(1, 5) is False
  369. def test_schreier_vector():
  370. G = CyclicGroup(50)
  371. v = [0]*50
  372. v[23] = -1
  373. assert G.schreier_vector(23) == v
  374. H = DihedralGroup(8)
  375. assert H.schreier_vector(2) == [0, 1, -1, 0, 0, 1, 0, 0]
  376. L = SymmetricGroup(4)
  377. assert L.schreier_vector(1) == [1, -1, 0, 0]
  378. def test_random_pr():
  379. D = DihedralGroup(6)
  380. r = 11
  381. n = 3
  382. _random_prec_n = {}
  383. _random_prec_n[0] = {'s': 7, 't': 3, 'x': 2, 'e': -1}
  384. _random_prec_n[1] = {'s': 5, 't': 5, 'x': 1, 'e': -1}
  385. _random_prec_n[2] = {'s': 3, 't': 4, 'x': 2, 'e': 1}
  386. D._random_pr_init(r, n, _random_prec_n=_random_prec_n)
  387. assert D._random_gens[11] == [0, 1, 2, 3, 4, 5]
  388. _random_prec = {'s': 2, 't': 9, 'x': 1, 'e': -1}
  389. assert D.random_pr(_random_prec=_random_prec) == \
  390. Permutation([0, 5, 4, 3, 2, 1])
  391. def test_is_alt_sym():
  392. G = DihedralGroup(10)
  393. assert G.is_alt_sym() is False
  394. assert G._eval_is_alt_sym_naive() is False
  395. assert G._eval_is_alt_sym_naive(only_alt=True) is False
  396. assert G._eval_is_alt_sym_naive(only_sym=True) is False
  397. S = SymmetricGroup(10)
  398. assert S._eval_is_alt_sym_naive() is True
  399. assert S._eval_is_alt_sym_naive(only_alt=True) is False
  400. assert S._eval_is_alt_sym_naive(only_sym=True) is True
  401. N_eps = 10
  402. _random_prec = {'N_eps': N_eps,
  403. 0: Permutation([[2], [1, 4], [0, 6, 7, 8, 9, 3, 5]]),
  404. 1: Permutation([[1, 8, 7, 6, 3, 5, 2, 9], [0, 4]]),
  405. 2: Permutation([[5, 8], [4, 7], [0, 1, 2, 3, 6, 9]]),
  406. 3: Permutation([[3], [0, 8, 2, 7, 4, 1, 6, 9, 5]]),
  407. 4: Permutation([[8], [4, 7, 9], [3, 6], [0, 5, 1, 2]]),
  408. 5: Permutation([[6], [0, 2, 4, 5, 1, 8, 3, 9, 7]]),
  409. 6: Permutation([[6, 9, 8], [4, 5], [1, 3, 7], [0, 2]]),
  410. 7: Permutation([[4], [0, 2, 9, 1, 3, 8, 6, 5, 7]]),
  411. 8: Permutation([[1, 5, 6, 3], [0, 2, 7, 8, 4, 9]]),
  412. 9: Permutation([[8], [6, 7], [2, 3, 4, 5], [0, 1, 9]])}
  413. assert S.is_alt_sym(_random_prec=_random_prec) is True
  414. A = AlternatingGroup(10)
  415. assert A._eval_is_alt_sym_naive() is True
  416. assert A._eval_is_alt_sym_naive(only_alt=True) is True
  417. assert A._eval_is_alt_sym_naive(only_sym=True) is False
  418. _random_prec = {'N_eps': N_eps,
  419. 0: Permutation([[1, 6, 4, 2, 7, 8, 5, 9, 3], [0]]),
  420. 1: Permutation([[1], [0, 5, 8, 4, 9, 2, 3, 6, 7]]),
  421. 2: Permutation([[1, 9, 8, 3, 2, 5], [0, 6, 7, 4]]),
  422. 3: Permutation([[6, 8, 9], [4, 5], [1, 3, 7, 2], [0]]),
  423. 4: Permutation([[8], [5], [4], [2, 6, 9, 3], [1], [0, 7]]),
  424. 5: Permutation([[3, 6], [0, 8, 1, 7, 5, 9, 4, 2]]),
  425. 6: Permutation([[5], [2, 9], [1, 8, 3], [0, 4, 7, 6]]),
  426. 7: Permutation([[1, 8, 4, 7, 2, 3], [0, 6, 9, 5]]),
  427. 8: Permutation([[5, 8, 7], [3], [1, 4, 2, 6], [0, 9]]),
  428. 9: Permutation([[4, 9, 6], [3, 8], [1, 2], [0, 5, 7]])}
  429. assert A.is_alt_sym(_random_prec=_random_prec) is False
  430. G = PermutationGroup(
  431. Permutation(1, 3, size=8)(0, 2, 4, 6),
  432. Permutation(5, 7, size=8)(0, 2, 4, 6))
  433. assert G.is_alt_sym() is False
  434. # Tests for monte-carlo c_n parameter setting, and which guarantees
  435. # to give False.
  436. G = DihedralGroup(10)
  437. assert G._eval_is_alt_sym_monte_carlo() is False
  438. G = DihedralGroup(20)
  439. assert G._eval_is_alt_sym_monte_carlo() is False
  440. # A dry-running test to check if it looks up for the updated cache.
  441. G = DihedralGroup(6)
  442. G.is_alt_sym()
  443. assert G.is_alt_sym() is False
  444. def test_minimal_block():
  445. D = DihedralGroup(6)
  446. block_system = D.minimal_block([0, 3])
  447. for i in range(3):
  448. assert block_system[i] == block_system[i + 3]
  449. S = SymmetricGroup(6)
  450. assert S.minimal_block([0, 1]) == [0, 0, 0, 0, 0, 0]
  451. assert Tetra.pgroup.minimal_block([0, 1]) == [0, 0, 0, 0]
  452. P1 = PermutationGroup(Permutation(1, 5)(2, 4), Permutation(0, 1, 2, 3, 4, 5))
  453. P2 = PermutationGroup(Permutation(0, 1, 2, 3, 4, 5), Permutation(1, 5)(2, 4))
  454. assert P1.minimal_block([0, 2]) == [0, 1, 0, 1, 0, 1]
  455. assert P2.minimal_block([0, 2]) == [0, 1, 0, 1, 0, 1]
  456. def test_minimal_blocks():
  457. P = PermutationGroup(Permutation(1, 5)(2, 4), Permutation(0, 1, 2, 3, 4, 5))
  458. assert P.minimal_blocks() == [[0, 1, 0, 1, 0, 1], [0, 1, 2, 0, 1, 2]]
  459. P = SymmetricGroup(5)
  460. assert P.minimal_blocks() == [[0]*5]
  461. P = PermutationGroup(Permutation(0, 3))
  462. assert P.minimal_blocks() is False
  463. def test_max_div():
  464. S = SymmetricGroup(10)
  465. assert S.max_div == 5
  466. def test_is_primitive():
  467. S = SymmetricGroup(5)
  468. assert S.is_primitive() is True
  469. C = CyclicGroup(7)
  470. assert C.is_primitive() is True
  471. a = Permutation(0, 1, 2, size=6)
  472. b = Permutation(3, 4, 5, size=6)
  473. G = PermutationGroup(a, b)
  474. assert G.is_primitive() is False
  475. def test_random_stab():
  476. S = SymmetricGroup(5)
  477. _random_el = Permutation([1, 3, 2, 0, 4])
  478. _random_prec = {'rand': _random_el}
  479. g = S.random_stab(2, _random_prec=_random_prec)
  480. assert g == Permutation([1, 3, 2, 0, 4])
  481. h = S.random_stab(1)
  482. assert h(1) == 1
  483. def test_transitivity_degree():
  484. perm = Permutation([1, 2, 0])
  485. C = PermutationGroup([perm])
  486. assert C.transitivity_degree == 1
  487. gen1 = Permutation([1, 2, 0, 3, 4])
  488. gen2 = Permutation([1, 2, 3, 4, 0])
  489. # alternating group of degree 5
  490. Alt = PermutationGroup([gen1, gen2])
  491. assert Alt.transitivity_degree == 3
  492. def test_schreier_sims_random():
  493. assert sorted(Tetra.pgroup.base) == [0, 1]
  494. S = SymmetricGroup(3)
  495. base = [0, 1]
  496. strong_gens = [Permutation([1, 2, 0]), Permutation([1, 0, 2]),
  497. Permutation([0, 2, 1])]
  498. assert S.schreier_sims_random(base, strong_gens, 5) == (base, strong_gens)
  499. D = DihedralGroup(3)
  500. _random_prec = {'g': [Permutation([2, 0, 1]), Permutation([1, 2, 0]),
  501. Permutation([1, 0, 2])]}
  502. base = [0, 1]
  503. strong_gens = [Permutation([1, 2, 0]), Permutation([2, 1, 0]),
  504. Permutation([0, 2, 1])]
  505. assert D.schreier_sims_random([], D.generators, 2,
  506. _random_prec=_random_prec) == (base, strong_gens)
  507. def test_baseswap():
  508. S = SymmetricGroup(4)
  509. S.schreier_sims()
  510. base = S.base
  511. strong_gens = S.strong_gens
  512. assert base == [0, 1, 2]
  513. deterministic = S.baseswap(base, strong_gens, 1, randomized=False)
  514. randomized = S.baseswap(base, strong_gens, 1)
  515. assert deterministic[0] == [0, 2, 1]
  516. assert _verify_bsgs(S, deterministic[0], deterministic[1]) is True
  517. assert randomized[0] == [0, 2, 1]
  518. assert _verify_bsgs(S, randomized[0], randomized[1]) is True
  519. def test_schreier_sims_incremental():
  520. identity = Permutation([0, 1, 2, 3, 4])
  521. TrivialGroup = PermutationGroup([identity])
  522. base, strong_gens = TrivialGroup.schreier_sims_incremental(base=[0, 1, 2])
  523. assert _verify_bsgs(TrivialGroup, base, strong_gens) is True
  524. S = SymmetricGroup(5)
  525. base, strong_gens = S.schreier_sims_incremental(base=[0, 1, 2])
  526. assert _verify_bsgs(S, base, strong_gens) is True
  527. D = DihedralGroup(2)
  528. base, strong_gens = D.schreier_sims_incremental(base=[1])
  529. assert _verify_bsgs(D, base, strong_gens) is True
  530. A = AlternatingGroup(7)
  531. gens = A.generators[:]
  532. gen0 = gens[0]
  533. gen1 = gens[1]
  534. gen1 = rmul(gen1, ~gen0)
  535. gen0 = rmul(gen0, gen1)
  536. gen1 = rmul(gen0, gen1)
  537. base, strong_gens = A.schreier_sims_incremental(base=[0, 1], gens=gens)
  538. assert _verify_bsgs(A, base, strong_gens) is True
  539. C = CyclicGroup(11)
  540. gen = C.generators[0]
  541. base, strong_gens = C.schreier_sims_incremental(gens=[gen**3])
  542. assert _verify_bsgs(C, base, strong_gens) is True
  543. def _subgroup_search(i, j, k):
  544. prop_true = lambda x: True
  545. prop_fix_points = lambda x: [x(point) for point in points] == points
  546. prop_comm_g = lambda x: rmul(x, g) == rmul(g, x)
  547. prop_even = lambda x: x.is_even
  548. for i in range(i, j, k):
  549. S = SymmetricGroup(i)
  550. A = AlternatingGroup(i)
  551. C = CyclicGroup(i)
  552. Sym = S.subgroup_search(prop_true)
  553. assert Sym.is_subgroup(S)
  554. Alt = S.subgroup_search(prop_even)
  555. assert Alt.is_subgroup(A)
  556. Sym = S.subgroup_search(prop_true, init_subgroup=C)
  557. assert Sym.is_subgroup(S)
  558. points = [7]
  559. assert S.stabilizer(7).is_subgroup(S.subgroup_search(prop_fix_points))
  560. points = [3, 4]
  561. assert S.stabilizer(3).stabilizer(4).is_subgroup(
  562. S.subgroup_search(prop_fix_points))
  563. points = [3, 5]
  564. fix35 = A.subgroup_search(prop_fix_points)
  565. points = [5]
  566. fix5 = A.subgroup_search(prop_fix_points)
  567. assert A.subgroup_search(prop_fix_points, init_subgroup=fix35
  568. ).is_subgroup(fix5)
  569. base, strong_gens = A.schreier_sims_incremental()
  570. g = A.generators[0]
  571. comm_g = \
  572. A.subgroup_search(prop_comm_g, base=base, strong_gens=strong_gens)
  573. assert _verify_bsgs(comm_g, base, comm_g.generators) is True
  574. assert [prop_comm_g(gen) is True for gen in comm_g.generators]
  575. def test_subgroup_search():
  576. _subgroup_search(10, 15, 2)
  577. @XFAIL
  578. def test_subgroup_search2():
  579. skip('takes too much time')
  580. _subgroup_search(16, 17, 1)
  581. def test_normal_closure():
  582. # the normal closure of the trivial group is trivial
  583. S = SymmetricGroup(3)
  584. identity = Permutation([0, 1, 2])
  585. closure = S.normal_closure(identity)
  586. assert closure.is_trivial
  587. # the normal closure of the entire group is the entire group
  588. A = AlternatingGroup(4)
  589. assert A.normal_closure(A).is_subgroup(A)
  590. # brute-force verifications for subgroups
  591. for i in (3, 4, 5):
  592. S = SymmetricGroup(i)
  593. A = AlternatingGroup(i)
  594. D = DihedralGroup(i)
  595. C = CyclicGroup(i)
  596. for gp in (A, D, C):
  597. assert _verify_normal_closure(S, gp)
  598. # brute-force verifications for all elements of a group
  599. S = SymmetricGroup(5)
  600. elements = list(S.generate_dimino())
  601. for element in elements:
  602. assert _verify_normal_closure(S, element)
  603. # small groups
  604. small = []
  605. for i in (1, 2, 3):
  606. small.append(SymmetricGroup(i))
  607. small.append(AlternatingGroup(i))
  608. small.append(DihedralGroup(i))
  609. small.append(CyclicGroup(i))
  610. for gp in small:
  611. for gp2 in small:
  612. if gp2.is_subgroup(gp, 0) and gp2.degree == gp.degree:
  613. assert _verify_normal_closure(gp, gp2)
  614. def test_derived_series():
  615. # the derived series of the trivial group consists only of the trivial group
  616. triv = PermutationGroup([Permutation([0, 1, 2])])
  617. assert triv.derived_series()[0].is_subgroup(triv)
  618. # the derived series for a simple group consists only of the group itself
  619. for i in (5, 6, 7):
  620. A = AlternatingGroup(i)
  621. assert A.derived_series()[0].is_subgroup(A)
  622. # the derived series for S_4 is S_4 > A_4 > K_4 > triv
  623. S = SymmetricGroup(4)
  624. series = S.derived_series()
  625. assert series[1].is_subgroup(AlternatingGroup(4))
  626. assert series[2].is_subgroup(DihedralGroup(2))
  627. assert series[3].is_trivial
  628. def test_lower_central_series():
  629. # the lower central series of the trivial group consists of the trivial
  630. # group
  631. triv = PermutationGroup([Permutation([0, 1, 2])])
  632. assert triv.lower_central_series()[0].is_subgroup(triv)
  633. # the lower central series of a simple group consists of the group itself
  634. for i in (5, 6, 7):
  635. A = AlternatingGroup(i)
  636. assert A.lower_central_series()[0].is_subgroup(A)
  637. # GAP-verified example
  638. S = SymmetricGroup(6)
  639. series = S.lower_central_series()
  640. assert len(series) == 2
  641. assert series[1].is_subgroup(AlternatingGroup(6))
  642. def test_commutator():
  643. # the commutator of the trivial group and the trivial group is trivial
  644. S = SymmetricGroup(3)
  645. triv = PermutationGroup([Permutation([0, 1, 2])])
  646. assert S.commutator(triv, triv).is_subgroup(triv)
  647. # the commutator of the trivial group and any other group is again trivial
  648. A = AlternatingGroup(3)
  649. assert S.commutator(triv, A).is_subgroup(triv)
  650. # the commutator is commutative
  651. for i in (3, 4, 5):
  652. S = SymmetricGroup(i)
  653. A = AlternatingGroup(i)
  654. D = DihedralGroup(i)
  655. assert S.commutator(A, D).is_subgroup(S.commutator(D, A))
  656. # the commutator of an abelian group is trivial
  657. S = SymmetricGroup(7)
  658. A1 = AbelianGroup(2, 5)
  659. A2 = AbelianGroup(3, 4)
  660. triv = PermutationGroup([Permutation([0, 1, 2, 3, 4, 5, 6])])
  661. assert S.commutator(A1, A1).is_subgroup(triv)
  662. assert S.commutator(A2, A2).is_subgroup(triv)
  663. # examples calculated by hand
  664. S = SymmetricGroup(3)
  665. A = AlternatingGroup(3)
  666. assert S.commutator(A, S).is_subgroup(A)
  667. def test_is_nilpotent():
  668. # every abelian group is nilpotent
  669. for i in (1, 2, 3):
  670. C = CyclicGroup(i)
  671. Ab = AbelianGroup(i, i + 2)
  672. assert C.is_nilpotent
  673. assert Ab.is_nilpotent
  674. Ab = AbelianGroup(5, 7, 10)
  675. assert Ab.is_nilpotent
  676. # A_5 is not solvable and thus not nilpotent
  677. assert AlternatingGroup(5).is_nilpotent is False
  678. def test_is_trivial():
  679. for i in range(5):
  680. triv = PermutationGroup([Permutation(list(range(i)))])
  681. assert triv.is_trivial
  682. def test_pointwise_stabilizer():
  683. S = SymmetricGroup(2)
  684. stab = S.pointwise_stabilizer([0])
  685. assert stab.generators == [Permutation(1)]
  686. S = SymmetricGroup(5)
  687. points = []
  688. stab = S
  689. for point in (2, 0, 3, 4, 1):
  690. stab = stab.stabilizer(point)
  691. points.append(point)
  692. assert S.pointwise_stabilizer(points).is_subgroup(stab)
  693. def test_make_perm():
  694. assert cube.pgroup.make_perm(5, seed=list(range(5))) == \
  695. Permutation([4, 7, 6, 5, 0, 3, 2, 1])
  696. assert cube.pgroup.make_perm(7, seed=list(range(7))) == \
  697. Permutation([6, 7, 3, 2, 5, 4, 0, 1])
  698. def test_elements():
  699. from sympy.sets.sets import FiniteSet
  700. p = Permutation(2, 3)
  701. assert set(PermutationGroup(p).elements) == {Permutation(3), Permutation(2, 3)}
  702. assert FiniteSet(*PermutationGroup(p).elements) \
  703. == FiniteSet(Permutation(2, 3), Permutation(3))
  704. def test_is_group():
  705. assert PermutationGroup(Permutation(1,2), Permutation(2,4)).is_group is True
  706. assert SymmetricGroup(4).is_group is True
  707. def test_PermutationGroup():
  708. assert PermutationGroup() == PermutationGroup(Permutation())
  709. assert (PermutationGroup() == 0) is False
  710. def test_coset_transvesal():
  711. G = AlternatingGroup(5)
  712. H = PermutationGroup(Permutation(0,1,2),Permutation(1,2)(3,4))
  713. assert G.coset_transversal(H) == \
  714. [Permutation(4), Permutation(2, 3, 4), Permutation(2, 4, 3),
  715. Permutation(1, 2, 4), Permutation(4)(1, 2, 3), Permutation(1, 3)(2, 4),
  716. Permutation(0, 1, 2, 3, 4), Permutation(0, 1, 2, 4, 3),
  717. Permutation(0, 1, 3, 2, 4), Permutation(0, 2, 4, 1, 3)]
  718. def test_coset_table():
  719. G = PermutationGroup(Permutation(0,1,2,3), Permutation(0,1,2),
  720. Permutation(0,4,2,7), Permutation(5,6), Permutation(0,7))
  721. H = PermutationGroup(Permutation(0,1,2,3), Permutation(0,7))
  722. assert G.coset_table(H) == \
  723. [[0, 0, 0, 0, 1, 2, 3, 3, 0, 0], [4, 5, 2, 5, 6, 0, 7, 7, 1, 1],
  724. [5, 4, 5, 1, 0, 6, 8, 8, 6, 6], [3, 3, 3, 3, 7, 8, 0, 0, 3, 3],
  725. [2, 1, 4, 4, 4, 4, 9, 9, 4, 4], [1, 2, 1, 2, 5, 5, 10, 10, 5, 5],
  726. [6, 6, 6, 6, 2, 1, 11, 11, 2, 2], [9, 10, 8, 10, 11, 3, 1, 1, 7, 7],
  727. [10, 9, 10, 7, 3, 11, 2, 2, 11, 11], [8, 7, 9, 9, 9, 9, 4, 4, 9, 9],
  728. [7, 8, 7, 8, 10, 10, 5, 5, 10, 10], [11, 11, 11, 11, 8, 7, 6, 6, 8, 8]]
  729. def test_subgroup():
  730. G = PermutationGroup(Permutation(0,1,2), Permutation(0,2,3))
  731. H = G.subgroup([Permutation(0,1,3)])
  732. assert H.is_subgroup(G)
  733. def test_generator_product():
  734. G = SymmetricGroup(5)
  735. p = Permutation(0, 2, 3)(1, 4)
  736. gens = G.generator_product(p)
  737. assert all(g in G.strong_gens for g in gens)
  738. w = G.identity
  739. for g in gens:
  740. w = g*w
  741. assert w == p
  742. def test_sylow_subgroup():
  743. P = PermutationGroup(Permutation(1, 5)(2, 4), Permutation(0, 1, 2, 3, 4, 5))
  744. S = P.sylow_subgroup(2)
  745. assert S.order() == 4
  746. P = DihedralGroup(12)
  747. S = P.sylow_subgroup(3)
  748. assert S.order() == 3
  749. P = PermutationGroup(
  750. Permutation(1, 5)(2, 4), Permutation(0, 1, 2, 3, 4, 5), Permutation(0, 2))
  751. S = P.sylow_subgroup(3)
  752. assert S.order() == 9
  753. S = P.sylow_subgroup(2)
  754. assert S.order() == 8
  755. P = SymmetricGroup(10)
  756. S = P.sylow_subgroup(2)
  757. assert S.order() == 256
  758. S = P.sylow_subgroup(3)
  759. assert S.order() == 81
  760. S = P.sylow_subgroup(5)
  761. assert S.order() == 25
  762. # the length of the lower central series
  763. # of a p-Sylow subgroup of Sym(n) grows with
  764. # the highest exponent exp of p such
  765. # that n >= p**exp
  766. exp = 1
  767. length = 0
  768. for i in range(2, 9):
  769. P = SymmetricGroup(i)
  770. S = P.sylow_subgroup(2)
  771. ls = S.lower_central_series()
  772. if i // 2**exp > 0:
  773. # length increases with exponent
  774. assert len(ls) > length
  775. length = len(ls)
  776. exp += 1
  777. else:
  778. assert len(ls) == length
  779. G = SymmetricGroup(100)
  780. S = G.sylow_subgroup(3)
  781. assert G.order() % S.order() == 0
  782. assert G.order()/S.order() % 3 > 0
  783. G = AlternatingGroup(100)
  784. S = G.sylow_subgroup(2)
  785. assert G.order() % S.order() == 0
  786. assert G.order()/S.order() % 2 > 0
  787. G = DihedralGroup(18)
  788. S = G.sylow_subgroup(p=2)
  789. assert S.order() == 4
  790. G = DihedralGroup(50)
  791. S = G.sylow_subgroup(p=2)
  792. assert S.order() == 4
  793. @slow
  794. def test_presentation():
  795. def _test(P):
  796. G = P.presentation()
  797. return G.order() == P.order()
  798. def _strong_test(P):
  799. G = P.strong_presentation()
  800. chk = len(G.generators) == len(P.strong_gens)
  801. return chk and G.order() == P.order()
  802. P = PermutationGroup(Permutation(0,1,5,2)(3,7,4,6), Permutation(0,3,5,4)(1,6,2,7))
  803. assert _test(P)
  804. P = AlternatingGroup(5)
  805. assert _test(P)
  806. P = SymmetricGroup(5)
  807. assert _test(P)
  808. P = PermutationGroup(
  809. [Permutation(0,3,1,2), Permutation(3)(0,1), Permutation(0,1)(2,3)])
  810. assert _strong_test(P)
  811. P = DihedralGroup(6)
  812. assert _strong_test(P)
  813. a = Permutation(0,1)(2,3)
  814. b = Permutation(0,2)(3,1)
  815. c = Permutation(4,5)
  816. P = PermutationGroup(c, a, b)
  817. assert _strong_test(P)
  818. def test_polycyclic():
  819. a = Permutation([0, 1, 2])
  820. b = Permutation([2, 1, 0])
  821. G = PermutationGroup([a, b])
  822. assert G.is_polycyclic is True
  823. a = Permutation([1, 2, 3, 4, 0])
  824. b = Permutation([1, 0, 2, 3, 4])
  825. G = PermutationGroup([a, b])
  826. assert G.is_polycyclic is False
  827. def test_elementary():
  828. a = Permutation([1, 5, 2, 0, 3, 6, 4])
  829. G = PermutationGroup([a])
  830. assert G.is_elementary(7) is False
  831. a = Permutation(0, 1)(2, 3)
  832. b = Permutation(0, 2)(3, 1)
  833. G = PermutationGroup([a, b])
  834. assert G.is_elementary(2) is True
  835. c = Permutation(4, 5, 6)
  836. G = PermutationGroup([a, b, c])
  837. assert G.is_elementary(2) is False
  838. G = SymmetricGroup(4).sylow_subgroup(2)
  839. assert G.is_elementary(2) is False
  840. H = AlternatingGroup(4).sylow_subgroup(2)
  841. assert H.is_elementary(2) is True
  842. def test_perfect():
  843. G = AlternatingGroup(3)
  844. assert G.is_perfect is False
  845. G = AlternatingGroup(5)
  846. assert G.is_perfect is True
  847. def test_index():
  848. G = PermutationGroup(Permutation(0,1,2), Permutation(0,2,3))
  849. H = G.subgroup([Permutation(0,1,3)])
  850. assert G.index(H) == 4
  851. def test_cyclic():
  852. G = SymmetricGroup(2)
  853. assert G.is_cyclic
  854. G = AbelianGroup(3, 7)
  855. assert G.is_cyclic
  856. G = AbelianGroup(7, 7)
  857. assert not G.is_cyclic
  858. G = AlternatingGroup(3)
  859. assert G.is_cyclic
  860. G = AlternatingGroup(4)
  861. assert not G.is_cyclic
  862. # Order less than 6
  863. G = PermutationGroup(Permutation(0, 1, 2), Permutation(0, 2, 1))
  864. assert G.is_cyclic
  865. G = PermutationGroup(
  866. Permutation(0, 1, 2, 3),
  867. Permutation(0, 2)(1, 3)
  868. )
  869. assert G.is_cyclic
  870. G = PermutationGroup(
  871. Permutation(3),
  872. Permutation(0, 1)(2, 3),
  873. Permutation(0, 2)(1, 3),
  874. Permutation(0, 3)(1, 2)
  875. )
  876. assert G.is_cyclic is False
  877. # Order 15
  878. G = PermutationGroup(
  879. Permutation(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14),
  880. Permutation(0, 2, 4, 6, 8, 10, 12, 14, 1, 3, 5, 7, 9, 11, 13)
  881. )
  882. assert G.is_cyclic
  883. # Distinct prime orders
  884. assert PermutationGroup._distinct_primes_lemma([3, 5]) is True
  885. assert PermutationGroup._distinct_primes_lemma([5, 7]) is True
  886. assert PermutationGroup._distinct_primes_lemma([2, 3]) is None
  887. assert PermutationGroup._distinct_primes_lemma([3, 5, 7]) is None
  888. assert PermutationGroup._distinct_primes_lemma([5, 7, 13]) is True
  889. G = PermutationGroup(
  890. Permutation(0, 1, 2, 3),
  891. Permutation(0, 2)(1, 3))
  892. assert G.is_cyclic
  893. assert G._is_abelian
  894. # Non-abelian and therefore not cyclic
  895. G = PermutationGroup(*SymmetricGroup(3).generators)
  896. assert G.is_cyclic is False
  897. # Abelian and cyclic
  898. G = PermutationGroup(
  899. Permutation(0, 1, 2, 3),
  900. Permutation(4, 5, 6)
  901. )
  902. assert G.is_cyclic
  903. # Abelian but not cyclic
  904. G = PermutationGroup(
  905. Permutation(0, 1),
  906. Permutation(2, 3),
  907. Permutation(4, 5, 6)
  908. )
  909. assert G.is_cyclic is False
  910. def test_dihedral():
  911. G = SymmetricGroup(2)
  912. assert G.is_dihedral
  913. G = SymmetricGroup(3)
  914. assert G.is_dihedral
  915. G = AbelianGroup(2, 2)
  916. assert G.is_dihedral
  917. G = CyclicGroup(4)
  918. assert not G.is_dihedral
  919. G = AbelianGroup(3, 5)
  920. assert not G.is_dihedral
  921. G = AbelianGroup(2)
  922. assert G.is_dihedral
  923. G = AbelianGroup(6)
  924. assert not G.is_dihedral
  925. # D6, generated by two adjacent flips
  926. G = PermutationGroup(
  927. Permutation(1, 5)(2, 4),
  928. Permutation(0, 1)(3, 4)(2, 5))
  929. assert G.is_dihedral
  930. # D7, generated by a flip and a rotation
  931. G = PermutationGroup(
  932. Permutation(1, 6)(2, 5)(3, 4),
  933. Permutation(0, 1, 2, 3, 4, 5, 6))
  934. assert G.is_dihedral
  935. # S4, presented by three generators, fails due to having exactly 9
  936. # elements of order 2:
  937. G = PermutationGroup(
  938. Permutation(0, 1), Permutation(0, 2),
  939. Permutation(0, 3))
  940. assert not G.is_dihedral
  941. # D7, given by three generators
  942. G = PermutationGroup(
  943. Permutation(1, 6)(2, 5)(3, 4),
  944. Permutation(2, 0)(3, 6)(4, 5),
  945. Permutation(0, 1, 2, 3, 4, 5, 6))
  946. assert G.is_dihedral
  947. def test_abelian_invariants():
  948. G = AbelianGroup(2, 3, 4)
  949. assert G.abelian_invariants() == [2, 3, 4]
  950. G=PermutationGroup([Permutation(1, 2, 3, 4), Permutation(1, 2), Permutation(5, 6)])
  951. assert G.abelian_invariants() == [2, 2]
  952. G = AlternatingGroup(7)
  953. assert G.abelian_invariants() == []
  954. G = AlternatingGroup(4)
  955. assert G.abelian_invariants() == [3]
  956. G = DihedralGroup(4)
  957. assert G.abelian_invariants() == [2, 2]
  958. G = PermutationGroup([Permutation(1, 2, 3, 4, 5, 6, 7)])
  959. assert G.abelian_invariants() == [7]
  960. G = DihedralGroup(12)
  961. S = G.sylow_subgroup(3)
  962. assert S.abelian_invariants() == [3]
  963. G = PermutationGroup(Permutation(0, 1, 2), Permutation(0, 2, 3))
  964. assert G.abelian_invariants() == [3]
  965. G = PermutationGroup([Permutation(0, 1), Permutation(0, 2, 4, 6)(1, 3, 5, 7)])
  966. assert G.abelian_invariants() == [2, 4]
  967. G = SymmetricGroup(30)
  968. S = G.sylow_subgroup(2)
  969. assert S.abelian_invariants() == [2, 2, 2, 2, 2, 2, 2, 2, 2, 2]
  970. S = G.sylow_subgroup(3)
  971. assert S.abelian_invariants() == [3, 3, 3, 3]
  972. S = G.sylow_subgroup(5)
  973. assert S.abelian_invariants() == [5, 5, 5]
  974. def test_composition_series():
  975. a = Permutation(1, 2, 3)
  976. b = Permutation(1, 2)
  977. G = PermutationGroup([a, b])
  978. comp_series = G.composition_series()
  979. assert comp_series == G.derived_series()
  980. # The first group in the composition series is always the group itself and
  981. # the last group in the series is the trivial group.
  982. S = SymmetricGroup(4)
  983. assert S.composition_series()[0] == S
  984. assert len(S.composition_series()) == 5
  985. A = AlternatingGroup(4)
  986. assert A.composition_series()[0] == A
  987. assert len(A.composition_series()) == 4
  988. # the composition series for C_8 is C_8 > C_4 > C_2 > triv
  989. G = CyclicGroup(8)
  990. series = G.composition_series()
  991. assert is_isomorphic(series[1], CyclicGroup(4))
  992. assert is_isomorphic(series[2], CyclicGroup(2))
  993. assert series[3].is_trivial
  994. def test_is_symmetric():
  995. a = Permutation(0, 1, 2)
  996. b = Permutation(0, 1, size=3)
  997. assert PermutationGroup(a, b).is_symmetric is True
  998. a = Permutation(0, 2, 1)
  999. b = Permutation(1, 2, size=3)
  1000. assert PermutationGroup(a, b).is_symmetric is True
  1001. a = Permutation(0, 1, 2, 3)
  1002. b = Permutation(0, 3)(1, 2)
  1003. assert PermutationGroup(a, b).is_symmetric is False
  1004. def test_conjugacy_class():
  1005. S = SymmetricGroup(4)
  1006. x = Permutation(1, 2, 3)
  1007. C = {Permutation(0, 1, 2, size = 4), Permutation(0, 1, 3),
  1008. Permutation(0, 2, 1, size = 4), Permutation(0, 2, 3),
  1009. Permutation(0, 3, 1), Permutation(0, 3, 2),
  1010. Permutation(1, 2, 3), Permutation(1, 3, 2)}
  1011. assert S.conjugacy_class(x) == C
  1012. def test_conjugacy_classes():
  1013. S = SymmetricGroup(3)
  1014. expected = [{Permutation(size = 3)},
  1015. {Permutation(0, 1, size = 3), Permutation(0, 2), Permutation(1, 2)},
  1016. {Permutation(0, 1, 2), Permutation(0, 2, 1)}]
  1017. computed = S.conjugacy_classes()
  1018. assert len(expected) == len(computed)
  1019. assert all(e in computed for e in expected)
  1020. def test_coset_class():
  1021. a = Permutation(1, 2)
  1022. b = Permutation(0, 1)
  1023. G = PermutationGroup([a, b])
  1024. #Creating right coset
  1025. rht_coset = G*a
  1026. #Checking whether it is left coset or right coset
  1027. assert rht_coset.is_right_coset
  1028. assert not rht_coset.is_left_coset
  1029. #Creating list representation of coset
  1030. list_repr = rht_coset.as_list()
  1031. expected = [Permutation(0, 2), Permutation(0, 2, 1), Permutation(1, 2),
  1032. Permutation(2), Permutation(2)(0, 1), Permutation(0, 1, 2)]
  1033. for ele in list_repr:
  1034. assert ele in expected
  1035. #Creating left coset
  1036. left_coset = a*G
  1037. #Checking whether it is left coset or right coset
  1038. assert not left_coset.is_right_coset
  1039. assert left_coset.is_left_coset
  1040. #Creating list representation of Coset
  1041. list_repr = left_coset.as_list()
  1042. expected = [Permutation(2)(0, 1), Permutation(0, 1, 2), Permutation(1, 2),
  1043. Permutation(2), Permutation(0, 2), Permutation(0, 2, 1)]
  1044. for ele in list_repr:
  1045. assert ele in expected
  1046. G = PermutationGroup(Permutation(1, 2, 3, 4), Permutation(2, 3, 4))
  1047. H = PermutationGroup(Permutation(1, 2, 3, 4))
  1048. g = Permutation(1, 3)(2, 4)
  1049. rht_coset = Coset(g, H, G, dir='+')
  1050. assert rht_coset.is_right_coset
  1051. list_repr = rht_coset.as_list()
  1052. expected = [Permutation(1, 2, 3, 4), Permutation(4), Permutation(1, 3)(2, 4),
  1053. Permutation(1, 4, 3, 2)]
  1054. for ele in list_repr:
  1055. assert ele in expected
  1056. def test_symmetricpermutationgroup():
  1057. a = SymmetricPermutationGroup(5)
  1058. assert a.degree == 5
  1059. assert a.order() == 120
  1060. assert a.identity() == Permutation(4)