test_secondquant.py 48 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301
  1. from sympy.functions.elementary.complexes import conjugate
  2. from sympy.functions.elementary.exponential import exp
  3. from sympy.physics.secondquant import (
  4. Dagger, Bd, VarBosonicBasis, BBra, B, BKet, FixedBosonicBasis,
  5. matrix_rep, apply_operators, InnerProduct, Commutator, KroneckerDelta,
  6. AnnihilateBoson, CreateBoson, BosonicOperator,
  7. F, Fd, FKet, BosonState, CreateFermion, AnnihilateFermion,
  8. evaluate_deltas, AntiSymmetricTensor, contraction, NO, wicks,
  9. PermutationOperator, simplify_index_permutations,
  10. _sort_anticommuting_fermions, _get_ordered_dummies,
  11. substitute_dummies, FockStateBosonKet,
  12. ContractionAppliesOnlyToFermions
  13. )
  14. from sympy.concrete.summations import Sum
  15. from sympy.core.function import (Function, expand)
  16. from sympy.core.numbers import (I, Rational)
  17. from sympy.core.singleton import S
  18. from sympy.core.symbol import (Dummy, Symbol, symbols)
  19. from sympy.functions.elementary.miscellaneous import sqrt
  20. from sympy.printing.repr import srepr
  21. from sympy.simplify.simplify import simplify
  22. from sympy.testing.pytest import slow, raises
  23. from sympy.printing.latex import latex
  24. def test_PermutationOperator():
  25. p, q, r, s = symbols('p,q,r,s')
  26. f, g, h, i = map(Function, 'fghi')
  27. P = PermutationOperator
  28. assert P(p, q).get_permuted(f(p)*g(q)) == -f(q)*g(p)
  29. assert P(p, q).get_permuted(f(p, q)) == -f(q, p)
  30. assert P(p, q).get_permuted(f(p)) == f(p)
  31. expr = (f(p)*g(q)*h(r)*i(s)
  32. - f(q)*g(p)*h(r)*i(s)
  33. - f(p)*g(q)*h(s)*i(r)
  34. + f(q)*g(p)*h(s)*i(r))
  35. perms = [P(p, q), P(r, s)]
  36. assert (simplify_index_permutations(expr, perms) ==
  37. P(p, q)*P(r, s)*f(p)*g(q)*h(r)*i(s))
  38. assert latex(P(p, q)) == 'P(pq)'
  39. p1, p2 = symbols('p1,p2')
  40. assert latex(P(p1,p2) == 'P(p_{1}p_{2})')
  41. def test_index_permutations_with_dummies():
  42. a, b, c, d = symbols('a b c d')
  43. p, q, r, s = symbols('p q r s', cls=Dummy)
  44. f, g = map(Function, 'fg')
  45. P = PermutationOperator
  46. # No dummy substitution necessary
  47. expr = f(a, b, p, q) - f(b, a, p, q)
  48. assert simplify_index_permutations(
  49. expr, [P(a, b)]) == P(a, b)*f(a, b, p, q)
  50. # Cases where dummy substitution is needed
  51. expected = P(a, b)*substitute_dummies(f(a, b, p, q))
  52. expr = f(a, b, p, q) - f(b, a, q, p)
  53. result = simplify_index_permutations(expr, [P(a, b)])
  54. assert expected == substitute_dummies(result)
  55. expr = f(a, b, q, p) - f(b, a, p, q)
  56. result = simplify_index_permutations(expr, [P(a, b)])
  57. assert expected == substitute_dummies(result)
  58. # A case where nothing can be done
  59. expr = f(a, b, q, p) - g(b, a, p, q)
  60. result = simplify_index_permutations(expr, [P(a, b)])
  61. assert expr == result
  62. def test_dagger():
  63. i, j, n, m = symbols('i,j,n,m')
  64. assert Dagger(1) == 1
  65. assert Dagger(1.0) == 1.0
  66. assert Dagger(2*I) == -2*I
  67. assert Dagger(S.Half*I/3.0) == I*Rational(-1, 2)/3.0
  68. assert Dagger(BKet([n])) == BBra([n])
  69. assert Dagger(B(0)) == Bd(0)
  70. assert Dagger(Bd(0)) == B(0)
  71. assert Dagger(B(n)) == Bd(n)
  72. assert Dagger(Bd(n)) == B(n)
  73. assert Dagger(B(0) + B(1)) == Bd(0) + Bd(1)
  74. assert Dagger(n*m) == Dagger(n)*Dagger(m) # n, m commute
  75. assert Dagger(B(n)*B(m)) == Bd(m)*Bd(n)
  76. assert Dagger(B(n)**10) == Dagger(B(n))**10
  77. assert Dagger('a') == Dagger(Symbol('a'))
  78. assert Dagger(Dagger('a')) == Symbol('a')
  79. assert Dagger(exp(2 * I)) == exp(-2 * I)
  80. assert Dagger(i) == conjugate(i)
  81. def test_operator():
  82. i, j = symbols('i,j')
  83. o = BosonicOperator(i)
  84. assert o.state == i
  85. assert o.is_symbolic
  86. o = BosonicOperator(1)
  87. assert o.state == 1
  88. assert not o.is_symbolic
  89. def test_create():
  90. i, j, n, m, p1 = symbols('i,j,n,m,p1')
  91. o = Bd(i)
  92. assert latex(o) == "{b^\\dagger_{i}}"
  93. assert latex(Bd(p1)) == "{b^\\dagger_{p_{1}}}"
  94. assert isinstance(o, CreateBoson)
  95. o = o.subs(i, j)
  96. assert o.atoms(Symbol) == {j}
  97. o = Bd(0)
  98. assert o.apply_operator(BKet([n])) == sqrt(n + 1)*BKet([n + 1])
  99. o = Bd(n)
  100. assert o.apply_operator(BKet([n])) == o*BKet([n])
  101. def test_annihilate():
  102. i, j, n, m, p1 = symbols('i,j,n,m,p1')
  103. o = B(i)
  104. assert latex(o) == "b_{i}"
  105. assert latex(B(p1)) == "b_{p_{1}}"
  106. assert isinstance(o, AnnihilateBoson)
  107. o = o.subs(i, j)
  108. assert o.atoms(Symbol) == {j}
  109. o = B(0)
  110. assert o.apply_operator(BKet([n])) == sqrt(n)*BKet([n - 1])
  111. o = B(n)
  112. assert o.apply_operator(BKet([n])) == o*BKet([n])
  113. def test_basic_state():
  114. i, j, n, m = symbols('i,j,n,m')
  115. s = BosonState([0, 1, 2, 3, 4])
  116. assert len(s) == 5
  117. assert s.args[0] == tuple(range(5))
  118. assert s.up(0) == BosonState([1, 1, 2, 3, 4])
  119. assert s.down(4) == BosonState([0, 1, 2, 3, 3])
  120. for i in range(5):
  121. assert s.up(i).down(i) == s
  122. assert s.down(0) == 0
  123. for i in range(5):
  124. assert s[i] == i
  125. s = BosonState([n, m])
  126. assert s.down(0) == BosonState([n - 1, m])
  127. assert s.up(0) == BosonState([n + 1, m])
  128. def test_basic_apply():
  129. n = symbols("n")
  130. e = B(0)*BKet([n])
  131. assert apply_operators(e) == sqrt(n)*BKet([n - 1])
  132. e = Bd(0)*BKet([n])
  133. assert apply_operators(e) == sqrt(n + 1)*BKet([n + 1])
  134. def test_complex_apply():
  135. n, m = symbols("n,m")
  136. o = Bd(0)*B(0)*Bd(1)*B(0)
  137. e = apply_operators(o*BKet([n, m]))
  138. answer = sqrt(n)*sqrt(m + 1)*(-1 + n)*BKet([-1 + n, 1 + m])
  139. assert expand(e) == expand(answer)
  140. def test_number_operator():
  141. n = symbols("n")
  142. o = Bd(0)*B(0)
  143. e = apply_operators(o*BKet([n]))
  144. assert e == n*BKet([n])
  145. def test_inner_product():
  146. i, j, k, l = symbols('i,j,k,l')
  147. s1 = BBra([0])
  148. s2 = BKet([1])
  149. assert InnerProduct(s1, Dagger(s1)) == 1
  150. assert InnerProduct(s1, s2) == 0
  151. s1 = BBra([i, j])
  152. s2 = BKet([k, l])
  153. r = InnerProduct(s1, s2)
  154. assert r == KroneckerDelta(i, k)*KroneckerDelta(j, l)
  155. def test_symbolic_matrix_elements():
  156. n, m = symbols('n,m')
  157. s1 = BBra([n])
  158. s2 = BKet([m])
  159. o = B(0)
  160. e = apply_operators(s1*o*s2)
  161. assert e == sqrt(m)*KroneckerDelta(n, m - 1)
  162. def test_matrix_elements():
  163. b = VarBosonicBasis(5)
  164. o = B(0)
  165. m = matrix_rep(o, b)
  166. for i in range(4):
  167. assert m[i, i + 1] == sqrt(i + 1)
  168. o = Bd(0)
  169. m = matrix_rep(o, b)
  170. for i in range(4):
  171. assert m[i + 1, i] == sqrt(i + 1)
  172. def test_fixed_bosonic_basis():
  173. b = FixedBosonicBasis(2, 2)
  174. # assert b == [FockState((2, 0)), FockState((1, 1)), FockState((0, 2))]
  175. state = b.state(1)
  176. assert state == FockStateBosonKet((1, 1))
  177. assert b.index(state) == 1
  178. assert b.state(1) == b[1]
  179. assert len(b) == 3
  180. assert str(b) == '[FockState((2, 0)), FockState((1, 1)), FockState((0, 2))]'
  181. assert repr(b) == '[FockState((2, 0)), FockState((1, 1)), FockState((0, 2))]'
  182. assert srepr(b) == '[FockState((2, 0)), FockState((1, 1)), FockState((0, 2))]'
  183. @slow
  184. def test_sho():
  185. n, m = symbols('n,m')
  186. h_n = Bd(n)*B(n)*(n + S.Half)
  187. H = Sum(h_n, (n, 0, 5))
  188. o = H.doit(deep=False)
  189. b = FixedBosonicBasis(2, 6)
  190. m = matrix_rep(o, b)
  191. # We need to double check these energy values to make sure that they
  192. # are correct and have the proper degeneracies!
  193. diag = [1, 2, 3, 3, 4, 5, 4, 5, 6, 7, 5, 6, 7, 8, 9, 6, 7, 8, 9, 10, 11]
  194. for i in range(len(diag)):
  195. assert diag[i] == m[i, i]
  196. def test_commutation():
  197. n, m = symbols("n,m", above_fermi=True)
  198. c = Commutator(B(0), Bd(0))
  199. assert c == 1
  200. c = Commutator(Bd(0), B(0))
  201. assert c == -1
  202. c = Commutator(B(n), Bd(0))
  203. assert c == KroneckerDelta(n, 0)
  204. c = Commutator(B(0), B(0))
  205. assert c == 0
  206. c = Commutator(B(0), Bd(0))
  207. e = simplify(apply_operators(c*BKet([n])))
  208. assert e == BKet([n])
  209. c = Commutator(B(0), B(1))
  210. e = simplify(apply_operators(c*BKet([n, m])))
  211. assert e == 0
  212. c = Commutator(F(m), Fd(m))
  213. assert c == +1 - 2*NO(Fd(m)*F(m))
  214. c = Commutator(Fd(m), F(m))
  215. assert c.expand() == -1 + 2*NO(Fd(m)*F(m))
  216. C = Commutator
  217. X, Y, Z = symbols('X,Y,Z', commutative=False)
  218. assert C(C(X, Y), Z) != 0
  219. assert C(C(X, Z), Y) != 0
  220. assert C(Y, C(X, Z)) != 0
  221. i, j, k, l = symbols('i,j,k,l', below_fermi=True)
  222. a, b, c, d = symbols('a,b,c,d', above_fermi=True)
  223. p, q, r, s = symbols('p,q,r,s')
  224. D = KroneckerDelta
  225. assert C(Fd(a), F(i)) == -2*NO(F(i)*Fd(a))
  226. assert C(Fd(j), NO(Fd(a)*F(i))).doit(wicks=True) == -D(j, i)*Fd(a)
  227. assert C(Fd(a)*F(i), Fd(b)*F(j)).doit(wicks=True) == 0
  228. c1 = Commutator(F(a), Fd(a))
  229. assert Commutator.eval(c1, c1) == 0
  230. c = Commutator(Fd(a)*F(i),Fd(b)*F(j))
  231. assert latex(c) == r'\left[{a^\dagger_{a}} a_{i},{a^\dagger_{b}} a_{j}\right]'
  232. assert repr(c) == 'Commutator(CreateFermion(a)*AnnihilateFermion(i),CreateFermion(b)*AnnihilateFermion(j))'
  233. assert str(c) == '[CreateFermion(a)*AnnihilateFermion(i),CreateFermion(b)*AnnihilateFermion(j)]'
  234. def test_create_f():
  235. i, j, n, m = symbols('i,j,n,m')
  236. o = Fd(i)
  237. assert isinstance(o, CreateFermion)
  238. o = o.subs(i, j)
  239. assert o.atoms(Symbol) == {j}
  240. o = Fd(1)
  241. assert o.apply_operator(FKet([n])) == FKet([1, n])
  242. assert o.apply_operator(FKet([n])) == -FKet([n, 1])
  243. o = Fd(n)
  244. assert o.apply_operator(FKet([])) == FKet([n])
  245. vacuum = FKet([], fermi_level=4)
  246. assert vacuum == FKet([], fermi_level=4)
  247. i, j, k, l = symbols('i,j,k,l', below_fermi=True)
  248. a, b, c, d = symbols('a,b,c,d', above_fermi=True)
  249. p, q, r, s = symbols('p,q,r,s')
  250. p1 = symbols("p1")
  251. assert Fd(i).apply_operator(FKet([i, j, k], 4)) == FKet([j, k], 4)
  252. assert Fd(a).apply_operator(FKet([i, b, k], 4)) == FKet([a, i, b, k], 4)
  253. assert Dagger(B(p)).apply_operator(q) == q*CreateBoson(p)
  254. assert repr(Fd(p)) == 'CreateFermion(p)'
  255. assert srepr(Fd(p)) == "CreateFermion(Symbol('p'))"
  256. assert latex(Fd(p)) == r'{a^\dagger_{p}}'
  257. assert latex(Fd(p1)) == r'{a^\dagger_{p_{1}}}'
  258. assert latex(FKet([a,i], 1)) == r"\left|\left( a, \ i\right)\right\rangle"
  259. assert latex(FKet([j,i,b,a], 2)) == r"\left|\left( a, \ b, \ i, \ j\right)\right\rangle"
  260. def test_annihilate_f():
  261. i, j, n, m = symbols('i,j,n,m')
  262. o = F(i)
  263. assert isinstance(o, AnnihilateFermion)
  264. o = o.subs(i, j)
  265. assert o.atoms(Symbol) == {j}
  266. o = F(1)
  267. assert o.apply_operator(FKet([1, n])) == FKet([n])
  268. assert o.apply_operator(FKet([n, 1])) == -FKet([n])
  269. o = F(n)
  270. assert o.apply_operator(FKet([n])) == FKet([])
  271. i, j, k, l = symbols('i,j,k,l', below_fermi=True)
  272. a, b, c, d = symbols('a,b,c,d', above_fermi=True)
  273. p, q, r, s = symbols('p,q,r,s')
  274. p1 = symbols('p1')
  275. assert F(i).apply_operator(FKet([i, j, k], 4)) == 0
  276. assert F(a).apply_operator(FKet([i, b, k], 4)) == 0
  277. assert F(l).apply_operator(FKet([i, j, k], 3)) == 0
  278. assert F(l).apply_operator(FKet([i, j, k], 4)) == FKet([l, i, j, k], 4)
  279. assert str(F(p)) == 'f(p)'
  280. assert repr(F(p)) == 'AnnihilateFermion(p)'
  281. assert srepr(F(p)) == "AnnihilateFermion(Symbol('p'))"
  282. assert latex(F(p)) == 'a_{p}'
  283. assert latex(F(p1)) == 'a_{p_{1}}'
  284. def test_create_b():
  285. i, j, n, m = symbols('i,j,n,m')
  286. o = Bd(i)
  287. assert isinstance(o, CreateBoson)
  288. o = o.subs(i, j)
  289. assert o.atoms(Symbol) == {j}
  290. o = Bd(0)
  291. assert o.apply_operator(BKet([n])) == sqrt(n + 1)*BKet([n + 1])
  292. o = Bd(n)
  293. assert o.apply_operator(BKet([n])) == o*BKet([n])
  294. def test_annihilate_b():
  295. i, j, n, m = symbols('i,j,n,m')
  296. o = B(i)
  297. assert isinstance(o, AnnihilateBoson)
  298. o = o.subs(i, j)
  299. assert o.atoms(Symbol) == {j}
  300. o = B(0)
  301. def test_wicks():
  302. p, q, r, s = symbols('p,q,r,s', above_fermi=True)
  303. # Testing for particles only
  304. str = F(p)*Fd(q)
  305. assert wicks(str) == NO(F(p)*Fd(q)) + KroneckerDelta(p, q)
  306. str = Fd(p)*F(q)
  307. assert wicks(str) == NO(Fd(p)*F(q))
  308. str = F(p)*Fd(q)*F(r)*Fd(s)
  309. nstr = wicks(str)
  310. fasit = NO(
  311. KroneckerDelta(p, q)*KroneckerDelta(r, s)
  312. + KroneckerDelta(p, q)*AnnihilateFermion(r)*CreateFermion(s)
  313. + KroneckerDelta(r, s)*AnnihilateFermion(p)*CreateFermion(q)
  314. - KroneckerDelta(p, s)*AnnihilateFermion(r)*CreateFermion(q)
  315. - AnnihilateFermion(p)*AnnihilateFermion(r)*CreateFermion(q)*CreateFermion(s))
  316. assert nstr == fasit
  317. assert (p*q*nstr).expand() == wicks(p*q*str)
  318. assert (nstr*p*q*2).expand() == wicks(str*p*q*2)
  319. # Testing CC equations particles and holes
  320. i, j, k, l = symbols('i j k l', below_fermi=True, cls=Dummy)
  321. a, b, c, d = symbols('a b c d', above_fermi=True, cls=Dummy)
  322. p, q, r, s = symbols('p q r s', cls=Dummy)
  323. assert (wicks(F(a)*NO(F(i)*F(j))*Fd(b)) ==
  324. NO(F(a)*F(i)*F(j)*Fd(b)) +
  325. KroneckerDelta(a, b)*NO(F(i)*F(j)))
  326. assert (wicks(F(a)*NO(F(i)*F(j)*F(k))*Fd(b)) ==
  327. NO(F(a)*F(i)*F(j)*F(k)*Fd(b)) -
  328. KroneckerDelta(a, b)*NO(F(i)*F(j)*F(k)))
  329. expr = wicks(Fd(i)*NO(Fd(j)*F(k))*F(l))
  330. assert (expr ==
  331. -KroneckerDelta(i, k)*NO(Fd(j)*F(l)) -
  332. KroneckerDelta(j, l)*NO(Fd(i)*F(k)) -
  333. KroneckerDelta(i, k)*KroneckerDelta(j, l) +
  334. KroneckerDelta(i, l)*NO(Fd(j)*F(k)) +
  335. NO(Fd(i)*Fd(j)*F(k)*F(l)))
  336. expr = wicks(F(a)*NO(F(b)*Fd(c))*Fd(d))
  337. assert (expr ==
  338. -KroneckerDelta(a, c)*NO(F(b)*Fd(d)) -
  339. KroneckerDelta(b, d)*NO(F(a)*Fd(c)) -
  340. KroneckerDelta(a, c)*KroneckerDelta(b, d) +
  341. KroneckerDelta(a, d)*NO(F(b)*Fd(c)) +
  342. NO(F(a)*F(b)*Fd(c)*Fd(d)))
  343. def test_NO():
  344. i, j, k, l = symbols('i j k l', below_fermi=True)
  345. a, b, c, d = symbols('a b c d', above_fermi=True)
  346. p, q, r, s = symbols('p q r s', cls=Dummy)
  347. assert (NO(Fd(p)*F(q) + Fd(a)*F(b)) ==
  348. NO(Fd(p)*F(q)) + NO(Fd(a)*F(b)))
  349. assert (NO(Fd(i)*NO(F(j)*Fd(a))) ==
  350. NO(Fd(i)*F(j)*Fd(a)))
  351. assert NO(1) == 1
  352. assert NO(i) == i
  353. assert (NO(Fd(a)*Fd(b)*(F(c) + F(d))) ==
  354. NO(Fd(a)*Fd(b)*F(c)) +
  355. NO(Fd(a)*Fd(b)*F(d)))
  356. assert NO(Fd(a)*F(b))._remove_brackets() == Fd(a)*F(b)
  357. assert NO(F(j)*Fd(i))._remove_brackets() == F(j)*Fd(i)
  358. assert (NO(Fd(p)*F(q)).subs(Fd(p), Fd(a) + Fd(i)) ==
  359. NO(Fd(a)*F(q)) + NO(Fd(i)*F(q)))
  360. assert (NO(Fd(p)*F(q)).subs(F(q), F(a) + F(i)) ==
  361. NO(Fd(p)*F(a)) + NO(Fd(p)*F(i)))
  362. expr = NO(Fd(p)*F(q))._remove_brackets()
  363. assert wicks(expr) == NO(expr)
  364. assert NO(Fd(a)*F(b)) == - NO(F(b)*Fd(a))
  365. no = NO(Fd(a)*F(i)*F(b)*Fd(j))
  366. l1 = list(no.iter_q_creators())
  367. assert l1 == [0, 1]
  368. l2 = list(no.iter_q_annihilators())
  369. assert l2 == [3, 2]
  370. no = NO(Fd(a)*Fd(i))
  371. assert no.has_q_creators == 1
  372. assert no.has_q_annihilators == -1
  373. assert str(no) == ':CreateFermion(a)*CreateFermion(i):'
  374. assert repr(no) == 'NO(CreateFermion(a)*CreateFermion(i))'
  375. assert latex(no) == r'\left\{{a^\dagger_{a}} {a^\dagger_{i}}\right\}'
  376. raises(NotImplementedError, lambda: NO(Bd(p)*F(q)))
  377. def test_sorting():
  378. i, j = symbols('i,j', below_fermi=True)
  379. a, b = symbols('a,b', above_fermi=True)
  380. p, q = symbols('p,q')
  381. # p, q
  382. assert _sort_anticommuting_fermions([Fd(p), F(q)]) == ([Fd(p), F(q)], 0)
  383. assert _sort_anticommuting_fermions([F(p), Fd(q)]) == ([Fd(q), F(p)], 1)
  384. # i, p
  385. assert _sort_anticommuting_fermions([F(p), Fd(i)]) == ([F(p), Fd(i)], 0)
  386. assert _sort_anticommuting_fermions([Fd(i), F(p)]) == ([F(p), Fd(i)], 1)
  387. assert _sort_anticommuting_fermions([Fd(p), Fd(i)]) == ([Fd(p), Fd(i)], 0)
  388. assert _sort_anticommuting_fermions([Fd(i), Fd(p)]) == ([Fd(p), Fd(i)], 1)
  389. assert _sort_anticommuting_fermions([F(p), F(i)]) == ([F(i), F(p)], 1)
  390. assert _sort_anticommuting_fermions([F(i), F(p)]) == ([F(i), F(p)], 0)
  391. assert _sort_anticommuting_fermions([Fd(p), F(i)]) == ([F(i), Fd(p)], 1)
  392. assert _sort_anticommuting_fermions([F(i), Fd(p)]) == ([F(i), Fd(p)], 0)
  393. # a, p
  394. assert _sort_anticommuting_fermions([F(p), Fd(a)]) == ([Fd(a), F(p)], 1)
  395. assert _sort_anticommuting_fermions([Fd(a), F(p)]) == ([Fd(a), F(p)], 0)
  396. assert _sort_anticommuting_fermions([Fd(p), Fd(a)]) == ([Fd(a), Fd(p)], 1)
  397. assert _sort_anticommuting_fermions([Fd(a), Fd(p)]) == ([Fd(a), Fd(p)], 0)
  398. assert _sort_anticommuting_fermions([F(p), F(a)]) == ([F(p), F(a)], 0)
  399. assert _sort_anticommuting_fermions([F(a), F(p)]) == ([F(p), F(a)], 1)
  400. assert _sort_anticommuting_fermions([Fd(p), F(a)]) == ([Fd(p), F(a)], 0)
  401. assert _sort_anticommuting_fermions([F(a), Fd(p)]) == ([Fd(p), F(a)], 1)
  402. # i, a
  403. assert _sort_anticommuting_fermions([F(i), Fd(j)]) == ([F(i), Fd(j)], 0)
  404. assert _sort_anticommuting_fermions([Fd(j), F(i)]) == ([F(i), Fd(j)], 1)
  405. assert _sort_anticommuting_fermions([Fd(a), Fd(i)]) == ([Fd(a), Fd(i)], 0)
  406. assert _sort_anticommuting_fermions([Fd(i), Fd(a)]) == ([Fd(a), Fd(i)], 1)
  407. assert _sort_anticommuting_fermions([F(a), F(i)]) == ([F(i), F(a)], 1)
  408. assert _sort_anticommuting_fermions([F(i), F(a)]) == ([F(i), F(a)], 0)
  409. def test_contraction():
  410. i, j, k, l = symbols('i,j,k,l', below_fermi=True)
  411. a, b, c, d = symbols('a,b,c,d', above_fermi=True)
  412. p, q, r, s = symbols('p,q,r,s')
  413. assert contraction(Fd(i), F(j)) == KroneckerDelta(i, j)
  414. assert contraction(F(a), Fd(b)) == KroneckerDelta(a, b)
  415. assert contraction(F(a), Fd(i)) == 0
  416. assert contraction(Fd(a), F(i)) == 0
  417. assert contraction(F(i), Fd(a)) == 0
  418. assert contraction(Fd(i), F(a)) == 0
  419. assert contraction(Fd(i), F(p)) == KroneckerDelta(i, p)
  420. restr = evaluate_deltas(contraction(Fd(p), F(q)))
  421. assert restr.is_only_below_fermi
  422. restr = evaluate_deltas(contraction(F(p), Fd(q)))
  423. assert restr.is_only_above_fermi
  424. raises(ContractionAppliesOnlyToFermions, lambda: contraction(B(a), Fd(b)))
  425. def test_evaluate_deltas():
  426. i, j, k = symbols('i,j,k')
  427. r = KroneckerDelta(i, j) * KroneckerDelta(j, k)
  428. assert evaluate_deltas(r) == KroneckerDelta(i, k)
  429. r = KroneckerDelta(i, 0) * KroneckerDelta(j, k)
  430. assert evaluate_deltas(r) == KroneckerDelta(i, 0) * KroneckerDelta(j, k)
  431. r = KroneckerDelta(1, j) * KroneckerDelta(j, k)
  432. assert evaluate_deltas(r) == KroneckerDelta(1, k)
  433. r = KroneckerDelta(j, 2) * KroneckerDelta(k, j)
  434. assert evaluate_deltas(r) == KroneckerDelta(2, k)
  435. r = KroneckerDelta(i, 0) * KroneckerDelta(i, j) * KroneckerDelta(j, 1)
  436. assert evaluate_deltas(r) == 0
  437. r = (KroneckerDelta(0, i) * KroneckerDelta(0, j)
  438. * KroneckerDelta(1, j) * KroneckerDelta(1, j))
  439. assert evaluate_deltas(r) == 0
  440. def test_Tensors():
  441. i, j, k, l = symbols('i j k l', below_fermi=True, cls=Dummy)
  442. a, b, c, d = symbols('a b c d', above_fermi=True, cls=Dummy)
  443. p, q, r, s = symbols('p q r s')
  444. AT = AntiSymmetricTensor
  445. assert AT('t', (a, b), (i, j)) == -AT('t', (b, a), (i, j))
  446. assert AT('t', (a, b), (i, j)) == AT('t', (b, a), (j, i))
  447. assert AT('t', (a, b), (i, j)) == -AT('t', (a, b), (j, i))
  448. assert AT('t', (a, a), (i, j)) == 0
  449. assert AT('t', (a, b), (i, i)) == 0
  450. assert AT('t', (a, b, c), (i, j)) == -AT('t', (b, a, c), (i, j))
  451. assert AT('t', (a, b, c), (i, j, k)) == AT('t', (b, a, c), (i, k, j))
  452. tabij = AT('t', (a, b), (i, j))
  453. assert tabij.has(a)
  454. assert tabij.has(b)
  455. assert tabij.has(i)
  456. assert tabij.has(j)
  457. assert tabij.subs(b, c) == AT('t', (a, c), (i, j))
  458. assert (2*tabij).subs(i, c) == 2*AT('t', (a, b), (c, j))
  459. assert tabij.symbol == Symbol('t')
  460. assert latex(tabij) == '{t^{ab}_{ij}}'
  461. assert str(tabij) == 't((_a, _b),(_i, _j))'
  462. assert AT('t', (a, a), (i, j)).subs(a, b) == AT('t', (b, b), (i, j))
  463. assert AT('t', (a, i), (a, j)).subs(a, b) == AT('t', (b, i), (b, j))
  464. a1, a2, a3, a4 = symbols('alpha1:5')
  465. u_alpha1234 = AntiSymmetricTensor("u", (a1, a2), (a3, a4))
  466. assert latex(u_alpha1234) == r'{u^{\alpha_{1}\alpha_{2}}_{\alpha_{3}\alpha_{4}}}'
  467. assert str(u_alpha1234) == 'u((alpha1, alpha2),(alpha3, alpha4))'
  468. def test_fully_contracted():
  469. i, j, k, l = symbols('i j k l', below_fermi=True)
  470. a, b, c, d = symbols('a b c d', above_fermi=True)
  471. p, q, r, s = symbols('p q r s', cls=Dummy)
  472. Fock = (AntiSymmetricTensor('f', (p,), (q,))*
  473. NO(Fd(p)*F(q)))
  474. V = (AntiSymmetricTensor('v', (p, q), (r, s))*
  475. NO(Fd(p)*Fd(q)*F(s)*F(r)))/4
  476. Fai = wicks(NO(Fd(i)*F(a))*Fock,
  477. keep_only_fully_contracted=True,
  478. simplify_kronecker_deltas=True)
  479. assert Fai == AntiSymmetricTensor('f', (a,), (i,))
  480. Vabij = wicks(NO(Fd(i)*Fd(j)*F(b)*F(a))*V,
  481. keep_only_fully_contracted=True,
  482. simplify_kronecker_deltas=True)
  483. assert Vabij == AntiSymmetricTensor('v', (a, b), (i, j))
  484. def test_substitute_dummies_without_dummies():
  485. i, j = symbols('i,j')
  486. assert substitute_dummies(att(i, j) + 2) == att(i, j) + 2
  487. assert substitute_dummies(att(i, j) + 1) == att(i, j) + 1
  488. def test_substitute_dummies_NO_operator():
  489. i, j = symbols('i j', cls=Dummy)
  490. assert substitute_dummies(att(i, j)*NO(Fd(i)*F(j))
  491. - att(j, i)*NO(Fd(j)*F(i))) == 0
  492. def test_substitute_dummies_SQ_operator():
  493. i, j = symbols('i j', cls=Dummy)
  494. assert substitute_dummies(att(i, j)*Fd(i)*F(j)
  495. - att(j, i)*Fd(j)*F(i)) == 0
  496. def test_substitute_dummies_new_indices():
  497. i, j = symbols('i j', below_fermi=True, cls=Dummy)
  498. a, b = symbols('a b', above_fermi=True, cls=Dummy)
  499. p, q = symbols('p q', cls=Dummy)
  500. f = Function('f')
  501. assert substitute_dummies(f(i, a, p) - f(j, b, q), new_indices=True) == 0
  502. def test_substitute_dummies_substitution_order():
  503. i, j, k, l = symbols('i j k l', below_fermi=True, cls=Dummy)
  504. f = Function('f')
  505. from sympy.utilities.iterables import variations
  506. for permut in variations([i, j, k, l], 4):
  507. assert substitute_dummies(f(*permut) - f(i, j, k, l)) == 0
  508. def test_dummy_order_inner_outer_lines_VT1T1T1():
  509. ii = symbols('i', below_fermi=True)
  510. aa = symbols('a', above_fermi=True)
  511. k, l = symbols('k l', below_fermi=True, cls=Dummy)
  512. c, d = symbols('c d', above_fermi=True, cls=Dummy)
  513. v = Function('v')
  514. t = Function('t')
  515. dums = _get_ordered_dummies
  516. # Coupled-Cluster T1 terms with V*T1*T1*T1
  517. # t^{a}_{k} t^{c}_{i} t^{d}_{l} v^{lk}_{dc}
  518. exprs = [
  519. # permut v and t <=> swapping internal lines, equivalent
  520. # irrespective of symmetries in v
  521. v(k, l, c, d)*t(c, ii)*t(d, l)*t(aa, k),
  522. v(l, k, c, d)*t(c, ii)*t(d, k)*t(aa, l),
  523. v(k, l, d, c)*t(d, ii)*t(c, l)*t(aa, k),
  524. v(l, k, d, c)*t(d, ii)*t(c, k)*t(aa, l),
  525. ]
  526. for permut in exprs[1:]:
  527. assert dums(exprs[0]) != dums(permut)
  528. assert substitute_dummies(exprs[0]) == substitute_dummies(permut)
  529. def test_dummy_order_inner_outer_lines_VT1T1T1T1():
  530. ii, jj = symbols('i j', below_fermi=True)
  531. aa, bb = symbols('a b', above_fermi=True)
  532. k, l = symbols('k l', below_fermi=True, cls=Dummy)
  533. c, d = symbols('c d', above_fermi=True, cls=Dummy)
  534. v = Function('v')
  535. t = Function('t')
  536. dums = _get_ordered_dummies
  537. # Coupled-Cluster T2 terms with V*T1*T1*T1*T1
  538. exprs = [
  539. # permut t <=> swapping external lines, not equivalent
  540. # except if v has certain symmetries.
  541. v(k, l, c, d)*t(c, ii)*t(d, jj)*t(aa, k)*t(bb, l),
  542. v(k, l, c, d)*t(c, jj)*t(d, ii)*t(aa, k)*t(bb, l),
  543. v(k, l, c, d)*t(c, ii)*t(d, jj)*t(bb, k)*t(aa, l),
  544. v(k, l, c, d)*t(c, jj)*t(d, ii)*t(bb, k)*t(aa, l),
  545. ]
  546. for permut in exprs[1:]:
  547. assert dums(exprs[0]) != dums(permut)
  548. assert substitute_dummies(exprs[0]) != substitute_dummies(permut)
  549. exprs = [
  550. # permut v <=> swapping external lines, not equivalent
  551. # except if v has certain symmetries.
  552. #
  553. # Note that in contrast to above, these permutations have identical
  554. # dummy order. That is because the proximity to external indices
  555. # has higher influence on the canonical dummy ordering than the
  556. # position of a dummy on the factors. In fact, the terms here are
  557. # similar in structure as the result of the dummy substitutions above.
  558. v(k, l, c, d)*t(c, ii)*t(d, jj)*t(aa, k)*t(bb, l),
  559. v(l, k, c, d)*t(c, ii)*t(d, jj)*t(aa, k)*t(bb, l),
  560. v(k, l, d, c)*t(c, ii)*t(d, jj)*t(aa, k)*t(bb, l),
  561. v(l, k, d, c)*t(c, ii)*t(d, jj)*t(aa, k)*t(bb, l),
  562. ]
  563. for permut in exprs[1:]:
  564. assert dums(exprs[0]) == dums(permut)
  565. assert substitute_dummies(exprs[0]) != substitute_dummies(permut)
  566. exprs = [
  567. # permut t and v <=> swapping internal lines, equivalent.
  568. # Canonical dummy order is different, and a consistent
  569. # substitution reveals the equivalence.
  570. v(k, l, c, d)*t(c, ii)*t(d, jj)*t(aa, k)*t(bb, l),
  571. v(k, l, d, c)*t(c, jj)*t(d, ii)*t(aa, k)*t(bb, l),
  572. v(l, k, c, d)*t(c, ii)*t(d, jj)*t(bb, k)*t(aa, l),
  573. v(l, k, d, c)*t(c, jj)*t(d, ii)*t(bb, k)*t(aa, l),
  574. ]
  575. for permut in exprs[1:]:
  576. assert dums(exprs[0]) != dums(permut)
  577. assert substitute_dummies(exprs[0]) == substitute_dummies(permut)
  578. def test_get_subNO():
  579. p, q, r = symbols('p,q,r')
  580. assert NO(F(p)*F(q)*F(r)).get_subNO(1) == NO(F(p)*F(r))
  581. assert NO(F(p)*F(q)*F(r)).get_subNO(0) == NO(F(q)*F(r))
  582. assert NO(F(p)*F(q)*F(r)).get_subNO(2) == NO(F(p)*F(q))
  583. def test_equivalent_internal_lines_VT1T1():
  584. i, j, k, l = symbols('i j k l', below_fermi=True, cls=Dummy)
  585. a, b, c, d = symbols('a b c d', above_fermi=True, cls=Dummy)
  586. v = Function('v')
  587. t = Function('t')
  588. dums = _get_ordered_dummies
  589. exprs = [ # permute v. Different dummy order. Not equivalent.
  590. v(i, j, a, b)*t(a, i)*t(b, j),
  591. v(j, i, a, b)*t(a, i)*t(b, j),
  592. v(i, j, b, a)*t(a, i)*t(b, j),
  593. ]
  594. for permut in exprs[1:]:
  595. assert dums(exprs[0]) != dums(permut)
  596. assert substitute_dummies(exprs[0]) != substitute_dummies(permut)
  597. exprs = [ # permute v. Different dummy order. Equivalent
  598. v(i, j, a, b)*t(a, i)*t(b, j),
  599. v(j, i, b, a)*t(a, i)*t(b, j),
  600. ]
  601. for permut in exprs[1:]:
  602. assert dums(exprs[0]) != dums(permut)
  603. assert substitute_dummies(exprs[0]) == substitute_dummies(permut)
  604. exprs = [ # permute t. Same dummy order, not equivalent.
  605. v(i, j, a, b)*t(a, i)*t(b, j),
  606. v(i, j, a, b)*t(b, i)*t(a, j),
  607. ]
  608. for permut in exprs[1:]:
  609. assert dums(exprs[0]) == dums(permut)
  610. assert substitute_dummies(exprs[0]) != substitute_dummies(permut)
  611. exprs = [ # permute v and t. Different dummy order, equivalent
  612. v(i, j, a, b)*t(a, i)*t(b, j),
  613. v(j, i, a, b)*t(a, j)*t(b, i),
  614. v(i, j, b, a)*t(b, i)*t(a, j),
  615. v(j, i, b, a)*t(b, j)*t(a, i),
  616. ]
  617. for permut in exprs[1:]:
  618. assert dums(exprs[0]) != dums(permut)
  619. assert substitute_dummies(exprs[0]) == substitute_dummies(permut)
  620. def test_equivalent_internal_lines_VT2conjT2():
  621. # this diagram requires special handling in TCE
  622. i, j, k, l, m, n = symbols('i j k l m n', below_fermi=True, cls=Dummy)
  623. a, b, c, d, e, f = symbols('a b c d e f', above_fermi=True, cls=Dummy)
  624. p1, p2, p3, p4 = symbols('p1 p2 p3 p4', above_fermi=True, cls=Dummy)
  625. h1, h2, h3, h4 = symbols('h1 h2 h3 h4', below_fermi=True, cls=Dummy)
  626. from sympy.utilities.iterables import variations
  627. v = Function('v')
  628. t = Function('t')
  629. dums = _get_ordered_dummies
  630. # v(abcd)t(abij)t(ijcd)
  631. template = v(p1, p2, p3, p4)*t(p1, p2, i, j)*t(i, j, p3, p4)
  632. permutator = variations([a, b, c, d], 4)
  633. base = template.subs(zip([p1, p2, p3, p4], next(permutator)))
  634. for permut in permutator:
  635. subslist = zip([p1, p2, p3, p4], permut)
  636. expr = template.subs(subslist)
  637. assert dums(base) != dums(expr)
  638. assert substitute_dummies(expr) == substitute_dummies(base)
  639. template = v(p1, p2, p3, p4)*t(p1, p2, j, i)*t(j, i, p3, p4)
  640. permutator = variations([a, b, c, d], 4)
  641. base = template.subs(zip([p1, p2, p3, p4], next(permutator)))
  642. for permut in permutator:
  643. subslist = zip([p1, p2, p3, p4], permut)
  644. expr = template.subs(subslist)
  645. assert dums(base) != dums(expr)
  646. assert substitute_dummies(expr) == substitute_dummies(base)
  647. # v(abcd)t(abij)t(jicd)
  648. template = v(p1, p2, p3, p4)*t(p1, p2, i, j)*t(j, i, p3, p4)
  649. permutator = variations([a, b, c, d], 4)
  650. base = template.subs(zip([p1, p2, p3, p4], next(permutator)))
  651. for permut in permutator:
  652. subslist = zip([p1, p2, p3, p4], permut)
  653. expr = template.subs(subslist)
  654. assert dums(base) != dums(expr)
  655. assert substitute_dummies(expr) == substitute_dummies(base)
  656. template = v(p1, p2, p3, p4)*t(p1, p2, j, i)*t(i, j, p3, p4)
  657. permutator = variations([a, b, c, d], 4)
  658. base = template.subs(zip([p1, p2, p3, p4], next(permutator)))
  659. for permut in permutator:
  660. subslist = zip([p1, p2, p3, p4], permut)
  661. expr = template.subs(subslist)
  662. assert dums(base) != dums(expr)
  663. assert substitute_dummies(expr) == substitute_dummies(base)
  664. def test_equivalent_internal_lines_VT2conjT2_ambiguous_order():
  665. # These diagrams invokes _determine_ambiguous() because the
  666. # dummies can not be ordered unambiguously by the key alone
  667. i, j, k, l, m, n = symbols('i j k l m n', below_fermi=True, cls=Dummy)
  668. a, b, c, d, e, f = symbols('a b c d e f', above_fermi=True, cls=Dummy)
  669. p1, p2, p3, p4 = symbols('p1 p2 p3 p4', above_fermi=True, cls=Dummy)
  670. h1, h2, h3, h4 = symbols('h1 h2 h3 h4', below_fermi=True, cls=Dummy)
  671. from sympy.utilities.iterables import variations
  672. v = Function('v')
  673. t = Function('t')
  674. dums = _get_ordered_dummies
  675. # v(abcd)t(abij)t(cdij)
  676. template = v(p1, p2, p3, p4)*t(p1, p2, i, j)*t(p3, p4, i, j)
  677. permutator = variations([a, b, c, d], 4)
  678. base = template.subs(zip([p1, p2, p3, p4], next(permutator)))
  679. for permut in permutator:
  680. subslist = zip([p1, p2, p3, p4], permut)
  681. expr = template.subs(subslist)
  682. assert dums(base) != dums(expr)
  683. assert substitute_dummies(expr) == substitute_dummies(base)
  684. template = v(p1, p2, p3, p4)*t(p1, p2, j, i)*t(p3, p4, i, j)
  685. permutator = variations([a, b, c, d], 4)
  686. base = template.subs(zip([p1, p2, p3, p4], next(permutator)))
  687. for permut in permutator:
  688. subslist = zip([p1, p2, p3, p4], permut)
  689. expr = template.subs(subslist)
  690. assert dums(base) != dums(expr)
  691. assert substitute_dummies(expr) == substitute_dummies(base)
  692. def test_equivalent_internal_lines_VT2():
  693. i, j, k, l = symbols('i j k l', below_fermi=True, cls=Dummy)
  694. a, b, c, d = symbols('a b c d', above_fermi=True, cls=Dummy)
  695. v = Function('v')
  696. t = Function('t')
  697. dums = _get_ordered_dummies
  698. exprs = [
  699. # permute v. Same dummy order, not equivalent.
  700. #
  701. # This test show that the dummy order may not be sensitive to all
  702. # index permutations. The following expressions have identical
  703. # structure as the resulting terms from of the dummy substitutions
  704. # in the test above. Here, all expressions have the same dummy
  705. # order, so they cannot be simplified by means of dummy
  706. # substitution. In order to simplify further, it is necessary to
  707. # exploit symmetries in the objects, for instance if t or v is
  708. # antisymmetric.
  709. v(i, j, a, b)*t(a, b, i, j),
  710. v(j, i, a, b)*t(a, b, i, j),
  711. v(i, j, b, a)*t(a, b, i, j),
  712. v(j, i, b, a)*t(a, b, i, j),
  713. ]
  714. for permut in exprs[1:]:
  715. assert dums(exprs[0]) == dums(permut)
  716. assert substitute_dummies(exprs[0]) != substitute_dummies(permut)
  717. exprs = [
  718. # permute t.
  719. v(i, j, a, b)*t(a, b, i, j),
  720. v(i, j, a, b)*t(b, a, i, j),
  721. v(i, j, a, b)*t(a, b, j, i),
  722. v(i, j, a, b)*t(b, a, j, i),
  723. ]
  724. for permut in exprs[1:]:
  725. assert dums(exprs[0]) != dums(permut)
  726. assert substitute_dummies(exprs[0]) != substitute_dummies(permut)
  727. exprs = [ # permute v and t. Relabelling of dummies should be equivalent.
  728. v(i, j, a, b)*t(a, b, i, j),
  729. v(j, i, a, b)*t(a, b, j, i),
  730. v(i, j, b, a)*t(b, a, i, j),
  731. v(j, i, b, a)*t(b, a, j, i),
  732. ]
  733. for permut in exprs[1:]:
  734. assert dums(exprs[0]) != dums(permut)
  735. assert substitute_dummies(exprs[0]) == substitute_dummies(permut)
  736. def test_internal_external_VT2T2():
  737. ii, jj = symbols('i j', below_fermi=True)
  738. aa, bb = symbols('a b', above_fermi=True)
  739. k, l = symbols('k l', below_fermi=True, cls=Dummy)
  740. c, d = symbols('c d', above_fermi=True, cls=Dummy)
  741. v = Function('v')
  742. t = Function('t')
  743. dums = _get_ordered_dummies
  744. exprs = [
  745. v(k, l, c, d)*t(aa, c, ii, k)*t(bb, d, jj, l),
  746. v(l, k, c, d)*t(aa, c, ii, l)*t(bb, d, jj, k),
  747. v(k, l, d, c)*t(aa, d, ii, k)*t(bb, c, jj, l),
  748. v(l, k, d, c)*t(aa, d, ii, l)*t(bb, c, jj, k),
  749. ]
  750. for permut in exprs[1:]:
  751. assert dums(exprs[0]) != dums(permut)
  752. assert substitute_dummies(exprs[0]) == substitute_dummies(permut)
  753. exprs = [
  754. v(k, l, c, d)*t(aa, c, ii, k)*t(d, bb, jj, l),
  755. v(l, k, c, d)*t(aa, c, ii, l)*t(d, bb, jj, k),
  756. v(k, l, d, c)*t(aa, d, ii, k)*t(c, bb, jj, l),
  757. v(l, k, d, c)*t(aa, d, ii, l)*t(c, bb, jj, k),
  758. ]
  759. for permut in exprs[1:]:
  760. assert dums(exprs[0]) != dums(permut)
  761. assert substitute_dummies(exprs[0]) == substitute_dummies(permut)
  762. exprs = [
  763. v(k, l, c, d)*t(c, aa, ii, k)*t(bb, d, jj, l),
  764. v(l, k, c, d)*t(c, aa, ii, l)*t(bb, d, jj, k),
  765. v(k, l, d, c)*t(d, aa, ii, k)*t(bb, c, jj, l),
  766. v(l, k, d, c)*t(d, aa, ii, l)*t(bb, c, jj, k),
  767. ]
  768. for permut in exprs[1:]:
  769. assert dums(exprs[0]) != dums(permut)
  770. assert substitute_dummies(exprs[0]) == substitute_dummies(permut)
  771. def test_internal_external_pqrs():
  772. ii, jj = symbols('i j')
  773. aa, bb = symbols('a b')
  774. k, l = symbols('k l', cls=Dummy)
  775. c, d = symbols('c d', cls=Dummy)
  776. v = Function('v')
  777. t = Function('t')
  778. dums = _get_ordered_dummies
  779. exprs = [
  780. v(k, l, c, d)*t(aa, c, ii, k)*t(bb, d, jj, l),
  781. v(l, k, c, d)*t(aa, c, ii, l)*t(bb, d, jj, k),
  782. v(k, l, d, c)*t(aa, d, ii, k)*t(bb, c, jj, l),
  783. v(l, k, d, c)*t(aa, d, ii, l)*t(bb, c, jj, k),
  784. ]
  785. for permut in exprs[1:]:
  786. assert dums(exprs[0]) != dums(permut)
  787. assert substitute_dummies(exprs[0]) == substitute_dummies(permut)
  788. def test_dummy_order_well_defined():
  789. aa, bb = symbols('a b', above_fermi=True)
  790. k, l, m = symbols('k l m', below_fermi=True, cls=Dummy)
  791. c, d = symbols('c d', above_fermi=True, cls=Dummy)
  792. p, q = symbols('p q', cls=Dummy)
  793. A = Function('A')
  794. B = Function('B')
  795. C = Function('C')
  796. dums = _get_ordered_dummies
  797. # We go through all key components in the order of increasing priority,
  798. # and consider only fully orderable expressions. Non-orderable expressions
  799. # are tested elsewhere.
  800. # pos in first factor determines sort order
  801. assert dums(A(k, l)*B(l, k)) == [k, l]
  802. assert dums(A(l, k)*B(l, k)) == [l, k]
  803. assert dums(A(k, l)*B(k, l)) == [k, l]
  804. assert dums(A(l, k)*B(k, l)) == [l, k]
  805. # factors involving the index
  806. assert dums(A(k, l)*B(l, m)*C(k, m)) == [l, k, m]
  807. assert dums(A(k, l)*B(l, m)*C(m, k)) == [l, k, m]
  808. assert dums(A(l, k)*B(l, m)*C(k, m)) == [l, k, m]
  809. assert dums(A(l, k)*B(l, m)*C(m, k)) == [l, k, m]
  810. assert dums(A(k, l)*B(m, l)*C(k, m)) == [l, k, m]
  811. assert dums(A(k, l)*B(m, l)*C(m, k)) == [l, k, m]
  812. assert dums(A(l, k)*B(m, l)*C(k, m)) == [l, k, m]
  813. assert dums(A(l, k)*B(m, l)*C(m, k)) == [l, k, m]
  814. # same, but with factor order determined by non-dummies
  815. assert dums(A(k, aa, l)*A(l, bb, m)*A(bb, k, m)) == [l, k, m]
  816. assert dums(A(k, aa, l)*A(l, bb, m)*A(bb, m, k)) == [l, k, m]
  817. assert dums(A(k, aa, l)*A(m, bb, l)*A(bb, k, m)) == [l, k, m]
  818. assert dums(A(k, aa, l)*A(m, bb, l)*A(bb, m, k)) == [l, k, m]
  819. assert dums(A(l, aa, k)*A(l, bb, m)*A(bb, k, m)) == [l, k, m]
  820. assert dums(A(l, aa, k)*A(l, bb, m)*A(bb, m, k)) == [l, k, m]
  821. assert dums(A(l, aa, k)*A(m, bb, l)*A(bb, k, m)) == [l, k, m]
  822. assert dums(A(l, aa, k)*A(m, bb, l)*A(bb, m, k)) == [l, k, m]
  823. # index range
  824. assert dums(A(p, c, k)*B(p, c, k)) == [k, c, p]
  825. assert dums(A(p, k, c)*B(p, c, k)) == [k, c, p]
  826. assert dums(A(c, k, p)*B(p, c, k)) == [k, c, p]
  827. assert dums(A(c, p, k)*B(p, c, k)) == [k, c, p]
  828. assert dums(A(k, c, p)*B(p, c, k)) == [k, c, p]
  829. assert dums(A(k, p, c)*B(p, c, k)) == [k, c, p]
  830. assert dums(B(p, c, k)*A(p, c, k)) == [k, c, p]
  831. assert dums(B(p, k, c)*A(p, c, k)) == [k, c, p]
  832. assert dums(B(c, k, p)*A(p, c, k)) == [k, c, p]
  833. assert dums(B(c, p, k)*A(p, c, k)) == [k, c, p]
  834. assert dums(B(k, c, p)*A(p, c, k)) == [k, c, p]
  835. assert dums(B(k, p, c)*A(p, c, k)) == [k, c, p]
  836. def test_dummy_order_ambiguous():
  837. aa, bb = symbols('a b', above_fermi=True)
  838. i, j, k, l, m = symbols('i j k l m', below_fermi=True, cls=Dummy)
  839. a, b, c, d, e = symbols('a b c d e', above_fermi=True, cls=Dummy)
  840. p, q = symbols('p q', cls=Dummy)
  841. p1, p2, p3, p4 = symbols('p1 p2 p3 p4', above_fermi=True, cls=Dummy)
  842. p5, p6, p7, p8 = symbols('p5 p6 p7 p8', above_fermi=True, cls=Dummy)
  843. h1, h2, h3, h4 = symbols('h1 h2 h3 h4', below_fermi=True, cls=Dummy)
  844. h5, h6, h7, h8 = symbols('h5 h6 h7 h8', below_fermi=True, cls=Dummy)
  845. A = Function('A')
  846. B = Function('B')
  847. from sympy.utilities.iterables import variations
  848. # A*A*A*A*B -- ordering of p5 and p4 is used to figure out the rest
  849. template = A(p1, p2)*A(p4, p1)*A(p2, p3)*A(p3, p5)*B(p5, p4)
  850. permutator = variations([a, b, c, d, e], 5)
  851. base = template.subs(zip([p1, p2, p3, p4, p5], next(permutator)))
  852. for permut in permutator:
  853. subslist = zip([p1, p2, p3, p4, p5], permut)
  854. expr = template.subs(subslist)
  855. assert substitute_dummies(expr) == substitute_dummies(base)
  856. # A*A*A*A*A -- an arbitrary index is assigned and the rest are figured out
  857. template = A(p1, p2)*A(p4, p1)*A(p2, p3)*A(p3, p5)*A(p5, p4)
  858. permutator = variations([a, b, c, d, e], 5)
  859. base = template.subs(zip([p1, p2, p3, p4, p5], next(permutator)))
  860. for permut in permutator:
  861. subslist = zip([p1, p2, p3, p4, p5], permut)
  862. expr = template.subs(subslist)
  863. assert substitute_dummies(expr) == substitute_dummies(base)
  864. # A*A*A -- ordering of p5 and p4 is used to figure out the rest
  865. template = A(p1, p2, p4, p1)*A(p2, p3, p3, p5)*A(p5, p4)
  866. permutator = variations([a, b, c, d, e], 5)
  867. base = template.subs(zip([p1, p2, p3, p4, p5], next(permutator)))
  868. for permut in permutator:
  869. subslist = zip([p1, p2, p3, p4, p5], permut)
  870. expr = template.subs(subslist)
  871. assert substitute_dummies(expr) == substitute_dummies(base)
  872. def atv(*args):
  873. return AntiSymmetricTensor('v', args[:2], args[2:] )
  874. def att(*args):
  875. if len(args) == 4:
  876. return AntiSymmetricTensor('t', args[:2], args[2:] )
  877. elif len(args) == 2:
  878. return AntiSymmetricTensor('t', (args[0],), (args[1],))
  879. def test_dummy_order_inner_outer_lines_VT1T1T1_AT():
  880. ii = symbols('i', below_fermi=True)
  881. aa = symbols('a', above_fermi=True)
  882. k, l = symbols('k l', below_fermi=True, cls=Dummy)
  883. c, d = symbols('c d', above_fermi=True, cls=Dummy)
  884. # Coupled-Cluster T1 terms with V*T1*T1*T1
  885. # t^{a}_{k} t^{c}_{i} t^{d}_{l} v^{lk}_{dc}
  886. exprs = [
  887. # permut v and t <=> swapping internal lines, equivalent
  888. # irrespective of symmetries in v
  889. atv(k, l, c, d)*att(c, ii)*att(d, l)*att(aa, k),
  890. atv(l, k, c, d)*att(c, ii)*att(d, k)*att(aa, l),
  891. atv(k, l, d, c)*att(d, ii)*att(c, l)*att(aa, k),
  892. atv(l, k, d, c)*att(d, ii)*att(c, k)*att(aa, l),
  893. ]
  894. for permut in exprs[1:]:
  895. assert substitute_dummies(exprs[0]) == substitute_dummies(permut)
  896. def test_dummy_order_inner_outer_lines_VT1T1T1T1_AT():
  897. ii, jj = symbols('i j', below_fermi=True)
  898. aa, bb = symbols('a b', above_fermi=True)
  899. k, l = symbols('k l', below_fermi=True, cls=Dummy)
  900. c, d = symbols('c d', above_fermi=True, cls=Dummy)
  901. # Coupled-Cluster T2 terms with V*T1*T1*T1*T1
  902. # non-equivalent substitutions (change of sign)
  903. exprs = [
  904. # permut t <=> swapping external lines
  905. atv(k, l, c, d)*att(c, ii)*att(d, jj)*att(aa, k)*att(bb, l),
  906. atv(k, l, c, d)*att(c, jj)*att(d, ii)*att(aa, k)*att(bb, l),
  907. atv(k, l, c, d)*att(c, ii)*att(d, jj)*att(bb, k)*att(aa, l),
  908. ]
  909. for permut in exprs[1:]:
  910. assert substitute_dummies(exprs[0]) == -substitute_dummies(permut)
  911. # equivalent substitutions
  912. exprs = [
  913. atv(k, l, c, d)*att(c, ii)*att(d, jj)*att(aa, k)*att(bb, l),
  914. # permut t <=> swapping external lines
  915. atv(k, l, c, d)*att(c, jj)*att(d, ii)*att(bb, k)*att(aa, l),
  916. ]
  917. for permut in exprs[1:]:
  918. assert substitute_dummies(exprs[0]) == substitute_dummies(permut)
  919. def test_equivalent_internal_lines_VT1T1_AT():
  920. i, j, k, l = symbols('i j k l', below_fermi=True, cls=Dummy)
  921. a, b, c, d = symbols('a b c d', above_fermi=True, cls=Dummy)
  922. exprs = [ # permute v. Different dummy order. Not equivalent.
  923. atv(i, j, a, b)*att(a, i)*att(b, j),
  924. atv(j, i, a, b)*att(a, i)*att(b, j),
  925. atv(i, j, b, a)*att(a, i)*att(b, j),
  926. ]
  927. for permut in exprs[1:]:
  928. assert substitute_dummies(exprs[0]) != substitute_dummies(permut)
  929. exprs = [ # permute v. Different dummy order. Equivalent
  930. atv(i, j, a, b)*att(a, i)*att(b, j),
  931. atv(j, i, b, a)*att(a, i)*att(b, j),
  932. ]
  933. for permut in exprs[1:]:
  934. assert substitute_dummies(exprs[0]) == substitute_dummies(permut)
  935. exprs = [ # permute t. Same dummy order, not equivalent.
  936. atv(i, j, a, b)*att(a, i)*att(b, j),
  937. atv(i, j, a, b)*att(b, i)*att(a, j),
  938. ]
  939. for permut in exprs[1:]:
  940. assert substitute_dummies(exprs[0]) != substitute_dummies(permut)
  941. exprs = [ # permute v and t. Different dummy order, equivalent
  942. atv(i, j, a, b)*att(a, i)*att(b, j),
  943. atv(j, i, a, b)*att(a, j)*att(b, i),
  944. atv(i, j, b, a)*att(b, i)*att(a, j),
  945. atv(j, i, b, a)*att(b, j)*att(a, i),
  946. ]
  947. for permut in exprs[1:]:
  948. assert substitute_dummies(exprs[0]) == substitute_dummies(permut)
  949. def test_equivalent_internal_lines_VT2conjT2_AT():
  950. # this diagram requires special handling in TCE
  951. i, j, k, l, m, n = symbols('i j k l m n', below_fermi=True, cls=Dummy)
  952. a, b, c, d, e, f = symbols('a b c d e f', above_fermi=True, cls=Dummy)
  953. p1, p2, p3, p4 = symbols('p1 p2 p3 p4', above_fermi=True, cls=Dummy)
  954. h1, h2, h3, h4 = symbols('h1 h2 h3 h4', below_fermi=True, cls=Dummy)
  955. from sympy.utilities.iterables import variations
  956. # atv(abcd)att(abij)att(ijcd)
  957. template = atv(p1, p2, p3, p4)*att(p1, p2, i, j)*att(i, j, p3, p4)
  958. permutator = variations([a, b, c, d], 4)
  959. base = template.subs(zip([p1, p2, p3, p4], next(permutator)))
  960. for permut in permutator:
  961. subslist = zip([p1, p2, p3, p4], permut)
  962. expr = template.subs(subslist)
  963. assert substitute_dummies(expr) == substitute_dummies(base)
  964. template = atv(p1, p2, p3, p4)*att(p1, p2, j, i)*att(j, i, p3, p4)
  965. permutator = variations([a, b, c, d], 4)
  966. base = template.subs(zip([p1, p2, p3, p4], next(permutator)))
  967. for permut in permutator:
  968. subslist = zip([p1, p2, p3, p4], permut)
  969. expr = template.subs(subslist)
  970. assert substitute_dummies(expr) == substitute_dummies(base)
  971. # atv(abcd)att(abij)att(jicd)
  972. template = atv(p1, p2, p3, p4)*att(p1, p2, i, j)*att(j, i, p3, p4)
  973. permutator = variations([a, b, c, d], 4)
  974. base = template.subs(zip([p1, p2, p3, p4], next(permutator)))
  975. for permut in permutator:
  976. subslist = zip([p1, p2, p3, p4], permut)
  977. expr = template.subs(subslist)
  978. assert substitute_dummies(expr) == substitute_dummies(base)
  979. template = atv(p1, p2, p3, p4)*att(p1, p2, j, i)*att(i, j, p3, p4)
  980. permutator = variations([a, b, c, d], 4)
  981. base = template.subs(zip([p1, p2, p3, p4], next(permutator)))
  982. for permut in permutator:
  983. subslist = zip([p1, p2, p3, p4], permut)
  984. expr = template.subs(subslist)
  985. assert substitute_dummies(expr) == substitute_dummies(base)
  986. def test_equivalent_internal_lines_VT2conjT2_ambiguous_order_AT():
  987. # These diagrams invokes _determine_ambiguous() because the
  988. # dummies can not be ordered unambiguously by the key alone
  989. i, j, k, l, m, n = symbols('i j k l m n', below_fermi=True, cls=Dummy)
  990. a, b, c, d, e, f = symbols('a b c d e f', above_fermi=True, cls=Dummy)
  991. p1, p2, p3, p4 = symbols('p1 p2 p3 p4', above_fermi=True, cls=Dummy)
  992. h1, h2, h3, h4 = symbols('h1 h2 h3 h4', below_fermi=True, cls=Dummy)
  993. from sympy.utilities.iterables import variations
  994. # atv(abcd)att(abij)att(cdij)
  995. template = atv(p1, p2, p3, p4)*att(p1, p2, i, j)*att(p3, p4, i, j)
  996. permutator = variations([a, b, c, d], 4)
  997. base = template.subs(zip([p1, p2, p3, p4], next(permutator)))
  998. for permut in permutator:
  999. subslist = zip([p1, p2, p3, p4], permut)
  1000. expr = template.subs(subslist)
  1001. assert substitute_dummies(expr) == substitute_dummies(base)
  1002. template = atv(p1, p2, p3, p4)*att(p1, p2, j, i)*att(p3, p4, i, j)
  1003. permutator = variations([a, b, c, d], 4)
  1004. base = template.subs(zip([p1, p2, p3, p4], next(permutator)))
  1005. for permut in permutator:
  1006. subslist = zip([p1, p2, p3, p4], permut)
  1007. expr = template.subs(subslist)
  1008. assert substitute_dummies(expr) == substitute_dummies(base)
  1009. def test_equivalent_internal_lines_VT2_AT():
  1010. i, j, k, l = symbols('i j k l', below_fermi=True, cls=Dummy)
  1011. a, b, c, d = symbols('a b c d', above_fermi=True, cls=Dummy)
  1012. exprs = [
  1013. # permute v. Same dummy order, not equivalent.
  1014. atv(i, j, a, b)*att(a, b, i, j),
  1015. atv(j, i, a, b)*att(a, b, i, j),
  1016. atv(i, j, b, a)*att(a, b, i, j),
  1017. ]
  1018. for permut in exprs[1:]:
  1019. assert substitute_dummies(exprs[0]) != substitute_dummies(permut)
  1020. exprs = [
  1021. # permute t.
  1022. atv(i, j, a, b)*att(a, b, i, j),
  1023. atv(i, j, a, b)*att(b, a, i, j),
  1024. atv(i, j, a, b)*att(a, b, j, i),
  1025. ]
  1026. for permut in exprs[1:]:
  1027. assert substitute_dummies(exprs[0]) != substitute_dummies(permut)
  1028. exprs = [ # permute v and t. Relabelling of dummies should be equivalent.
  1029. atv(i, j, a, b)*att(a, b, i, j),
  1030. atv(j, i, a, b)*att(a, b, j, i),
  1031. atv(i, j, b, a)*att(b, a, i, j),
  1032. atv(j, i, b, a)*att(b, a, j, i),
  1033. ]
  1034. for permut in exprs[1:]:
  1035. assert substitute_dummies(exprs[0]) == substitute_dummies(permut)
  1036. def test_internal_external_VT2T2_AT():
  1037. ii, jj = symbols('i j', below_fermi=True)
  1038. aa, bb = symbols('a b', above_fermi=True)
  1039. k, l = symbols('k l', below_fermi=True, cls=Dummy)
  1040. c, d = symbols('c d', above_fermi=True, cls=Dummy)
  1041. exprs = [
  1042. atv(k, l, c, d)*att(aa, c, ii, k)*att(bb, d, jj, l),
  1043. atv(l, k, c, d)*att(aa, c, ii, l)*att(bb, d, jj, k),
  1044. atv(k, l, d, c)*att(aa, d, ii, k)*att(bb, c, jj, l),
  1045. atv(l, k, d, c)*att(aa, d, ii, l)*att(bb, c, jj, k),
  1046. ]
  1047. for permut in exprs[1:]:
  1048. assert substitute_dummies(exprs[0]) == substitute_dummies(permut)
  1049. exprs = [
  1050. atv(k, l, c, d)*att(aa, c, ii, k)*att(d, bb, jj, l),
  1051. atv(l, k, c, d)*att(aa, c, ii, l)*att(d, bb, jj, k),
  1052. atv(k, l, d, c)*att(aa, d, ii, k)*att(c, bb, jj, l),
  1053. atv(l, k, d, c)*att(aa, d, ii, l)*att(c, bb, jj, k),
  1054. ]
  1055. for permut in exprs[1:]:
  1056. assert substitute_dummies(exprs[0]) == substitute_dummies(permut)
  1057. exprs = [
  1058. atv(k, l, c, d)*att(c, aa, ii, k)*att(bb, d, jj, l),
  1059. atv(l, k, c, d)*att(c, aa, ii, l)*att(bb, d, jj, k),
  1060. atv(k, l, d, c)*att(d, aa, ii, k)*att(bb, c, jj, l),
  1061. atv(l, k, d, c)*att(d, aa, ii, l)*att(bb, c, jj, k),
  1062. ]
  1063. for permut in exprs[1:]:
  1064. assert substitute_dummies(exprs[0]) == substitute_dummies(permut)
  1065. def test_internal_external_pqrs_AT():
  1066. ii, jj = symbols('i j')
  1067. aa, bb = symbols('a b')
  1068. k, l = symbols('k l', cls=Dummy)
  1069. c, d = symbols('c d', cls=Dummy)
  1070. exprs = [
  1071. atv(k, l, c, d)*att(aa, c, ii, k)*att(bb, d, jj, l),
  1072. atv(l, k, c, d)*att(aa, c, ii, l)*att(bb, d, jj, k),
  1073. atv(k, l, d, c)*att(aa, d, ii, k)*att(bb, c, jj, l),
  1074. atv(l, k, d, c)*att(aa, d, ii, l)*att(bb, c, jj, k),
  1075. ]
  1076. for permut in exprs[1:]:
  1077. assert substitute_dummies(exprs[0]) == substitute_dummies(permut)
  1078. def test_issue_19661():
  1079. a = Symbol('0')
  1080. assert latex(Commutator(Bd(a)**2, B(a))
  1081. ) == '- \\left[b_{0},{b^\\dagger_{0}}^{2}\\right]'
  1082. def test_canonical_ordering_AntiSymmetricTensor():
  1083. v = symbols("v")
  1084. c, d = symbols(('c','d'), above_fermi=True,
  1085. cls=Dummy)
  1086. k, l = symbols(('k','l'), below_fermi=True,
  1087. cls=Dummy)
  1088. # formerly, the left gave either the left or the right
  1089. assert AntiSymmetricTensor(v, (k, l), (d, c)
  1090. ) == -AntiSymmetricTensor(v, (l, k), (d, c))