test_qapply.py 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. from sympy.core.mul import Mul
  2. from sympy.core.numbers import (I, Integer, Rational)
  3. from sympy.core.singleton import S
  4. from sympy.core.symbol import symbols
  5. from sympy.functions.elementary.miscellaneous import sqrt
  6. from sympy.physics.quantum.anticommutator import AntiCommutator
  7. from sympy.physics.quantum.commutator import Commutator
  8. from sympy.physics.quantum.constants import hbar
  9. from sympy.physics.quantum.dagger import Dagger
  10. from sympy.physics.quantum.gate import H, XGate, IdentityGate
  11. from sympy.physics.quantum.operator import Operator, IdentityOperator
  12. from sympy.physics.quantum.qapply import qapply
  13. from sympy.physics.quantum.spin import Jx, Jy, Jz, Jplus, Jminus, J2, JzKet
  14. from sympy.physics.quantum.tensorproduct import TensorProduct
  15. from sympy.physics.quantum.state import Ket
  16. from sympy.physics.quantum.density import Density
  17. from sympy.physics.quantum.qubit import Qubit, QubitBra
  18. from sympy.physics.quantum.boson import BosonOp, BosonFockKet, BosonFockBra
  19. j, jp, m, mp = symbols("j j' m m'")
  20. z = JzKet(1, 0)
  21. po = JzKet(1, 1)
  22. mo = JzKet(1, -1)
  23. A = Operator('A')
  24. class Foo(Operator):
  25. def _apply_operator_JzKet(self, ket, **options):
  26. return ket
  27. def test_basic():
  28. assert qapply(Jz*po) == hbar*po
  29. assert qapply(Jx*z) == hbar*po/sqrt(2) + hbar*mo/sqrt(2)
  30. assert qapply((Jplus + Jminus)*z/sqrt(2)) == hbar*po + hbar*mo
  31. assert qapply(Jz*(po + mo)) == hbar*po - hbar*mo
  32. assert qapply(Jz*po + Jz*mo) == hbar*po - hbar*mo
  33. assert qapply(Jminus*Jminus*po) == 2*hbar**2*mo
  34. assert qapply(Jplus**2*mo) == 2*hbar**2*po
  35. assert qapply(Jplus**2*Jminus**2*po) == 4*hbar**4*po
  36. def test_extra():
  37. extra = z.dual*A*z
  38. assert qapply(Jz*po*extra) == hbar*po*extra
  39. assert qapply(Jx*z*extra) == (hbar*po/sqrt(2) + hbar*mo/sqrt(2))*extra
  40. assert qapply(
  41. (Jplus + Jminus)*z/sqrt(2)*extra) == hbar*po*extra + hbar*mo*extra
  42. assert qapply(Jz*(po + mo)*extra) == hbar*po*extra - hbar*mo*extra
  43. assert qapply(Jz*po*extra + Jz*mo*extra) == hbar*po*extra - hbar*mo*extra
  44. assert qapply(Jminus*Jminus*po*extra) == 2*hbar**2*mo*extra
  45. assert qapply(Jplus**2*mo*extra) == 2*hbar**2*po*extra
  46. assert qapply(Jplus**2*Jminus**2*po*extra) == 4*hbar**4*po*extra
  47. def test_innerproduct():
  48. assert qapply(po.dual*Jz*po, ip_doit=False) == hbar*(po.dual*po)
  49. assert qapply(po.dual*Jz*po) == hbar
  50. def test_zero():
  51. assert qapply(0) == 0
  52. assert qapply(Integer(0)) == 0
  53. def test_commutator():
  54. assert qapply(Commutator(Jx, Jy)*Jz*po) == I*hbar**3*po
  55. assert qapply(Commutator(J2, Jz)*Jz*po) == 0
  56. assert qapply(Commutator(Jz, Foo('F'))*po) == 0
  57. assert qapply(Commutator(Foo('F'), Jz)*po) == 0
  58. def test_anticommutator():
  59. assert qapply(AntiCommutator(Jz, Foo('F'))*po) == 2*hbar*po
  60. assert qapply(AntiCommutator(Foo('F'), Jz)*po) == 2*hbar*po
  61. def test_outerproduct():
  62. e = Jz*(mo*po.dual)*Jz*po
  63. assert qapply(e) == -hbar**2*mo
  64. assert qapply(e, ip_doit=False) == -hbar**2*(po.dual*po)*mo
  65. assert qapply(e).doit() == -hbar**2*mo
  66. def test_tensorproduct():
  67. a = BosonOp("a")
  68. b = BosonOp("b")
  69. ket1 = TensorProduct(BosonFockKet(1), BosonFockKet(2))
  70. ket2 = TensorProduct(BosonFockKet(0), BosonFockKet(0))
  71. ket3 = TensorProduct(BosonFockKet(0), BosonFockKet(2))
  72. bra1 = TensorProduct(BosonFockBra(0), BosonFockBra(0))
  73. bra2 = TensorProduct(BosonFockBra(1), BosonFockBra(2))
  74. assert qapply(TensorProduct(a, b ** 2) * ket1) == sqrt(2) * ket2
  75. assert qapply(TensorProduct(a, Dagger(b) * b) * ket1) == 2 * ket3
  76. assert qapply(bra1 * TensorProduct(a, b * b),
  77. dagger=True) == sqrt(2) * bra2
  78. assert qapply(bra2 * ket1).doit() == TensorProduct(1, 1)
  79. assert qapply(TensorProduct(a, b * b) * ket1) == sqrt(2) * ket2
  80. assert qapply(Dagger(TensorProduct(a, b * b) * ket1),
  81. dagger=True) == sqrt(2) * Dagger(ket2)
  82. def test_dagger():
  83. lhs = Dagger(Qubit(0))*Dagger(H(0))
  84. rhs = Dagger(Qubit(1))/sqrt(2) + Dagger(Qubit(0))/sqrt(2)
  85. assert qapply(lhs, dagger=True) == rhs
  86. def test_issue_6073():
  87. x, y = symbols('x y', commutative=False)
  88. A = Ket(x, y)
  89. B = Operator('B')
  90. assert qapply(A) == A
  91. assert qapply(A.dual*B) == A.dual*B
  92. def test_density():
  93. d = Density([Jz*mo, 0.5], [Jz*po, 0.5])
  94. assert qapply(d) == Density([-hbar*mo, 0.5], [hbar*po, 0.5])
  95. def test_issue3044():
  96. expr1 = TensorProduct(Jz*JzKet(S(2),S.NegativeOne)/sqrt(2), Jz*JzKet(S.Half,S.Half))
  97. result = Mul(S.NegativeOne, Rational(1, 4), 2**S.Half, hbar**2)
  98. result *= TensorProduct(JzKet(2,-1), JzKet(S.Half,S.Half))
  99. assert qapply(expr1) == result
  100. # Issue 24158: Tests whether qapply incorrectly evaluates some ket*op as op*ket
  101. def test_issue24158_ket_times_op():
  102. P = BosonFockKet(0) * BosonOp("a") # undefined term
  103. # Does lhs._apply_operator_BosonOp(rhs) still evaluate ket*op as op*ket?
  104. assert qapply(P) == P # qapply(P) -> BosonOp("a")*BosonFockKet(0) = 0 before fix
  105. P = Qubit(1) * XGate(0) # undefined term
  106. # Does rhs._apply_operator_Qubit(lhs) still evaluate ket*op as op*ket?
  107. assert qapply(P) == P # qapply(P) -> Qubit(0) before fix
  108. P1 = Mul(QubitBra(0), Mul(QubitBra(0), Qubit(0)), XGate(0)) # legal expr <0| * (<1|*|1>) * X
  109. assert qapply(P1) == QubitBra(0) * XGate(0) # qapply(P1) -> 0 before fix
  110. P1 = qapply(P1, dagger = True) # unsatisfactorily -> <0|*X(0), expect <1| since dagger=True
  111. assert qapply(P1, dagger = True) == QubitBra(1) # qapply(P1, dagger=True) -> 0 before fix
  112. P2 = QubitBra(0) * QubitBra(0) * Qubit(0) * XGate(0) # 'forgot' to set brackets
  113. P2 = qapply(P2, dagger = True) # unsatisfactorily -> <0|*X(0), expect <1| since dagger=True
  114. assert qapply(P2, dagger = True) == QubitBra(1) # qapply(P1) -> 0 before fix
  115. # Pull Request 24237: IdentityOperator from the right without dagger=True option
  116. assert qapply(QubitBra(1)*IdentityOperator()) == QubitBra(1)
  117. assert qapply(IdentityGate(0)*(Qubit(0) + Qubit(1))) == Qubit(0) + Qubit(1)