151 lines
5.9 KiB
Python
151 lines
5.9 KiB
Python
|
from sympy.core.mul import Mul
|
||
|
from sympy.core.numbers import (I, Integer, Rational)
|
||
|
from sympy.core.singleton import S
|
||
|
from sympy.core.symbol import symbols
|
||
|
from sympy.functions.elementary.miscellaneous import sqrt
|
||
|
|
||
|
from sympy.physics.quantum.anticommutator import AntiCommutator
|
||
|
from sympy.physics.quantum.commutator import Commutator
|
||
|
from sympy.physics.quantum.constants import hbar
|
||
|
from sympy.physics.quantum.dagger import Dagger
|
||
|
from sympy.physics.quantum.gate import H, XGate, IdentityGate
|
||
|
from sympy.physics.quantum.operator import Operator, IdentityOperator
|
||
|
from sympy.physics.quantum.qapply import qapply
|
||
|
from sympy.physics.quantum.spin import Jx, Jy, Jz, Jplus, Jminus, J2, JzKet
|
||
|
from sympy.physics.quantum.tensorproduct import TensorProduct
|
||
|
from sympy.physics.quantum.state import Ket
|
||
|
from sympy.physics.quantum.density import Density
|
||
|
from sympy.physics.quantum.qubit import Qubit, QubitBra
|
||
|
from sympy.physics.quantum.boson import BosonOp, BosonFockKet, BosonFockBra
|
||
|
|
||
|
|
||
|
j, jp, m, mp = symbols("j j' m m'")
|
||
|
|
||
|
z = JzKet(1, 0)
|
||
|
po = JzKet(1, 1)
|
||
|
mo = JzKet(1, -1)
|
||
|
|
||
|
A = Operator('A')
|
||
|
|
||
|
|
||
|
class Foo(Operator):
|
||
|
def _apply_operator_JzKet(self, ket, **options):
|
||
|
return ket
|
||
|
|
||
|
|
||
|
def test_basic():
|
||
|
assert qapply(Jz*po) == hbar*po
|
||
|
assert qapply(Jx*z) == hbar*po/sqrt(2) + hbar*mo/sqrt(2)
|
||
|
assert qapply((Jplus + Jminus)*z/sqrt(2)) == hbar*po + hbar*mo
|
||
|
assert qapply(Jz*(po + mo)) == hbar*po - hbar*mo
|
||
|
assert qapply(Jz*po + Jz*mo) == hbar*po - hbar*mo
|
||
|
assert qapply(Jminus*Jminus*po) == 2*hbar**2*mo
|
||
|
assert qapply(Jplus**2*mo) == 2*hbar**2*po
|
||
|
assert qapply(Jplus**2*Jminus**2*po) == 4*hbar**4*po
|
||
|
|
||
|
|
||
|
def test_extra():
|
||
|
extra = z.dual*A*z
|
||
|
assert qapply(Jz*po*extra) == hbar*po*extra
|
||
|
assert qapply(Jx*z*extra) == (hbar*po/sqrt(2) + hbar*mo/sqrt(2))*extra
|
||
|
assert qapply(
|
||
|
(Jplus + Jminus)*z/sqrt(2)*extra) == hbar*po*extra + hbar*mo*extra
|
||
|
assert qapply(Jz*(po + mo)*extra) == hbar*po*extra - hbar*mo*extra
|
||
|
assert qapply(Jz*po*extra + Jz*mo*extra) == hbar*po*extra - hbar*mo*extra
|
||
|
assert qapply(Jminus*Jminus*po*extra) == 2*hbar**2*mo*extra
|
||
|
assert qapply(Jplus**2*mo*extra) == 2*hbar**2*po*extra
|
||
|
assert qapply(Jplus**2*Jminus**2*po*extra) == 4*hbar**4*po*extra
|
||
|
|
||
|
|
||
|
def test_innerproduct():
|
||
|
assert qapply(po.dual*Jz*po, ip_doit=False) == hbar*(po.dual*po)
|
||
|
assert qapply(po.dual*Jz*po) == hbar
|
||
|
|
||
|
|
||
|
def test_zero():
|
||
|
assert qapply(0) == 0
|
||
|
assert qapply(Integer(0)) == 0
|
||
|
|
||
|
|
||
|
def test_commutator():
|
||
|
assert qapply(Commutator(Jx, Jy)*Jz*po) == I*hbar**3*po
|
||
|
assert qapply(Commutator(J2, Jz)*Jz*po) == 0
|
||
|
assert qapply(Commutator(Jz, Foo('F'))*po) == 0
|
||
|
assert qapply(Commutator(Foo('F'), Jz)*po) == 0
|
||
|
|
||
|
|
||
|
def test_anticommutator():
|
||
|
assert qapply(AntiCommutator(Jz, Foo('F'))*po) == 2*hbar*po
|
||
|
assert qapply(AntiCommutator(Foo('F'), Jz)*po) == 2*hbar*po
|
||
|
|
||
|
|
||
|
def test_outerproduct():
|
||
|
e = Jz*(mo*po.dual)*Jz*po
|
||
|
assert qapply(e) == -hbar**2*mo
|
||
|
assert qapply(e, ip_doit=False) == -hbar**2*(po.dual*po)*mo
|
||
|
assert qapply(e).doit() == -hbar**2*mo
|
||
|
|
||
|
|
||
|
def test_tensorproduct():
|
||
|
a = BosonOp("a")
|
||
|
b = BosonOp("b")
|
||
|
ket1 = TensorProduct(BosonFockKet(1), BosonFockKet(2))
|
||
|
ket2 = TensorProduct(BosonFockKet(0), BosonFockKet(0))
|
||
|
ket3 = TensorProduct(BosonFockKet(0), BosonFockKet(2))
|
||
|
bra1 = TensorProduct(BosonFockBra(0), BosonFockBra(0))
|
||
|
bra2 = TensorProduct(BosonFockBra(1), BosonFockBra(2))
|
||
|
assert qapply(TensorProduct(a, b ** 2) * ket1) == sqrt(2) * ket2
|
||
|
assert qapply(TensorProduct(a, Dagger(b) * b) * ket1) == 2 * ket3
|
||
|
assert qapply(bra1 * TensorProduct(a, b * b),
|
||
|
dagger=True) == sqrt(2) * bra2
|
||
|
assert qapply(bra2 * ket1).doit() == TensorProduct(1, 1)
|
||
|
assert qapply(TensorProduct(a, b * b) * ket1) == sqrt(2) * ket2
|
||
|
assert qapply(Dagger(TensorProduct(a, b * b) * ket1),
|
||
|
dagger=True) == sqrt(2) * Dagger(ket2)
|
||
|
|
||
|
|
||
|
def test_dagger():
|
||
|
lhs = Dagger(Qubit(0))*Dagger(H(0))
|
||
|
rhs = Dagger(Qubit(1))/sqrt(2) + Dagger(Qubit(0))/sqrt(2)
|
||
|
assert qapply(lhs, dagger=True) == rhs
|
||
|
|
||
|
|
||
|
def test_issue_6073():
|
||
|
x, y = symbols('x y', commutative=False)
|
||
|
A = Ket(x, y)
|
||
|
B = Operator('B')
|
||
|
assert qapply(A) == A
|
||
|
assert qapply(A.dual*B) == A.dual*B
|
||
|
|
||
|
|
||
|
def test_density():
|
||
|
d = Density([Jz*mo, 0.5], [Jz*po, 0.5])
|
||
|
assert qapply(d) == Density([-hbar*mo, 0.5], [hbar*po, 0.5])
|
||
|
|
||
|
|
||
|
def test_issue3044():
|
||
|
expr1 = TensorProduct(Jz*JzKet(S(2),S.NegativeOne)/sqrt(2), Jz*JzKet(S.Half,S.Half))
|
||
|
result = Mul(S.NegativeOne, Rational(1, 4), 2**S.Half, hbar**2)
|
||
|
result *= TensorProduct(JzKet(2,-1), JzKet(S.Half,S.Half))
|
||
|
assert qapply(expr1) == result
|
||
|
|
||
|
|
||
|
# Issue 24158: Tests whether qapply incorrectly evaluates some ket*op as op*ket
|
||
|
def test_issue24158_ket_times_op():
|
||
|
P = BosonFockKet(0) * BosonOp("a") # undefined term
|
||
|
# Does lhs._apply_operator_BosonOp(rhs) still evaluate ket*op as op*ket?
|
||
|
assert qapply(P) == P # qapply(P) -> BosonOp("a")*BosonFockKet(0) = 0 before fix
|
||
|
P = Qubit(1) * XGate(0) # undefined term
|
||
|
# Does rhs._apply_operator_Qubit(lhs) still evaluate ket*op as op*ket?
|
||
|
assert qapply(P) == P # qapply(P) -> Qubit(0) before fix
|
||
|
P1 = Mul(QubitBra(0), Mul(QubitBra(0), Qubit(0)), XGate(0)) # legal expr <0| * (<1|*|1>) * X
|
||
|
assert qapply(P1) == QubitBra(0) * XGate(0) # qapply(P1) -> 0 before fix
|
||
|
P1 = qapply(P1, dagger = True) # unsatisfactorily -> <0|*X(0), expect <1| since dagger=True
|
||
|
assert qapply(P1, dagger = True) == QubitBra(1) # qapply(P1, dagger=True) -> 0 before fix
|
||
|
P2 = QubitBra(0) * QubitBra(0) * Qubit(0) * XGate(0) # 'forgot' to set brackets
|
||
|
P2 = qapply(P2, dagger = True) # unsatisfactorily -> <0|*X(0), expect <1| since dagger=True
|
||
|
assert qapply(P2, dagger = True) == QubitBra(1) # qapply(P1) -> 0 before fix
|
||
|
# Pull Request 24237: IdentityOperator from the right without dagger=True option
|
||
|
assert qapply(QubitBra(1)*IdentityOperator()) == QubitBra(1)
|
||
|
assert qapply(IdentityGate(0)*(Qubit(0) + Qubit(1))) == Qubit(0) + Qubit(1)
|