test_tensor_can.py 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560
  1. from sympy.combinatorics.permutations import Permutation, Perm
  2. from sympy.combinatorics.tensor_can import (perm_af_direct_product, dummy_sgs,
  3. riemann_bsgs, get_symmetric_group_sgs, canonicalize, bsgs_direct_product)
  4. from sympy.combinatorics.testutil import canonicalize_naive, graph_certificate
  5. from sympy.testing.pytest import skip, XFAIL
  6. def test_perm_af_direct_product():
  7. gens1 = [[1,0,2,3], [0,1,3,2]]
  8. gens2 = [[1,0]]
  9. assert perm_af_direct_product(gens1, gens2, 0) == [[1, 0, 2, 3, 4, 5], [0, 1, 3, 2, 4, 5], [0, 1, 2, 3, 5, 4]]
  10. gens1 = [[1,0,2,3,5,4], [0,1,3,2,4,5]]
  11. gens2 = [[1,0,2,3]]
  12. assert [[1, 0, 2, 3, 4, 5, 7, 6], [0, 1, 3, 2, 4, 5, 6, 7], [0, 1, 2, 3, 5, 4, 6, 7]]
  13. def test_dummy_sgs():
  14. a = dummy_sgs([1,2], 0, 4)
  15. assert a == [[0,2,1,3,4,5]]
  16. a = dummy_sgs([2,3,4,5], 0, 8)
  17. assert a == [x._array_form for x in [Perm(9)(2,3), Perm(9)(4,5),
  18. Perm(9)(2,4)(3,5)]]
  19. a = dummy_sgs([2,3,4,5], 1, 8)
  20. assert a == [x._array_form for x in [Perm(2,3)(8,9), Perm(4,5)(8,9),
  21. Perm(9)(2,4)(3,5)]]
  22. def test_get_symmetric_group_sgs():
  23. assert get_symmetric_group_sgs(2) == ([0], [Permutation(3)(0,1)])
  24. assert get_symmetric_group_sgs(2, 1) == ([0], [Permutation(0,1)(2,3)])
  25. assert get_symmetric_group_sgs(3) == ([0,1], [Permutation(4)(0,1), Permutation(4)(1,2)])
  26. assert get_symmetric_group_sgs(3, 1) == ([0,1], [Permutation(0,1)(3,4), Permutation(1,2)(3,4)])
  27. assert get_symmetric_group_sgs(4) == ([0,1,2], [Permutation(5)(0,1), Permutation(5)(1,2), Permutation(5)(2,3)])
  28. assert get_symmetric_group_sgs(4, 1) == ([0,1,2], [Permutation(0,1)(4,5), Permutation(1,2)(4,5), Permutation(2,3)(4,5)])
  29. def test_canonicalize_no_slot_sym():
  30. # cases in which there is no slot symmetry after fixing the
  31. # free indices; here and in the following if the symmetry of the
  32. # metric is not specified, it is assumed to be symmetric.
  33. # If it is not specified, tensors are commuting.
  34. # A_d0 * B^d0; g = [1,0, 2,3]; T_c = A^d0*B_d0; can = [0,1,2,3]
  35. base1, gens1 = get_symmetric_group_sgs(1)
  36. dummies = [0, 1]
  37. g = Permutation([1,0,2,3])
  38. can = canonicalize(g, dummies, 0, (base1,gens1,1,0), (base1,gens1,1,0))
  39. assert can == [0,1,2,3]
  40. # equivalently
  41. can = canonicalize(g, dummies, 0, (base1, gens1, 2, None))
  42. assert can == [0,1,2,3]
  43. # with antisymmetric metric; T_c = -A^d0*B_d0; can = [0,1,3,2]
  44. can = canonicalize(g, dummies, 1, (base1,gens1,1,0), (base1,gens1,1,0))
  45. assert can == [0,1,3,2]
  46. # A^a * B^b; ord = [a,b]; g = [0,1,2,3]; can = g
  47. g = Permutation([0,1,2,3])
  48. dummies = []
  49. t0 = t1 = (base1, gens1, 1, 0)
  50. can = canonicalize(g, dummies, 0, t0, t1)
  51. assert can == [0,1,2,3]
  52. # B^b * A^a
  53. g = Permutation([1,0,2,3])
  54. can = canonicalize(g, dummies, 0, t0, t1)
  55. assert can == [1,0,2,3]
  56. # A symmetric
  57. # A^{b}_{d0}*A^{d0, a} order a,b,d0,-d0; T_c = A^{a d0}*A{b}_{d0}
  58. # g = [1,3,2,0,4,5]; can = [0,2,1,3,4,5]
  59. base2, gens2 = get_symmetric_group_sgs(2)
  60. dummies = [2,3]
  61. g = Permutation([1,3,2,0,4,5])
  62. can = canonicalize(g, dummies, 0, (base2, gens2, 2, 0))
  63. assert can == [0, 2, 1, 3, 4, 5]
  64. # with antisymmetric metric
  65. can = canonicalize(g, dummies, 1, (base2, gens2, 2, 0))
  66. assert can == [0, 2, 1, 3, 4, 5]
  67. # A^{a}_{d0}*A^{d0, b}
  68. g = Permutation([0,3,2,1,4,5])
  69. can = canonicalize(g, dummies, 1, (base2, gens2, 2, 0))
  70. assert can == [0, 2, 1, 3, 5, 4]
  71. # A, B symmetric
  72. # A^b_d0*B^{d0,a}; g=[1,3,2,0,4,5]
  73. # T_c = A^{b,d0}*B_{a,d0}; can = [1,2,0,3,4,5]
  74. dummies = [2,3]
  75. g = Permutation([1,3,2,0,4,5])
  76. can = canonicalize(g, dummies, 0, (base2,gens2,1,0), (base2,gens2,1,0))
  77. assert can == [1,2,0,3,4,5]
  78. # same with antisymmetric metric
  79. can = canonicalize(g, dummies, 1, (base2,gens2,1,0), (base2,gens2,1,0))
  80. assert can == [1,2,0,3,5,4]
  81. # A^{d1}_{d0}*B^d0*C_d1 ord=[d0,-d0,d1,-d1]; g = [2,1,0,3,4,5]
  82. # T_c = A^{d0 d1}*B_d0*C_d1; can = [0,2,1,3,4,5]
  83. base1, gens1 = get_symmetric_group_sgs(1)
  84. base2, gens2 = get_symmetric_group_sgs(2)
  85. g = Permutation([2,1,0,3,4,5])
  86. dummies = [0,1,2,3]
  87. t0 = (base2, gens2, 1, 0)
  88. t1 = t2 = (base1, gens1, 1, 0)
  89. can = canonicalize(g, dummies, 0, t0, t1, t2)
  90. assert can == [0, 2, 1, 3, 4, 5]
  91. # A without symmetry
  92. # A^{d1}_{d0}*B^d0*C_d1 ord=[d0,-d0,d1,-d1]; g = [2,1,0,3,4,5]
  93. # T_c = A^{d0 d1}*B_d1*C_d0; can = [0,2,3,1,4,5]
  94. g = Permutation([2,1,0,3,4,5])
  95. dummies = [0,1,2,3]
  96. t0 = ([], [Permutation(list(range(4)))], 1, 0)
  97. can = canonicalize(g, dummies, 0, t0, t1, t2)
  98. assert can == [0,2,3,1,4,5]
  99. # A, B without symmetry
  100. # A^{d1}_{d0}*B_{d1}^{d0}; g = [2,1,3,0,4,5]
  101. # T_c = A^{d0 d1}*B_{d0 d1}; can = [0,2,1,3,4,5]
  102. t0 = t1 = ([], [Permutation(list(range(4)))], 1, 0)
  103. dummies = [0,1,2,3]
  104. g = Permutation([2,1,3,0,4,5])
  105. can = canonicalize(g, dummies, 0, t0, t1)
  106. assert can == [0, 2, 1, 3, 4, 5]
  107. # A_{d0}^{d1}*B_{d1}^{d0}; g = [1,2,3,0,4,5]
  108. # T_c = A^{d0 d1}*B_{d1 d0}; can = [0,2,3,1,4,5]
  109. g = Permutation([1,2,3,0,4,5])
  110. can = canonicalize(g, dummies, 0, t0, t1)
  111. assert can == [0,2,3,1,4,5]
  112. # A, B, C without symmetry
  113. # A^{d1 d0}*B_{a d0}*C_{d1 b} ord=[a,b,d0,-d0,d1,-d1]
  114. # g=[4,2,0,3,5,1,6,7]
  115. # T_c=A^{d0 d1}*B_{a d1}*C_{d0 b}; can = [2,4,0,5,3,1,6,7]
  116. t0 = t1 = t2 = ([], [Permutation(list(range(4)))], 1, 0)
  117. dummies = [2,3,4,5]
  118. g = Permutation([4,2,0,3,5,1,6,7])
  119. can = canonicalize(g, dummies, 0, t0, t1, t2)
  120. assert can == [2,4,0,5,3,1,6,7]
  121. # A symmetric, B and C without symmetry
  122. # A^{d1 d0}*B_{a d0}*C_{d1 b} ord=[a,b,d0,-d0,d1,-d1]
  123. # g=[4,2,0,3,5,1,6,7]
  124. # T_c = A^{d0 d1}*B_{a d0}*C_{d1 b}; can = [2,4,0,3,5,1,6,7]
  125. t0 = (base2,gens2,1,0)
  126. t1 = t2 = ([], [Permutation(list(range(4)))], 1, 0)
  127. dummies = [2,3,4,5]
  128. g = Permutation([4,2,0,3,5,1,6,7])
  129. can = canonicalize(g, dummies, 0, t0, t1, t2)
  130. assert can == [2,4,0,3,5,1,6,7]
  131. # A and C symmetric, B without symmetry
  132. # A^{d1 d0}*B_{a d0}*C_{d1 b} ord=[a,b,d0,-d0,d1,-d1]
  133. # g=[4,2,0,3,5,1,6,7]
  134. # T_c = A^{d0 d1}*B_{a d0}*C_{b d1}; can = [2,4,0,3,1,5,6,7]
  135. t0 = t2 = (base2,gens2,1,0)
  136. t1 = ([], [Permutation(list(range(4)))], 1, 0)
  137. dummies = [2,3,4,5]
  138. g = Permutation([4,2,0,3,5,1,6,7])
  139. can = canonicalize(g, dummies, 0, t0, t1, t2)
  140. assert can == [2,4,0,3,1,5,6,7]
  141. # A symmetric, B without symmetry, C antisymmetric
  142. # A^{d1 d0}*B_{a d0}*C_{d1 b} ord=[a,b,d0,-d0,d1,-d1]
  143. # g=[4,2,0,3,5,1,6,7]
  144. # T_c = -A^{d0 d1}*B_{a d0}*C_{b d1}; can = [2,4,0,3,1,5,7,6]
  145. t0 = (base2,gens2, 1, 0)
  146. t1 = ([], [Permutation(list(range(4)))], 1, 0)
  147. base2a, gens2a = get_symmetric_group_sgs(2, 1)
  148. t2 = (base2a, gens2a, 1, 0)
  149. dummies = [2,3,4,5]
  150. g = Permutation([4,2,0,3,5,1,6,7])
  151. can = canonicalize(g, dummies, 0, t0, t1, t2)
  152. assert can == [2,4,0,3,1,5,7,6]
  153. def test_canonicalize_no_dummies():
  154. base1, gens1 = get_symmetric_group_sgs(1)
  155. base2, gens2 = get_symmetric_group_sgs(2)
  156. base2a, gens2a = get_symmetric_group_sgs(2, 1)
  157. # A commuting
  158. # A^c A^b A^a; ord = [a,b,c]; g = [2,1,0,3,4]
  159. # T_c = A^a A^b A^c; can = list(range(5))
  160. g = Permutation([2,1,0,3,4])
  161. can = canonicalize(g, [], 0, (base1, gens1, 3, 0))
  162. assert can == list(range(5))
  163. # A anticommuting
  164. # A^c A^b A^a; ord = [a,b,c]; g = [2,1,0,3,4]
  165. # T_c = -A^a A^b A^c; can = [0,1,2,4,3]
  166. g = Permutation([2,1,0,3,4])
  167. can = canonicalize(g, [], 0, (base1, gens1, 3, 1))
  168. assert can == [0,1,2,4,3]
  169. # A commuting and symmetric
  170. # A^{b,d}*A^{c,a}; ord = [a,b,c,d]; g = [1,3,2,0,4,5]
  171. # T_c = A^{a c}*A^{b d}; can = [0,2,1,3,4,5]
  172. g = Permutation([1,3,2,0,4,5])
  173. can = canonicalize(g, [], 0, (base2, gens2, 2, 0))
  174. assert can == [0,2,1,3,4,5]
  175. # A anticommuting and symmetric
  176. # A^{b,d}*A^{c,a}; ord = [a,b,c,d]; g = [1,3,2,0,4,5]
  177. # T_c = -A^{a c}*A^{b d}; can = [0,2,1,3,5,4]
  178. g = Permutation([1,3,2,0,4,5])
  179. can = canonicalize(g, [], 0, (base2, gens2, 2, 1))
  180. assert can == [0,2,1,3,5,4]
  181. # A^{c,a}*A^{b,d} ; g = [2,0,1,3,4,5]
  182. # T_c = A^{a c}*A^{b d}; can = [0,2,1,3,4,5]
  183. g = Permutation([2,0,1,3,4,5])
  184. can = canonicalize(g, [], 0, (base2, gens2, 2, 1))
  185. assert can == [0,2,1,3,4,5]
  186. def test_no_metric_symmetry():
  187. # no metric symmetry
  188. # A^d1_d0 * A^d0_d1; ord = [d0,-d0,d1,-d1]; g= [2,1,0,3,4,5]
  189. # T_c = A^d0_d1 * A^d1_d0; can = [0,3,2,1,4,5]
  190. g = Permutation([2,1,0,3,4,5])
  191. can = canonicalize(g, list(range(4)), None, [[], [Permutation(list(range(4)))], 2, 0])
  192. assert can == [0,3,2,1,4,5]
  193. # A^d1_d2 * A^d0_d3 * A^d2_d1 * A^d3_d0
  194. # ord = [d0,-d0,d1,-d1,d2,-d2,d3,-d3]
  195. # 0 1 2 3 4 5 6 7
  196. # g = [2,5,0,7,4,3,6,1,8,9]
  197. # T_c = A^d0_d1 * A^d1_d0 * A^d2_d3 * A^d3_d2
  198. # can = [0,3,2,1,4,7,6,5,8,9]
  199. g = Permutation([2,5,0,7,4,3,6,1,8,9])
  200. #can = canonicalize(g, list(range(8)), 0, [[], [list(range(4))], 4, 0])
  201. #assert can == [0, 2, 3, 1, 4, 6, 7, 5, 8, 9]
  202. can = canonicalize(g, list(range(8)), None, [[], [Permutation(list(range(4)))], 4, 0])
  203. assert can == [0, 3, 2, 1, 4, 7, 6, 5, 8, 9]
  204. # A^d0_d2 * A^d1_d3 * A^d3_d0 * A^d2_d1
  205. # g = [0,5,2,7,6,1,4,3,8,9]
  206. # T_c = A^d0_d1 * A^d1_d2 * A^d2_d3 * A^d3_d0
  207. # can = [0,3,2,5,4,7,6,1,8,9]
  208. g = Permutation([0,5,2,7,6,1,4,3,8,9])
  209. can = canonicalize(g, list(range(8)), None, [[], [Permutation(list(range(4)))], 4, 0])
  210. assert can == [0,3,2,5,4,7,6,1,8,9]
  211. g = Permutation([12,7,10,3,14,13,4,11,6,1,2,9,0,15,8,5,16,17])
  212. can = canonicalize(g, list(range(16)), None, [[], [Permutation(list(range(4)))], 8, 0])
  213. assert can == [0,3,2,5,4,7,6,1,8,11,10,13,12,15,14,9,16,17]
  214. def test_canonical_free():
  215. # t = A^{d0 a1}*A_d0^a0
  216. # ord = [a0,a1,d0,-d0]; g = [2,1,3,0,4,5]; dummies = [[2,3]]
  217. # t_c = A_d0^a0*A^{d0 a1}
  218. # can = [3,0, 2,1, 4,5]
  219. g = Permutation([2,1,3,0,4,5])
  220. dummies = [[2,3]]
  221. can = canonicalize(g, dummies, [None], ([], [Permutation(3)], 2, 0))
  222. assert can == [3,0, 2,1, 4,5]
  223. def test_canonicalize1():
  224. base1, gens1 = get_symmetric_group_sgs(1)
  225. base1a, gens1a = get_symmetric_group_sgs(1, 1)
  226. base2, gens2 = get_symmetric_group_sgs(2)
  227. base3, gens3 = get_symmetric_group_sgs(3)
  228. base2a, gens2a = get_symmetric_group_sgs(2, 1)
  229. base3a, gens3a = get_symmetric_group_sgs(3, 1)
  230. # A_d0*A^d0; ord = [d0,-d0]; g = [1,0,2,3]
  231. # T_c = A^d0*A_d0; can = [0,1,2,3]
  232. g = Permutation([1,0,2,3])
  233. can = canonicalize(g, [0, 1], 0, (base1, gens1, 2, 0))
  234. assert can == list(range(4))
  235. # A commuting
  236. # A_d0*A_d1*A_d2*A^d2*A^d1*A^d0; ord=[d0,-d0,d1,-d1,d2,-d2]
  237. # g = [1,3,5,4,2,0,6,7]
  238. # T_c = A^d0*A_d0*A^d1*A_d1*A^d2*A_d2; can = list(range(8))
  239. g = Permutation([1,3,5,4,2,0,6,7])
  240. can = canonicalize(g, list(range(6)), 0, (base1, gens1, 6, 0))
  241. assert can == list(range(8))
  242. # A anticommuting
  243. # A_d0*A_d1*A_d2*A^d2*A^d1*A^d0; ord=[d0,-d0,d1,-d1,d2,-d2]
  244. # g = [1,3,5,4,2,0,6,7]
  245. # T_c 0; can = 0
  246. g = Permutation([1,3,5,4,2,0,6,7])
  247. can = canonicalize(g, list(range(6)), 0, (base1, gens1, 6, 1))
  248. assert can == 0
  249. can1 = canonicalize_naive(g, list(range(6)), 0, (base1, gens1, 6, 1))
  250. assert can1 == 0
  251. # A commuting symmetric
  252. # A^{d0 b}*A^a_d1*A^d1_d0; ord=[a,b,d0,-d0,d1,-d1]
  253. # g = [2,1,0,5,4,3,6,7]
  254. # T_c = A^{a d0}*A^{b d1}*A_{d0 d1}; can = [0,2,1,4,3,5,6,7]
  255. g = Permutation([2,1,0,5,4,3,6,7])
  256. can = canonicalize(g, list(range(2,6)), 0, (base2, gens2, 3, 0))
  257. assert can == [0,2,1,4,3,5,6,7]
  258. # A, B commuting symmetric
  259. # A^{d0 b}*A^d1_d0*B^a_d1; ord=[a,b,d0,-d0,d1,-d1]
  260. # g = [2,1,4,3,0,5,6,7]
  261. # T_c = A^{b d0}*A_d0^d1*B^a_d1; can = [1,2,3,4,0,5,6,7]
  262. g = Permutation([2,1,4,3,0,5,6,7])
  263. can = canonicalize(g, list(range(2,6)), 0, (base2,gens2,2,0), (base2,gens2,1,0))
  264. assert can == [1,2,3,4,0,5,6,7]
  265. # A commuting symmetric
  266. # A^{d1 d0 b}*A^{a}_{d1 d0}; ord=[a,b, d0,-d0,d1,-d1]
  267. # g = [4,2,1,0,5,3,6,7]
  268. # T_c = A^{a d0 d1}*A^{b}_{d0 d1}; can = [0,2,4,1,3,5,6,7]
  269. g = Permutation([4,2,1,0,5,3,6,7])
  270. can = canonicalize(g, list(range(2,6)), 0, (base3, gens3, 2, 0))
  271. assert can == [0,2,4,1,3,5,6,7]
  272. # A^{d3 d0 d2}*A^a0_{d1 d2}*A^d1_d3^a1*A^{a2 a3}_d0
  273. # ord = [a0,a1,a2,a3,d0,-d0,d1,-d1,d2,-d2,d3,-d3]
  274. # 0 1 2 3 4 5 6 7 8 9 10 11
  275. # g = [10,4,8, 0,7,9, 6,11,1, 2,3,5, 12,13]
  276. # T_c = A^{a0 d0 d1}*A^a1_d0^d2*A^{a2 a3 d3}*A_{d1 d2 d3}
  277. # can = [0,4,6, 1,5,8, 2,3,10, 7,9,11, 12,13]
  278. g = Permutation([10,4,8, 0,7,9, 6,11,1, 2,3,5, 12,13])
  279. can = canonicalize(g, list(range(4,12)), 0, (base3, gens3, 4, 0))
  280. assert can == [0,4,6, 1,5,8, 2,3,10, 7,9,11, 12,13]
  281. # A commuting symmetric, B antisymmetric
  282. # A^{d0 d1 d2} * A_{d2 d3 d1} * B_d0^d3
  283. # ord = [d0,-d0,d1,-d1,d2,-d2,d3,-d3]
  284. # g = [0,2,4,5,7,3,1,6,8,9]
  285. # in this esxample and in the next three,
  286. # renaming dummy indices and using symmetry of A,
  287. # T = A^{d0 d1 d2} * A_{d0 d1 d3} * B_d2^d3
  288. # can = 0
  289. g = Permutation([0,2,4,5,7,3,1,6,8,9])
  290. can = canonicalize(g, list(range(8)), 0, (base3, gens3,2,0), (base2a,gens2a,1,0))
  291. assert can == 0
  292. # A anticommuting symmetric, B anticommuting
  293. # A^{d0 d1 d2} * A_{d2 d3 d1} * B_d0^d3
  294. # T_c = A^{d0 d1 d2} * A_{d0 d1}^d3 * B_{d2 d3}
  295. # can = [0,2,4, 1,3,6, 5,7, 8,9]
  296. can = canonicalize(g, list(range(8)), 0, (base3, gens3,2,1), (base2a,gens2a,1,0))
  297. assert can == [0,2,4, 1,3,6, 5,7, 8,9]
  298. # A anticommuting symmetric, B antisymmetric commuting, antisymmetric metric
  299. # A^{d0 d1 d2} * A_{d2 d3 d1} * B_d0^d3
  300. # T_c = -A^{d0 d1 d2} * A_{d0 d1}^d3 * B_{d2 d3}
  301. # can = [0,2,4, 1,3,6, 5,7, 9,8]
  302. can = canonicalize(g, list(range(8)), 1, (base3, gens3,2,1), (base2a,gens2a,1,0))
  303. assert can == [0,2,4, 1,3,6, 5,7, 9,8]
  304. # A anticommuting symmetric, B anticommuting anticommuting,
  305. # no metric symmetry
  306. # A^{d0 d1 d2} * A_{d2 d3 d1} * B_d0^d3
  307. # T_c = A^{d0 d1 d2} * A_{d0 d1 d3} * B_d2^d3
  308. # can = [0,2,4, 1,3,7, 5,6, 8,9]
  309. can = canonicalize(g, list(range(8)), None, (base3, gens3,2,1), (base2a,gens2a,1,0))
  310. assert can == [0,2,4,1,3,7,5,6,8,9]
  311. # Gamma anticommuting
  312. # Gamma_{mu nu} * gamma^rho * Gamma^{nu mu alpha}
  313. # ord = [alpha, rho, mu,-mu,nu,-nu]
  314. # g = [3,5,1,4,2,0,6,7]
  315. # T_c = -Gamma^{mu nu} * gamma^rho * Gamma_{alpha mu nu}
  316. # can = [2,4,1,0,3,5,7,6]]
  317. g = Permutation([3,5,1,4,2,0,6,7])
  318. t0 = (base2a, gens2a, 1, None)
  319. t1 = (base1, gens1, 1, None)
  320. t2 = (base3a, gens3a, 1, None)
  321. can = canonicalize(g, list(range(2, 6)), 0, t0, t1, t2)
  322. assert can == [2,4,1,0,3,5,7,6]
  323. # Gamma_{mu nu} * Gamma^{gamma beta} * gamma_rho * Gamma^{nu mu alpha}
  324. # ord = [alpha, beta, gamma, -rho, mu,-mu,nu,-nu]
  325. # 0 1 2 3 4 5 6 7
  326. # g = [5,7,2,1,3,6,4,0,8,9]
  327. # T_c = Gamma^{mu nu} * Gamma^{beta gamma} * gamma_rho * Gamma^alpha_{mu nu} # can = [4,6,1,2,3,0,5,7,8,9]
  328. t0 = (base2a, gens2a, 2, None)
  329. g = Permutation([5,7,2,1,3,6,4,0,8,9])
  330. can = canonicalize(g, list(range(4, 8)), 0, t0, t1, t2)
  331. assert can == [4,6,1,2,3,0,5,7,8,9]
  332. # f^a_{b,c} antisymmetric in b,c; A_mu^a no symmetry
  333. # f^c_{d a} * f_{c e b} * A_mu^d * A_nu^a * A^{nu e} * A^{mu b}
  334. # ord = [mu,-mu,nu,-nu,a,-a,b,-b,c,-c,d,-d, e, -e]
  335. # 0 1 2 3 4 5 6 7 8 9 10 11 12 13
  336. # g = [8,11,5, 9,13,7, 1,10, 3,4, 2,12, 0,6, 14,15]
  337. # T_c = -f^{a b c} * f_a^{d e} * A^mu_b * A_{mu d} * A^nu_c * A_{nu e}
  338. # can = [4,6,8, 5,10,12, 0,7, 1,11, 2,9, 3,13, 15,14]
  339. g = Permutation([8,11,5, 9,13,7, 1,10, 3,4, 2,12, 0,6, 14,15])
  340. base_f, gens_f = bsgs_direct_product(base1, gens1, base2a, gens2a)
  341. base_A, gens_A = bsgs_direct_product(base1, gens1, base1, gens1)
  342. t0 = (base_f, gens_f, 2, 0)
  343. t1 = (base_A, gens_A, 4, 0)
  344. can = canonicalize(g, [list(range(4)), list(range(4, 14))], [0, 0], t0, t1)
  345. assert can == [4,6,8, 5,10,12, 0,7, 1,11, 2,9, 3,13, 15,14]
  346. def test_riemann_invariants():
  347. baser, gensr = riemann_bsgs
  348. # R^{d0 d1}_{d1 d0}; ord = [d0,-d0,d1,-d1]; g = [0,2,3,1,4,5]
  349. # T_c = -R^{d0 d1}_{d0 d1}; can = [0,2,1,3,5,4]
  350. g = Permutation([0,2,3,1,4,5])
  351. can = canonicalize(g, list(range(2, 4)), 0, (baser, gensr, 1, 0))
  352. assert can == [0,2,1,3,5,4]
  353. # use a non minimal BSGS
  354. can = canonicalize(g, list(range(2, 4)), 0, ([2, 0], [Permutation([1,0,2,3,5,4]), Permutation([2,3,0,1,4,5])], 1, 0))
  355. assert can == [0,2,1,3,5,4]
  356. """
  357. The following tests in test_riemann_invariants and in
  358. test_riemann_invariants1 have been checked using xperm.c from XPerm in
  359. in [1] and with an older version contained in [2]
  360. [1] xperm.c part of xPerm written by J. M. Martin-Garcia
  361. http://www.xact.es/index.html
  362. [2] test_xperm.cc in cadabra by Kasper Peeters, http://cadabra.phi-sci.com/
  363. """
  364. # R_d11^d1_d0^d5 * R^{d6 d4 d0}_d5 * R_{d7 d2 d8 d9} *
  365. # R_{d10 d3 d6 d4} * R^{d2 d7 d11}_d1 * R^{d8 d9 d3 d10}
  366. # ord: contravariant d_k ->2*k, covariant d_k -> 2*k+1
  367. # T_c = R^{d0 d1 d2 d3} * R_{d0 d1}^{d4 d5} * R_{d2 d3}^{d6 d7} *
  368. # R_{d4 d5}^{d8 d9} * R_{d6 d7}^{d10 d11} * R_{d8 d9 d10 d11}
  369. g = Permutation([23,2,1,10,12,8,0,11,15,5,17,19,21,7,13,9,4,14,22,3,16,18,6,20,24,25])
  370. can = canonicalize(g, list(range(24)), 0, (baser, gensr, 6, 0))
  371. assert can == [0,2,4,6,1,3,8,10,5,7,12,14,9,11,16,18,13,15,20,22,17,19,21,23,24,25]
  372. # use a non minimal BSGS
  373. can = canonicalize(g, list(range(24)), 0, ([2, 0], [Permutation([1,0,2,3,5,4]), Permutation([2,3,0,1,4,5])], 6, 0))
  374. assert can == [0,2,4,6,1,3,8,10,5,7,12,14,9,11,16,18,13,15,20,22,17,19,21,23,24,25]
  375. g = Permutation([0,2,5,7,4,6,9,11,8,10,13,15,12,14,17,19,16,18,21,23,20,22,25,27,24,26,29,31,28,30,33,35,32,34,37,39,36,38,1,3,40,41])
  376. can = canonicalize(g, list(range(40)), 0, (baser, gensr, 10, 0))
  377. assert can == [0,2,4,6,1,3,8,10,5,7,12,14,9,11,16,18,13,15,20,22,17,19,24,26,21,23,28,30,25,27,32,34,29,31,36,38,33,35,37,39,40,41]
  378. @XFAIL
  379. def test_riemann_invariants1():
  380. skip('takes too much time')
  381. baser, gensr = riemann_bsgs
  382. g = Permutation([17, 44, 11, 3, 0, 19, 23, 15, 38, 4, 25, 27, 43, 36, 22, 14, 8, 30, 41, 20, 2, 10, 12, 28, 18, 1, 29, 13, 37, 42, 33, 7, 9, 31, 24, 26, 39, 5, 34, 47, 32, 6, 21, 40, 35, 46, 45, 16, 48, 49])
  383. can = canonicalize(g, list(range(48)), 0, (baser, gensr, 12, 0))
  384. assert can == [0, 2, 4, 6, 1, 3, 8, 10, 5, 7, 12, 14, 9, 11, 16, 18, 13, 15, 20, 22, 17, 19, 24, 26, 21, 23, 28, 30, 25, 27, 32, 34, 29, 31, 36, 38, 33, 35, 40, 42, 37, 39, 44, 46, 41, 43, 45, 47, 48, 49]
  385. g = Permutation([0,2,4,6, 7,8,10,12, 14,16,18,20, 19,22,24,26, 5,21,28,30, 32,34,36,38, 40,42,44,46, 13,48,50,52, 15,49,54,56, 17,33,41,58, 9,23,60,62, 29,35,63,64, 3,45,66,68, 25,37,47,57, 11,31,69,70, 27,39,53,72, 1,59,73,74, 55,61,67,76, 43,65,75,78, 51,71,77,79, 80,81])
  386. can = canonicalize(g, list(range(80)), 0, (baser, gensr, 20, 0))
  387. assert can == [0,2,4,6, 1,8,10,12, 3,14,16,18, 5,20,22,24, 7,26,28,30, 9,15,32,34, 11,36,23,38, 13,40,42,44, 17,39,29,46, 19,48,43,50, 21,45,52,54, 25,56,33,58, 27,60,53,62, 31,51,64,66, 35,65,47,68, 37,70,49,72, 41,74,57,76, 55,67,59,78, 61,69,71,75, 63,79,73,77, 80,81]
  388. def test_riemann_products():
  389. baser, gensr = riemann_bsgs
  390. base1, gens1 = get_symmetric_group_sgs(1)
  391. base2, gens2 = get_symmetric_group_sgs(2)
  392. base2a, gens2a = get_symmetric_group_sgs(2, 1)
  393. # R^{a b d0}_d0 = 0
  394. g = Permutation([0,1,2,3,4,5])
  395. can = canonicalize(g, list(range(2,4)), 0, (baser, gensr, 1, 0))
  396. assert can == 0
  397. # R^{d0 b a}_d0 ; ord = [a,b,d0,-d0}; g = [2,1,0,3,4,5]
  398. # T_c = -R^{a d0 b}_d0; can = [0,2,1,3,5,4]
  399. g = Permutation([2,1,0,3,4,5])
  400. can = canonicalize(g, list(range(2, 4)), 0, (baser, gensr, 1, 0))
  401. assert can == [0,2,1,3,5,4]
  402. # R^d1_d2^b_d0 * R^{d0 a}_d1^d2; ord=[a,b,d0,-d0,d1,-d1,d2,-d2]
  403. # g = [4,7,1,3,2,0,5,6,8,9]
  404. # T_c = -R^{a d0 d1 d2}* R^b_{d0 d1 d2}
  405. # can = [0,2,4,6,1,3,5,7,9,8]
  406. g = Permutation([4,7,1,3,2,0,5,6,8,9])
  407. can = canonicalize(g, list(range(2,8)), 0, (baser, gensr, 2, 0))
  408. assert can == [0,2,4,6,1,3,5,7,9,8]
  409. can1 = canonicalize_naive(g, list(range(2,8)), 0, (baser, gensr, 2, 0))
  410. assert can == can1
  411. # A symmetric commuting
  412. # R^{d6 d5}_d2^d1 * R^{d4 d0 d2 d3} * A_{d6 d0} A_{d3 d1} * A_{d4 d5}
  413. # g = [12,10,5,2, 8,0,4,6, 13,1, 7,3, 9,11,14,15]
  414. # T_c = -R^{d0 d1 d2 d3} * R_d0^{d4 d5 d6} * A_{d1 d4}*A_{d2 d5}*A_{d3 d6}
  415. g = Permutation([12,10,5,2,8,0,4,6,13,1,7,3,9,11,14,15])
  416. can = canonicalize(g, list(range(14)), 0, ((baser,gensr,2,0)), (base2,gens2,3,0))
  417. assert can == [0, 2, 4, 6, 1, 8, 10, 12, 3, 9, 5, 11, 7, 13, 15, 14]
  418. # R^{d2 a0 a2 d0} * R^d1_d2^{a1 a3} * R^{a4 a5}_{d0 d1}
  419. # ord = [a0,a1,a2,a3,a4,a5,d0,-d0,d1,-d1,d2,-d2]
  420. # 0 1 2 3 4 5 6 7 8 9 10 11
  421. # can = [0, 6, 2, 8, 1, 3, 7, 10, 4, 5, 9, 11, 12, 13]
  422. # T_c = R^{a0 d0 a2 d1}*R^{a1 a3}_d0^d2*R^{a4 a5}_{d1 d2}
  423. g = Permutation([10,0,2,6,8,11,1,3,4,5,7,9,12,13])
  424. can = canonicalize(g, list(range(6,12)), 0, (baser, gensr, 3, 0))
  425. assert can == [0, 6, 2, 8, 1, 3, 7, 10, 4, 5, 9, 11, 12, 13]
  426. #can1 = canonicalize_naive(g, list(range(6,12)), 0, (baser, gensr, 3, 0))
  427. #assert can == can1
  428. # A^n_{i, j} antisymmetric in i,j
  429. # A_m0^d0_a1 * A_m1^a0_d0; ord = [m0,m1,a0,a1,d0,-d0]
  430. # g = [0,4,3,1,2,5,6,7]
  431. # T_c = -A_{m a1}^d0 * A_m1^a0_d0
  432. # can = [0,3,4,1,2,5,7,6]
  433. base, gens = bsgs_direct_product(base1, gens1, base2a, gens2a)
  434. dummies = list(range(4, 6))
  435. g = Permutation([0,4,3,1,2,5,6,7])
  436. can = canonicalize(g, dummies, 0, (base, gens, 2, 0))
  437. assert can == [0, 3, 4, 1, 2, 5, 7, 6]
  438. # A^n_{i, j} symmetric in i,j
  439. # A^m0_a0^d2 * A^n0_d2^d1 * A^n1_d1^d0 * A_{m0 d0}^a1
  440. # ordering: first the free indices; then first n, then d
  441. # ord=[n0,n1,a0,a1, m0,-m0,d0,-d0,d1,-d1,d2,-d2]
  442. # 0 1 2 3 4 5 6 7 8 9 10 11]
  443. # g = [4,2,10, 0,11,8, 1,9,6, 5,7,3, 12,13]
  444. # if the dummy indices m_i and d_i were separated,
  445. # one gets
  446. # T_c = A^{n0 d0 d1} * A^n1_d0^d2 * A^m0^a0_d1 * A_m0^a1_d2
  447. # can = [0, 6, 8, 1, 7, 10, 4, 2, 9, 5, 3, 11, 12, 13]
  448. # If they are not, so can is
  449. # T_c = A^{n0 m0 d0} A^n1_m0^d1 A^{d2 a0}_d0 A_d2^a1_d1
  450. # can = [0, 4, 6, 1, 5, 8, 10, 2, 7, 11, 3, 9, 12, 13]
  451. # case with single type of indices
  452. base, gens = bsgs_direct_product(base1, gens1, base2, gens2)
  453. dummies = list(range(4, 12))
  454. g = Permutation([4,2,10, 0,11,8, 1,9,6, 5,7,3, 12,13])
  455. can = canonicalize(g, dummies, 0, (base, gens, 4, 0))
  456. assert can == [0, 4, 6, 1, 5, 8, 10, 2, 7, 11, 3, 9, 12, 13]
  457. # case with separated indices
  458. dummies = [list(range(4, 6)), list(range(6,12))]
  459. sym = [0, 0]
  460. can = canonicalize(g, dummies, sym, (base, gens, 4, 0))
  461. assert can == [0, 6, 8, 1, 7, 10, 4, 2, 9, 5, 3, 11, 12, 13]
  462. # case with separated indices with the second type of index
  463. # with antisymmetric metric: there is a sign change
  464. sym = [0, 1]
  465. can = canonicalize(g, dummies, sym, (base, gens, 4, 0))
  466. assert can == [0, 6, 8, 1, 7, 10, 4, 2, 9, 5, 3, 11, 13, 12]
  467. def test_graph_certificate():
  468. # test tensor invariants constructed from random regular graphs;
  469. # checked graph isomorphism with networkx
  470. import random
  471. def randomize_graph(size, g):
  472. p = list(range(size))
  473. random.shuffle(p)
  474. g1a = {}
  475. for k, v in g1.items():
  476. g1a[p[k]] = [p[i] for i in v]
  477. return g1a
  478. g1 = {0: [2, 3, 7], 1: [4, 5, 7], 2: [0, 4, 6], 3: [0, 6, 7], 4: [1, 2, 5], 5: [1, 4, 6], 6: [2, 3, 5], 7: [0, 1, 3]}
  479. g2 = {0: [2, 3, 7], 1: [2, 4, 5], 2: [0, 1, 5], 3: [0, 6, 7], 4: [1, 5, 6], 5: [1, 2, 4], 6: [3, 4, 7], 7: [0, 3, 6]}
  480. c1 = graph_certificate(g1)
  481. c2 = graph_certificate(g2)
  482. assert c1 != c2
  483. g1a = randomize_graph(8, g1)
  484. c1a = graph_certificate(g1a)
  485. assert c1 == c1a
  486. g1 = {0: [8, 1, 9, 7], 1: [0, 9, 3, 4], 2: [3, 4, 6, 7], 3: [1, 2, 5, 6], 4: [8, 1, 2, 5], 5: [9, 3, 4, 7], 6: [8, 2, 3, 7], 7: [0, 2, 5, 6], 8: [0, 9, 4, 6], 9: [8, 0, 5, 1]}
  487. g2 = {0: [1, 2, 5, 6], 1: [0, 9, 5, 7], 2: [0, 4, 6, 7], 3: [8, 9, 6, 7], 4: [8, 2, 6, 7], 5: [0, 9, 8, 1], 6: [0, 2, 3, 4], 7: [1, 2, 3, 4], 8: [9, 3, 4, 5], 9: [8, 1, 3, 5]}
  488. c1 = graph_certificate(g1)
  489. c2 = graph_certificate(g2)
  490. assert c1 != c2
  491. g1a = randomize_graph(10, g1)
  492. c1a = graph_certificate(g1a)
  493. assert c1 == c1a