Spaces:
Running
Running
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) | |