add read me
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,56 @@
|
||||
from sympy.core.numbers import Integer
|
||||
from sympy.core.symbol import symbols
|
||||
|
||||
from sympy.physics.quantum.dagger import Dagger
|
||||
from sympy.physics.quantum.anticommutator import AntiCommutator as AComm
|
||||
from sympy.physics.quantum.operator import Operator
|
||||
|
||||
|
||||
a, b, c = symbols('a,b,c')
|
||||
A, B, C, D = symbols('A,B,C,D', commutative=False)
|
||||
|
||||
|
||||
def test_anticommutator():
|
||||
ac = AComm(A, B)
|
||||
assert isinstance(ac, AComm)
|
||||
assert ac.is_commutative is False
|
||||
assert ac.subs(A, C) == AComm(C, B)
|
||||
|
||||
|
||||
def test_commutator_identities():
|
||||
assert AComm(a*A, b*B) == a*b*AComm(A, B)
|
||||
assert AComm(A, A) == 2*A**2
|
||||
assert AComm(A, B) == AComm(B, A)
|
||||
assert AComm(a, b) == 2*a*b
|
||||
assert AComm(A, B).doit() == A*B + B*A
|
||||
|
||||
|
||||
def test_anticommutator_dagger():
|
||||
assert Dagger(AComm(A, B)) == AComm(Dagger(A), Dagger(B))
|
||||
|
||||
|
||||
class Foo(Operator):
|
||||
|
||||
def _eval_anticommutator_Bar(self, bar):
|
||||
return Integer(0)
|
||||
|
||||
|
||||
class Bar(Operator):
|
||||
pass
|
||||
|
||||
|
||||
class Tam(Operator):
|
||||
|
||||
def _eval_anticommutator_Foo(self, foo):
|
||||
return Integer(1)
|
||||
|
||||
|
||||
def test_eval_commutator():
|
||||
F = Foo('F')
|
||||
B = Bar('B')
|
||||
T = Tam('T')
|
||||
assert AComm(F, B).doit() == 0
|
||||
assert AComm(B, F).doit() == 0
|
||||
assert AComm(F, T).doit() == 1
|
||||
assert AComm(T, F).doit() == 1
|
||||
assert AComm(B, T).doit() == B*T + T*B
|
||||
@@ -0,0 +1,50 @@
|
||||
from math import prod
|
||||
|
||||
from sympy.core.numbers import Rational
|
||||
from sympy.functions.elementary.exponential import exp
|
||||
from sympy.functions.elementary.miscellaneous import sqrt
|
||||
from sympy.physics.quantum import Dagger, Commutator, qapply
|
||||
from sympy.physics.quantum.boson import BosonOp
|
||||
from sympy.physics.quantum.boson import (
|
||||
BosonFockKet, BosonFockBra, BosonCoherentKet, BosonCoherentBra)
|
||||
|
||||
|
||||
def test_bosonoperator():
|
||||
a = BosonOp('a')
|
||||
b = BosonOp('b')
|
||||
|
||||
assert isinstance(a, BosonOp)
|
||||
assert isinstance(Dagger(a), BosonOp)
|
||||
|
||||
assert a.is_annihilation
|
||||
assert not Dagger(a).is_annihilation
|
||||
|
||||
assert BosonOp("a") == BosonOp("a", True)
|
||||
assert BosonOp("a") != BosonOp("c")
|
||||
assert BosonOp("a", True) != BosonOp("a", False)
|
||||
|
||||
assert Commutator(a, Dagger(a)).doit() == 1
|
||||
|
||||
assert Commutator(a, Dagger(b)).doit() == a * Dagger(b) - Dagger(b) * a
|
||||
|
||||
assert Dagger(exp(a)) == exp(Dagger(a))
|
||||
|
||||
|
||||
def test_boson_states():
|
||||
a = BosonOp("a")
|
||||
|
||||
# Fock states
|
||||
n = 3
|
||||
assert (BosonFockBra(0) * BosonFockKet(1)).doit() == 0
|
||||
assert (BosonFockBra(1) * BosonFockKet(1)).doit() == 1
|
||||
assert qapply(BosonFockBra(n) * Dagger(a)**n * BosonFockKet(0)) \
|
||||
== sqrt(prod(range(1, n+1)))
|
||||
|
||||
# Coherent states
|
||||
alpha1, alpha2 = 1.2, 4.3
|
||||
assert (BosonCoherentBra(alpha1) * BosonCoherentKet(alpha1)).doit() == 1
|
||||
assert (BosonCoherentBra(alpha2) * BosonCoherentKet(alpha2)).doit() == 1
|
||||
assert abs((BosonCoherentBra(alpha1) * BosonCoherentKet(alpha2)).doit() -
|
||||
exp((alpha1 - alpha2) ** 2 * Rational(-1, 2))) < 1e-12
|
||||
assert qapply(a * BosonCoherentKet(alpha1)) == \
|
||||
alpha1 * BosonCoherentKet(alpha1)
|
||||
@@ -0,0 +1,113 @@
|
||||
"""Tests for cartesian.py"""
|
||||
|
||||
from sympy.core.numbers import (I, pi)
|
||||
from sympy.core.singleton import S
|
||||
from sympy.core.symbol import symbols
|
||||
from sympy.functions.elementary.exponential import exp
|
||||
from sympy.functions.elementary.miscellaneous import sqrt
|
||||
from sympy.functions.special.delta_functions import DiracDelta
|
||||
from sympy.sets.sets import Interval
|
||||
from sympy.testing.pytest import XFAIL
|
||||
|
||||
from sympy.physics.quantum import qapply, represent, L2, Dagger
|
||||
from sympy.physics.quantum import Commutator, hbar
|
||||
from sympy.physics.quantum.cartesian import (
|
||||
XOp, YOp, ZOp, PxOp, X, Y, Z, Px, XKet, XBra, PxKet, PxBra,
|
||||
PositionKet3D, PositionBra3D
|
||||
)
|
||||
from sympy.physics.quantum.operator import DifferentialOperator
|
||||
|
||||
x, y, z, x_1, x_2, x_3, y_1, z_1 = symbols('x,y,z,x_1,x_2,x_3,y_1,z_1')
|
||||
px, py, px_1, px_2 = symbols('px py px_1 px_2')
|
||||
|
||||
|
||||
def test_x():
|
||||
assert X.hilbert_space == L2(Interval(S.NegativeInfinity, S.Infinity))
|
||||
assert Commutator(X, Px).doit() == I*hbar
|
||||
assert qapply(X*XKet(x)) == x*XKet(x)
|
||||
assert XKet(x).dual_class() == XBra
|
||||
assert XBra(x).dual_class() == XKet
|
||||
assert (Dagger(XKet(y))*XKet(x)).doit() == DiracDelta(x - y)
|
||||
assert (PxBra(px)*XKet(x)).doit() == \
|
||||
exp(-I*x*px/hbar)/sqrt(2*pi*hbar)
|
||||
assert represent(XKet(x)) == DiracDelta(x - x_1)
|
||||
assert represent(XBra(x)) == DiracDelta(-x + x_1)
|
||||
assert XBra(x).position == x
|
||||
assert represent(XOp()*XKet()) == x*DiracDelta(x - x_2)
|
||||
assert represent(XBra("y")*XKet()) == DiracDelta(x - y)
|
||||
assert represent(
|
||||
XKet()*XBra()) == DiracDelta(x - x_2) * DiracDelta(x_1 - x)
|
||||
|
||||
rep_p = represent(XOp(), basis=PxOp)
|
||||
assert rep_p == hbar*I*DiracDelta(px_1 - px_2)*DifferentialOperator(px_1)
|
||||
assert rep_p == represent(XOp(), basis=PxOp())
|
||||
assert rep_p == represent(XOp(), basis=PxKet)
|
||||
assert rep_p == represent(XOp(), basis=PxKet())
|
||||
|
||||
assert represent(XOp()*PxKet(), basis=PxKet) == \
|
||||
hbar*I*DiracDelta(px - px_2)*DifferentialOperator(px)
|
||||
|
||||
|
||||
@XFAIL
|
||||
def _text_x_broken():
|
||||
# represent has some broken logic that is relying in particular
|
||||
# forms of input, rather than a full and proper handling of
|
||||
# all valid quantum expressions. Marking this test as XFAIL until
|
||||
# we can refactor represent.
|
||||
assert represent(XOp()*XKet()*XBra('y')) == \
|
||||
x*DiracDelta(x - x_3)*DiracDelta(x_1 - y)
|
||||
|
||||
|
||||
def test_p():
|
||||
assert Px.hilbert_space == L2(Interval(S.NegativeInfinity, S.Infinity))
|
||||
assert qapply(Px*PxKet(px)) == px*PxKet(px)
|
||||
assert PxKet(px).dual_class() == PxBra
|
||||
assert PxBra(x).dual_class() == PxKet
|
||||
assert (Dagger(PxKet(py))*PxKet(px)).doit() == DiracDelta(px - py)
|
||||
assert (XBra(x)*PxKet(px)).doit() == \
|
||||
exp(I*x*px/hbar)/sqrt(2*pi*hbar)
|
||||
assert represent(PxKet(px)) == DiracDelta(px - px_1)
|
||||
|
||||
rep_x = represent(PxOp(), basis=XOp)
|
||||
assert rep_x == -hbar*I*DiracDelta(x_1 - x_2)*DifferentialOperator(x_1)
|
||||
assert rep_x == represent(PxOp(), basis=XOp())
|
||||
assert rep_x == represent(PxOp(), basis=XKet)
|
||||
assert rep_x == represent(PxOp(), basis=XKet())
|
||||
|
||||
assert represent(PxOp()*XKet(), basis=XKet) == \
|
||||
-hbar*I*DiracDelta(x - x_2)*DifferentialOperator(x)
|
||||
assert represent(XBra("y")*PxOp()*XKet(), basis=XKet) == \
|
||||
-hbar*I*DiracDelta(x - y)*DifferentialOperator(x)
|
||||
|
||||
|
||||
def test_3dpos():
|
||||
assert Y.hilbert_space == L2(Interval(S.NegativeInfinity, S.Infinity))
|
||||
assert Z.hilbert_space == L2(Interval(S.NegativeInfinity, S.Infinity))
|
||||
|
||||
test_ket = PositionKet3D(x, y, z)
|
||||
assert qapply(X*test_ket) == x*test_ket
|
||||
assert qapply(Y*test_ket) == y*test_ket
|
||||
assert qapply(Z*test_ket) == z*test_ket
|
||||
assert qapply(X*Y*test_ket) == x*y*test_ket
|
||||
assert qapply(X*Y*Z*test_ket) == x*y*z*test_ket
|
||||
assert qapply(Y*Z*test_ket) == y*z*test_ket
|
||||
|
||||
assert PositionKet3D() == test_ket
|
||||
assert YOp() == Y
|
||||
assert ZOp() == Z
|
||||
|
||||
assert PositionKet3D.dual_class() == PositionBra3D
|
||||
assert PositionBra3D.dual_class() == PositionKet3D
|
||||
|
||||
other_ket = PositionKet3D(x_1, y_1, z_1)
|
||||
assert (Dagger(other_ket)*test_ket).doit() == \
|
||||
DiracDelta(x - x_1)*DiracDelta(y - y_1)*DiracDelta(z - z_1)
|
||||
|
||||
assert test_ket.position_x == x
|
||||
assert test_ket.position_y == y
|
||||
assert test_ket.position_z == z
|
||||
assert other_ket.position_x == x_1
|
||||
assert other_ket.position_y == y_1
|
||||
assert other_ket.position_z == z_1
|
||||
|
||||
# TODO: Add tests for representations
|
||||
@@ -0,0 +1,183 @@
|
||||
from sympy.concrete.summations import Sum
|
||||
from sympy.core.numbers import Rational
|
||||
from sympy.core.singleton import S
|
||||
from sympy.core.symbol import symbols
|
||||
from sympy.functions.elementary.miscellaneous import sqrt
|
||||
from sympy.physics.quantum.cg import Wigner3j, Wigner6j, Wigner9j, CG, cg_simp
|
||||
from sympy.functions.special.tensor_functions import KroneckerDelta
|
||||
|
||||
|
||||
def test_cg_simp_add():
|
||||
j, m1, m1p, m2, m2p = symbols('j m1 m1p m2 m2p')
|
||||
# Test Varshalovich 8.7.1 Eq 1
|
||||
a = CG(S.Half, S.Half, 0, 0, S.Half, S.Half)
|
||||
b = CG(S.Half, Rational(-1, 2), 0, 0, S.Half, Rational(-1, 2))
|
||||
c = CG(1, 1, 0, 0, 1, 1)
|
||||
d = CG(1, 0, 0, 0, 1, 0)
|
||||
e = CG(1, -1, 0, 0, 1, -1)
|
||||
assert cg_simp(a + b) == 2
|
||||
assert cg_simp(c + d + e) == 3
|
||||
assert cg_simp(a + b + c + d + e) == 5
|
||||
assert cg_simp(a + b + c) == 2 + c
|
||||
assert cg_simp(2*a + b) == 2 + a
|
||||
assert cg_simp(2*c + d + e) == 3 + c
|
||||
assert cg_simp(5*a + 5*b) == 10
|
||||
assert cg_simp(5*c + 5*d + 5*e) == 15
|
||||
assert cg_simp(-a - b) == -2
|
||||
assert cg_simp(-c - d - e) == -3
|
||||
assert cg_simp(-6*a - 6*b) == -12
|
||||
assert cg_simp(-4*c - 4*d - 4*e) == -12
|
||||
a = CG(S.Half, S.Half, j, 0, S.Half, S.Half)
|
||||
b = CG(S.Half, Rational(-1, 2), j, 0, S.Half, Rational(-1, 2))
|
||||
c = CG(1, 1, j, 0, 1, 1)
|
||||
d = CG(1, 0, j, 0, 1, 0)
|
||||
e = CG(1, -1, j, 0, 1, -1)
|
||||
assert cg_simp(a + b) == 2*KroneckerDelta(j, 0)
|
||||
assert cg_simp(c + d + e) == 3*KroneckerDelta(j, 0)
|
||||
assert cg_simp(a + b + c + d + e) == 5*KroneckerDelta(j, 0)
|
||||
assert cg_simp(a + b + c) == 2*KroneckerDelta(j, 0) + c
|
||||
assert cg_simp(2*a + b) == 2*KroneckerDelta(j, 0) + a
|
||||
assert cg_simp(2*c + d + e) == 3*KroneckerDelta(j, 0) + c
|
||||
assert cg_simp(5*a + 5*b) == 10*KroneckerDelta(j, 0)
|
||||
assert cg_simp(5*c + 5*d + 5*e) == 15*KroneckerDelta(j, 0)
|
||||
assert cg_simp(-a - b) == -2*KroneckerDelta(j, 0)
|
||||
assert cg_simp(-c - d - e) == -3*KroneckerDelta(j, 0)
|
||||
assert cg_simp(-6*a - 6*b) == -12*KroneckerDelta(j, 0)
|
||||
assert cg_simp(-4*c - 4*d - 4*e) == -12*KroneckerDelta(j, 0)
|
||||
# Test Varshalovich 8.7.1 Eq 2
|
||||
a = CG(S.Half, S.Half, S.Half, Rational(-1, 2), 0, 0)
|
||||
b = CG(S.Half, Rational(-1, 2), S.Half, S.Half, 0, 0)
|
||||
c = CG(1, 1, 1, -1, 0, 0)
|
||||
d = CG(1, 0, 1, 0, 0, 0)
|
||||
e = CG(1, -1, 1, 1, 0, 0)
|
||||
assert cg_simp(a - b) == sqrt(2)
|
||||
assert cg_simp(c - d + e) == sqrt(3)
|
||||
assert cg_simp(a - b + c - d + e) == sqrt(2) + sqrt(3)
|
||||
assert cg_simp(a - b + c) == sqrt(2) + c
|
||||
assert cg_simp(2*a - b) == sqrt(2) + a
|
||||
assert cg_simp(2*c - d + e) == sqrt(3) + c
|
||||
assert cg_simp(5*a - 5*b) == 5*sqrt(2)
|
||||
assert cg_simp(5*c - 5*d + 5*e) == 5*sqrt(3)
|
||||
assert cg_simp(-a + b) == -sqrt(2)
|
||||
assert cg_simp(-c + d - e) == -sqrt(3)
|
||||
assert cg_simp(-6*a + 6*b) == -6*sqrt(2)
|
||||
assert cg_simp(-4*c + 4*d - 4*e) == -4*sqrt(3)
|
||||
a = CG(S.Half, S.Half, S.Half, Rational(-1, 2), j, 0)
|
||||
b = CG(S.Half, Rational(-1, 2), S.Half, S.Half, j, 0)
|
||||
c = CG(1, 1, 1, -1, j, 0)
|
||||
d = CG(1, 0, 1, 0, j, 0)
|
||||
e = CG(1, -1, 1, 1, j, 0)
|
||||
assert cg_simp(a - b) == sqrt(2)*KroneckerDelta(j, 0)
|
||||
assert cg_simp(c - d + e) == sqrt(3)*KroneckerDelta(j, 0)
|
||||
assert cg_simp(a - b + c - d + e) == sqrt(
|
||||
2)*KroneckerDelta(j, 0) + sqrt(3)*KroneckerDelta(j, 0)
|
||||
assert cg_simp(a - b + c) == sqrt(2)*KroneckerDelta(j, 0) + c
|
||||
assert cg_simp(2*a - b) == sqrt(2)*KroneckerDelta(j, 0) + a
|
||||
assert cg_simp(2*c - d + e) == sqrt(3)*KroneckerDelta(j, 0) + c
|
||||
assert cg_simp(5*a - 5*b) == 5*sqrt(2)*KroneckerDelta(j, 0)
|
||||
assert cg_simp(5*c - 5*d + 5*e) == 5*sqrt(3)*KroneckerDelta(j, 0)
|
||||
assert cg_simp(-a + b) == -sqrt(2)*KroneckerDelta(j, 0)
|
||||
assert cg_simp(-c + d - e) == -sqrt(3)*KroneckerDelta(j, 0)
|
||||
assert cg_simp(-6*a + 6*b) == -6*sqrt(2)*KroneckerDelta(j, 0)
|
||||
assert cg_simp(-4*c + 4*d - 4*e) == -4*sqrt(3)*KroneckerDelta(j, 0)
|
||||
# Test Varshalovich 8.7.2 Eq 9
|
||||
# alpha=alphap,beta=betap case
|
||||
# numerical
|
||||
a = CG(S.Half, S.Half, S.Half, Rational(-1, 2), 1, 0)**2
|
||||
b = CG(S.Half, S.Half, S.Half, Rational(-1, 2), 0, 0)**2
|
||||
c = CG(1, 0, 1, 1, 1, 1)**2
|
||||
d = CG(1, 0, 1, 1, 2, 1)**2
|
||||
assert cg_simp(a + b) == 1
|
||||
assert cg_simp(c + d) == 1
|
||||
assert cg_simp(a + b + c + d) == 2
|
||||
assert cg_simp(4*a + 4*b) == 4
|
||||
assert cg_simp(4*c + 4*d) == 4
|
||||
assert cg_simp(5*a + 3*b) == 3 + 2*a
|
||||
assert cg_simp(5*c + 3*d) == 3 + 2*c
|
||||
assert cg_simp(-a - b) == -1
|
||||
assert cg_simp(-c - d) == -1
|
||||
# symbolic
|
||||
a = CG(S.Half, m1, S.Half, m2, 1, 1)**2
|
||||
b = CG(S.Half, m1, S.Half, m2, 1, 0)**2
|
||||
c = CG(S.Half, m1, S.Half, m2, 1, -1)**2
|
||||
d = CG(S.Half, m1, S.Half, m2, 0, 0)**2
|
||||
assert cg_simp(a + b + c + d) == 1
|
||||
assert cg_simp(4*a + 4*b + 4*c + 4*d) == 4
|
||||
assert cg_simp(3*a + 5*b + 3*c + 4*d) == 3 + 2*b + d
|
||||
assert cg_simp(-a - b - c - d) == -1
|
||||
a = CG(1, m1, 1, m2, 2, 2)**2
|
||||
b = CG(1, m1, 1, m2, 2, 1)**2
|
||||
c = CG(1, m1, 1, m2, 2, 0)**2
|
||||
d = CG(1, m1, 1, m2, 2, -1)**2
|
||||
e = CG(1, m1, 1, m2, 2, -2)**2
|
||||
f = CG(1, m1, 1, m2, 1, 1)**2
|
||||
g = CG(1, m1, 1, m2, 1, 0)**2
|
||||
h = CG(1, m1, 1, m2, 1, -1)**2
|
||||
i = CG(1, m1, 1, m2, 0, 0)**2
|
||||
assert cg_simp(a + b + c + d + e + f + g + h + i) == 1
|
||||
assert cg_simp(4*(a + b + c + d + e + f + g + h + i)) == 4
|
||||
assert cg_simp(a + b + 2*c + d + 4*e + f + g + h + i) == 1 + c + 3*e
|
||||
assert cg_simp(-a - b - c - d - e - f - g - h - i) == -1
|
||||
# alpha!=alphap or beta!=betap case
|
||||
# numerical
|
||||
a = CG(S.Half, S(
|
||||
1)/2, S.Half, Rational(-1, 2), 1, 0)*CG(S.Half, Rational(-1, 2), S.Half, S.Half, 1, 0)
|
||||
b = CG(S.Half, S(
|
||||
1)/2, S.Half, Rational(-1, 2), 0, 0)*CG(S.Half, Rational(-1, 2), S.Half, S.Half, 0, 0)
|
||||
c = CG(1, 1, 1, 0, 2, 1)*CG(1, 0, 1, 1, 2, 1)
|
||||
d = CG(1, 1, 1, 0, 1, 1)*CG(1, 0, 1, 1, 1, 1)
|
||||
assert cg_simp(a + b) == 0
|
||||
assert cg_simp(c + d) == 0
|
||||
# symbolic
|
||||
a = CG(S.Half, m1, S.Half, m2, 1, 1)*CG(S.Half, m1p, S.Half, m2p, 1, 1)
|
||||
b = CG(S.Half, m1, S.Half, m2, 1, 0)*CG(S.Half, m1p, S.Half, m2p, 1, 0)
|
||||
c = CG(S.Half, m1, S.Half, m2, 1, -1)*CG(S.Half, m1p, S.Half, m2p, 1, -1)
|
||||
d = CG(S.Half, m1, S.Half, m2, 0, 0)*CG(S.Half, m1p, S.Half, m2p, 0, 0)
|
||||
assert cg_simp(a + b + c + d) == KroneckerDelta(m1, m1p)*KroneckerDelta(m2, m2p)
|
||||
a = CG(1, m1, 1, m2, 2, 2)*CG(1, m1p, 1, m2p, 2, 2)
|
||||
b = CG(1, m1, 1, m2, 2, 1)*CG(1, m1p, 1, m2p, 2, 1)
|
||||
c = CG(1, m1, 1, m2, 2, 0)*CG(1, m1p, 1, m2p, 2, 0)
|
||||
d = CG(1, m1, 1, m2, 2, -1)*CG(1, m1p, 1, m2p, 2, -1)
|
||||
e = CG(1, m1, 1, m2, 2, -2)*CG(1, m1p, 1, m2p, 2, -2)
|
||||
f = CG(1, m1, 1, m2, 1, 1)*CG(1, m1p, 1, m2p, 1, 1)
|
||||
g = CG(1, m1, 1, m2, 1, 0)*CG(1, m1p, 1, m2p, 1, 0)
|
||||
h = CG(1, m1, 1, m2, 1, -1)*CG(1, m1p, 1, m2p, 1, -1)
|
||||
i = CG(1, m1, 1, m2, 0, 0)*CG(1, m1p, 1, m2p, 0, 0)
|
||||
assert cg_simp(
|
||||
a + b + c + d + e + f + g + h + i) == KroneckerDelta(m1, m1p)*KroneckerDelta(m2, m2p)
|
||||
|
||||
|
||||
def test_cg_simp_sum():
|
||||
x, a, b, c, cp, alpha, beta, gamma, gammap = symbols(
|
||||
'x a b c cp alpha beta gamma gammap')
|
||||
# Varshalovich 8.7.1 Eq 1
|
||||
assert cg_simp(x * Sum(CG(a, alpha, b, 0, a, alpha), (alpha, -a, a)
|
||||
)) == x*(2*a + 1)*KroneckerDelta(b, 0)
|
||||
assert cg_simp(x * Sum(CG(a, alpha, b, 0, a, alpha), (alpha, -a, a)) + CG(1, 0, 1, 0, 1, 0)) == x*(2*a + 1)*KroneckerDelta(b, 0) + CG(1, 0, 1, 0, 1, 0)
|
||||
assert cg_simp(2 * Sum(CG(1, alpha, 0, 0, 1, alpha), (alpha, -1, 1))) == 6
|
||||
# Varshalovich 8.7.1 Eq 2
|
||||
assert cg_simp(x*Sum((-1)**(a - alpha) * CG(a, alpha, a, -alpha, c,
|
||||
0), (alpha, -a, a))) == x*sqrt(2*a + 1)*KroneckerDelta(c, 0)
|
||||
assert cg_simp(3*Sum((-1)**(2 - alpha) * CG(
|
||||
2, alpha, 2, -alpha, 0, 0), (alpha, -2, 2))) == 3*sqrt(5)
|
||||
# Varshalovich 8.7.2 Eq 4
|
||||
assert cg_simp(Sum(CG(a, alpha, b, beta, c, gamma)*CG(a, alpha, b, beta, cp, gammap), (alpha, -a, a), (beta, -b, b))) == KroneckerDelta(c, cp)*KroneckerDelta(gamma, gammap)
|
||||
assert cg_simp(Sum(CG(a, alpha, b, beta, c, gamma)*CG(a, alpha, b, beta, c, gammap), (alpha, -a, a), (beta, -b, b))) == KroneckerDelta(gamma, gammap)
|
||||
assert cg_simp(Sum(CG(a, alpha, b, beta, c, gamma)*CG(a, alpha, b, beta, cp, gamma), (alpha, -a, a), (beta, -b, b))) == KroneckerDelta(c, cp)
|
||||
assert cg_simp(Sum(CG(
|
||||
a, alpha, b, beta, c, gamma)**2, (alpha, -a, a), (beta, -b, b))) == 1
|
||||
assert cg_simp(Sum(CG(2, alpha, 1, beta, 2, gamma)*CG(2, alpha, 1, beta, 2, gammap), (alpha, -2, 2), (beta, -1, 1))) == KroneckerDelta(gamma, gammap)
|
||||
|
||||
|
||||
def test_doit():
|
||||
assert Wigner3j(S.Half, Rational(-1, 2), S.Half, S.Half, 0, 0).doit() == -sqrt(2)/2
|
||||
assert Wigner3j(1/2,1/2,1/2,1/2,1/2,1/2).doit() == 0
|
||||
assert Wigner3j(9/2,9/2,9/2,9/2,9/2,9/2).doit() == 0
|
||||
assert Wigner6j(1, 2, 3, 2, 1, 2).doit() == sqrt(21)/105
|
||||
assert Wigner6j(3, 1, 2, 2, 2, 1).doit() == sqrt(21) / 105
|
||||
assert Wigner9j(
|
||||
2, 1, 1, Rational(3, 2), S.Half, 1, S.Half, S.Half, 0).doit() == sqrt(2)/12
|
||||
assert CG(S.Half, S.Half, S.Half, Rational(-1, 2), 1, 0).doit() == sqrt(2)/2
|
||||
# J minus M is not integer
|
||||
assert Wigner3j(1, -1, S.Half, S.Half, 1, S.Half).doit() == 0
|
||||
assert CG(4, -1, S.Half, S.Half, 4, Rational(-1, 2)).doit() == 0
|
||||
@@ -0,0 +1,69 @@
|
||||
from sympy.physics.quantum.circuitplot import labeller, render_label, Mz, CreateOneQubitGate,\
|
||||
CreateCGate
|
||||
from sympy.physics.quantum.gate import CNOT, H, SWAP, CGate, S, T
|
||||
from sympy.external import import_module
|
||||
from sympy.testing.pytest import skip
|
||||
|
||||
mpl = import_module('matplotlib')
|
||||
|
||||
def test_render_label():
|
||||
assert render_label('q0') == r'$\left|q0\right\rangle$'
|
||||
assert render_label('q0', {'q0': '0'}) == r'$\left|q0\right\rangle=\left|0\right\rangle$'
|
||||
|
||||
def test_Mz():
|
||||
assert str(Mz(0)) == 'Mz(0)'
|
||||
|
||||
def test_create1():
|
||||
Qgate = CreateOneQubitGate('Q')
|
||||
assert str(Qgate(0)) == 'Q(0)'
|
||||
|
||||
def test_createc():
|
||||
Qgate = CreateCGate('Q')
|
||||
assert str(Qgate([1],0)) == 'C((1),Q(0))'
|
||||
|
||||
def test_labeller():
|
||||
"""Test the labeller utility"""
|
||||
assert labeller(2) == ['q_1', 'q_0']
|
||||
assert labeller(3,'j') == ['j_2', 'j_1', 'j_0']
|
||||
|
||||
def test_cnot():
|
||||
"""Test a simple cnot circuit. Right now this only makes sure the code doesn't
|
||||
raise an exception, and some simple properties
|
||||
"""
|
||||
if not mpl:
|
||||
skip("matplotlib not installed")
|
||||
else:
|
||||
from sympy.physics.quantum.circuitplot import CircuitPlot
|
||||
|
||||
c = CircuitPlot(CNOT(1,0),2,labels=labeller(2))
|
||||
assert c.ngates == 2
|
||||
assert c.nqubits == 2
|
||||
assert c.labels == ['q_1', 'q_0']
|
||||
|
||||
c = CircuitPlot(CNOT(1,0),2)
|
||||
assert c.ngates == 2
|
||||
assert c.nqubits == 2
|
||||
assert c.labels == []
|
||||
|
||||
def test_ex1():
|
||||
if not mpl:
|
||||
skip("matplotlib not installed")
|
||||
else:
|
||||
from sympy.physics.quantum.circuitplot import CircuitPlot
|
||||
|
||||
c = CircuitPlot(CNOT(1,0)*H(1),2,labels=labeller(2))
|
||||
assert c.ngates == 2
|
||||
assert c.nqubits == 2
|
||||
assert c.labels == ['q_1', 'q_0']
|
||||
|
||||
def test_ex4():
|
||||
if not mpl:
|
||||
skip("matplotlib not installed")
|
||||
else:
|
||||
from sympy.physics.quantum.circuitplot import CircuitPlot
|
||||
|
||||
c = CircuitPlot(SWAP(0,2)*H(0)* CGate((0,),S(1)) *H(1)*CGate((0,),T(2))\
|
||||
*CGate((1,),S(2))*H(2),3,labels=labeller(3,'j'))
|
||||
assert c.ngates == 7
|
||||
assert c.nqubits == 3
|
||||
assert c.labels == ['j_2', 'j_1', 'j_0']
|
||||
@@ -0,0 +1,402 @@
|
||||
from sympy.core.mul import Mul
|
||||
from sympy.core.numbers import Integer
|
||||
from sympy.core.symbol import Symbol
|
||||
from sympy.utilities import numbered_symbols
|
||||
from sympy.physics.quantum.gate import X, Y, Z, H, CNOT, CGate
|
||||
from sympy.physics.quantum.identitysearch import bfs_identity_search
|
||||
from sympy.physics.quantum.circuitutils import (kmp_table, find_subcircuit,
|
||||
replace_subcircuit, convert_to_symbolic_indices,
|
||||
convert_to_real_indices, random_reduce, random_insert,
|
||||
flatten_ids)
|
||||
from sympy.testing.pytest import slow
|
||||
|
||||
|
||||
def create_gate_sequence(qubit=0):
|
||||
gates = (X(qubit), Y(qubit), Z(qubit), H(qubit))
|
||||
return gates
|
||||
|
||||
|
||||
def test_kmp_table():
|
||||
word = ('a', 'b', 'c', 'd', 'a', 'b', 'd')
|
||||
expected_table = [-1, 0, 0, 0, 0, 1, 2]
|
||||
assert expected_table == kmp_table(word)
|
||||
|
||||
word = ('P', 'A', 'R', 'T', 'I', 'C', 'I', 'P', 'A', 'T', 'E', ' ',
|
||||
'I', 'N', ' ', 'P', 'A', 'R', 'A', 'C', 'H', 'U', 'T', 'E')
|
||||
expected_table = [-1, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0,
|
||||
0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0]
|
||||
assert expected_table == kmp_table(word)
|
||||
|
||||
x = X(0)
|
||||
y = Y(0)
|
||||
z = Z(0)
|
||||
h = H(0)
|
||||
word = (x, y, y, x, z)
|
||||
expected_table = [-1, 0, 0, 0, 1]
|
||||
assert expected_table == kmp_table(word)
|
||||
|
||||
word = (x, x, y, h, z)
|
||||
expected_table = [-1, 0, 1, 0, 0]
|
||||
assert expected_table == kmp_table(word)
|
||||
|
||||
|
||||
def test_find_subcircuit():
|
||||
x = X(0)
|
||||
y = Y(0)
|
||||
z = Z(0)
|
||||
h = H(0)
|
||||
x1 = X(1)
|
||||
y1 = Y(1)
|
||||
|
||||
i0 = Symbol('i0')
|
||||
x_i0 = X(i0)
|
||||
y_i0 = Y(i0)
|
||||
z_i0 = Z(i0)
|
||||
h_i0 = H(i0)
|
||||
|
||||
circuit = (x, y, z)
|
||||
|
||||
assert find_subcircuit(circuit, (x,)) == 0
|
||||
assert find_subcircuit(circuit, (x1,)) == -1
|
||||
assert find_subcircuit(circuit, (y,)) == 1
|
||||
assert find_subcircuit(circuit, (h,)) == -1
|
||||
assert find_subcircuit(circuit, Mul(x, h)) == -1
|
||||
assert find_subcircuit(circuit, Mul(x, y, z)) == 0
|
||||
assert find_subcircuit(circuit, Mul(y, z)) == 1
|
||||
assert find_subcircuit(Mul(*circuit), (x, y, z, h)) == -1
|
||||
assert find_subcircuit(Mul(*circuit), (z, y, x)) == -1
|
||||
assert find_subcircuit(circuit, (x,), start=2, end=1) == -1
|
||||
|
||||
circuit = (x, y, x, y, z)
|
||||
assert find_subcircuit(Mul(*circuit), Mul(x, y, z)) == 2
|
||||
assert find_subcircuit(circuit, (x,), start=1) == 2
|
||||
assert find_subcircuit(circuit, (x, y), start=1, end=2) == -1
|
||||
assert find_subcircuit(Mul(*circuit), (x, y), start=1, end=3) == -1
|
||||
assert find_subcircuit(circuit, (x, y), start=1, end=4) == 2
|
||||
assert find_subcircuit(circuit, (x, y), start=2, end=4) == 2
|
||||
|
||||
circuit = (x, y, z, x1, x, y, z, h, x, y, x1,
|
||||
x, y, z, h, y1, h)
|
||||
assert find_subcircuit(circuit, (x, y, z, h, y1)) == 11
|
||||
|
||||
circuit = (x, y, x_i0, y_i0, z_i0, z)
|
||||
assert find_subcircuit(circuit, (x_i0, y_i0, z_i0)) == 2
|
||||
|
||||
circuit = (x_i0, y_i0, z_i0, x_i0, y_i0, h_i0)
|
||||
subcircuit = (x_i0, y_i0, z_i0)
|
||||
result = find_subcircuit(circuit, subcircuit)
|
||||
assert result == 0
|
||||
|
||||
|
||||
def test_replace_subcircuit():
|
||||
x = X(0)
|
||||
y = Y(0)
|
||||
z = Z(0)
|
||||
h = H(0)
|
||||
cnot = CNOT(1, 0)
|
||||
cgate_z = CGate((0,), Z(1))
|
||||
|
||||
# Standard cases
|
||||
circuit = (z, y, x, x)
|
||||
remove = (z, y, x)
|
||||
assert replace_subcircuit(circuit, Mul(*remove)) == (x,)
|
||||
assert replace_subcircuit(circuit, remove + (x,)) == ()
|
||||
assert replace_subcircuit(circuit, remove, pos=1) == circuit
|
||||
assert replace_subcircuit(circuit, remove, pos=0) == (x,)
|
||||
assert replace_subcircuit(circuit, (x, x), pos=2) == (z, y)
|
||||
assert replace_subcircuit(circuit, (h,)) == circuit
|
||||
|
||||
circuit = (x, y, x, y, z)
|
||||
remove = (x, y, z)
|
||||
assert replace_subcircuit(Mul(*circuit), Mul(*remove)) == (x, y)
|
||||
remove = (x, y, x, y)
|
||||
assert replace_subcircuit(circuit, remove) == (z,)
|
||||
|
||||
circuit = (x, h, cgate_z, h, cnot)
|
||||
remove = (x, h, cgate_z)
|
||||
assert replace_subcircuit(circuit, Mul(*remove), pos=-1) == (h, cnot)
|
||||
assert replace_subcircuit(circuit, remove, pos=1) == circuit
|
||||
remove = (h, h)
|
||||
assert replace_subcircuit(circuit, remove) == circuit
|
||||
remove = (h, cgate_z, h, cnot)
|
||||
assert replace_subcircuit(circuit, remove) == (x,)
|
||||
|
||||
replace = (h, x)
|
||||
actual = replace_subcircuit(circuit, remove,
|
||||
replace=replace)
|
||||
assert actual == (x, h, x)
|
||||
|
||||
circuit = (x, y, h, x, y, z)
|
||||
remove = (x, y)
|
||||
replace = (cnot, cgate_z)
|
||||
actual = replace_subcircuit(circuit, remove,
|
||||
replace=Mul(*replace))
|
||||
assert actual == (cnot, cgate_z, h, x, y, z)
|
||||
|
||||
actual = replace_subcircuit(circuit, remove,
|
||||
replace=replace, pos=1)
|
||||
assert actual == (x, y, h, cnot, cgate_z, z)
|
||||
|
||||
|
||||
def test_convert_to_symbolic_indices():
|
||||
(x, y, z, h) = create_gate_sequence()
|
||||
|
||||
i0 = Symbol('i0')
|
||||
exp_map = {i0: Integer(0)}
|
||||
actual, act_map, sndx, gen = convert_to_symbolic_indices((x,))
|
||||
assert actual == (X(i0),)
|
||||
assert act_map == exp_map
|
||||
|
||||
expected = (X(i0), Y(i0), Z(i0), H(i0))
|
||||
exp_map = {i0: Integer(0)}
|
||||
actual, act_map, sndx, gen = convert_to_symbolic_indices((x, y, z, h))
|
||||
assert actual == expected
|
||||
assert exp_map == act_map
|
||||
|
||||
(x1, y1, z1, h1) = create_gate_sequence(1)
|
||||
i1 = Symbol('i1')
|
||||
|
||||
expected = (X(i0), Y(i0), Z(i0), H(i0))
|
||||
exp_map = {i0: Integer(1)}
|
||||
actual, act_map, sndx, gen = convert_to_symbolic_indices((x1, y1, z1, h1))
|
||||
assert actual == expected
|
||||
assert act_map == exp_map
|
||||
|
||||
expected = (X(i0), Y(i0), Z(i0), H(i0), X(i1), Y(i1), Z(i1), H(i1))
|
||||
exp_map = {i0: Integer(0), i1: Integer(1)}
|
||||
actual, act_map, sndx, gen = convert_to_symbolic_indices((x, y, z, h,
|
||||
x1, y1, z1, h1))
|
||||
assert actual == expected
|
||||
assert act_map == exp_map
|
||||
|
||||
exp_map = {i0: Integer(1), i1: Integer(0)}
|
||||
actual, act_map, sndx, gen = convert_to_symbolic_indices(Mul(x1, y1,
|
||||
z1, h1, x, y, z, h))
|
||||
assert actual == expected
|
||||
assert act_map == exp_map
|
||||
|
||||
expected = (X(i0), X(i1), Y(i0), Y(i1), Z(i0), Z(i1), H(i0), H(i1))
|
||||
exp_map = {i0: Integer(0), i1: Integer(1)}
|
||||
actual, act_map, sndx, gen = convert_to_symbolic_indices(Mul(x, x1,
|
||||
y, y1, z, z1, h, h1))
|
||||
assert actual == expected
|
||||
assert act_map == exp_map
|
||||
|
||||
exp_map = {i0: Integer(1), i1: Integer(0)}
|
||||
actual, act_map, sndx, gen = convert_to_symbolic_indices((x1, x, y1, y,
|
||||
z1, z, h1, h))
|
||||
assert actual == expected
|
||||
assert act_map == exp_map
|
||||
|
||||
cnot_10 = CNOT(1, 0)
|
||||
cnot_01 = CNOT(0, 1)
|
||||
cgate_z_10 = CGate(1, Z(0))
|
||||
cgate_z_01 = CGate(0, Z(1))
|
||||
|
||||
expected = (X(i0), X(i1), Y(i0), Y(i1), Z(i0), Z(i1),
|
||||
H(i0), H(i1), CNOT(i1, i0), CNOT(i0, i1),
|
||||
CGate(i1, Z(i0)), CGate(i0, Z(i1)))
|
||||
exp_map = {i0: Integer(0), i1: Integer(1)}
|
||||
args = (x, x1, y, y1, z, z1, h, h1, cnot_10, cnot_01,
|
||||
cgate_z_10, cgate_z_01)
|
||||
actual, act_map, sndx, gen = convert_to_symbolic_indices(args)
|
||||
assert actual == expected
|
||||
assert act_map == exp_map
|
||||
|
||||
args = (x1, x, y1, y, z1, z, h1, h, cnot_10, cnot_01,
|
||||
cgate_z_10, cgate_z_01)
|
||||
expected = (X(i0), X(i1), Y(i0), Y(i1), Z(i0), Z(i1),
|
||||
H(i0), H(i1), CNOT(i0, i1), CNOT(i1, i0),
|
||||
CGate(i0, Z(i1)), CGate(i1, Z(i0)))
|
||||
exp_map = {i0: Integer(1), i1: Integer(0)}
|
||||
actual, act_map, sndx, gen = convert_to_symbolic_indices(args)
|
||||
assert actual == expected
|
||||
assert act_map == exp_map
|
||||
|
||||
args = (cnot_10, h, cgate_z_01, h)
|
||||
expected = (CNOT(i0, i1), H(i1), CGate(i1, Z(i0)), H(i1))
|
||||
exp_map = {i0: Integer(1), i1: Integer(0)}
|
||||
actual, act_map, sndx, gen = convert_to_symbolic_indices(args)
|
||||
assert actual == expected
|
||||
assert act_map == exp_map
|
||||
|
||||
args = (cnot_01, h1, cgate_z_10, h1)
|
||||
exp_map = {i0: Integer(0), i1: Integer(1)}
|
||||
actual, act_map, sndx, gen = convert_to_symbolic_indices(args)
|
||||
assert actual == expected
|
||||
assert act_map == exp_map
|
||||
|
||||
args = (cnot_10, h1, cgate_z_01, h1)
|
||||
expected = (CNOT(i0, i1), H(i0), CGate(i1, Z(i0)), H(i0))
|
||||
exp_map = {i0: Integer(1), i1: Integer(0)}
|
||||
actual, act_map, sndx, gen = convert_to_symbolic_indices(args)
|
||||
assert actual == expected
|
||||
assert act_map == exp_map
|
||||
|
||||
i2 = Symbol('i2')
|
||||
ccgate_z = CGate(0, CGate(1, Z(2)))
|
||||
ccgate_x = CGate(1, CGate(2, X(0)))
|
||||
args = (ccgate_z, ccgate_x)
|
||||
|
||||
expected = (CGate(i0, CGate(i1, Z(i2))), CGate(i1, CGate(i2, X(i0))))
|
||||
exp_map = {i0: Integer(0), i1: Integer(1), i2: Integer(2)}
|
||||
actual, act_map, sndx, gen = convert_to_symbolic_indices(args)
|
||||
assert actual == expected
|
||||
assert act_map == exp_map
|
||||
|
||||
ndx_map = {i0: Integer(0)}
|
||||
index_gen = numbered_symbols(prefix='i', start=1)
|
||||
actual, act_map, sndx, gen = convert_to_symbolic_indices(args,
|
||||
qubit_map=ndx_map,
|
||||
start=i0,
|
||||
gen=index_gen)
|
||||
assert actual == expected
|
||||
assert act_map == exp_map
|
||||
|
||||
i3 = Symbol('i3')
|
||||
cgate_x0_c321 = CGate((3, 2, 1), X(0))
|
||||
exp_map = {i0: Integer(3), i1: Integer(2),
|
||||
i2: Integer(1), i3: Integer(0)}
|
||||
expected = (CGate((i0, i1, i2), X(i3)),)
|
||||
args = (cgate_x0_c321,)
|
||||
actual, act_map, sndx, gen = convert_to_symbolic_indices(args)
|
||||
assert actual == expected
|
||||
assert act_map == exp_map
|
||||
|
||||
|
||||
def test_convert_to_real_indices():
|
||||
i0 = Symbol('i0')
|
||||
i1 = Symbol('i1')
|
||||
|
||||
(x, y, z, h) = create_gate_sequence()
|
||||
|
||||
x_i0 = X(i0)
|
||||
y_i0 = Y(i0)
|
||||
z_i0 = Z(i0)
|
||||
|
||||
qubit_map = {i0: 0}
|
||||
args = (z_i0, y_i0, x_i0)
|
||||
expected = (z, y, x)
|
||||
actual = convert_to_real_indices(args, qubit_map)
|
||||
assert actual == expected
|
||||
|
||||
cnot_10 = CNOT(1, 0)
|
||||
cnot_01 = CNOT(0, 1)
|
||||
cgate_z_10 = CGate(1, Z(0))
|
||||
cgate_z_01 = CGate(0, Z(1))
|
||||
|
||||
cnot_i1_i0 = CNOT(i1, i0)
|
||||
cnot_i0_i1 = CNOT(i0, i1)
|
||||
cgate_z_i1_i0 = CGate(i1, Z(i0))
|
||||
|
||||
qubit_map = {i0: 0, i1: 1}
|
||||
args = (cnot_i1_i0,)
|
||||
expected = (cnot_10,)
|
||||
actual = convert_to_real_indices(args, qubit_map)
|
||||
assert actual == expected
|
||||
|
||||
args = (cgate_z_i1_i0,)
|
||||
expected = (cgate_z_10,)
|
||||
actual = convert_to_real_indices(args, qubit_map)
|
||||
assert actual == expected
|
||||
|
||||
args = (cnot_i0_i1,)
|
||||
expected = (cnot_01,)
|
||||
actual = convert_to_real_indices(args, qubit_map)
|
||||
assert actual == expected
|
||||
|
||||
qubit_map = {i0: 1, i1: 0}
|
||||
args = (cgate_z_i1_i0,)
|
||||
expected = (cgate_z_01,)
|
||||
actual = convert_to_real_indices(args, qubit_map)
|
||||
assert actual == expected
|
||||
|
||||
i2 = Symbol('i2')
|
||||
ccgate_z = CGate(i0, CGate(i1, Z(i2)))
|
||||
ccgate_x = CGate(i1, CGate(i2, X(i0)))
|
||||
|
||||
qubit_map = {i0: 0, i1: 1, i2: 2}
|
||||
args = (ccgate_z, ccgate_x)
|
||||
expected = (CGate(0, CGate(1, Z(2))), CGate(1, CGate(2, X(0))))
|
||||
actual = convert_to_real_indices(Mul(*args), qubit_map)
|
||||
assert actual == expected
|
||||
|
||||
qubit_map = {i0: 1, i2: 0, i1: 2}
|
||||
args = (ccgate_x, ccgate_z)
|
||||
expected = (CGate(2, CGate(0, X(1))), CGate(1, CGate(2, Z(0))))
|
||||
actual = convert_to_real_indices(args, qubit_map)
|
||||
assert actual == expected
|
||||
|
||||
|
||||
@slow
|
||||
def test_random_reduce():
|
||||
x = X(0)
|
||||
y = Y(0)
|
||||
z = Z(0)
|
||||
h = H(0)
|
||||
cnot = CNOT(1, 0)
|
||||
cgate_z = CGate((0,), Z(1))
|
||||
|
||||
gate_list = [x, y, z]
|
||||
ids = list(bfs_identity_search(gate_list, 1, max_depth=4))
|
||||
|
||||
circuit = (x, y, h, z, cnot)
|
||||
assert random_reduce(circuit, []) == circuit
|
||||
assert random_reduce(circuit, ids) == circuit
|
||||
|
||||
seq = [2, 11, 9, 3, 5]
|
||||
circuit = (x, y, z, x, y, h)
|
||||
assert random_reduce(circuit, ids, seed=seq) == (x, y, h)
|
||||
|
||||
circuit = (x, x, y, y, z, z)
|
||||
assert random_reduce(circuit, ids, seed=seq) == (x, x, y, y)
|
||||
|
||||
seq = [14, 13, 0]
|
||||
assert random_reduce(circuit, ids, seed=seq) == (y, y, z, z)
|
||||
|
||||
gate_list = [x, y, z, h, cnot, cgate_z]
|
||||
ids = list(bfs_identity_search(gate_list, 2, max_depth=4))
|
||||
|
||||
seq = [25]
|
||||
circuit = (x, y, z, y, h, y, h, cgate_z, h, cnot)
|
||||
expected = (x, y, z, cgate_z, h, cnot)
|
||||
assert random_reduce(circuit, ids, seed=seq) == expected
|
||||
circuit = Mul(*circuit)
|
||||
assert random_reduce(circuit, ids, seed=seq) == expected
|
||||
|
||||
|
||||
@slow
|
||||
def test_random_insert():
|
||||
x = X(0)
|
||||
y = Y(0)
|
||||
z = Z(0)
|
||||
h = H(0)
|
||||
cnot = CNOT(1, 0)
|
||||
cgate_z = CGate((0,), Z(1))
|
||||
|
||||
choices = [(x, x)]
|
||||
circuit = (y, y)
|
||||
loc, choice = 0, 0
|
||||
actual = random_insert(circuit, choices, seed=[loc, choice])
|
||||
assert actual == (x, x, y, y)
|
||||
|
||||
circuit = (x, y, z, h)
|
||||
choices = [(h, h), (x, y, z)]
|
||||
expected = (x, x, y, z, y, z, h)
|
||||
loc, choice = 1, 1
|
||||
actual = random_insert(circuit, choices, seed=[loc, choice])
|
||||
assert actual == expected
|
||||
|
||||
gate_list = [x, y, z, h, cnot, cgate_z]
|
||||
ids = list(bfs_identity_search(gate_list, 2, max_depth=4))
|
||||
|
||||
eq_ids = flatten_ids(ids)
|
||||
|
||||
circuit = (x, y, h, cnot, cgate_z)
|
||||
expected = (x, z, x, z, x, y, h, cnot, cgate_z)
|
||||
loc, choice = 1, 30
|
||||
actual = random_insert(circuit, eq_ids, seed=[loc, choice])
|
||||
assert actual == expected
|
||||
circuit = Mul(*circuit)
|
||||
actual = random_insert(circuit, eq_ids, seed=[loc, choice])
|
||||
assert actual == expected
|
||||
@@ -0,0 +1,81 @@
|
||||
from sympy.core.numbers import Integer
|
||||
from sympy.core.symbol import symbols
|
||||
|
||||
from sympy.physics.quantum.dagger import Dagger
|
||||
from sympy.physics.quantum.commutator import Commutator as Comm
|
||||
from sympy.physics.quantum.operator import Operator
|
||||
|
||||
|
||||
a, b, c = symbols('a,b,c')
|
||||
n = symbols('n', integer=True)
|
||||
A, B, C, D = symbols('A,B,C,D', commutative=False)
|
||||
|
||||
|
||||
def test_commutator():
|
||||
c = Comm(A, B)
|
||||
assert c.is_commutative is False
|
||||
assert isinstance(c, Comm)
|
||||
assert c.subs(A, C) == Comm(C, B)
|
||||
|
||||
|
||||
def test_commutator_identities():
|
||||
assert Comm(a*A, b*B) == a*b*Comm(A, B)
|
||||
assert Comm(A, A) == 0
|
||||
assert Comm(a, b) == 0
|
||||
assert Comm(A, B) == -Comm(B, A)
|
||||
assert Comm(A, B).doit() == A*B - B*A
|
||||
assert Comm(A, B*C).expand(commutator=True) == Comm(A, B)*C + B*Comm(A, C)
|
||||
assert Comm(A*B, C*D).expand(commutator=True) == \
|
||||
A*C*Comm(B, D) + A*Comm(B, C)*D + C*Comm(A, D)*B + Comm(A, C)*D*B
|
||||
assert Comm(A, B**2).expand(commutator=True) == Comm(A, B)*B + B*Comm(A, B)
|
||||
assert Comm(A**2, C**2).expand(commutator=True) == \
|
||||
Comm(A*B, C*D).expand(commutator=True).replace(B, A).replace(D, C) == \
|
||||
A*C*Comm(A, C) + A*Comm(A, C)*C + C*Comm(A, C)*A + Comm(A, C)*C*A
|
||||
assert Comm(A, C**-2).expand(commutator=True) == \
|
||||
Comm(A, (1/C)*(1/D)).expand(commutator=True).replace(D, C)
|
||||
assert Comm(A + B, C + D).expand(commutator=True) == \
|
||||
Comm(A, C) + Comm(A, D) + Comm(B, C) + Comm(B, D)
|
||||
assert Comm(A, B + C).expand(commutator=True) == Comm(A, B) + Comm(A, C)
|
||||
assert Comm(A**n, B).expand(commutator=True) == Comm(A**n, B)
|
||||
|
||||
e = Comm(A, Comm(B, C)) + Comm(B, Comm(C, A)) + Comm(C, Comm(A, B))
|
||||
assert e.doit().expand() == 0
|
||||
|
||||
|
||||
def test_commutator_dagger():
|
||||
comm = Comm(A*B, C)
|
||||
assert Dagger(comm).expand(commutator=True) == \
|
||||
- Comm(Dagger(B), Dagger(C))*Dagger(A) - \
|
||||
Dagger(B)*Comm(Dagger(A), Dagger(C))
|
||||
|
||||
|
||||
class Foo(Operator):
|
||||
|
||||
def _eval_commutator_Bar(self, bar):
|
||||
return Integer(0)
|
||||
|
||||
|
||||
class Bar(Operator):
|
||||
pass
|
||||
|
||||
|
||||
class Tam(Operator):
|
||||
|
||||
def _eval_commutator_Foo(self, foo):
|
||||
return Integer(1)
|
||||
|
||||
|
||||
def test_eval_commutator():
|
||||
F = Foo('F')
|
||||
B = Bar('B')
|
||||
T = Tam('T')
|
||||
assert Comm(F, B).doit() == 0
|
||||
assert Comm(B, F).doit() == 0
|
||||
assert Comm(F, T).doit() == -1
|
||||
assert Comm(T, F).doit() == 1
|
||||
assert Comm(B, T).doit() == B*T - T*B
|
||||
assert Comm(F**2, B).expand(commutator=True).doit() == 0
|
||||
assert Comm(F**2, T).expand(commutator=True).doit() == -2*F
|
||||
assert Comm(F, T**2).expand(commutator=True).doit() == -2*T
|
||||
assert Comm(T**2, F).expand(commutator=True).doit() == 2*T
|
||||
assert Comm(T**2, F**3).expand(commutator=True).doit() == 2*F*T*F + 2*F**2*T + 2*T*F**2
|
||||
@@ -0,0 +1,13 @@
|
||||
from sympy.core.numbers import Float
|
||||
|
||||
from sympy.physics.quantum.constants import hbar
|
||||
|
||||
|
||||
def test_hbar():
|
||||
assert hbar.is_commutative is True
|
||||
assert hbar.is_real is True
|
||||
assert hbar.is_positive is True
|
||||
assert hbar.is_negative is False
|
||||
assert hbar.is_irrational is True
|
||||
|
||||
assert hbar.evalf() == Float(1.05457162e-34)
|
||||
@@ -0,0 +1,103 @@
|
||||
from sympy.core.expr import Expr
|
||||
from sympy.core.mul import Mul
|
||||
from sympy.core.numbers import (I, Integer)
|
||||
from sympy.core.symbol import symbols
|
||||
from sympy.functions.elementary.complexes import conjugate
|
||||
from sympy.matrices.dense import Matrix
|
||||
|
||||
from sympy.physics.quantum.dagger import adjoint, Dagger
|
||||
from sympy.external import import_module
|
||||
from sympy.testing.pytest import skip, warns_deprecated_sympy
|
||||
from sympy.physics.quantum.operator import Operator, IdentityOperator
|
||||
|
||||
|
||||
def test_scalars():
|
||||
x = symbols('x', complex=True)
|
||||
assert Dagger(x) == conjugate(x)
|
||||
assert Dagger(I*x) == -I*conjugate(x)
|
||||
|
||||
i = symbols('i', real=True)
|
||||
assert Dagger(i) == i
|
||||
|
||||
p = symbols('p')
|
||||
assert isinstance(Dagger(p), conjugate)
|
||||
|
||||
i = Integer(3)
|
||||
assert Dagger(i) == i
|
||||
|
||||
A = symbols('A', commutative=False)
|
||||
assert Dagger(A).is_commutative is False
|
||||
|
||||
|
||||
def test_matrix():
|
||||
x = symbols('x')
|
||||
m = Matrix([[I, x*I], [2, 4]])
|
||||
assert Dagger(m) == m.H
|
||||
|
||||
|
||||
def test_dagger_mul():
|
||||
O = Operator('O')
|
||||
assert Dagger(O)*O == Dagger(O)*O
|
||||
with warns_deprecated_sympy():
|
||||
I = IdentityOperator()
|
||||
assert Dagger(O)*O*I == Mul(Dagger(O), O)*I
|
||||
assert Dagger(O)*Dagger(O) == Dagger(O)**2
|
||||
assert Dagger(O)*Dagger(I) == Dagger(O)
|
||||
|
||||
|
||||
class Foo(Expr):
|
||||
|
||||
def _eval_adjoint(self):
|
||||
return I
|
||||
|
||||
|
||||
def test_eval_adjoint():
|
||||
f = Foo()
|
||||
d = Dagger(f)
|
||||
assert d == I
|
||||
|
||||
np = import_module('numpy')
|
||||
|
||||
|
||||
def test_numpy_dagger():
|
||||
if not np:
|
||||
skip("numpy not installed.")
|
||||
|
||||
a = np.array([[1.0, 2.0j], [-1.0j, 2.0]])
|
||||
adag = a.copy().transpose().conjugate()
|
||||
assert (Dagger(a) == adag).all()
|
||||
|
||||
|
||||
scipy = import_module('scipy', import_kwargs={'fromlist': ['sparse']})
|
||||
|
||||
|
||||
def test_scipy_sparse_dagger():
|
||||
if not np:
|
||||
skip("numpy not installed.")
|
||||
if not scipy:
|
||||
skip("scipy not installed.")
|
||||
else:
|
||||
sparse = scipy.sparse
|
||||
|
||||
a = sparse.csr_matrix([[1.0 + 0.0j, 2.0j], [-1.0j, 2.0 + 0.0j]])
|
||||
adag = a.copy().transpose().conjugate()
|
||||
assert np.linalg.norm((Dagger(a) - adag).todense()) == 0.0
|
||||
|
||||
|
||||
def test_unknown():
|
||||
"""Check treatment of unknown objects.
|
||||
Objects without adjoint or conjugate/transpose methods
|
||||
are sympified and wrapped in dagger.
|
||||
"""
|
||||
x = symbols("x", commutative=False)
|
||||
result = Dagger(x)
|
||||
assert result.args == (x,) and isinstance(result, adjoint)
|
||||
|
||||
|
||||
def test_unevaluated():
|
||||
"""Check that evaluate=False returns unevaluated Dagger.
|
||||
"""
|
||||
x = symbols("x", real=True)
|
||||
assert Dagger(x) == x
|
||||
result = Dagger(x, evaluate=False)
|
||||
assert result.args == (x,) and isinstance(result, adjoint)
|
||||
@@ -0,0 +1,289 @@
|
||||
from sympy.core.numbers import Rational
|
||||
from sympy.core.singleton import S
|
||||
from sympy.core.symbol import symbols
|
||||
from sympy.functions.elementary.exponential import log
|
||||
from sympy.external import import_module
|
||||
from sympy.physics.quantum.density import Density, entropy, fidelity
|
||||
from sympy.physics.quantum.state import Ket, TimeDepKet
|
||||
from sympy.physics.quantum.qubit import Qubit
|
||||
from sympy.physics.quantum.represent import represent
|
||||
from sympy.physics.quantum.dagger import Dagger
|
||||
from sympy.physics.quantum.cartesian import XKet, PxKet, PxOp, XOp
|
||||
from sympy.physics.quantum.spin import JzKet
|
||||
from sympy.physics.quantum.operator import OuterProduct
|
||||
from sympy.physics.quantum.trace import Tr
|
||||
from sympy.functions import sqrt
|
||||
from sympy.testing.pytest import raises
|
||||
from sympy.physics.quantum.matrixutils import scipy_sparse_matrix
|
||||
from sympy.physics.quantum.tensorproduct import TensorProduct
|
||||
|
||||
|
||||
def test_eval_args():
|
||||
# check instance created
|
||||
assert isinstance(Density([Ket(0), 0.5], [Ket(1), 0.5]), Density)
|
||||
assert isinstance(Density([Qubit('00'), 1/sqrt(2)],
|
||||
[Qubit('11'), 1/sqrt(2)]), Density)
|
||||
|
||||
#test if Qubit object type preserved
|
||||
d = Density([Qubit('00'), 1/sqrt(2)], [Qubit('11'), 1/sqrt(2)])
|
||||
for (state, prob) in d.args:
|
||||
assert isinstance(state, Qubit)
|
||||
|
||||
# check for value error, when prob is not provided
|
||||
raises(ValueError, lambda: Density([Ket(0)], [Ket(1)]))
|
||||
|
||||
|
||||
def test_doit():
|
||||
|
||||
x, y = symbols('x y')
|
||||
A, B, C, D, E, F = symbols('A B C D E F', commutative=False)
|
||||
d = Density([XKet(), 0.5], [PxKet(), 0.5])
|
||||
assert (0.5*(PxKet()*Dagger(PxKet())) +
|
||||
0.5*(XKet()*Dagger(XKet()))) == d.doit()
|
||||
|
||||
# check for kets with expr in them
|
||||
d_with_sym = Density([XKet(x*y), 0.5], [PxKet(x*y), 0.5])
|
||||
assert (0.5*(PxKet(x*y)*Dagger(PxKet(x*y))) +
|
||||
0.5*(XKet(x*y)*Dagger(XKet(x*y)))) == d_with_sym.doit()
|
||||
|
||||
d = Density([(A + B)*C, 1.0])
|
||||
assert d.doit() == (1.0*A*C*Dagger(C)*Dagger(A) +
|
||||
1.0*A*C*Dagger(C)*Dagger(B) +
|
||||
1.0*B*C*Dagger(C)*Dagger(A) +
|
||||
1.0*B*C*Dagger(C)*Dagger(B))
|
||||
|
||||
# With TensorProducts as args
|
||||
# Density with simple tensor products as args
|
||||
t = TensorProduct(A, B, C)
|
||||
d = Density([t, 1.0])
|
||||
assert d.doit() == \
|
||||
1.0 * TensorProduct(A*Dagger(A), B*Dagger(B), C*Dagger(C))
|
||||
|
||||
# Density with multiple Tensorproducts as states
|
||||
t2 = TensorProduct(A, B)
|
||||
t3 = TensorProduct(C, D)
|
||||
|
||||
d = Density([t2, 0.5], [t3, 0.5])
|
||||
assert d.doit() == (0.5 * TensorProduct(A*Dagger(A), B*Dagger(B)) +
|
||||
0.5 * TensorProduct(C*Dagger(C), D*Dagger(D)))
|
||||
|
||||
#Density with mixed states
|
||||
d = Density([t2 + t3, 1.0])
|
||||
assert d.doit() == (1.0 * TensorProduct(A*Dagger(A), B*Dagger(B)) +
|
||||
1.0 * TensorProduct(A*Dagger(C), B*Dagger(D)) +
|
||||
1.0 * TensorProduct(C*Dagger(A), D*Dagger(B)) +
|
||||
1.0 * TensorProduct(C*Dagger(C), D*Dagger(D)))
|
||||
|
||||
#Density operators with spin states
|
||||
tp1 = TensorProduct(JzKet(1, 1), JzKet(1, -1))
|
||||
d = Density([tp1, 1])
|
||||
|
||||
# full trace
|
||||
t = Tr(d)
|
||||
assert t.doit() == 1
|
||||
|
||||
#Partial trace on density operators with spin states
|
||||
t = Tr(d, [0])
|
||||
assert t.doit() == JzKet(1, -1) * Dagger(JzKet(1, -1))
|
||||
t = Tr(d, [1])
|
||||
assert t.doit() == JzKet(1, 1) * Dagger(JzKet(1, 1))
|
||||
|
||||
# with another spin state
|
||||
tp2 = TensorProduct(JzKet(S.Half, S.Half), JzKet(S.Half, Rational(-1, 2)))
|
||||
d = Density([tp2, 1])
|
||||
|
||||
#full trace
|
||||
t = Tr(d)
|
||||
assert t.doit() == 1
|
||||
|
||||
#Partial trace on density operators with spin states
|
||||
t = Tr(d, [0])
|
||||
assert t.doit() == JzKet(S.Half, Rational(-1, 2)) * Dagger(JzKet(S.Half, Rational(-1, 2)))
|
||||
t = Tr(d, [1])
|
||||
assert t.doit() == JzKet(S.Half, S.Half) * Dagger(JzKet(S.Half, S.Half))
|
||||
|
||||
|
||||
def test_apply_op():
|
||||
d = Density([Ket(0), 0.5], [Ket(1), 0.5])
|
||||
assert d.apply_op(XOp()) == Density([XOp()*Ket(0), 0.5],
|
||||
[XOp()*Ket(1), 0.5])
|
||||
|
||||
|
||||
def test_represent():
|
||||
x, y = symbols('x y')
|
||||
d = Density([XKet(), 0.5], [PxKet(), 0.5])
|
||||
assert (represent(0.5*(PxKet()*Dagger(PxKet()))) +
|
||||
represent(0.5*(XKet()*Dagger(XKet())))) == represent(d)
|
||||
|
||||
# check for kets with expr in them
|
||||
d_with_sym = Density([XKet(x*y), 0.5], [PxKet(x*y), 0.5])
|
||||
assert (represent(0.5*(PxKet(x*y)*Dagger(PxKet(x*y)))) +
|
||||
represent(0.5*(XKet(x*y)*Dagger(XKet(x*y))))) == \
|
||||
represent(d_with_sym)
|
||||
|
||||
# check when given explicit basis
|
||||
assert (represent(0.5*(XKet()*Dagger(XKet())), basis=PxOp()) +
|
||||
represent(0.5*(PxKet()*Dagger(PxKet())), basis=PxOp())) == \
|
||||
represent(d, basis=PxOp())
|
||||
|
||||
|
||||
def test_states():
|
||||
d = Density([Ket(0), 0.5], [Ket(1), 0.5])
|
||||
states = d.states()
|
||||
assert states[0] == Ket(0) and states[1] == Ket(1)
|
||||
|
||||
|
||||
def test_probs():
|
||||
d = Density([Ket(0), .75], [Ket(1), 0.25])
|
||||
probs = d.probs()
|
||||
assert probs[0] == 0.75 and probs[1] == 0.25
|
||||
|
||||
#probs can be symbols
|
||||
x, y = symbols('x y')
|
||||
d = Density([Ket(0), x], [Ket(1), y])
|
||||
probs = d.probs()
|
||||
assert probs[0] == x and probs[1] == y
|
||||
|
||||
|
||||
def test_get_state():
|
||||
x, y = symbols('x y')
|
||||
d = Density([Ket(0), x], [Ket(1), y])
|
||||
states = (d.get_state(0), d.get_state(1))
|
||||
assert states[0] == Ket(0) and states[1] == Ket(1)
|
||||
|
||||
|
||||
def test_get_prob():
|
||||
x, y = symbols('x y')
|
||||
d = Density([Ket(0), x], [Ket(1), y])
|
||||
probs = (d.get_prob(0), d.get_prob(1))
|
||||
assert probs[0] == x and probs[1] == y
|
||||
|
||||
|
||||
def test_entropy():
|
||||
up = JzKet(S.Half, S.Half)
|
||||
down = JzKet(S.Half, Rational(-1, 2))
|
||||
d = Density((up, S.Half), (down, S.Half))
|
||||
|
||||
# test for density object
|
||||
ent = entropy(d)
|
||||
assert entropy(d) == log(2)/2
|
||||
assert d.entropy() == log(2)/2
|
||||
|
||||
np = import_module('numpy', min_module_version='1.4.0')
|
||||
if np:
|
||||
#do this test only if 'numpy' is available on test machine
|
||||
np_mat = represent(d, format='numpy')
|
||||
ent = entropy(np_mat)
|
||||
assert isinstance(np_mat, np.ndarray)
|
||||
assert ent.real == 0.69314718055994529
|
||||
assert ent.imag == 0
|
||||
|
||||
scipy = import_module('scipy', import_kwargs={'fromlist': ['sparse']})
|
||||
if scipy and np:
|
||||
#do this test only if numpy and scipy are available
|
||||
mat = represent(d, format="scipy.sparse")
|
||||
assert isinstance(mat, scipy_sparse_matrix)
|
||||
assert ent.real == 0.69314718055994529
|
||||
assert ent.imag == 0
|
||||
|
||||
|
||||
def test_eval_trace():
|
||||
up = JzKet(S.Half, S.Half)
|
||||
down = JzKet(S.Half, Rational(-1, 2))
|
||||
d = Density((up, 0.5), (down, 0.5))
|
||||
|
||||
t = Tr(d)
|
||||
assert t.doit() == 1.0
|
||||
|
||||
#test dummy time dependent states
|
||||
class TestTimeDepKet(TimeDepKet):
|
||||
def _eval_trace(self, bra, **options):
|
||||
return 1
|
||||
|
||||
x, t = symbols('x t')
|
||||
k1 = TestTimeDepKet(0, 0.5)
|
||||
k2 = TestTimeDepKet(0, 1)
|
||||
d = Density([k1, 0.5], [k2, 0.5])
|
||||
assert d.doit() == (0.5 * OuterProduct(k1, k1.dual) +
|
||||
0.5 * OuterProduct(k2, k2.dual))
|
||||
|
||||
t = Tr(d)
|
||||
assert t.doit() == 1.0
|
||||
|
||||
|
||||
def test_fidelity():
|
||||
#test with kets
|
||||
up = JzKet(S.Half, S.Half)
|
||||
down = JzKet(S.Half, Rational(-1, 2))
|
||||
updown = (S.One/sqrt(2))*up + (S.One/sqrt(2))*down
|
||||
|
||||
#check with matrices
|
||||
up_dm = represent(up * Dagger(up))
|
||||
down_dm = represent(down * Dagger(down))
|
||||
updown_dm = represent(updown * Dagger(updown))
|
||||
|
||||
assert abs(fidelity(up_dm, up_dm) - 1) < 1e-3
|
||||
assert fidelity(up_dm, down_dm) < 1e-3
|
||||
assert abs(fidelity(up_dm, updown_dm) - (S.One/sqrt(2))) < 1e-3
|
||||
assert abs(fidelity(updown_dm, down_dm) - (S.One/sqrt(2))) < 1e-3
|
||||
|
||||
#check with density
|
||||
up_dm = Density([up, 1.0])
|
||||
down_dm = Density([down, 1.0])
|
||||
updown_dm = Density([updown, 1.0])
|
||||
|
||||
assert abs(fidelity(up_dm, up_dm) - 1) < 1e-3
|
||||
assert abs(fidelity(up_dm, down_dm)) < 1e-3
|
||||
assert abs(fidelity(up_dm, updown_dm) - (S.One/sqrt(2))) < 1e-3
|
||||
assert abs(fidelity(updown_dm, down_dm) - (S.One/sqrt(2))) < 1e-3
|
||||
|
||||
#check mixed states with density
|
||||
updown2 = sqrt(3)/2*up + S.Half*down
|
||||
d1 = Density([updown, 0.25], [updown2, 0.75])
|
||||
d2 = Density([updown, 0.75], [updown2, 0.25])
|
||||
assert abs(fidelity(d1, d2) - 0.991) < 1e-3
|
||||
assert abs(fidelity(d2, d1) - fidelity(d1, d2)) < 1e-3
|
||||
|
||||
#using qubits/density(pure states)
|
||||
state1 = Qubit('0')
|
||||
state2 = Qubit('1')
|
||||
state3 = S.One/sqrt(2)*state1 + S.One/sqrt(2)*state2
|
||||
state4 = sqrt(Rational(2, 3))*state1 + S.One/sqrt(3)*state2
|
||||
|
||||
state1_dm = Density([state1, 1])
|
||||
state2_dm = Density([state2, 1])
|
||||
state3_dm = Density([state3, 1])
|
||||
|
||||
assert fidelity(state1_dm, state1_dm) == 1
|
||||
assert fidelity(state1_dm, state2_dm) == 0
|
||||
assert abs(fidelity(state1_dm, state3_dm) - 1/sqrt(2)) < 1e-3
|
||||
assert abs(fidelity(state3_dm, state2_dm) - 1/sqrt(2)) < 1e-3
|
||||
|
||||
#using qubits/density(mixed states)
|
||||
d1 = Density([state3, 0.70], [state4, 0.30])
|
||||
d2 = Density([state3, 0.20], [state4, 0.80])
|
||||
assert abs(fidelity(d1, d1) - 1) < 1e-3
|
||||
assert abs(fidelity(d1, d2) - 0.996) < 1e-3
|
||||
assert abs(fidelity(d1, d2) - fidelity(d2, d1)) < 1e-3
|
||||
|
||||
#TODO: test for invalid arguments
|
||||
# non-square matrix
|
||||
mat1 = [[0, 0],
|
||||
[0, 0],
|
||||
[0, 0]]
|
||||
|
||||
mat2 = [[0, 0],
|
||||
[0, 0]]
|
||||
raises(ValueError, lambda: fidelity(mat1, mat2))
|
||||
|
||||
# unequal dimensions
|
||||
mat1 = [[0, 0],
|
||||
[0, 0]]
|
||||
mat2 = [[0, 0, 0],
|
||||
[0, 0, 0],
|
||||
[0, 0, 0]]
|
||||
raises(ValueError, lambda: fidelity(mat1, mat2))
|
||||
|
||||
# unsupported data-type
|
||||
x, y = 1, 2 # random values that is not a matrix
|
||||
raises(ValueError, lambda: fidelity(x, y))
|
||||
@@ -0,0 +1,62 @@
|
||||
from pytest import raises
|
||||
|
||||
import sympy
|
||||
from sympy.physics.quantum import Dagger, AntiCommutator, qapply
|
||||
from sympy.physics.quantum.fermion import FermionOp
|
||||
from sympy.physics.quantum.fermion import FermionFockKet, FermionFockBra
|
||||
from sympy import Symbol
|
||||
|
||||
|
||||
def test_fermionoperator():
|
||||
c = FermionOp('c')
|
||||
d = FermionOp('d')
|
||||
|
||||
assert isinstance(c, FermionOp)
|
||||
assert isinstance(Dagger(c), FermionOp)
|
||||
|
||||
assert c.is_annihilation
|
||||
assert not Dagger(c).is_annihilation
|
||||
|
||||
assert FermionOp("c") == FermionOp("c", True)
|
||||
assert FermionOp("c") != FermionOp("d")
|
||||
assert FermionOp("c", True) != FermionOp("c", False)
|
||||
|
||||
assert AntiCommutator(c, Dagger(c)).doit() == 1
|
||||
|
||||
assert AntiCommutator(c, Dagger(d)).doit() == c * Dagger(d) + Dagger(d) * c
|
||||
|
||||
|
||||
def test_fermion_states():
|
||||
c = FermionOp("c")
|
||||
|
||||
# Fock states
|
||||
assert (FermionFockBra(0) * FermionFockKet(1)).doit() == 0
|
||||
assert (FermionFockBra(1) * FermionFockKet(1)).doit() == 1
|
||||
|
||||
assert qapply(c * FermionFockKet(1)) == FermionFockKet(0)
|
||||
assert qapply(c * FermionFockKet(0)) == 0
|
||||
|
||||
assert qapply(Dagger(c) * FermionFockKet(0)) == FermionFockKet(1)
|
||||
assert qapply(Dagger(c) * FermionFockKet(1)) == 0
|
||||
|
||||
|
||||
def test_power():
|
||||
c = FermionOp("c")
|
||||
assert c**0 == 1
|
||||
assert c**1 == c
|
||||
assert c**2 == 0
|
||||
assert c**3 == 0
|
||||
assert Dagger(c)**1 == Dagger(c)
|
||||
assert Dagger(c)**2 == 0
|
||||
|
||||
assert (c**Symbol('a')).func == sympy.core.power.Pow
|
||||
assert (c**Symbol('a')).args == (c, Symbol('a'))
|
||||
|
||||
with raises(ValueError):
|
||||
c**-1
|
||||
|
||||
with raises(ValueError):
|
||||
c**3.2
|
||||
|
||||
with raises(TypeError):
|
||||
c**1j
|
||||
@@ -0,0 +1,360 @@
|
||||
from sympy.core.mul import Mul
|
||||
from sympy.core.numbers import (I, Integer, Rational, pi)
|
||||
from sympy.core.symbol import (Wild, symbols)
|
||||
from sympy.functions.elementary.exponential import exp
|
||||
from sympy.functions.elementary.miscellaneous import sqrt
|
||||
from sympy.matrices import Matrix, ImmutableMatrix
|
||||
|
||||
from sympy.physics.quantum.gate import (XGate, YGate, ZGate, random_circuit,
|
||||
CNOT, IdentityGate, H, X, Y, S, T, Z, SwapGate, gate_simp, gate_sort,
|
||||
CNotGate, TGate, HadamardGate, PhaseGate, UGate, CGate)
|
||||
from sympy.physics.quantum.commutator import Commutator
|
||||
from sympy.physics.quantum.anticommutator import AntiCommutator
|
||||
from sympy.physics.quantum.represent import represent
|
||||
from sympy.physics.quantum.qapply import qapply
|
||||
from sympy.physics.quantum.qubit import Qubit, IntQubit, qubit_to_matrix, \
|
||||
matrix_to_qubit
|
||||
from sympy.physics.quantum.matrixutils import matrix_to_zero
|
||||
from sympy.physics.quantum.matrixcache import sqrt2_inv
|
||||
from sympy.physics.quantum import Dagger
|
||||
|
||||
|
||||
def test_gate():
|
||||
"""Test a basic gate."""
|
||||
h = HadamardGate(1)
|
||||
assert h.min_qubits == 2
|
||||
assert h.nqubits == 1
|
||||
|
||||
i0 = Wild('i0')
|
||||
i1 = Wild('i1')
|
||||
h0_w1 = HadamardGate(i0)
|
||||
h0_w2 = HadamardGate(i0)
|
||||
h1_w1 = HadamardGate(i1)
|
||||
|
||||
assert h0_w1 == h0_w2
|
||||
assert h0_w1 != h1_w1
|
||||
assert h1_w1 != h0_w2
|
||||
|
||||
cnot_10_w1 = CNOT(i1, i0)
|
||||
cnot_10_w2 = CNOT(i1, i0)
|
||||
cnot_01_w1 = CNOT(i0, i1)
|
||||
|
||||
assert cnot_10_w1 == cnot_10_w2
|
||||
assert cnot_10_w1 != cnot_01_w1
|
||||
assert cnot_10_w2 != cnot_01_w1
|
||||
|
||||
|
||||
def test_UGate():
|
||||
a, b, c, d = symbols('a,b,c,d')
|
||||
uMat = Matrix([[a, b], [c, d]])
|
||||
|
||||
# Test basic case where gate exists in 1-qubit space
|
||||
u1 = UGate((0,), uMat)
|
||||
assert represent(u1, nqubits=1) == uMat
|
||||
assert qapply(u1*Qubit('0')) == a*Qubit('0') + c*Qubit('1')
|
||||
assert qapply(u1*Qubit('1')) == b*Qubit('0') + d*Qubit('1')
|
||||
|
||||
# Test case where gate exists in a larger space
|
||||
u2 = UGate((1,), uMat)
|
||||
u2Rep = represent(u2, nqubits=2)
|
||||
for i in range(4):
|
||||
assert u2Rep*qubit_to_matrix(IntQubit(i, 2)) == \
|
||||
qubit_to_matrix(qapply(u2*IntQubit(i, 2)))
|
||||
|
||||
|
||||
def test_cgate():
|
||||
"""Test the general CGate."""
|
||||
# Test single control functionality
|
||||
CNOTMatrix = Matrix(
|
||||
[[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]])
|
||||
assert represent(CGate(1, XGate(0)), nqubits=2) == CNOTMatrix
|
||||
|
||||
# Test multiple control bit functionality
|
||||
ToffoliGate = CGate((1, 2), XGate(0))
|
||||
assert represent(ToffoliGate, nqubits=3) == \
|
||||
Matrix(
|
||||
[[1, 0, 0, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0, 0],
|
||||
[0, 0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 0, 0,
|
||||
1, 0, 0], [0, 0, 0, 0, 0, 0, 0, 1],
|
||||
[0, 0, 0, 0, 0, 0, 1, 0]])
|
||||
|
||||
ToffoliGate = CGate((3, 0), XGate(1))
|
||||
assert qapply(ToffoliGate*Qubit('1001')) == \
|
||||
matrix_to_qubit(represent(ToffoliGate*Qubit('1001'), nqubits=4))
|
||||
assert qapply(ToffoliGate*Qubit('0000')) == \
|
||||
matrix_to_qubit(represent(ToffoliGate*Qubit('0000'), nqubits=4))
|
||||
|
||||
CYGate = CGate(1, YGate(0))
|
||||
CYGate_matrix = Matrix(
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 0, -I), (0, 0, I, 0)))
|
||||
# Test 2 qubit controlled-Y gate decompose method.
|
||||
assert represent(CYGate.decompose(), nqubits=2) == CYGate_matrix
|
||||
|
||||
CZGate = CGate(0, ZGate(1))
|
||||
CZGate_matrix = Matrix(
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, -1)))
|
||||
assert qapply(CZGate*Qubit('11')) == -Qubit('11')
|
||||
assert matrix_to_qubit(represent(CZGate*Qubit('11'), nqubits=2)) == \
|
||||
-Qubit('11')
|
||||
# Test 2 qubit controlled-Z gate decompose method.
|
||||
assert represent(CZGate.decompose(), nqubits=2) == CZGate_matrix
|
||||
|
||||
CPhaseGate = CGate(0, PhaseGate(1))
|
||||
assert qapply(CPhaseGate*Qubit('11')) == \
|
||||
I*Qubit('11')
|
||||
assert matrix_to_qubit(represent(CPhaseGate*Qubit('11'), nqubits=2)) == \
|
||||
I*Qubit('11')
|
||||
|
||||
# Test that the dagger, inverse, and power of CGate is evaluated properly
|
||||
assert Dagger(CZGate) == CZGate
|
||||
assert pow(CZGate, 1) == Dagger(CZGate)
|
||||
assert Dagger(CZGate) == CZGate.inverse()
|
||||
assert Dagger(CPhaseGate) != CPhaseGate
|
||||
assert Dagger(CPhaseGate) == CPhaseGate.inverse()
|
||||
assert Dagger(CPhaseGate) == pow(CPhaseGate, -1)
|
||||
assert pow(CPhaseGate, -1) == CPhaseGate.inverse()
|
||||
|
||||
|
||||
def test_UGate_CGate_combo():
|
||||
a, b, c, d = symbols('a,b,c,d')
|
||||
uMat = Matrix([[a, b], [c, d]])
|
||||
cMat = Matrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, a, b], [0, 0, c, d]])
|
||||
|
||||
# Test basic case where gate exists in 1-qubit space.
|
||||
u1 = UGate((0,), uMat)
|
||||
cu1 = CGate(1, u1)
|
||||
assert represent(cu1, nqubits=2) == cMat
|
||||
assert qapply(cu1*Qubit('10')) == a*Qubit('10') + c*Qubit('11')
|
||||
assert qapply(cu1*Qubit('11')) == b*Qubit('10') + d*Qubit('11')
|
||||
assert qapply(cu1*Qubit('01')) == Qubit('01')
|
||||
assert qapply(cu1*Qubit('00')) == Qubit('00')
|
||||
|
||||
# Test case where gate exists in a larger space.
|
||||
u2 = UGate((1,), uMat)
|
||||
u2Rep = represent(u2, nqubits=2)
|
||||
for i in range(4):
|
||||
assert u2Rep*qubit_to_matrix(IntQubit(i, 2)) == \
|
||||
qubit_to_matrix(qapply(u2*IntQubit(i, 2)))
|
||||
|
||||
def test_UGate_OneQubitGate_combo():
|
||||
v, w, f, g = symbols('v w f g')
|
||||
uMat1 = ImmutableMatrix([[v, w], [f, g]])
|
||||
cMat1 = Matrix([[v, w + 1, 0, 0], [f + 1, g, 0, 0], [0, 0, v, w + 1], [0, 0, f + 1, g]])
|
||||
u1 = X(0) + UGate(0, uMat1)
|
||||
assert represent(u1, nqubits=2) == cMat1
|
||||
|
||||
uMat2 = ImmutableMatrix([[1/sqrt(2), 1/sqrt(2)], [I/sqrt(2), -I/sqrt(2)]])
|
||||
cMat2_1 = Matrix([[Rational(1, 2) + I/2, Rational(1, 2) - I/2],
|
||||
[Rational(1, 2) - I/2, Rational(1, 2) + I/2]])
|
||||
cMat2_2 = Matrix([[1, 0], [0, I]])
|
||||
u2 = UGate(0, uMat2)
|
||||
assert represent(H(0)*u2, nqubits=1) == cMat2_1
|
||||
assert represent(u2*H(0), nqubits=1) == cMat2_2
|
||||
|
||||
def test_represent_hadamard():
|
||||
"""Test the representation of the hadamard gate."""
|
||||
circuit = HadamardGate(0)*Qubit('00')
|
||||
answer = represent(circuit, nqubits=2)
|
||||
# Check that the answers are same to within an epsilon.
|
||||
assert answer == Matrix([sqrt2_inv, sqrt2_inv, 0, 0])
|
||||
|
||||
|
||||
def test_represent_xgate():
|
||||
"""Test the representation of the X gate."""
|
||||
circuit = XGate(0)*Qubit('00')
|
||||
answer = represent(circuit, nqubits=2)
|
||||
assert Matrix([0, 1, 0, 0]) == answer
|
||||
|
||||
|
||||
def test_represent_ygate():
|
||||
"""Test the representation of the Y gate."""
|
||||
circuit = YGate(0)*Qubit('00')
|
||||
answer = represent(circuit, nqubits=2)
|
||||
assert answer[0] == 0 and answer[1] == I and \
|
||||
answer[2] == 0 and answer[3] == 0
|
||||
|
||||
|
||||
def test_represent_zgate():
|
||||
"""Test the representation of the Z gate."""
|
||||
circuit = ZGate(0)*Qubit('00')
|
||||
answer = represent(circuit, nqubits=2)
|
||||
assert Matrix([1, 0, 0, 0]) == answer
|
||||
|
||||
|
||||
def test_represent_phasegate():
|
||||
"""Test the representation of the S gate."""
|
||||
circuit = PhaseGate(0)*Qubit('01')
|
||||
answer = represent(circuit, nqubits=2)
|
||||
assert Matrix([0, I, 0, 0]) == answer
|
||||
|
||||
|
||||
def test_represent_tgate():
|
||||
"""Test the representation of the T gate."""
|
||||
circuit = TGate(0)*Qubit('01')
|
||||
assert Matrix([0, exp(I*pi/4), 0, 0]) == represent(circuit, nqubits=2)
|
||||
|
||||
|
||||
def test_compound_gates():
|
||||
"""Test a compound gate representation."""
|
||||
circuit = YGate(0)*ZGate(0)*XGate(0)*HadamardGate(0)*Qubit('00')
|
||||
answer = represent(circuit, nqubits=2)
|
||||
assert Matrix([I/sqrt(2), I/sqrt(2), 0, 0]) == answer
|
||||
|
||||
|
||||
def test_cnot_gate():
|
||||
"""Test the CNOT gate."""
|
||||
circuit = CNotGate(1, 0)
|
||||
assert represent(circuit, nqubits=2) == \
|
||||
Matrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]])
|
||||
circuit = circuit*Qubit('111')
|
||||
assert matrix_to_qubit(represent(circuit, nqubits=3)) == \
|
||||
qapply(circuit)
|
||||
|
||||
circuit = CNotGate(1, 0)
|
||||
assert Dagger(circuit) == circuit
|
||||
assert Dagger(Dagger(circuit)) == circuit
|
||||
assert circuit*circuit == 1
|
||||
|
||||
|
||||
def test_gate_sort():
|
||||
"""Test gate_sort."""
|
||||
for g in (X, Y, Z, H, S, T):
|
||||
assert gate_sort(g(2)*g(1)*g(0)) == g(0)*g(1)*g(2)
|
||||
e = gate_sort(X(1)*H(0)**2*CNOT(0, 1)*X(1)*X(0))
|
||||
assert e == H(0)**2*CNOT(0, 1)*X(0)*X(1)**2
|
||||
assert gate_sort(Z(0)*X(0)) == -X(0)*Z(0)
|
||||
assert gate_sort(Z(0)*X(0)**2) == X(0)**2*Z(0)
|
||||
assert gate_sort(Y(0)*H(0)) == -H(0)*Y(0)
|
||||
assert gate_sort(Y(0)*X(0)) == -X(0)*Y(0)
|
||||
assert gate_sort(Z(0)*Y(0)) == -Y(0)*Z(0)
|
||||
assert gate_sort(T(0)*S(0)) == S(0)*T(0)
|
||||
assert gate_sort(Z(0)*S(0)) == S(0)*Z(0)
|
||||
assert gate_sort(Z(0)*T(0)) == T(0)*Z(0)
|
||||
assert gate_sort(Z(0)*CNOT(0, 1)) == CNOT(0, 1)*Z(0)
|
||||
assert gate_sort(S(0)*CNOT(0, 1)) == CNOT(0, 1)*S(0)
|
||||
assert gate_sort(T(0)*CNOT(0, 1)) == CNOT(0, 1)*T(0)
|
||||
assert gate_sort(X(1)*CNOT(0, 1)) == CNOT(0, 1)*X(1)
|
||||
# This takes a long time and should only be uncommented once in a while.
|
||||
# nqubits = 5
|
||||
# ngates = 10
|
||||
# trials = 10
|
||||
# for i in range(trials):
|
||||
# c = random_circuit(ngates, nqubits)
|
||||
# assert represent(c, nqubits=nqubits) == \
|
||||
# represent(gate_sort(c), nqubits=nqubits)
|
||||
|
||||
|
||||
def test_gate_simp():
|
||||
"""Test gate_simp."""
|
||||
e = H(0)*X(1)*H(0)**2*CNOT(0, 1)*X(1)**3*X(0)*Z(3)**2*S(4)**3
|
||||
assert gate_simp(e) == H(0)*CNOT(0, 1)*S(4)*X(0)*Z(4)
|
||||
assert gate_simp(X(0)*X(0)) == 1
|
||||
assert gate_simp(Y(0)*Y(0)) == 1
|
||||
assert gate_simp(Z(0)*Z(0)) == 1
|
||||
assert gate_simp(H(0)*H(0)) == 1
|
||||
assert gate_simp(T(0)*T(0)) == S(0)
|
||||
assert gate_simp(S(0)*S(0)) == Z(0)
|
||||
assert gate_simp(Integer(1)) == Integer(1)
|
||||
assert gate_simp(X(0)**2 + Y(0)**2) == Integer(2)
|
||||
|
||||
|
||||
def test_swap_gate():
|
||||
"""Test the SWAP gate."""
|
||||
swap_gate_matrix = Matrix(
|
||||
((1, 0, 0, 0), (0, 0, 1, 0), (0, 1, 0, 0), (0, 0, 0, 1)))
|
||||
assert represent(SwapGate(1, 0).decompose(), nqubits=2) == swap_gate_matrix
|
||||
assert qapply(SwapGate(1, 3)*Qubit('0010')) == Qubit('1000')
|
||||
nqubits = 4
|
||||
for i in range(nqubits):
|
||||
for j in range(i):
|
||||
assert represent(SwapGate(i, j), nqubits=nqubits) == \
|
||||
represent(SwapGate(i, j).decompose(), nqubits=nqubits)
|
||||
|
||||
|
||||
def test_one_qubit_commutators():
|
||||
"""Test single qubit gate commutation relations."""
|
||||
for g1 in (IdentityGate, X, Y, Z, H, T, S):
|
||||
for g2 in (IdentityGate, X, Y, Z, H, T, S):
|
||||
e = Commutator(g1(0), g2(0))
|
||||
a = matrix_to_zero(represent(e, nqubits=1, format='sympy'))
|
||||
b = matrix_to_zero(represent(e.doit(), nqubits=1, format='sympy'))
|
||||
assert a == b
|
||||
|
||||
e = Commutator(g1(0), g2(1))
|
||||
assert e.doit() == 0
|
||||
|
||||
|
||||
def test_one_qubit_anticommutators():
|
||||
"""Test single qubit gate anticommutation relations."""
|
||||
for g1 in (IdentityGate, X, Y, Z, H):
|
||||
for g2 in (IdentityGate, X, Y, Z, H):
|
||||
e = AntiCommutator(g1(0), g2(0))
|
||||
a = matrix_to_zero(represent(e, nqubits=1, format='sympy'))
|
||||
b = matrix_to_zero(represent(e.doit(), nqubits=1, format='sympy'))
|
||||
assert a == b
|
||||
e = AntiCommutator(g1(0), g2(1))
|
||||
a = matrix_to_zero(represent(e, nqubits=2, format='sympy'))
|
||||
b = matrix_to_zero(represent(e.doit(), nqubits=2, format='sympy'))
|
||||
assert a == b
|
||||
|
||||
|
||||
def test_cnot_commutators():
|
||||
"""Test commutators of involving CNOT gates."""
|
||||
assert Commutator(CNOT(0, 1), Z(0)).doit() == 0
|
||||
assert Commutator(CNOT(0, 1), T(0)).doit() == 0
|
||||
assert Commutator(CNOT(0, 1), S(0)).doit() == 0
|
||||
assert Commutator(CNOT(0, 1), X(1)).doit() == 0
|
||||
assert Commutator(CNOT(0, 1), CNOT(0, 1)).doit() == 0
|
||||
assert Commutator(CNOT(0, 1), CNOT(0, 2)).doit() == 0
|
||||
assert Commutator(CNOT(0, 2), CNOT(0, 1)).doit() == 0
|
||||
assert Commutator(CNOT(1, 2), CNOT(1, 0)).doit() == 0
|
||||
|
||||
|
||||
def test_random_circuit():
|
||||
c = random_circuit(10, 3)
|
||||
assert isinstance(c, Mul)
|
||||
m = represent(c, nqubits=3)
|
||||
assert m.shape == (8, 8)
|
||||
assert isinstance(m, Matrix)
|
||||
|
||||
|
||||
def test_hermitian_XGate():
|
||||
x = XGate(1, 2)
|
||||
x_dagger = Dagger(x)
|
||||
|
||||
assert (x == x_dagger)
|
||||
|
||||
|
||||
def test_hermitian_YGate():
|
||||
y = YGate(1, 2)
|
||||
y_dagger = Dagger(y)
|
||||
|
||||
assert (y == y_dagger)
|
||||
|
||||
|
||||
def test_hermitian_ZGate():
|
||||
z = ZGate(1, 2)
|
||||
z_dagger = Dagger(z)
|
||||
|
||||
assert (z == z_dagger)
|
||||
|
||||
|
||||
def test_unitary_XGate():
|
||||
x = XGate(1, 2)
|
||||
x_dagger = Dagger(x)
|
||||
|
||||
assert (x*x_dagger == 1)
|
||||
|
||||
|
||||
def test_unitary_YGate():
|
||||
y = YGate(1, 2)
|
||||
y_dagger = Dagger(y)
|
||||
|
||||
assert (y*y_dagger == 1)
|
||||
|
||||
|
||||
def test_unitary_ZGate():
|
||||
z = ZGate(1, 2)
|
||||
z_dagger = Dagger(z)
|
||||
|
||||
assert (z*z_dagger == 1)
|
||||
@@ -0,0 +1,92 @@
|
||||
from sympy.functions.elementary.miscellaneous import sqrt
|
||||
from sympy.matrices.dense import Matrix
|
||||
from sympy.physics.quantum.represent import represent
|
||||
from sympy.physics.quantum.qapply import qapply
|
||||
from sympy.physics.quantum.qubit import IntQubit
|
||||
from sympy.physics.quantum.grover import (apply_grover, superposition_basis,
|
||||
OracleGate, grover_iteration, WGate)
|
||||
|
||||
|
||||
def return_one_on_two(qubits):
|
||||
return qubits == IntQubit(2, qubits.nqubits)
|
||||
|
||||
|
||||
def return_one_on_one(qubits):
|
||||
return qubits == IntQubit(1, nqubits=qubits.nqubits)
|
||||
|
||||
|
||||
def test_superposition_basis():
|
||||
nbits = 2
|
||||
first_half_state = IntQubit(0, nqubits=nbits)/2 + IntQubit(1, nqubits=nbits)/2
|
||||
second_half_state = IntQubit(2, nbits)/2 + IntQubit(3, nbits)/2
|
||||
assert first_half_state + second_half_state == superposition_basis(nbits)
|
||||
|
||||
nbits = 3
|
||||
firstq = (1/sqrt(8))*IntQubit(0, nqubits=nbits) + (1/sqrt(8))*IntQubit(1, nqubits=nbits)
|
||||
secondq = (1/sqrt(8))*IntQubit(2, nbits) + (1/sqrt(8))*IntQubit(3, nbits)
|
||||
thirdq = (1/sqrt(8))*IntQubit(4, nbits) + (1/sqrt(8))*IntQubit(5, nbits)
|
||||
fourthq = (1/sqrt(8))*IntQubit(6, nbits) + (1/sqrt(8))*IntQubit(7, nbits)
|
||||
assert firstq + secondq + thirdq + fourthq == superposition_basis(nbits)
|
||||
|
||||
|
||||
def test_OracleGate():
|
||||
v = OracleGate(1, lambda qubits: qubits == IntQubit(0))
|
||||
assert qapply(v*IntQubit(0)) == -IntQubit(0)
|
||||
assert qapply(v*IntQubit(1)) == IntQubit(1)
|
||||
|
||||
nbits = 2
|
||||
v = OracleGate(2, return_one_on_two)
|
||||
assert qapply(v*IntQubit(0, nbits)) == IntQubit(0, nqubits=nbits)
|
||||
assert qapply(v*IntQubit(1, nbits)) == IntQubit(1, nqubits=nbits)
|
||||
assert qapply(v*IntQubit(2, nbits)) == -IntQubit(2, nbits)
|
||||
assert qapply(v*IntQubit(3, nbits)) == IntQubit(3, nbits)
|
||||
|
||||
assert represent(OracleGate(1, lambda qubits: qubits == IntQubit(0)), nqubits=1) == \
|
||||
Matrix([[-1, 0], [0, 1]])
|
||||
assert represent(v, nqubits=2) == Matrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, -1, 0], [0, 0, 0, 1]])
|
||||
|
||||
|
||||
def test_WGate():
|
||||
nqubits = 2
|
||||
basis_states = superposition_basis(nqubits)
|
||||
assert qapply(WGate(nqubits)*basis_states) == basis_states
|
||||
|
||||
expected = ((2/sqrt(pow(2, nqubits)))*basis_states) - IntQubit(1, nqubits=nqubits)
|
||||
assert qapply(WGate(nqubits)*IntQubit(1, nqubits=nqubits)) == expected
|
||||
|
||||
|
||||
def test_grover_iteration_1():
|
||||
numqubits = 2
|
||||
basis_states = superposition_basis(numqubits)
|
||||
v = OracleGate(numqubits, return_one_on_one)
|
||||
expected = IntQubit(1, nqubits=numqubits)
|
||||
assert qapply(grover_iteration(basis_states, v)) == expected
|
||||
|
||||
|
||||
def test_grover_iteration_2():
|
||||
numqubits = 4
|
||||
basis_states = superposition_basis(numqubits)
|
||||
v = OracleGate(numqubits, return_one_on_two)
|
||||
# After (pi/4)sqrt(pow(2, n)), IntQubit(2) should have highest prob
|
||||
# In this case, after around pi times (3 or 4)
|
||||
iterated = grover_iteration(basis_states, v)
|
||||
iterated = qapply(iterated)
|
||||
iterated = grover_iteration(iterated, v)
|
||||
iterated = qapply(iterated)
|
||||
iterated = grover_iteration(iterated, v)
|
||||
iterated = qapply(iterated)
|
||||
# In this case, probability was highest after 3 iterations
|
||||
# Probability of Qubit('0010') was 251/256 (3) vs 781/1024 (4)
|
||||
# Ask about measurement
|
||||
expected = (-13*basis_states)/64 + 264*IntQubit(2, numqubits)/256
|
||||
assert qapply(expected) == iterated
|
||||
|
||||
|
||||
def test_grover():
|
||||
nqubits = 2
|
||||
assert apply_grover(return_one_on_one, nqubits) == IntQubit(1, nqubits=nqubits)
|
||||
|
||||
nqubits = 4
|
||||
basis_states = superposition_basis(nqubits)
|
||||
expected = (-13*basis_states)/64 + 264*IntQubit(2, nqubits)/256
|
||||
assert apply_grover(return_one_on_two, 4) == qapply(expected)
|
||||
@@ -0,0 +1,110 @@
|
||||
from sympy.physics.quantum.hilbert import (
|
||||
HilbertSpace, ComplexSpace, L2, FockSpace, TensorProductHilbertSpace,
|
||||
DirectSumHilbertSpace, TensorPowerHilbertSpace
|
||||
)
|
||||
|
||||
from sympy.core.numbers import oo
|
||||
from sympy.core.symbol import Symbol
|
||||
from sympy.printing.repr import srepr
|
||||
from sympy.printing.str import sstr
|
||||
from sympy.sets.sets import Interval
|
||||
|
||||
|
||||
def test_hilbert_space():
|
||||
hs = HilbertSpace()
|
||||
assert isinstance(hs, HilbertSpace)
|
||||
assert sstr(hs) == 'H'
|
||||
assert srepr(hs) == 'HilbertSpace()'
|
||||
|
||||
|
||||
def test_complex_space():
|
||||
c1 = ComplexSpace(2)
|
||||
assert isinstance(c1, ComplexSpace)
|
||||
assert c1.dimension == 2
|
||||
assert sstr(c1) == 'C(2)'
|
||||
assert srepr(c1) == 'ComplexSpace(Integer(2))'
|
||||
|
||||
n = Symbol('n')
|
||||
c2 = ComplexSpace(n)
|
||||
assert isinstance(c2, ComplexSpace)
|
||||
assert c2.dimension == n
|
||||
assert sstr(c2) == 'C(n)'
|
||||
assert srepr(c2) == "ComplexSpace(Symbol('n'))"
|
||||
assert c2.subs(n, 2) == ComplexSpace(2)
|
||||
|
||||
|
||||
def test_L2():
|
||||
b1 = L2(Interval(-oo, 1))
|
||||
assert isinstance(b1, L2)
|
||||
assert b1.dimension is oo
|
||||
assert b1.interval == Interval(-oo, 1)
|
||||
|
||||
x = Symbol('x', real=True)
|
||||
y = Symbol('y', real=True)
|
||||
b2 = L2(Interval(x, y))
|
||||
assert b2.dimension is oo
|
||||
assert b2.interval == Interval(x, y)
|
||||
assert b2.subs(x, -1) == L2(Interval(-1, y))
|
||||
|
||||
|
||||
def test_fock_space():
|
||||
f1 = FockSpace()
|
||||
f2 = FockSpace()
|
||||
assert isinstance(f1, FockSpace)
|
||||
assert f1.dimension is oo
|
||||
assert f1 == f2
|
||||
|
||||
|
||||
def test_tensor_product():
|
||||
n = Symbol('n')
|
||||
hs1 = ComplexSpace(2)
|
||||
hs2 = ComplexSpace(n)
|
||||
|
||||
h = hs1*hs2
|
||||
assert isinstance(h, TensorProductHilbertSpace)
|
||||
assert h.dimension == 2*n
|
||||
assert h.spaces == (hs1, hs2)
|
||||
|
||||
h = hs2*hs2
|
||||
assert isinstance(h, TensorPowerHilbertSpace)
|
||||
assert h.base == hs2
|
||||
assert h.exp == 2
|
||||
assert h.dimension == n**2
|
||||
|
||||
f = FockSpace()
|
||||
h = hs1*hs2*f
|
||||
assert h.dimension is oo
|
||||
|
||||
|
||||
def test_tensor_power():
|
||||
n = Symbol('n')
|
||||
hs1 = ComplexSpace(2)
|
||||
hs2 = ComplexSpace(n)
|
||||
|
||||
h = hs1**2
|
||||
assert isinstance(h, TensorPowerHilbertSpace)
|
||||
assert h.base == hs1
|
||||
assert h.exp == 2
|
||||
assert h.dimension == 4
|
||||
|
||||
h = hs2**3
|
||||
assert isinstance(h, TensorPowerHilbertSpace)
|
||||
assert h.base == hs2
|
||||
assert h.exp == 3
|
||||
assert h.dimension == n**3
|
||||
|
||||
|
||||
def test_direct_sum():
|
||||
n = Symbol('n')
|
||||
hs1 = ComplexSpace(2)
|
||||
hs2 = ComplexSpace(n)
|
||||
|
||||
h = hs1 + hs2
|
||||
assert isinstance(h, DirectSumHilbertSpace)
|
||||
assert h.dimension == 2 + n
|
||||
assert h.spaces == (hs1, hs2)
|
||||
|
||||
f = FockSpace()
|
||||
h = hs1 + f + hs2
|
||||
assert h.dimension is oo
|
||||
assert h.spaces == (hs1, f, hs2)
|
||||
@@ -0,0 +1,492 @@
|
||||
from sympy.external import import_module
|
||||
from sympy.core.mul import Mul
|
||||
from sympy.core.numbers import Integer
|
||||
from sympy.physics.quantum.dagger import Dagger
|
||||
from sympy.physics.quantum.gate import (X, Y, Z, H, CNOT,
|
||||
IdentityGate, CGate, PhaseGate, TGate)
|
||||
from sympy.physics.quantum.identitysearch import (generate_gate_rules,
|
||||
generate_equivalent_ids, GateIdentity, bfs_identity_search,
|
||||
is_scalar_sparse_matrix,
|
||||
is_scalar_nonsparse_matrix, is_degenerate, is_reducible)
|
||||
from sympy.testing.pytest import skip
|
||||
|
||||
|
||||
def create_gate_sequence(qubit=0):
|
||||
gates = (X(qubit), Y(qubit), Z(qubit), H(qubit))
|
||||
return gates
|
||||
|
||||
|
||||
def test_generate_gate_rules_1():
|
||||
# Test with tuples
|
||||
(x, y, z, h) = create_gate_sequence()
|
||||
ph = PhaseGate(0)
|
||||
cgate_t = CGate(0, TGate(1))
|
||||
|
||||
assert generate_gate_rules((x,)) == {((x,), ())}
|
||||
|
||||
gate_rules = {((x, x), ()),
|
||||
((x,), (x,))}
|
||||
assert generate_gate_rules((x, x)) == gate_rules
|
||||
|
||||
gate_rules = {((x, y, x), ()),
|
||||
((y, x, x), ()),
|
||||
((x, x, y), ()),
|
||||
((y, x), (x,)),
|
||||
((x, y), (x,)),
|
||||
((y,), (x, x))}
|
||||
assert generate_gate_rules((x, y, x)) == gate_rules
|
||||
|
||||
gate_rules = {((x, y, z), ()), ((y, z, x), ()), ((z, x, y), ()),
|
||||
((), (x, z, y)), ((), (y, x, z)), ((), (z, y, x)),
|
||||
((x,), (z, y)), ((y, z), (x,)), ((y,), (x, z)),
|
||||
((z, x), (y,)), ((z,), (y, x)), ((x, y), (z,))}
|
||||
actual = generate_gate_rules((x, y, z))
|
||||
assert actual == gate_rules
|
||||
|
||||
gate_rules = {
|
||||
((), (h, z, y, x)), ((), (x, h, z, y)), ((), (y, x, h, z)),
|
||||
((), (z, y, x, h)), ((h,), (z, y, x)), ((x,), (h, z, y)),
|
||||
((y,), (x, h, z)), ((z,), (y, x, h)), ((h, x), (z, y)),
|
||||
((x, y), (h, z)), ((y, z), (x, h)), ((z, h), (y, x)),
|
||||
((h, x, y), (z,)), ((x, y, z), (h,)), ((y, z, h), (x,)),
|
||||
((z, h, x), (y,)), ((h, x, y, z), ()), ((x, y, z, h), ()),
|
||||
((y, z, h, x), ()), ((z, h, x, y), ())}
|
||||
actual = generate_gate_rules((x, y, z, h))
|
||||
assert actual == gate_rules
|
||||
|
||||
gate_rules = {((), (cgate_t**(-1), ph**(-1), x)),
|
||||
((), (ph**(-1), x, cgate_t**(-1))),
|
||||
((), (x, cgate_t**(-1), ph**(-1))),
|
||||
((cgate_t,), (ph**(-1), x)),
|
||||
((ph,), (x, cgate_t**(-1))),
|
||||
((x,), (cgate_t**(-1), ph**(-1))),
|
||||
((cgate_t, x), (ph**(-1),)),
|
||||
((ph, cgate_t), (x,)),
|
||||
((x, ph), (cgate_t**(-1),)),
|
||||
((cgate_t, x, ph), ()),
|
||||
((ph, cgate_t, x), ()),
|
||||
((x, ph, cgate_t), ())}
|
||||
actual = generate_gate_rules((x, ph, cgate_t))
|
||||
assert actual == gate_rules
|
||||
|
||||
gate_rules = {(Integer(1), cgate_t**(-1)*ph**(-1)*x),
|
||||
(Integer(1), ph**(-1)*x*cgate_t**(-1)),
|
||||
(Integer(1), x*cgate_t**(-1)*ph**(-1)),
|
||||
(cgate_t, ph**(-1)*x),
|
||||
(ph, x*cgate_t**(-1)),
|
||||
(x, cgate_t**(-1)*ph**(-1)),
|
||||
(cgate_t*x, ph**(-1)),
|
||||
(ph*cgate_t, x),
|
||||
(x*ph, cgate_t**(-1)),
|
||||
(cgate_t*x*ph, Integer(1)),
|
||||
(ph*cgate_t*x, Integer(1)),
|
||||
(x*ph*cgate_t, Integer(1))}
|
||||
actual = generate_gate_rules((x, ph, cgate_t), return_as_muls=True)
|
||||
assert actual == gate_rules
|
||||
|
||||
|
||||
def test_generate_gate_rules_2():
|
||||
# Test with Muls
|
||||
(x, y, z, h) = create_gate_sequence()
|
||||
ph = PhaseGate(0)
|
||||
cgate_t = CGate(0, TGate(1))
|
||||
|
||||
# Note: 1 (type int) is not the same as 1 (type One)
|
||||
expected = {(x, Integer(1))}
|
||||
assert generate_gate_rules((x,), return_as_muls=True) == expected
|
||||
|
||||
expected = {(Integer(1), Integer(1))}
|
||||
assert generate_gate_rules(x*x, return_as_muls=True) == expected
|
||||
|
||||
expected = {((), ())}
|
||||
assert generate_gate_rules(x*x, return_as_muls=False) == expected
|
||||
|
||||
gate_rules = {(x*y*x, Integer(1)),
|
||||
(y, Integer(1)),
|
||||
(y*x, x),
|
||||
(x*y, x)}
|
||||
assert generate_gate_rules(x*y*x, return_as_muls=True) == gate_rules
|
||||
|
||||
gate_rules = {(x*y*z, Integer(1)),
|
||||
(y*z*x, Integer(1)),
|
||||
(z*x*y, Integer(1)),
|
||||
(Integer(1), x*z*y),
|
||||
(Integer(1), y*x*z),
|
||||
(Integer(1), z*y*x),
|
||||
(x, z*y),
|
||||
(y*z, x),
|
||||
(y, x*z),
|
||||
(z*x, y),
|
||||
(z, y*x),
|
||||
(x*y, z)}
|
||||
actual = generate_gate_rules(x*y*z, return_as_muls=True)
|
||||
assert actual == gate_rules
|
||||
|
||||
gate_rules = {(Integer(1), h*z*y*x),
|
||||
(Integer(1), x*h*z*y),
|
||||
(Integer(1), y*x*h*z),
|
||||
(Integer(1), z*y*x*h),
|
||||
(h, z*y*x), (x, h*z*y),
|
||||
(y, x*h*z), (z, y*x*h),
|
||||
(h*x, z*y), (z*h, y*x),
|
||||
(x*y, h*z), (y*z, x*h),
|
||||
(h*x*y, z), (x*y*z, h),
|
||||
(y*z*h, x), (z*h*x, y),
|
||||
(h*x*y*z, Integer(1)),
|
||||
(x*y*z*h, Integer(1)),
|
||||
(y*z*h*x, Integer(1)),
|
||||
(z*h*x*y, Integer(1))}
|
||||
actual = generate_gate_rules(x*y*z*h, return_as_muls=True)
|
||||
assert actual == gate_rules
|
||||
|
||||
gate_rules = {(Integer(1), cgate_t**(-1)*ph**(-1)*x),
|
||||
(Integer(1), ph**(-1)*x*cgate_t**(-1)),
|
||||
(Integer(1), x*cgate_t**(-1)*ph**(-1)),
|
||||
(cgate_t, ph**(-1)*x),
|
||||
(ph, x*cgate_t**(-1)),
|
||||
(x, cgate_t**(-1)*ph**(-1)),
|
||||
(cgate_t*x, ph**(-1)),
|
||||
(ph*cgate_t, x),
|
||||
(x*ph, cgate_t**(-1)),
|
||||
(cgate_t*x*ph, Integer(1)),
|
||||
(ph*cgate_t*x, Integer(1)),
|
||||
(x*ph*cgate_t, Integer(1))}
|
||||
actual = generate_gate_rules(x*ph*cgate_t, return_as_muls=True)
|
||||
assert actual == gate_rules
|
||||
|
||||
gate_rules = {((), (cgate_t**(-1), ph**(-1), x)),
|
||||
((), (ph**(-1), x, cgate_t**(-1))),
|
||||
((), (x, cgate_t**(-1), ph**(-1))),
|
||||
((cgate_t,), (ph**(-1), x)),
|
||||
((ph,), (x, cgate_t**(-1))),
|
||||
((x,), (cgate_t**(-1), ph**(-1))),
|
||||
((cgate_t, x), (ph**(-1),)),
|
||||
((ph, cgate_t), (x,)),
|
||||
((x, ph), (cgate_t**(-1),)),
|
||||
((cgate_t, x, ph), ()),
|
||||
((ph, cgate_t, x), ()),
|
||||
((x, ph, cgate_t), ())}
|
||||
actual = generate_gate_rules(x*ph*cgate_t)
|
||||
assert actual == gate_rules
|
||||
|
||||
|
||||
def test_generate_equivalent_ids_1():
|
||||
# Test with tuples
|
||||
(x, y, z, h) = create_gate_sequence()
|
||||
|
||||
assert generate_equivalent_ids((x,)) == {(x,)}
|
||||
assert generate_equivalent_ids((x, x)) == {(x, x)}
|
||||
assert generate_equivalent_ids((x, y)) == {(x, y), (y, x)}
|
||||
|
||||
gate_seq = (x, y, z)
|
||||
gate_ids = {(x, y, z), (y, z, x), (z, x, y), (z, y, x),
|
||||
(y, x, z), (x, z, y)}
|
||||
assert generate_equivalent_ids(gate_seq) == gate_ids
|
||||
|
||||
gate_ids = {Mul(x, y, z), Mul(y, z, x), Mul(z, x, y),
|
||||
Mul(z, y, x), Mul(y, x, z), Mul(x, z, y)}
|
||||
assert generate_equivalent_ids(gate_seq, return_as_muls=True) == gate_ids
|
||||
|
||||
gate_seq = (x, y, z, h)
|
||||
gate_ids = {(x, y, z, h), (y, z, h, x),
|
||||
(h, x, y, z), (h, z, y, x),
|
||||
(z, y, x, h), (y, x, h, z),
|
||||
(z, h, x, y), (x, h, z, y)}
|
||||
assert generate_equivalent_ids(gate_seq) == gate_ids
|
||||
|
||||
gate_seq = (x, y, x, y)
|
||||
gate_ids = {(x, y, x, y), (y, x, y, x)}
|
||||
assert generate_equivalent_ids(gate_seq) == gate_ids
|
||||
|
||||
cgate_y = CGate((1,), y)
|
||||
gate_seq = (y, cgate_y, y, cgate_y)
|
||||
gate_ids = {(y, cgate_y, y, cgate_y), (cgate_y, y, cgate_y, y)}
|
||||
assert generate_equivalent_ids(gate_seq) == gate_ids
|
||||
|
||||
cnot = CNOT(1, 0)
|
||||
cgate_z = CGate((0,), Z(1))
|
||||
gate_seq = (cnot, h, cgate_z, h)
|
||||
gate_ids = {(cnot, h, cgate_z, h), (h, cgate_z, h, cnot),
|
||||
(h, cnot, h, cgate_z), (cgate_z, h, cnot, h)}
|
||||
assert generate_equivalent_ids(gate_seq) == gate_ids
|
||||
|
||||
|
||||
def test_generate_equivalent_ids_2():
|
||||
# Test with Muls
|
||||
(x, y, z, h) = create_gate_sequence()
|
||||
|
||||
assert generate_equivalent_ids((x,), return_as_muls=True) == {x}
|
||||
|
||||
gate_ids = {Integer(1)}
|
||||
assert generate_equivalent_ids(x*x, return_as_muls=True) == gate_ids
|
||||
|
||||
gate_ids = {x*y, y*x}
|
||||
assert generate_equivalent_ids(x*y, return_as_muls=True) == gate_ids
|
||||
|
||||
gate_ids = {(x, y), (y, x)}
|
||||
assert generate_equivalent_ids(x*y) == gate_ids
|
||||
|
||||
circuit = Mul(*(x, y, z))
|
||||
gate_ids = {x*y*z, y*z*x, z*x*y, z*y*x,
|
||||
y*x*z, x*z*y}
|
||||
assert generate_equivalent_ids(circuit, return_as_muls=True) == gate_ids
|
||||
|
||||
circuit = Mul(*(x, y, z, h))
|
||||
gate_ids = {x*y*z*h, y*z*h*x,
|
||||
h*x*y*z, h*z*y*x,
|
||||
z*y*x*h, y*x*h*z,
|
||||
z*h*x*y, x*h*z*y}
|
||||
assert generate_equivalent_ids(circuit, return_as_muls=True) == gate_ids
|
||||
|
||||
circuit = Mul(*(x, y, x, y))
|
||||
gate_ids = {x*y*x*y, y*x*y*x}
|
||||
assert generate_equivalent_ids(circuit, return_as_muls=True) == gate_ids
|
||||
|
||||
cgate_y = CGate((1,), y)
|
||||
circuit = Mul(*(y, cgate_y, y, cgate_y))
|
||||
gate_ids = {y*cgate_y*y*cgate_y, cgate_y*y*cgate_y*y}
|
||||
assert generate_equivalent_ids(circuit, return_as_muls=True) == gate_ids
|
||||
|
||||
cnot = CNOT(1, 0)
|
||||
cgate_z = CGate((0,), Z(1))
|
||||
circuit = Mul(*(cnot, h, cgate_z, h))
|
||||
gate_ids = {cnot*h*cgate_z*h, h*cgate_z*h*cnot,
|
||||
h*cnot*h*cgate_z, cgate_z*h*cnot*h}
|
||||
assert generate_equivalent_ids(circuit, return_as_muls=True) == gate_ids
|
||||
|
||||
|
||||
def test_is_scalar_nonsparse_matrix():
|
||||
numqubits = 2
|
||||
id_only = False
|
||||
|
||||
id_gate = (IdentityGate(1),)
|
||||
actual = is_scalar_nonsparse_matrix(id_gate, numqubits, id_only)
|
||||
assert actual is True
|
||||
|
||||
x0 = X(0)
|
||||
xx_circuit = (x0, x0)
|
||||
actual = is_scalar_nonsparse_matrix(xx_circuit, numqubits, id_only)
|
||||
assert actual is True
|
||||
|
||||
x1 = X(1)
|
||||
y1 = Y(1)
|
||||
xy_circuit = (x1, y1)
|
||||
actual = is_scalar_nonsparse_matrix(xy_circuit, numqubits, id_only)
|
||||
assert actual is False
|
||||
|
||||
z1 = Z(1)
|
||||
xyz_circuit = (x1, y1, z1)
|
||||
actual = is_scalar_nonsparse_matrix(xyz_circuit, numqubits, id_only)
|
||||
assert actual is True
|
||||
|
||||
cnot = CNOT(1, 0)
|
||||
cnot_circuit = (cnot, cnot)
|
||||
actual = is_scalar_nonsparse_matrix(cnot_circuit, numqubits, id_only)
|
||||
assert actual is True
|
||||
|
||||
h = H(0)
|
||||
hh_circuit = (h, h)
|
||||
actual = is_scalar_nonsparse_matrix(hh_circuit, numqubits, id_only)
|
||||
assert actual is True
|
||||
|
||||
h1 = H(1)
|
||||
xhzh_circuit = (x1, h1, z1, h1)
|
||||
actual = is_scalar_nonsparse_matrix(xhzh_circuit, numqubits, id_only)
|
||||
assert actual is True
|
||||
|
||||
id_only = True
|
||||
actual = is_scalar_nonsparse_matrix(xhzh_circuit, numqubits, id_only)
|
||||
assert actual is True
|
||||
actual = is_scalar_nonsparse_matrix(xyz_circuit, numqubits, id_only)
|
||||
assert actual is False
|
||||
actual = is_scalar_nonsparse_matrix(cnot_circuit, numqubits, id_only)
|
||||
assert actual is True
|
||||
actual = is_scalar_nonsparse_matrix(hh_circuit, numqubits, id_only)
|
||||
assert actual is True
|
||||
|
||||
|
||||
def test_is_scalar_sparse_matrix():
|
||||
np = import_module('numpy')
|
||||
if not np:
|
||||
skip("numpy not installed.")
|
||||
|
||||
scipy = import_module('scipy', import_kwargs={'fromlist': ['sparse']})
|
||||
if not scipy:
|
||||
skip("scipy not installed.")
|
||||
|
||||
numqubits = 2
|
||||
id_only = False
|
||||
|
||||
id_gate = (IdentityGate(1),)
|
||||
assert is_scalar_sparse_matrix(id_gate, numqubits, id_only) is True
|
||||
|
||||
x0 = X(0)
|
||||
xx_circuit = (x0, x0)
|
||||
assert is_scalar_sparse_matrix(xx_circuit, numqubits, id_only) is True
|
||||
|
||||
x1 = X(1)
|
||||
y1 = Y(1)
|
||||
xy_circuit = (x1, y1)
|
||||
assert is_scalar_sparse_matrix(xy_circuit, numqubits, id_only) is False
|
||||
|
||||
z1 = Z(1)
|
||||
xyz_circuit = (x1, y1, z1)
|
||||
assert is_scalar_sparse_matrix(xyz_circuit, numqubits, id_only) is True
|
||||
|
||||
cnot = CNOT(1, 0)
|
||||
cnot_circuit = (cnot, cnot)
|
||||
assert is_scalar_sparse_matrix(cnot_circuit, numqubits, id_only) is True
|
||||
|
||||
h = H(0)
|
||||
hh_circuit = (h, h)
|
||||
assert is_scalar_sparse_matrix(hh_circuit, numqubits, id_only) is True
|
||||
|
||||
# NOTE:
|
||||
# The elements of the sparse matrix for the following circuit
|
||||
# is actually 1.0000000000000002+0.0j.
|
||||
h1 = H(1)
|
||||
xhzh_circuit = (x1, h1, z1, h1)
|
||||
assert is_scalar_sparse_matrix(xhzh_circuit, numqubits, id_only) is True
|
||||
|
||||
id_only = True
|
||||
assert is_scalar_sparse_matrix(xhzh_circuit, numqubits, id_only) is True
|
||||
assert is_scalar_sparse_matrix(xyz_circuit, numqubits, id_only) is False
|
||||
assert is_scalar_sparse_matrix(cnot_circuit, numqubits, id_only) is True
|
||||
assert is_scalar_sparse_matrix(hh_circuit, numqubits, id_only) is True
|
||||
|
||||
|
||||
def test_is_degenerate():
|
||||
(x, y, z, h) = create_gate_sequence()
|
||||
|
||||
gate_id = GateIdentity(x, y, z)
|
||||
ids = {gate_id}
|
||||
|
||||
another_id = (z, y, x)
|
||||
assert is_degenerate(ids, another_id) is True
|
||||
|
||||
|
||||
def test_is_reducible():
|
||||
nqubits = 2
|
||||
(x, y, z, h) = create_gate_sequence()
|
||||
|
||||
circuit = (x, y, y)
|
||||
assert is_reducible(circuit, nqubits, 1, 3) is True
|
||||
|
||||
circuit = (x, y, x)
|
||||
assert is_reducible(circuit, nqubits, 1, 3) is False
|
||||
|
||||
circuit = (x, y, y, x)
|
||||
assert is_reducible(circuit, nqubits, 0, 4) is True
|
||||
|
||||
circuit = (x, y, y, x)
|
||||
assert is_reducible(circuit, nqubits, 1, 3) is True
|
||||
|
||||
circuit = (x, y, z, y, y)
|
||||
assert is_reducible(circuit, nqubits, 1, 5) is True
|
||||
|
||||
|
||||
def test_bfs_identity_search():
|
||||
assert bfs_identity_search([], 1) == set()
|
||||
|
||||
(x, y, z, h) = create_gate_sequence()
|
||||
|
||||
gate_list = [x]
|
||||
id_set = {GateIdentity(x, x)}
|
||||
assert bfs_identity_search(gate_list, 1, max_depth=2) == id_set
|
||||
|
||||
# Set should not contain degenerate quantum circuits
|
||||
gate_list = [x, y, z]
|
||||
id_set = {GateIdentity(x, x),
|
||||
GateIdentity(y, y),
|
||||
GateIdentity(z, z),
|
||||
GateIdentity(x, y, z)}
|
||||
assert bfs_identity_search(gate_list, 1) == id_set
|
||||
|
||||
id_set = {GateIdentity(x, x),
|
||||
GateIdentity(y, y),
|
||||
GateIdentity(z, z),
|
||||
GateIdentity(x, y, z),
|
||||
GateIdentity(x, y, x, y),
|
||||
GateIdentity(x, z, x, z),
|
||||
GateIdentity(y, z, y, z)}
|
||||
assert bfs_identity_search(gate_list, 1, max_depth=4) == id_set
|
||||
assert bfs_identity_search(gate_list, 1, max_depth=5) == id_set
|
||||
|
||||
gate_list = [x, y, z, h]
|
||||
id_set = {GateIdentity(x, x),
|
||||
GateIdentity(y, y),
|
||||
GateIdentity(z, z),
|
||||
GateIdentity(h, h),
|
||||
GateIdentity(x, y, z),
|
||||
GateIdentity(x, y, x, y),
|
||||
GateIdentity(x, z, x, z),
|
||||
GateIdentity(x, h, z, h),
|
||||
GateIdentity(y, z, y, z),
|
||||
GateIdentity(y, h, y, h)}
|
||||
assert bfs_identity_search(gate_list, 1) == id_set
|
||||
|
||||
id_set = {GateIdentity(x, x),
|
||||
GateIdentity(y, y),
|
||||
GateIdentity(z, z),
|
||||
GateIdentity(h, h)}
|
||||
assert id_set == bfs_identity_search(gate_list, 1, max_depth=3,
|
||||
identity_only=True)
|
||||
|
||||
id_set = {GateIdentity(x, x),
|
||||
GateIdentity(y, y),
|
||||
GateIdentity(z, z),
|
||||
GateIdentity(h, h),
|
||||
GateIdentity(x, y, z),
|
||||
GateIdentity(x, y, x, y),
|
||||
GateIdentity(x, z, x, z),
|
||||
GateIdentity(x, h, z, h),
|
||||
GateIdentity(y, z, y, z),
|
||||
GateIdentity(y, h, y, h),
|
||||
GateIdentity(x, y, h, x, h),
|
||||
GateIdentity(x, z, h, y, h),
|
||||
GateIdentity(y, z, h, z, h)}
|
||||
assert bfs_identity_search(gate_list, 1, max_depth=5) == id_set
|
||||
|
||||
id_set = {GateIdentity(x, x),
|
||||
GateIdentity(y, y),
|
||||
GateIdentity(z, z),
|
||||
GateIdentity(h, h),
|
||||
GateIdentity(x, h, z, h)}
|
||||
assert id_set == bfs_identity_search(gate_list, 1, max_depth=4,
|
||||
identity_only=True)
|
||||
|
||||
cnot = CNOT(1, 0)
|
||||
gate_list = [x, cnot]
|
||||
id_set = {GateIdentity(x, x),
|
||||
GateIdentity(cnot, cnot),
|
||||
GateIdentity(x, cnot, x, cnot)}
|
||||
assert bfs_identity_search(gate_list, 2, max_depth=4) == id_set
|
||||
|
||||
cgate_x = CGate((1,), x)
|
||||
gate_list = [x, cgate_x]
|
||||
id_set = {GateIdentity(x, x),
|
||||
GateIdentity(cgate_x, cgate_x),
|
||||
GateIdentity(x, cgate_x, x, cgate_x)}
|
||||
assert bfs_identity_search(gate_list, 2, max_depth=4) == id_set
|
||||
|
||||
cgate_z = CGate((0,), Z(1))
|
||||
gate_list = [cnot, cgate_z, h]
|
||||
id_set = {GateIdentity(h, h),
|
||||
GateIdentity(cgate_z, cgate_z),
|
||||
GateIdentity(cnot, cnot),
|
||||
GateIdentity(cnot, h, cgate_z, h)}
|
||||
assert bfs_identity_search(gate_list, 2, max_depth=4) == id_set
|
||||
|
||||
s = PhaseGate(0)
|
||||
t = TGate(0)
|
||||
gate_list = [s, t]
|
||||
id_set = {GateIdentity(s, s, s, s)}
|
||||
assert bfs_identity_search(gate_list, 1, max_depth=4) == id_set
|
||||
|
||||
|
||||
def test_bfs_identity_search_xfail():
|
||||
s = PhaseGate(0)
|
||||
t = TGate(0)
|
||||
gate_list = [Dagger(s), t]
|
||||
id_set = {GateIdentity(Dagger(s), t, t)}
|
||||
assert bfs_identity_search(gate_list, 1, max_depth=3) == id_set
|
||||
@@ -0,0 +1,71 @@
|
||||
from sympy.core.numbers import (I, Integer)
|
||||
|
||||
from sympy.physics.quantum.innerproduct import InnerProduct
|
||||
from sympy.physics.quantum.dagger import Dagger
|
||||
from sympy.physics.quantum.state import Bra, Ket, StateBase
|
||||
|
||||
|
||||
def test_innerproduct():
|
||||
k = Ket('k')
|
||||
b = Bra('b')
|
||||
ip = InnerProduct(b, k)
|
||||
assert isinstance(ip, InnerProduct)
|
||||
assert ip.bra == b
|
||||
assert ip.ket == k
|
||||
assert b*k == InnerProduct(b, k)
|
||||
assert k*(b*k)*b == k*InnerProduct(b, k)*b
|
||||
assert InnerProduct(b, k).subs(b, Dagger(k)) == Dagger(k)*k
|
||||
|
||||
|
||||
def test_innerproduct_dagger():
|
||||
k = Ket('k')
|
||||
b = Bra('b')
|
||||
ip = b*k
|
||||
assert Dagger(ip) == Dagger(k)*Dagger(b)
|
||||
|
||||
|
||||
class FooState(StateBase):
|
||||
pass
|
||||
|
||||
|
||||
class FooKet(Ket, FooState):
|
||||
|
||||
@classmethod
|
||||
def dual_class(self):
|
||||
return FooBra
|
||||
|
||||
def _eval_innerproduct_FooBra(self, bra):
|
||||
return Integer(1)
|
||||
|
||||
def _eval_innerproduct_BarBra(self, bra):
|
||||
return I
|
||||
|
||||
|
||||
class FooBra(Bra, FooState):
|
||||
@classmethod
|
||||
def dual_class(self):
|
||||
return FooKet
|
||||
|
||||
|
||||
class BarState(StateBase):
|
||||
pass
|
||||
|
||||
|
||||
class BarKet(Ket, BarState):
|
||||
@classmethod
|
||||
def dual_class(self):
|
||||
return BarBra
|
||||
|
||||
|
||||
class BarBra(Bra, BarState):
|
||||
@classmethod
|
||||
def dual_class(self):
|
||||
return BarKet
|
||||
|
||||
|
||||
def test_doit():
|
||||
f = FooKet('foo')
|
||||
b = BarBra('bar')
|
||||
assert InnerProduct(b, f).doit() == I
|
||||
assert InnerProduct(Dagger(f), Dagger(b)).doit() == -I
|
||||
assert InnerProduct(Dagger(f), f).doit() == Integer(1)
|
||||
@@ -0,0 +1,75 @@
|
||||
"""Tests for sympy.physics.quantum.kind."""
|
||||
|
||||
from sympy.core.kind import NumberKind, UndefinedKind
|
||||
from sympy.core.symbol import symbols
|
||||
|
||||
from sympy.physics.quantum.kind import (
|
||||
OperatorKind, KetKind, BraKind
|
||||
)
|
||||
from sympy.physics.quantum.anticommutator import AntiCommutator
|
||||
from sympy.physics.quantum.commutator import Commutator
|
||||
from sympy.physics.quantum.dagger import Dagger
|
||||
from sympy.physics.quantum.operator import Operator
|
||||
from sympy.physics.quantum.state import Ket, Bra
|
||||
from sympy.physics.quantum.tensorproduct import TensorProduct
|
||||
|
||||
k = Ket('k')
|
||||
b = Bra('k')
|
||||
A = Operator('A')
|
||||
B = Operator('B')
|
||||
x, y, z = symbols('x y z', integer=True)
|
||||
|
||||
def test_bra_ket():
|
||||
assert k.kind == KetKind
|
||||
assert b.kind == BraKind
|
||||
assert (b*k).kind == NumberKind # inner product
|
||||
assert (x*k).kind == KetKind
|
||||
assert (x*b).kind == BraKind
|
||||
|
||||
|
||||
def test_operator_kind():
|
||||
assert A.kind == OperatorKind
|
||||
assert (A*B).kind == OperatorKind
|
||||
assert (x*A).kind == OperatorKind
|
||||
assert (x*A*B).kind == OperatorKind
|
||||
assert (x*k*b).kind == OperatorKind # outer product
|
||||
|
||||
|
||||
def test_undefind_kind():
|
||||
# Because of limitations in the kind dispatcher API, we are currently
|
||||
# unable to have OperatorKind*KetKind -> KetKind (and similar for bras).
|
||||
assert (A*k).kind == UndefinedKind
|
||||
assert (b*A).kind == UndefinedKind
|
||||
assert (x*b*A*k).kind == UndefinedKind
|
||||
|
||||
|
||||
def test_dagger_kind():
|
||||
assert Dagger(k).kind == BraKind
|
||||
assert Dagger(b).kind == KetKind
|
||||
assert Dagger(A).kind == OperatorKind
|
||||
|
||||
|
||||
def test_commutator_kind():
|
||||
assert Commutator(A, B).kind == OperatorKind
|
||||
assert Commutator(A, x*B).kind == OperatorKind
|
||||
assert Commutator(x*A, B).kind == OperatorKind
|
||||
assert Commutator(x*A, x*B).kind == OperatorKind
|
||||
|
||||
|
||||
def test_anticommutator_kind():
|
||||
assert AntiCommutator(A, B).kind == OperatorKind
|
||||
assert AntiCommutator(A, x*B).kind == OperatorKind
|
||||
assert AntiCommutator(x*A, B).kind == OperatorKind
|
||||
assert AntiCommutator(x*A, x*B).kind == OperatorKind
|
||||
|
||||
|
||||
def test_tensorproduct_kind():
|
||||
assert TensorProduct(k,k).kind == KetKind
|
||||
assert TensorProduct(b,b).kind == BraKind
|
||||
assert TensorProduct(x*k,y*k).kind == KetKind
|
||||
assert TensorProduct(x*b,y*b).kind == BraKind
|
||||
assert TensorProduct(x*b*k, y*b*k).kind == NumberKind
|
||||
assert TensorProduct(x*k*b, y*k*b).kind == OperatorKind
|
||||
assert TensorProduct(A, B).kind == OperatorKind
|
||||
assert TensorProduct(A, x*B).kind == OperatorKind
|
||||
assert TensorProduct(x*A, B).kind == OperatorKind
|
||||
@@ -0,0 +1,136 @@
|
||||
from sympy.core.random import randint
|
||||
|
||||
from sympy.core.numbers import Integer
|
||||
from sympy.matrices.dense import (Matrix, ones, zeros)
|
||||
|
||||
from sympy.physics.quantum.matrixutils import (
|
||||
to_sympy, to_numpy, to_scipy_sparse, matrix_tensor_product,
|
||||
matrix_to_zero, matrix_zeros, numpy_ndarray, scipy_sparse_matrix
|
||||
)
|
||||
|
||||
from sympy.external import import_module
|
||||
from sympy.testing.pytest import skip
|
||||
|
||||
m = Matrix([[1, 2], [3, 4]])
|
||||
|
||||
|
||||
def test_sympy_to_sympy():
|
||||
assert to_sympy(m) == m
|
||||
|
||||
|
||||
def test_matrix_to_zero():
|
||||
assert matrix_to_zero(m) == m
|
||||
assert matrix_to_zero(Matrix([[0, 0], [0, 0]])) == Integer(0)
|
||||
|
||||
np = import_module('numpy')
|
||||
|
||||
|
||||
def test_to_numpy():
|
||||
if not np:
|
||||
skip("numpy not installed.")
|
||||
|
||||
result = np.array([[1, 2], [3, 4]], dtype='complex')
|
||||
assert (to_numpy(m) == result).all()
|
||||
|
||||
|
||||
def test_matrix_tensor_product():
|
||||
if not np:
|
||||
skip("numpy not installed.")
|
||||
|
||||
l1 = zeros(4)
|
||||
for i in range(16):
|
||||
l1[i] = 2**i
|
||||
l2 = zeros(4)
|
||||
for i in range(16):
|
||||
l2[i] = i
|
||||
l3 = zeros(2)
|
||||
for i in range(4):
|
||||
l3[i] = i
|
||||
vec = Matrix([1, 2, 3])
|
||||
|
||||
#test for Matrix known 4x4 matrices
|
||||
numpyl1 = np.array(l1.tolist())
|
||||
numpyl2 = np.array(l2.tolist())
|
||||
numpy_product = np.kron(numpyl1, numpyl2)
|
||||
args = [l1, l2]
|
||||
sympy_product = matrix_tensor_product(*args)
|
||||
assert numpy_product.tolist() == sympy_product.tolist()
|
||||
numpy_product = np.kron(numpyl2, numpyl1)
|
||||
args = [l2, l1]
|
||||
sympy_product = matrix_tensor_product(*args)
|
||||
assert numpy_product.tolist() == sympy_product.tolist()
|
||||
|
||||
#test for other known matrix of different dimensions
|
||||
numpyl2 = np.array(l3.tolist())
|
||||
numpy_product = np.kron(numpyl1, numpyl2)
|
||||
args = [l1, l3]
|
||||
sympy_product = matrix_tensor_product(*args)
|
||||
assert numpy_product.tolist() == sympy_product.tolist()
|
||||
numpy_product = np.kron(numpyl2, numpyl1)
|
||||
args = [l3, l1]
|
||||
sympy_product = matrix_tensor_product(*args)
|
||||
assert numpy_product.tolist() == sympy_product.tolist()
|
||||
|
||||
#test for non square matrix
|
||||
numpyl2 = np.array(vec.tolist())
|
||||
numpy_product = np.kron(numpyl1, numpyl2)
|
||||
args = [l1, vec]
|
||||
sympy_product = matrix_tensor_product(*args)
|
||||
assert numpy_product.tolist() == sympy_product.tolist()
|
||||
numpy_product = np.kron(numpyl2, numpyl1)
|
||||
args = [vec, l1]
|
||||
sympy_product = matrix_tensor_product(*args)
|
||||
assert numpy_product.tolist() == sympy_product.tolist()
|
||||
|
||||
#test for random matrix with random values that are floats
|
||||
random_matrix1 = np.random.rand(randint(1, 5), randint(1, 5))
|
||||
random_matrix2 = np.random.rand(randint(1, 5), randint(1, 5))
|
||||
numpy_product = np.kron(random_matrix1, random_matrix2)
|
||||
args = [Matrix(random_matrix1.tolist()), Matrix(random_matrix2.tolist())]
|
||||
sympy_product = matrix_tensor_product(*args)
|
||||
assert not (sympy_product - Matrix(numpy_product.tolist())).tolist() > \
|
||||
(ones(sympy_product.rows, sympy_product.cols)*epsilon).tolist()
|
||||
|
||||
#test for three matrix kronecker
|
||||
sympy_product = matrix_tensor_product(l1, vec, l2)
|
||||
|
||||
numpy_product = np.kron(l1, np.kron(vec, l2))
|
||||
assert numpy_product.tolist() == sympy_product.tolist()
|
||||
|
||||
|
||||
scipy = import_module('scipy', import_kwargs={'fromlist': ['sparse']})
|
||||
|
||||
|
||||
def test_to_scipy_sparse():
|
||||
if not np:
|
||||
skip("numpy not installed.")
|
||||
if not scipy:
|
||||
skip("scipy not installed.")
|
||||
else:
|
||||
sparse = scipy.sparse
|
||||
|
||||
result = sparse.csr_matrix([[1, 2], [3, 4]], dtype='complex')
|
||||
assert np.linalg.norm((to_scipy_sparse(m) - result).todense()) == 0.0
|
||||
|
||||
epsilon = .000001
|
||||
|
||||
|
||||
def test_matrix_zeros_sympy():
|
||||
sym = matrix_zeros(4, 4, format='sympy')
|
||||
assert isinstance(sym, Matrix)
|
||||
|
||||
def test_matrix_zeros_numpy():
|
||||
if not np:
|
||||
skip("numpy not installed.")
|
||||
|
||||
num = matrix_zeros(4, 4, format='numpy')
|
||||
assert isinstance(num, numpy_ndarray)
|
||||
|
||||
def test_matrix_zeros_scipy():
|
||||
if not np:
|
||||
skip("numpy not installed.")
|
||||
if not scipy:
|
||||
skip("scipy not installed.")
|
||||
|
||||
sci = matrix_zeros(4, 4, format='scipy.sparse')
|
||||
assert isinstance(sci, scipy_sparse_matrix)
|
||||
@@ -0,0 +1,269 @@
|
||||
from sympy.core.function import (Derivative, Function, diff)
|
||||
from sympy.core.mul import Mul
|
||||
from sympy.core.numbers import (Integer, pi)
|
||||
from sympy.core.symbol import (Symbol, symbols)
|
||||
from sympy.core.sympify import sympify
|
||||
from sympy.functions.elementary.trigonometric import sin
|
||||
from sympy.physics.quantum.qexpr import QExpr
|
||||
from sympy.physics.quantum.dagger import Dagger
|
||||
from sympy.physics.quantum.hilbert import HilbertSpace
|
||||
from sympy.physics.quantum.operator import (Operator, UnitaryOperator,
|
||||
HermitianOperator, OuterProduct,
|
||||
DifferentialOperator,
|
||||
IdentityOperator)
|
||||
from sympy.physics.quantum.state import Ket, Bra, Wavefunction
|
||||
from sympy.physics.quantum.qapply import qapply
|
||||
from sympy.physics.quantum.represent import represent
|
||||
from sympy.physics.quantum.spin import JzKet, JzBra
|
||||
from sympy.physics.quantum.trace import Tr
|
||||
from sympy.matrices import eye
|
||||
|
||||
from sympy.testing.pytest import warns_deprecated_sympy
|
||||
|
||||
|
||||
class CustomKet(Ket):
|
||||
@classmethod
|
||||
def default_args(self):
|
||||
return ("t",)
|
||||
|
||||
|
||||
class CustomOp(HermitianOperator):
|
||||
@classmethod
|
||||
def default_args(self):
|
||||
return ("T",)
|
||||
|
||||
t_ket = CustomKet()
|
||||
t_op = CustomOp()
|
||||
|
||||
|
||||
def test_operator():
|
||||
A = Operator('A')
|
||||
B = Operator('B')
|
||||
C = Operator('C')
|
||||
|
||||
assert isinstance(A, Operator)
|
||||
assert isinstance(A, QExpr)
|
||||
|
||||
assert A.label == (Symbol('A'),)
|
||||
assert A.is_commutative is False
|
||||
assert A.hilbert_space == HilbertSpace()
|
||||
|
||||
assert A*B != B*A
|
||||
|
||||
assert (A*(B + C)).expand() == A*B + A*C
|
||||
assert ((A + B)**2).expand() == A**2 + A*B + B*A + B**2
|
||||
|
||||
assert t_op.label[0] == Symbol(t_op.default_args()[0])
|
||||
|
||||
assert Operator() == Operator("O")
|
||||
with warns_deprecated_sympy():
|
||||
assert A*IdentityOperator() == A
|
||||
|
||||
|
||||
def test_operator_inv():
|
||||
A = Operator('A')
|
||||
assert A*A.inv() == 1
|
||||
assert A.inv()*A == 1
|
||||
|
||||
|
||||
def test_hermitian():
|
||||
H = HermitianOperator('H')
|
||||
|
||||
assert isinstance(H, HermitianOperator)
|
||||
assert isinstance(H, Operator)
|
||||
|
||||
assert Dagger(H) == H
|
||||
assert H.inv() != H
|
||||
assert H.is_commutative is False
|
||||
assert Dagger(H).is_commutative is False
|
||||
|
||||
|
||||
def test_unitary():
|
||||
U = UnitaryOperator('U')
|
||||
|
||||
assert isinstance(U, UnitaryOperator)
|
||||
assert isinstance(U, Operator)
|
||||
|
||||
assert U.inv() == Dagger(U)
|
||||
assert U*Dagger(U) == 1
|
||||
assert Dagger(U)*U == 1
|
||||
assert U.is_commutative is False
|
||||
assert Dagger(U).is_commutative is False
|
||||
|
||||
|
||||
def test_identity():
|
||||
with warns_deprecated_sympy():
|
||||
I = IdentityOperator()
|
||||
O = Operator('O')
|
||||
x = Symbol("x")
|
||||
three = sympify(3)
|
||||
|
||||
assert isinstance(I, IdentityOperator)
|
||||
assert isinstance(I, Operator)
|
||||
|
||||
assert I * O == O
|
||||
assert O * I == O
|
||||
assert I * Dagger(O) == Dagger(O)
|
||||
assert Dagger(O) * I == Dagger(O)
|
||||
assert isinstance(I * I, IdentityOperator)
|
||||
assert three * I == three
|
||||
assert I * x == x
|
||||
assert I.inv() == I
|
||||
assert Dagger(I) == I
|
||||
assert qapply(I * O) == O
|
||||
assert qapply(O * I) == O
|
||||
|
||||
for n in [2, 3, 5]:
|
||||
assert represent(IdentityOperator(n)) == eye(n)
|
||||
|
||||
|
||||
def test_outer_product():
|
||||
k = Ket('k')
|
||||
b = Bra('b')
|
||||
op = OuterProduct(k, b)
|
||||
|
||||
assert isinstance(op, OuterProduct)
|
||||
assert isinstance(op, Operator)
|
||||
|
||||
assert op.ket == k
|
||||
assert op.bra == b
|
||||
assert op.label == (k, b)
|
||||
assert op.is_commutative is False
|
||||
|
||||
op = k*b
|
||||
|
||||
assert isinstance(op, OuterProduct)
|
||||
assert isinstance(op, Operator)
|
||||
|
||||
assert op.ket == k
|
||||
assert op.bra == b
|
||||
assert op.label == (k, b)
|
||||
assert op.is_commutative is False
|
||||
|
||||
op = 2*k*b
|
||||
|
||||
assert op == Mul(Integer(2), k, b)
|
||||
|
||||
op = 2*(k*b)
|
||||
|
||||
assert op == Mul(Integer(2), OuterProduct(k, b))
|
||||
|
||||
assert Dagger(k*b) == OuterProduct(Dagger(b), Dagger(k))
|
||||
assert Dagger(k*b).is_commutative is False
|
||||
|
||||
#test the _eval_trace
|
||||
assert Tr(OuterProduct(JzKet(1, 1), JzBra(1, 1))).doit() == 1
|
||||
|
||||
# test scaled kets and bras
|
||||
assert OuterProduct(2 * k, b) == 2 * OuterProduct(k, b)
|
||||
assert OuterProduct(k, 2 * b) == 2 * OuterProduct(k, b)
|
||||
|
||||
# test sums of kets and bras
|
||||
k1, k2 = Ket('k1'), Ket('k2')
|
||||
b1, b2 = Bra('b1'), Bra('b2')
|
||||
assert (OuterProduct(k1 + k2, b1) ==
|
||||
OuterProduct(k1, b1) + OuterProduct(k2, b1))
|
||||
assert (OuterProduct(k1, b1 + b2) ==
|
||||
OuterProduct(k1, b1) + OuterProduct(k1, b2))
|
||||
assert (OuterProduct(1 * k1 + 2 * k2, 3 * b1 + 4 * b2) ==
|
||||
3 * OuterProduct(k1, b1) +
|
||||
4 * OuterProduct(k1, b2) +
|
||||
6 * OuterProduct(k2, b1) +
|
||||
8 * OuterProduct(k2, b2))
|
||||
|
||||
|
||||
def test_operator_dagger():
|
||||
A = Operator('A')
|
||||
B = Operator('B')
|
||||
assert Dagger(A*B) == Dagger(B)*Dagger(A)
|
||||
assert Dagger(A + B) == Dagger(A) + Dagger(B)
|
||||
assert Dagger(A**2) == Dagger(A)**2
|
||||
|
||||
|
||||
def test_differential_operator():
|
||||
x = Symbol('x')
|
||||
f = Function('f')
|
||||
d = DifferentialOperator(Derivative(f(x), x), f(x))
|
||||
g = Wavefunction(x**2, x)
|
||||
assert qapply(d*g) == Wavefunction(2*x, x)
|
||||
assert d.expr == Derivative(f(x), x)
|
||||
assert d.function == f(x)
|
||||
assert d.variables == (x,)
|
||||
assert diff(d, x) == DifferentialOperator(Derivative(f(x), x, 2), f(x))
|
||||
|
||||
d = DifferentialOperator(Derivative(f(x), x, 2), f(x))
|
||||
g = Wavefunction(x**3, x)
|
||||
assert qapply(d*g) == Wavefunction(6*x, x)
|
||||
assert d.expr == Derivative(f(x), x, 2)
|
||||
assert d.function == f(x)
|
||||
assert d.variables == (x,)
|
||||
assert diff(d, x) == DifferentialOperator(Derivative(f(x), x, 3), f(x))
|
||||
|
||||
d = DifferentialOperator(1/x*Derivative(f(x), x), f(x))
|
||||
assert d.expr == 1/x*Derivative(f(x), x)
|
||||
assert d.function == f(x)
|
||||
assert d.variables == (x,)
|
||||
assert diff(d, x) == \
|
||||
DifferentialOperator(Derivative(1/x*Derivative(f(x), x), x), f(x))
|
||||
assert qapply(d*g) == Wavefunction(3*x, x)
|
||||
|
||||
# 2D cartesian Laplacian
|
||||
y = Symbol('y')
|
||||
d = DifferentialOperator(Derivative(f(x, y), x, 2) +
|
||||
Derivative(f(x, y), y, 2), f(x, y))
|
||||
w = Wavefunction(x**3*y**2 + y**3*x**2, x, y)
|
||||
assert d.expr == Derivative(f(x, y), x, 2) + Derivative(f(x, y), y, 2)
|
||||
assert d.function == f(x, y)
|
||||
assert d.variables == (x, y)
|
||||
assert diff(d, x) == \
|
||||
DifferentialOperator(Derivative(d.expr, x), f(x, y))
|
||||
assert diff(d, y) == \
|
||||
DifferentialOperator(Derivative(d.expr, y), f(x, y))
|
||||
assert qapply(d*w) == Wavefunction(2*x**3 + 6*x*y**2 + 6*x**2*y + 2*y**3,
|
||||
x, y)
|
||||
|
||||
# 2D polar Laplacian (th = theta)
|
||||
r, th = symbols('r th')
|
||||
d = DifferentialOperator(1/r*Derivative(r*Derivative(f(r, th), r), r) +
|
||||
1/(r**2)*Derivative(f(r, th), th, 2), f(r, th))
|
||||
w = Wavefunction(r**2*sin(th), r, (th, 0, pi))
|
||||
assert d.expr == \
|
||||
1/r*Derivative(r*Derivative(f(r, th), r), r) + \
|
||||
1/(r**2)*Derivative(f(r, th), th, 2)
|
||||
assert d.function == f(r, th)
|
||||
assert d.variables == (r, th)
|
||||
assert diff(d, r) == \
|
||||
DifferentialOperator(Derivative(d.expr, r), f(r, th))
|
||||
assert diff(d, th) == \
|
||||
DifferentialOperator(Derivative(d.expr, th), f(r, th))
|
||||
assert qapply(d*w) == Wavefunction(3*sin(th), r, (th, 0, pi))
|
||||
|
||||
|
||||
def test_eval_power():
|
||||
from sympy.core import Pow
|
||||
from sympy.core.expr import unchanged
|
||||
O = Operator('O')
|
||||
U = UnitaryOperator('U')
|
||||
H = HermitianOperator('H')
|
||||
assert O**-1 == O.inv() # same as doc test
|
||||
assert U**-1 == U.inv()
|
||||
assert H**-1 == H.inv()
|
||||
x = symbols("x", commutative = True)
|
||||
assert unchanged(Pow, H, x) # verify Pow(H,x)=="X^n"
|
||||
assert H**x == Pow(H, x)
|
||||
assert Pow(H,x) == Pow(H, x, evaluate=False) # Just check
|
||||
from sympy.physics.quantum.gate import XGate
|
||||
X = XGate(0) # is hermitian and unitary
|
||||
assert unchanged(Pow, X, x) # verify Pow(X,x)=="X^x"
|
||||
assert X**x == Pow(X, x)
|
||||
assert Pow(X, x, evaluate=False) == Pow(X, x) # Just check
|
||||
n = symbols("n", integer=True, even=True)
|
||||
assert X**n == 1
|
||||
n = symbols("n", integer=True, odd=True)
|
||||
assert X**n == X
|
||||
n = symbols("n", integer=True)
|
||||
assert unchanged(Pow, X, n) # verify Pow(X,n)=="X^n"
|
||||
assert X**n == Pow(X, n)
|
||||
assert Pow(X, n, evaluate=False)==Pow(X, n) # Just check
|
||||
assert X**4 == 1
|
||||
assert X**7 == X
|
||||
@@ -0,0 +1,50 @@
|
||||
from sympy.physics.quantum import Dagger
|
||||
from sympy.physics.quantum.boson import BosonOp
|
||||
from sympy.physics.quantum.fermion import FermionOp
|
||||
from sympy.physics.quantum.operatorordering import (normal_order,
|
||||
normal_ordered_form)
|
||||
|
||||
|
||||
def test_normal_order():
|
||||
a = BosonOp('a')
|
||||
|
||||
c = FermionOp('c')
|
||||
|
||||
assert normal_order(a * Dagger(a)) == Dagger(a) * a
|
||||
assert normal_order(Dagger(a) * a) == Dagger(a) * a
|
||||
assert normal_order(a * Dagger(a) ** 2) == Dagger(a) ** 2 * a
|
||||
|
||||
assert normal_order(c * Dagger(c)) == - Dagger(c) * c
|
||||
assert normal_order(Dagger(c) * c) == Dagger(c) * c
|
||||
assert normal_order(c * Dagger(c) ** 2) == Dagger(c) ** 2 * c
|
||||
|
||||
|
||||
def test_normal_ordered_form():
|
||||
a = BosonOp('a')
|
||||
b = BosonOp('b')
|
||||
|
||||
c = FermionOp('c')
|
||||
d = FermionOp('d')
|
||||
|
||||
assert normal_ordered_form(Dagger(a) * a) == Dagger(a) * a
|
||||
assert normal_ordered_form(a * Dagger(a)) == 1 + Dagger(a) * a
|
||||
assert normal_ordered_form(a ** 2 * Dagger(a)) == \
|
||||
2 * a + Dagger(a) * a ** 2
|
||||
assert normal_ordered_form(a ** 3 * Dagger(a)) == \
|
||||
3 * a ** 2 + Dagger(a) * a ** 3
|
||||
|
||||
assert normal_ordered_form(Dagger(c) * c) == Dagger(c) * c
|
||||
assert normal_ordered_form(c * Dagger(c)) == 1 - Dagger(c) * c
|
||||
assert normal_ordered_form(c ** 2 * Dagger(c)) == Dagger(c) * c ** 2
|
||||
assert normal_ordered_form(c ** 3 * Dagger(c)) == \
|
||||
c ** 2 - Dagger(c) * c ** 3
|
||||
|
||||
assert normal_ordered_form(a * Dagger(b), True) == Dagger(b) * a
|
||||
assert normal_ordered_form(Dagger(a) * b, True) == Dagger(a) * b
|
||||
assert normal_ordered_form(b * a, True) == a * b
|
||||
assert normal_ordered_form(Dagger(b) * Dagger(a), True) == Dagger(a) * Dagger(b)
|
||||
|
||||
assert normal_ordered_form(c * Dagger(d), True) == -Dagger(d) * c
|
||||
assert normal_ordered_form(Dagger(c) * d, True) == Dagger(c) * d
|
||||
assert normal_ordered_form(d * c, True) == -c * d
|
||||
assert normal_ordered_form(Dagger(d) * Dagger(c), True) == -Dagger(c) * Dagger(d)
|
||||
@@ -0,0 +1,68 @@
|
||||
from sympy.core.singleton import S
|
||||
|
||||
from sympy.physics.quantum.operatorset import (
|
||||
operators_to_state, state_to_operators
|
||||
)
|
||||
|
||||
from sympy.physics.quantum.cartesian import (
|
||||
XOp, XKet, PxOp, PxKet, XBra, PxBra
|
||||
)
|
||||
|
||||
from sympy.physics.quantum.state import Ket, Bra
|
||||
from sympy.physics.quantum.operator import Operator
|
||||
from sympy.physics.quantum.spin import (
|
||||
JxKet, JyKet, JzKet, JxBra, JyBra, JzBra,
|
||||
JxOp, JyOp, JzOp, J2Op
|
||||
)
|
||||
|
||||
from sympy.testing.pytest import raises
|
||||
|
||||
|
||||
def test_spin():
|
||||
assert operators_to_state({J2Op, JxOp}) == JxKet
|
||||
assert operators_to_state({J2Op, JyOp}) == JyKet
|
||||
assert operators_to_state({J2Op, JzOp}) == JzKet
|
||||
assert operators_to_state({J2Op(), JxOp()}) == JxKet
|
||||
assert operators_to_state({J2Op(), JyOp()}) == JyKet
|
||||
assert operators_to_state({J2Op(), JzOp()}) == JzKet
|
||||
|
||||
assert state_to_operators(JxKet) == {J2Op, JxOp}
|
||||
assert state_to_operators(JyKet) == {J2Op, JyOp}
|
||||
assert state_to_operators(JzKet) == {J2Op, JzOp}
|
||||
assert state_to_operators(JxBra) == {J2Op, JxOp}
|
||||
assert state_to_operators(JyBra) == {J2Op, JyOp}
|
||||
assert state_to_operators(JzBra) == {J2Op, JzOp}
|
||||
|
||||
assert state_to_operators(JxKet(S.Half, S.Half)) == {J2Op(), JxOp()}
|
||||
assert state_to_operators(JyKet(S.Half, S.Half)) == {J2Op(), JyOp()}
|
||||
assert state_to_operators(JzKet(S.Half, S.Half)) == {J2Op(), JzOp()}
|
||||
assert state_to_operators(JxBra(S.Half, S.Half)) == {J2Op(), JxOp()}
|
||||
assert state_to_operators(JyBra(S.Half, S.Half)) == {J2Op(), JyOp()}
|
||||
assert state_to_operators(JzBra(S.Half, S.Half)) == {J2Op(), JzOp()}
|
||||
|
||||
|
||||
def test_op_to_state():
|
||||
assert operators_to_state(XOp) == XKet()
|
||||
assert operators_to_state(PxOp) == PxKet()
|
||||
assert operators_to_state(Operator) == Ket()
|
||||
|
||||
assert state_to_operators(operators_to_state(XOp("Q"))) == XOp("Q")
|
||||
assert state_to_operators(operators_to_state(XOp())) == XOp()
|
||||
|
||||
raises(NotImplementedError, lambda: operators_to_state(XKet))
|
||||
|
||||
|
||||
def test_state_to_op():
|
||||
assert state_to_operators(XKet) == XOp()
|
||||
assert state_to_operators(PxKet) == PxOp()
|
||||
assert state_to_operators(XBra) == XOp()
|
||||
assert state_to_operators(PxBra) == PxOp()
|
||||
assert state_to_operators(Ket) == Operator()
|
||||
assert state_to_operators(Bra) == Operator()
|
||||
|
||||
assert operators_to_state(state_to_operators(XKet("test"))) == XKet("test")
|
||||
assert operators_to_state(state_to_operators(XBra("test"))) == XKet("test")
|
||||
assert operators_to_state(state_to_operators(XKet())) == XKet()
|
||||
assert operators_to_state(state_to_operators(XBra())) == XKet()
|
||||
|
||||
raises(NotImplementedError, lambda: state_to_operators(XOp))
|
||||
@@ -0,0 +1,159 @@
|
||||
from sympy.core.mul import Mul
|
||||
from sympy.core.numbers import I
|
||||
from sympy.matrices.dense import Matrix
|
||||
from sympy.printing.latex import latex
|
||||
from sympy.physics.quantum import (Dagger, Commutator, AntiCommutator, qapply,
|
||||
Operator, represent)
|
||||
from sympy.physics.quantum.pauli import (SigmaOpBase, SigmaX, SigmaY, SigmaZ,
|
||||
SigmaMinus, SigmaPlus,
|
||||
qsimplify_pauli)
|
||||
from sympy.physics.quantum.pauli import SigmaZKet, SigmaZBra
|
||||
from sympy.testing.pytest import raises
|
||||
|
||||
|
||||
sx, sy, sz = SigmaX(), SigmaY(), SigmaZ()
|
||||
sx1, sy1, sz1 = SigmaX(1), SigmaY(1), SigmaZ(1)
|
||||
sx2, sy2, sz2 = SigmaX(2), SigmaY(2), SigmaZ(2)
|
||||
|
||||
sm, sp = SigmaMinus(), SigmaPlus()
|
||||
sm1, sp1 = SigmaMinus(1), SigmaPlus(1)
|
||||
A, B = Operator("A"), Operator("B")
|
||||
|
||||
|
||||
def test_pauli_operators_types():
|
||||
|
||||
assert isinstance(sx, SigmaOpBase) and isinstance(sx, SigmaX)
|
||||
assert isinstance(sy, SigmaOpBase) and isinstance(sy, SigmaY)
|
||||
assert isinstance(sz, SigmaOpBase) and isinstance(sz, SigmaZ)
|
||||
assert isinstance(sm, SigmaOpBase) and isinstance(sm, SigmaMinus)
|
||||
assert isinstance(sp, SigmaOpBase) and isinstance(sp, SigmaPlus)
|
||||
|
||||
|
||||
def test_pauli_operators_commutator():
|
||||
|
||||
assert Commutator(sx, sy).doit() == 2 * I * sz
|
||||
assert Commutator(sy, sz).doit() == 2 * I * sx
|
||||
assert Commutator(sz, sx).doit() == 2 * I * sy
|
||||
|
||||
|
||||
def test_pauli_operators_commutator_with_labels():
|
||||
|
||||
assert Commutator(sx1, sy1).doit() == 2 * I * sz1
|
||||
assert Commutator(sy1, sz1).doit() == 2 * I * sx1
|
||||
assert Commutator(sz1, sx1).doit() == 2 * I * sy1
|
||||
|
||||
assert Commutator(sx2, sy2).doit() == 2 * I * sz2
|
||||
assert Commutator(sy2, sz2).doit() == 2 * I * sx2
|
||||
assert Commutator(sz2, sx2).doit() == 2 * I * sy2
|
||||
|
||||
assert Commutator(sx1, sy2).doit() == 0
|
||||
assert Commutator(sy1, sz2).doit() == 0
|
||||
assert Commutator(sz1, sx2).doit() == 0
|
||||
|
||||
|
||||
def test_pauli_operators_anticommutator():
|
||||
|
||||
assert AntiCommutator(sy, sz).doit() == 0
|
||||
assert AntiCommutator(sz, sx).doit() == 0
|
||||
assert AntiCommutator(sx, sm).doit() == 1
|
||||
assert AntiCommutator(sx, sp).doit() == 1
|
||||
|
||||
|
||||
def test_pauli_operators_adjoint():
|
||||
|
||||
assert Dagger(sx) == sx
|
||||
assert Dagger(sy) == sy
|
||||
assert Dagger(sz) == sz
|
||||
|
||||
|
||||
def test_pauli_operators_adjoint_with_labels():
|
||||
|
||||
assert Dagger(sx1) == sx1
|
||||
assert Dagger(sy1) == sy1
|
||||
assert Dagger(sz1) == sz1
|
||||
|
||||
assert Dagger(sx1) != sx2
|
||||
assert Dagger(sy1) != sy2
|
||||
assert Dagger(sz1) != sz2
|
||||
|
||||
|
||||
def test_pauli_operators_multiplication():
|
||||
|
||||
assert qsimplify_pauli(sx * sx) == 1
|
||||
assert qsimplify_pauli(sy * sy) == 1
|
||||
assert qsimplify_pauli(sz * sz) == 1
|
||||
|
||||
assert qsimplify_pauli(sx * sy) == I * sz
|
||||
assert qsimplify_pauli(sy * sz) == I * sx
|
||||
assert qsimplify_pauli(sz * sx) == I * sy
|
||||
|
||||
assert qsimplify_pauli(sy * sx) == - I * sz
|
||||
assert qsimplify_pauli(sz * sy) == - I * sx
|
||||
assert qsimplify_pauli(sx * sz) == - I * sy
|
||||
|
||||
|
||||
def test_pauli_operators_multiplication_with_labels():
|
||||
|
||||
assert qsimplify_pauli(sx1 * sx1) == 1
|
||||
assert qsimplify_pauli(sy1 * sy1) == 1
|
||||
assert qsimplify_pauli(sz1 * sz1) == 1
|
||||
|
||||
assert isinstance(sx1 * sx2, Mul)
|
||||
assert isinstance(sy1 * sy2, Mul)
|
||||
assert isinstance(sz1 * sz2, Mul)
|
||||
|
||||
assert qsimplify_pauli(sx1 * sy1 * sx2 * sy2) == - sz1 * sz2
|
||||
assert qsimplify_pauli(sy1 * sz1 * sz2 * sx2) == - sx1 * sy2
|
||||
|
||||
|
||||
def test_pauli_states():
|
||||
sx, sz = SigmaX(), SigmaZ()
|
||||
|
||||
up = SigmaZKet(0)
|
||||
down = SigmaZKet(1)
|
||||
|
||||
assert qapply(sx * up) == down
|
||||
assert qapply(sx * down) == up
|
||||
assert qapply(sz * up) == up
|
||||
assert qapply(sz * down) == - down
|
||||
|
||||
up = SigmaZBra(0)
|
||||
down = SigmaZBra(1)
|
||||
|
||||
assert qapply(up * sx, dagger=True) == down
|
||||
assert qapply(down * sx, dagger=True) == up
|
||||
assert qapply(up * sz, dagger=True) == up
|
||||
assert qapply(down * sz, dagger=True) == - down
|
||||
|
||||
assert Dagger(SigmaZKet(0)) == SigmaZBra(0)
|
||||
assert Dagger(SigmaZBra(1)) == SigmaZKet(1)
|
||||
raises(ValueError, lambda: SigmaZBra(2))
|
||||
raises(ValueError, lambda: SigmaZKet(2))
|
||||
|
||||
|
||||
def test_use_name():
|
||||
assert sm.use_name is False
|
||||
assert sm1.use_name is True
|
||||
assert sx.use_name is False
|
||||
assert sx1.use_name is True
|
||||
|
||||
|
||||
def test_printing():
|
||||
assert latex(sx) == r'{\sigma_x}'
|
||||
assert latex(sx1) == r'{\sigma_x^{(1)}}'
|
||||
assert latex(sy) == r'{\sigma_y}'
|
||||
assert latex(sy1) == r'{\sigma_y^{(1)}}'
|
||||
assert latex(sz) == r'{\sigma_z}'
|
||||
assert latex(sz1) == r'{\sigma_z^{(1)}}'
|
||||
assert latex(sm) == r'{\sigma_-}'
|
||||
assert latex(sm1) == r'{\sigma_-^{(1)}}'
|
||||
assert latex(sp) == r'{\sigma_+}'
|
||||
assert latex(sp1) == r'{\sigma_+^{(1)}}'
|
||||
|
||||
|
||||
def test_represent():
|
||||
assert represent(sx) == Matrix([[0, 1], [1, 0]])
|
||||
assert represent(sy) == Matrix([[0, -I], [I, 0]])
|
||||
assert represent(sz) == Matrix([[1, 0], [0, -1]])
|
||||
assert represent(sm) == Matrix([[0, 0], [1, 0]])
|
||||
assert represent(sp) == Matrix([[0, 1], [0, 0]])
|
||||
@@ -0,0 +1,29 @@
|
||||
"""Tests for piab.py"""
|
||||
|
||||
from sympy.core.numbers import pi
|
||||
from sympy.core.singleton import S
|
||||
from sympy.core.symbol import symbols
|
||||
from sympy.functions.elementary.miscellaneous import sqrt
|
||||
from sympy.functions.elementary.trigonometric import sin
|
||||
from sympy.sets.sets import Interval
|
||||
from sympy.functions.special.tensor_functions import KroneckerDelta
|
||||
from sympy.physics.quantum import L2, qapply, hbar, represent
|
||||
from sympy.physics.quantum.piab import PIABHamiltonian, PIABKet, PIABBra, m, L
|
||||
|
||||
i, j, n, x = symbols('i j n x')
|
||||
|
||||
|
||||
def test_H():
|
||||
assert PIABHamiltonian('H').hilbert_space == \
|
||||
L2(Interval(S.NegativeInfinity, S.Infinity))
|
||||
assert qapply(PIABHamiltonian('H')*PIABKet(n)) == \
|
||||
(n**2*pi**2*hbar**2)/(2*m*L**2)*PIABKet(n)
|
||||
|
||||
|
||||
def test_states():
|
||||
assert PIABKet(n).dual_class() == PIABBra
|
||||
assert PIABKet(n).hilbert_space == \
|
||||
L2(Interval(S.NegativeInfinity, S.Infinity))
|
||||
assert represent(PIABKet(n)) == sqrt(2/L)*sin(n*pi*x/L)
|
||||
assert (PIABBra(i)*PIABKet(j)).doit() == KroneckerDelta(i, j)
|
||||
assert PIABBra(n).dual_class() == PIABKet
|
||||
@@ -0,0 +1,900 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
"""
|
||||
TODO:
|
||||
* Address Issue 2251, printing of spin states
|
||||
"""
|
||||
from __future__ import annotations
|
||||
from typing import Any
|
||||
|
||||
from sympy.physics.quantum.anticommutator import AntiCommutator
|
||||
from sympy.physics.quantum.cg import CG, Wigner3j, Wigner6j, Wigner9j
|
||||
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 CGate, CNotGate, IdentityGate, UGate, XGate
|
||||
from sympy.physics.quantum.hilbert import ComplexSpace, FockSpace, HilbertSpace, L2
|
||||
from sympy.physics.quantum.innerproduct import InnerProduct
|
||||
from sympy.physics.quantum.operator import Operator, OuterProduct, DifferentialOperator
|
||||
from sympy.physics.quantum.qexpr import QExpr
|
||||
from sympy.physics.quantum.qubit import Qubit, IntQubit
|
||||
from sympy.physics.quantum.spin import Jz, J2, JzBra, JzBraCoupled, JzKet, JzKetCoupled, Rotation, WignerD
|
||||
from sympy.physics.quantum.state import Bra, Ket, TimeDepBra, TimeDepKet
|
||||
from sympy.physics.quantum.tensorproduct import TensorProduct
|
||||
from sympy.physics.quantum.sho1d import RaisingOp
|
||||
|
||||
from sympy.core.function import (Derivative, Function)
|
||||
from sympy.core.numbers import oo
|
||||
from sympy.core.power import Pow
|
||||
from sympy.core.singleton import S
|
||||
from sympy.core.symbol import (Symbol, symbols)
|
||||
from sympy.matrices.dense import Matrix
|
||||
from sympy.sets.sets import Interval
|
||||
from sympy.testing.pytest import XFAIL
|
||||
|
||||
# Imports used in srepr strings
|
||||
from sympy.physics.quantum.spin import JzOp
|
||||
|
||||
from sympy.printing import srepr
|
||||
from sympy.printing.pretty import pretty as xpretty
|
||||
from sympy.printing.latex import latex
|
||||
|
||||
MutableDenseMatrix = Matrix
|
||||
|
||||
|
||||
ENV: dict[str, Any] = {}
|
||||
exec('from sympy import *', ENV)
|
||||
exec('from sympy.physics.quantum import *', ENV)
|
||||
exec('from sympy.physics.quantum.cg import *', ENV)
|
||||
exec('from sympy.physics.quantum.spin import *', ENV)
|
||||
exec('from sympy.physics.quantum.hilbert import *', ENV)
|
||||
exec('from sympy.physics.quantum.qubit import *', ENV)
|
||||
exec('from sympy.physics.quantum.qexpr import *', ENV)
|
||||
exec('from sympy.physics.quantum.gate import *', ENV)
|
||||
exec('from sympy.physics.quantum.constants import *', ENV)
|
||||
|
||||
|
||||
def sT(expr, string):
|
||||
"""
|
||||
sT := sreprTest
|
||||
from sympy/printing/tests/test_repr.py
|
||||
"""
|
||||
assert srepr(expr) == string
|
||||
assert eval(string, ENV) == expr
|
||||
|
||||
|
||||
def pretty(expr):
|
||||
"""ASCII pretty-printing"""
|
||||
return xpretty(expr, use_unicode=False, wrap_line=False)
|
||||
|
||||
|
||||
def upretty(expr):
|
||||
"""Unicode pretty-printing"""
|
||||
return xpretty(expr, use_unicode=True, wrap_line=False)
|
||||
|
||||
|
||||
def test_anticommutator():
|
||||
A = Operator('A')
|
||||
B = Operator('B')
|
||||
ac = AntiCommutator(A, B)
|
||||
ac_tall = AntiCommutator(A**2, B)
|
||||
assert str(ac) == '{A,B}'
|
||||
assert pretty(ac) == '{A,B}'
|
||||
assert upretty(ac) == '{A,B}'
|
||||
assert latex(ac) == r'\left\{A,B\right\}'
|
||||
sT(ac, "AntiCommutator(Operator(Symbol('A')),Operator(Symbol('B')))")
|
||||
assert str(ac_tall) == '{A**2,B}'
|
||||
ascii_str = \
|
||||
"""\
|
||||
/ 2 \\\n\
|
||||
<A ,B>\n\
|
||||
\\ /\
|
||||
"""
|
||||
ucode_str = \
|
||||
"""\
|
||||
⎧ 2 ⎫\n\
|
||||
⎨A ,B⎬\n\
|
||||
⎩ ⎭\
|
||||
"""
|
||||
assert pretty(ac_tall) == ascii_str
|
||||
assert upretty(ac_tall) == ucode_str
|
||||
assert latex(ac_tall) == r'\left\{A^{2},B\right\}'
|
||||
sT(ac_tall, "AntiCommutator(Pow(Operator(Symbol('A')), Integer(2)),Operator(Symbol('B')))")
|
||||
|
||||
|
||||
def test_cg():
|
||||
cg = CG(1, 2, 3, 4, 5, 6)
|
||||
wigner3j = Wigner3j(1, 2, 3, 4, 5, 6)
|
||||
wigner6j = Wigner6j(1, 2, 3, 4, 5, 6)
|
||||
wigner9j = Wigner9j(1, 2, 3, 4, 5, 6, 7, 8, 9)
|
||||
assert str(cg) == 'CG(1, 2, 3, 4, 5, 6)'
|
||||
ascii_str = \
|
||||
"""\
|
||||
5,6 \n\
|
||||
C \n\
|
||||
1,2,3,4\
|
||||
"""
|
||||
ucode_str = \
|
||||
"""\
|
||||
5,6 \n\
|
||||
C \n\
|
||||
1,2,3,4\
|
||||
"""
|
||||
assert pretty(cg) == ascii_str
|
||||
assert upretty(cg) == ucode_str
|
||||
assert latex(cg) == 'C^{5,6}_{1,2,3,4}'
|
||||
assert latex(cg ** 2) == R'\left(C^{5,6}_{1,2,3,4}\right)^{2}'
|
||||
sT(cg, "CG(Integer(1), Integer(2), Integer(3), Integer(4), Integer(5), Integer(6))")
|
||||
assert str(wigner3j) == 'Wigner3j(1, 2, 3, 4, 5, 6)'
|
||||
ascii_str = \
|
||||
"""\
|
||||
/1 3 5\\\n\
|
||||
| |\n\
|
||||
\\2 4 6/\
|
||||
"""
|
||||
ucode_str = \
|
||||
"""\
|
||||
⎛1 3 5⎞\n\
|
||||
⎜ ⎟\n\
|
||||
⎝2 4 6⎠\
|
||||
"""
|
||||
assert pretty(wigner3j) == ascii_str
|
||||
assert upretty(wigner3j) == ucode_str
|
||||
assert latex(wigner3j) == \
|
||||
r'\left(\begin{array}{ccc} 1 & 3 & 5 \\ 2 & 4 & 6 \end{array}\right)'
|
||||
sT(wigner3j, "Wigner3j(Integer(1), Integer(2), Integer(3), Integer(4), Integer(5), Integer(6))")
|
||||
assert str(wigner6j) == 'Wigner6j(1, 2, 3, 4, 5, 6)'
|
||||
ascii_str = \
|
||||
"""\
|
||||
/1 2 3\\\n\
|
||||
< >\n\
|
||||
\\4 5 6/\
|
||||
"""
|
||||
ucode_str = \
|
||||
"""\
|
||||
⎧1 2 3⎫\n\
|
||||
⎨ ⎬\n\
|
||||
⎩4 5 6⎭\
|
||||
"""
|
||||
assert pretty(wigner6j) == ascii_str
|
||||
assert upretty(wigner6j) == ucode_str
|
||||
assert latex(wigner6j) == \
|
||||
r'\left\{\begin{array}{ccc} 1 & 2 & 3 \\ 4 & 5 & 6 \end{array}\right\}'
|
||||
sT(wigner6j, "Wigner6j(Integer(1), Integer(2), Integer(3), Integer(4), Integer(5), Integer(6))")
|
||||
assert str(wigner9j) == 'Wigner9j(1, 2, 3, 4, 5, 6, 7, 8, 9)'
|
||||
ascii_str = \
|
||||
"""\
|
||||
/1 2 3\\\n\
|
||||
| |\n\
|
||||
<4 5 6>\n\
|
||||
| |\n\
|
||||
\\7 8 9/\
|
||||
"""
|
||||
ucode_str = \
|
||||
"""\
|
||||
⎧1 2 3⎫\n\
|
||||
⎪ ⎪\n\
|
||||
⎨4 5 6⎬\n\
|
||||
⎪ ⎪\n\
|
||||
⎩7 8 9⎭\
|
||||
"""
|
||||
assert pretty(wigner9j) == ascii_str
|
||||
assert upretty(wigner9j) == ucode_str
|
||||
assert latex(wigner9j) == \
|
||||
r'\left\{\begin{array}{ccc} 1 & 2 & 3 \\ 4 & 5 & 6 \\ 7 & 8 & 9 \end{array}\right\}'
|
||||
sT(wigner9j, "Wigner9j(Integer(1), Integer(2), Integer(3), Integer(4), Integer(5), Integer(6), Integer(7), Integer(8), Integer(9))")
|
||||
|
||||
|
||||
def test_commutator():
|
||||
A = Operator('A')
|
||||
B = Operator('B')
|
||||
c = Commutator(A, B)
|
||||
c_tall = Commutator(A**2, B)
|
||||
assert str(c) == '[A,B]'
|
||||
assert pretty(c) == '[A,B]'
|
||||
assert upretty(c) == '[A,B]'
|
||||
assert latex(c) == r'\left[A,B\right]'
|
||||
sT(c, "Commutator(Operator(Symbol('A')),Operator(Symbol('B')))")
|
||||
assert str(c_tall) == '[A**2,B]'
|
||||
ascii_str = \
|
||||
"""\
|
||||
[ 2 ]\n\
|
||||
[A ,B]\
|
||||
"""
|
||||
ucode_str = \
|
||||
"""\
|
||||
⎡ 2 ⎤\n\
|
||||
⎣A ,B⎦\
|
||||
"""
|
||||
assert pretty(c_tall) == ascii_str
|
||||
assert upretty(c_tall) == ucode_str
|
||||
assert latex(c_tall) == r'\left[A^{2},B\right]'
|
||||
sT(c_tall, "Commutator(Pow(Operator(Symbol('A')), Integer(2)),Operator(Symbol('B')))")
|
||||
|
||||
|
||||
def test_constants():
|
||||
assert str(hbar) == 'hbar'
|
||||
assert pretty(hbar) == 'hbar'
|
||||
assert upretty(hbar) == 'ℏ'
|
||||
assert latex(hbar) == r'\hbar'
|
||||
sT(hbar, "HBar()")
|
||||
|
||||
|
||||
def test_dagger():
|
||||
x = symbols('x', commutative=False)
|
||||
expr = Dagger(x)
|
||||
assert str(expr) == 'Dagger(x)'
|
||||
ascii_str = \
|
||||
"""\
|
||||
+\n\
|
||||
x \
|
||||
"""
|
||||
ucode_str = \
|
||||
"""\
|
||||
†\n\
|
||||
x \
|
||||
"""
|
||||
assert pretty(expr) == ascii_str
|
||||
assert upretty(expr) == ucode_str
|
||||
assert latex(expr) == r'x^{\dagger}'
|
||||
sT(expr, "Dagger(Symbol('x', commutative=False))")
|
||||
|
||||
|
||||
@XFAIL
|
||||
def test_gate_failing():
|
||||
a, b, c, d = symbols('a,b,c,d')
|
||||
uMat = Matrix([[a, b], [c, d]])
|
||||
g = UGate((0,), uMat)
|
||||
assert str(g) == 'U(0)'
|
||||
|
||||
|
||||
def test_gate():
|
||||
a, b, c, d = symbols('a,b,c,d')
|
||||
uMat = Matrix([[a, b], [c, d]])
|
||||
q = Qubit(1, 0, 1, 0, 1)
|
||||
g1 = IdentityGate(2)
|
||||
g2 = CGate((3, 0), XGate(1))
|
||||
g3 = CNotGate(1, 0)
|
||||
g4 = UGate((0,), uMat)
|
||||
assert str(g1) == '1(2)'
|
||||
assert pretty(g1) == '1 \n 2'
|
||||
assert upretty(g1) == '1 \n 2'
|
||||
assert latex(g1) == r'1_{2}'
|
||||
sT(g1, "IdentityGate(Integer(2))")
|
||||
assert str(g1*q) == '1(2)*|10101>'
|
||||
ascii_str = \
|
||||
"""\
|
||||
1 *|10101>\n\
|
||||
2 \
|
||||
"""
|
||||
ucode_str = \
|
||||
"""\
|
||||
1 ⋅❘10101⟩\n\
|
||||
2 \
|
||||
"""
|
||||
assert pretty(g1*q) == ascii_str
|
||||
assert upretty(g1*q) == ucode_str
|
||||
assert latex(g1*q) == r'1_{2} {\left|10101\right\rangle }'
|
||||
sT(g1*q, "Mul(IdentityGate(Integer(2)), Qubit(Integer(1),Integer(0),Integer(1),Integer(0),Integer(1)))")
|
||||
assert str(g2) == 'C((3,0),X(1))'
|
||||
ascii_str = \
|
||||
"""\
|
||||
C /X \\\n\
|
||||
3,0\\ 1/\
|
||||
"""
|
||||
ucode_str = \
|
||||
"""\
|
||||
C ⎛X ⎞\n\
|
||||
3,0⎝ 1⎠\
|
||||
"""
|
||||
assert pretty(g2) == ascii_str
|
||||
assert upretty(g2) == ucode_str
|
||||
assert latex(g2) == r'C_{3,0}{\left(X_{1}\right)}'
|
||||
sT(g2, "CGate(Tuple(Integer(3), Integer(0)),XGate(Integer(1)))")
|
||||
assert str(g3) == 'CNOT(1,0)'
|
||||
ascii_str = \
|
||||
"""\
|
||||
CNOT \n\
|
||||
1,0\
|
||||
"""
|
||||
ucode_str = \
|
||||
"""\
|
||||
CNOT \n\
|
||||
1,0\
|
||||
"""
|
||||
assert pretty(g3) == ascii_str
|
||||
assert upretty(g3) == ucode_str
|
||||
assert latex(g3) == r'\text{CNOT}_{1,0}'
|
||||
sT(g3, "CNotGate(Integer(1),Integer(0))")
|
||||
ascii_str = \
|
||||
"""\
|
||||
U \n\
|
||||
0\
|
||||
"""
|
||||
ucode_str = \
|
||||
"""\
|
||||
U \n\
|
||||
0\
|
||||
"""
|
||||
assert str(g4) == \
|
||||
"""\
|
||||
U((0,),Matrix([\n\
|
||||
[a, b],\n\
|
||||
[c, d]]))\
|
||||
"""
|
||||
assert pretty(g4) == ascii_str
|
||||
assert upretty(g4) == ucode_str
|
||||
assert latex(g4) == r'U_{0}'
|
||||
sT(g4, "UGate(Tuple(Integer(0)),ImmutableDenseMatrix([[Symbol('a'), Symbol('b')], [Symbol('c'), Symbol('d')]]))")
|
||||
|
||||
|
||||
def test_hilbert():
|
||||
h1 = HilbertSpace()
|
||||
h2 = ComplexSpace(2)
|
||||
h3 = FockSpace()
|
||||
h4 = L2(Interval(0, oo))
|
||||
assert str(h1) == 'H'
|
||||
assert pretty(h1) == 'H'
|
||||
assert upretty(h1) == 'H'
|
||||
assert latex(h1) == r'\mathcal{H}'
|
||||
sT(h1, "HilbertSpace()")
|
||||
assert str(h2) == 'C(2)'
|
||||
ascii_str = \
|
||||
"""\
|
||||
2\n\
|
||||
C \
|
||||
"""
|
||||
ucode_str = \
|
||||
"""\
|
||||
2\n\
|
||||
C \
|
||||
"""
|
||||
assert pretty(h2) == ascii_str
|
||||
assert upretty(h2) == ucode_str
|
||||
assert latex(h2) == r'\mathcal{C}^{2}'
|
||||
sT(h2, "ComplexSpace(Integer(2))")
|
||||
assert str(h3) == 'F'
|
||||
assert pretty(h3) == 'F'
|
||||
assert upretty(h3) == 'F'
|
||||
assert latex(h3) == r'\mathcal{F}'
|
||||
sT(h3, "FockSpace()")
|
||||
assert str(h4) == 'L2(Interval(0, oo))'
|
||||
ascii_str = \
|
||||
"""\
|
||||
2\n\
|
||||
L \
|
||||
"""
|
||||
ucode_str = \
|
||||
"""\
|
||||
2\n\
|
||||
L \
|
||||
"""
|
||||
assert pretty(h4) == ascii_str
|
||||
assert upretty(h4) == ucode_str
|
||||
assert latex(h4) == r'{\mathcal{L}^2}\left( \left[0, \infty\right) \right)'
|
||||
sT(h4, "L2(Interval(Integer(0), oo, false, true))")
|
||||
assert str(h1 + h2) == 'H+C(2)'
|
||||
ascii_str = \
|
||||
"""\
|
||||
2\n\
|
||||
H + C \
|
||||
"""
|
||||
ucode_str = \
|
||||
"""\
|
||||
2\n\
|
||||
H ⊕ C \
|
||||
"""
|
||||
assert pretty(h1 + h2) == ascii_str
|
||||
assert upretty(h1 + h2) == ucode_str
|
||||
assert latex(h1 + h2)
|
||||
sT(h1 + h2, "DirectSumHilbertSpace(HilbertSpace(),ComplexSpace(Integer(2)))")
|
||||
assert str(h1*h2) == "H*C(2)"
|
||||
ascii_str = \
|
||||
"""\
|
||||
2\n\
|
||||
H x C \
|
||||
"""
|
||||
ucode_str = \
|
||||
"""\
|
||||
2\n\
|
||||
H ⨂ C \
|
||||
"""
|
||||
assert pretty(h1*h2) == ascii_str
|
||||
assert upretty(h1*h2) == ucode_str
|
||||
assert latex(h1*h2)
|
||||
sT(h1*h2,
|
||||
"TensorProductHilbertSpace(HilbertSpace(),ComplexSpace(Integer(2)))")
|
||||
assert str(h1**2) == 'H**2'
|
||||
ascii_str = \
|
||||
"""\
|
||||
x2\n\
|
||||
H \
|
||||
"""
|
||||
ucode_str = \
|
||||
"""\
|
||||
⨂2\n\
|
||||
H \
|
||||
"""
|
||||
assert pretty(h1**2) == ascii_str
|
||||
assert upretty(h1**2) == ucode_str
|
||||
assert latex(h1**2) == r'{\mathcal{H}}^{\otimes 2}'
|
||||
sT(h1**2, "TensorPowerHilbertSpace(HilbertSpace(),Integer(2))")
|
||||
|
||||
|
||||
def test_innerproduct():
|
||||
x = symbols('x')
|
||||
ip1 = InnerProduct(Bra(), Ket())
|
||||
ip2 = InnerProduct(TimeDepBra(), TimeDepKet())
|
||||
ip3 = InnerProduct(JzBra(1, 1), JzKet(1, 1))
|
||||
ip4 = InnerProduct(JzBraCoupled(1, 1, (1, 1)), JzKetCoupled(1, 1, (1, 1)))
|
||||
ip_tall1 = InnerProduct(Bra(x/2), Ket(x/2))
|
||||
ip_tall2 = InnerProduct(Bra(x), Ket(x/2))
|
||||
ip_tall3 = InnerProduct(Bra(x/2), Ket(x))
|
||||
assert str(ip1) == '<psi|psi>'
|
||||
assert pretty(ip1) == '<psi|psi>'
|
||||
assert upretty(ip1) == '⟨ψ❘ψ⟩'
|
||||
assert latex(
|
||||
ip1) == r'\left\langle \psi \right. {\left|\psi\right\rangle }'
|
||||
sT(ip1, "InnerProduct(Bra(Symbol('psi')),Ket(Symbol('psi')))")
|
||||
assert str(ip2) == '<psi;t|psi;t>'
|
||||
assert pretty(ip2) == '<psi;t|psi;t>'
|
||||
assert upretty(ip2) == '⟨ψ;t❘ψ;t⟩'
|
||||
assert latex(ip2) == \
|
||||
r'\left\langle \psi;t \right. {\left|\psi;t\right\rangle }'
|
||||
sT(ip2, "InnerProduct(TimeDepBra(Symbol('psi'),Symbol('t')),TimeDepKet(Symbol('psi'),Symbol('t')))")
|
||||
assert str(ip3) == "<1,1|1,1>"
|
||||
assert pretty(ip3) == '<1,1|1,1>'
|
||||
assert upretty(ip3) == '⟨1,1❘1,1⟩'
|
||||
assert latex(ip3) == r'\left\langle 1,1 \right. {\left|1,1\right\rangle }'
|
||||
sT(ip3, "InnerProduct(JzBra(Integer(1),Integer(1)),JzKet(Integer(1),Integer(1)))")
|
||||
assert str(ip4) == "<1,1,j1=1,j2=1|1,1,j1=1,j2=1>"
|
||||
assert pretty(ip4) == '<1,1,j1=1,j2=1|1,1,j1=1,j2=1>'
|
||||
assert upretty(ip4) == '⟨1,1,j₁=1,j₂=1❘1,1,j₁=1,j₂=1⟩'
|
||||
assert latex(ip4) == \
|
||||
r'\left\langle 1,1,j_{1}=1,j_{2}=1 \right. {\left|1,1,j_{1}=1,j_{2}=1\right\rangle }'
|
||||
sT(ip4, "InnerProduct(JzBraCoupled(Integer(1),Integer(1),Tuple(Integer(1), Integer(1)),Tuple(Tuple(Integer(1), Integer(2), Integer(1)))),JzKetCoupled(Integer(1),Integer(1),Tuple(Integer(1), Integer(1)),Tuple(Tuple(Integer(1), Integer(2), Integer(1)))))")
|
||||
assert str(ip_tall1) == '<x/2|x/2>'
|
||||
ascii_str = \
|
||||
"""\
|
||||
/ | \\ \n\
|
||||
/ x|x \\\n\
|
||||
\\ -|- /\n\
|
||||
\\2|2/ \
|
||||
"""
|
||||
ucode_str = \
|
||||
"""\
|
||||
╱ │ ╲ \n\
|
||||
╱ x│x ╲\n\
|
||||
╲ ─│─ ╱\n\
|
||||
╲2│2╱ \
|
||||
"""
|
||||
assert pretty(ip_tall1) == ascii_str
|
||||
assert upretty(ip_tall1) == ucode_str
|
||||
assert latex(ip_tall1) == \
|
||||
r'\left\langle \frac{x}{2} \right. {\left|\frac{x}{2}\right\rangle }'
|
||||
sT(ip_tall1, "InnerProduct(Bra(Mul(Rational(1, 2), Symbol('x'))),Ket(Mul(Rational(1, 2), Symbol('x'))))")
|
||||
assert str(ip_tall2) == '<x|x/2>'
|
||||
ascii_str = \
|
||||
"""\
|
||||
/ | \\ \n\
|
||||
/ |x \\\n\
|
||||
\\ x|- /\n\
|
||||
\\ |2/ \
|
||||
"""
|
||||
ucode_str = \
|
||||
"""\
|
||||
╱ │ ╲ \n\
|
||||
╱ │x ╲\n\
|
||||
╲ x│─ ╱\n\
|
||||
╲ │2╱ \
|
||||
"""
|
||||
assert pretty(ip_tall2) == ascii_str
|
||||
assert upretty(ip_tall2) == ucode_str
|
||||
assert latex(ip_tall2) == \
|
||||
r'\left\langle x \right. {\left|\frac{x}{2}\right\rangle }'
|
||||
sT(ip_tall2,
|
||||
"InnerProduct(Bra(Symbol('x')),Ket(Mul(Rational(1, 2), Symbol('x'))))")
|
||||
assert str(ip_tall3) == '<x/2|x>'
|
||||
ascii_str = \
|
||||
"""\
|
||||
/ | \\ \n\
|
||||
/ x| \\\n\
|
||||
\\ -|x /\n\
|
||||
\\2| / \
|
||||
"""
|
||||
ucode_str = \
|
||||
"""\
|
||||
╱ │ ╲ \n\
|
||||
╱ x│ ╲\n\
|
||||
╲ ─│x ╱\n\
|
||||
╲2│ ╱ \
|
||||
"""
|
||||
assert pretty(ip_tall3) == ascii_str
|
||||
assert upretty(ip_tall3) == ucode_str
|
||||
assert latex(ip_tall3) == \
|
||||
r'\left\langle \frac{x}{2} \right. {\left|x\right\rangle }'
|
||||
sT(ip_tall3,
|
||||
"InnerProduct(Bra(Mul(Rational(1, 2), Symbol('x'))),Ket(Symbol('x')))")
|
||||
|
||||
|
||||
def test_operator():
|
||||
a = Operator('A')
|
||||
b = Operator('B', Symbol('t'), S.Half)
|
||||
inv = a.inv()
|
||||
f = Function('f')
|
||||
x = symbols('x')
|
||||
d = DifferentialOperator(Derivative(f(x), x), f(x))
|
||||
op = OuterProduct(Ket(), Bra())
|
||||
assert str(a) == 'A'
|
||||
assert pretty(a) == 'A'
|
||||
assert upretty(a) == 'A'
|
||||
assert latex(a) == 'A'
|
||||
sT(a, "Operator(Symbol('A'))")
|
||||
assert str(inv) == 'A**(-1)'
|
||||
ascii_str = \
|
||||
"""\
|
||||
-1\n\
|
||||
A \
|
||||
"""
|
||||
ucode_str = \
|
||||
"""\
|
||||
-1\n\
|
||||
A \
|
||||
"""
|
||||
assert pretty(inv) == ascii_str
|
||||
assert upretty(inv) == ucode_str
|
||||
assert latex(inv) == r'A^{-1}'
|
||||
sT(inv, "Pow(Operator(Symbol('A')), Integer(-1))")
|
||||
assert str(d) == 'DifferentialOperator(Derivative(f(x), x),f(x))'
|
||||
ascii_str = \
|
||||
"""\
|
||||
/d \\\n\
|
||||
DifferentialOperator|--(f(x)),f(x)|\n\
|
||||
\\dx /\
|
||||
"""
|
||||
ucode_str = \
|
||||
"""\
|
||||
⎛d ⎞\n\
|
||||
DifferentialOperator⎜──(f(x)),f(x)⎟\n\
|
||||
⎝dx ⎠\
|
||||
"""
|
||||
assert pretty(d) == ascii_str
|
||||
assert upretty(d) == ucode_str
|
||||
assert latex(d) == \
|
||||
r'DifferentialOperator\left(\frac{d}{d x} f{\left(x \right)},f{\left(x \right)}\right)'
|
||||
sT(d, "DifferentialOperator(Derivative(Function('f')(Symbol('x')), Tuple(Symbol('x'), Integer(1))),Function('f')(Symbol('x')))")
|
||||
assert str(b) == 'Operator(B,t,1/2)'
|
||||
assert pretty(b) == 'Operator(B,t,1/2)'
|
||||
assert upretty(b) == 'Operator(B,t,1/2)'
|
||||
assert latex(b) == r'Operator\left(B,t,\frac{1}{2}\right)'
|
||||
sT(b, "Operator(Symbol('B'),Symbol('t'),Rational(1, 2))")
|
||||
assert str(op) == '|psi><psi|'
|
||||
assert pretty(op) == '|psi><psi|'
|
||||
assert upretty(op) == '❘ψ⟩⟨ψ❘'
|
||||
assert latex(op) == r'{\left|\psi\right\rangle }{\left\langle \psi\right|}'
|
||||
sT(op, "OuterProduct(Ket(Symbol('psi')),Bra(Symbol('psi')))")
|
||||
|
||||
|
||||
def test_qexpr():
|
||||
q = QExpr('q')
|
||||
assert str(q) == 'q'
|
||||
assert pretty(q) == 'q'
|
||||
assert upretty(q) == 'q'
|
||||
assert latex(q) == r'q'
|
||||
sT(q, "QExpr(Symbol('q'))")
|
||||
|
||||
|
||||
def test_qubit():
|
||||
q1 = Qubit('0101')
|
||||
q2 = IntQubit(8)
|
||||
assert str(q1) == '|0101>'
|
||||
assert pretty(q1) == '|0101>'
|
||||
assert upretty(q1) == '❘0101⟩'
|
||||
assert latex(q1) == r'{\left|0101\right\rangle }'
|
||||
sT(q1, "Qubit(Integer(0),Integer(1),Integer(0),Integer(1))")
|
||||
assert str(q2) == '|8>'
|
||||
assert pretty(q2) == '|8>'
|
||||
assert upretty(q2) == '❘8⟩'
|
||||
assert latex(q2) == r'{\left|8\right\rangle }'
|
||||
sT(q2, "IntQubit(8)")
|
||||
|
||||
|
||||
def test_spin():
|
||||
lz = JzOp('L')
|
||||
ket = JzKet(1, 0)
|
||||
bra = JzBra(1, 0)
|
||||
cket = JzKetCoupled(1, 0, (1, 2))
|
||||
cbra = JzBraCoupled(1, 0, (1, 2))
|
||||
cket_big = JzKetCoupled(1, 0, (1, 2, 3))
|
||||
cbra_big = JzBraCoupled(1, 0, (1, 2, 3))
|
||||
rot = Rotation(1, 2, 3)
|
||||
bigd = WignerD(1, 2, 3, 4, 5, 6)
|
||||
smalld = WignerD(1, 2, 3, 0, 4, 0)
|
||||
assert str(lz) == 'Lz'
|
||||
ascii_str = \
|
||||
"""\
|
||||
L \n\
|
||||
z\
|
||||
"""
|
||||
ucode_str = \
|
||||
"""\
|
||||
L \n\
|
||||
z\
|
||||
"""
|
||||
assert pretty(lz) == ascii_str
|
||||
assert upretty(lz) == ucode_str
|
||||
assert latex(lz) == 'L_z'
|
||||
sT(lz, "JzOp(Symbol('L'))")
|
||||
assert str(J2) == 'J2'
|
||||
ascii_str = \
|
||||
"""\
|
||||
2\n\
|
||||
J \
|
||||
"""
|
||||
ucode_str = \
|
||||
"""\
|
||||
2\n\
|
||||
J \
|
||||
"""
|
||||
assert pretty(J2) == ascii_str
|
||||
assert upretty(J2) == ucode_str
|
||||
assert latex(J2) == r'J^2'
|
||||
sT(J2, "J2Op(Symbol('J'))")
|
||||
assert str(Jz) == 'Jz'
|
||||
ascii_str = \
|
||||
"""\
|
||||
J \n\
|
||||
z\
|
||||
"""
|
||||
ucode_str = \
|
||||
"""\
|
||||
J \n\
|
||||
z\
|
||||
"""
|
||||
assert pretty(Jz) == ascii_str
|
||||
assert upretty(Jz) == ucode_str
|
||||
assert latex(Jz) == 'J_z'
|
||||
sT(Jz, "JzOp(Symbol('J'))")
|
||||
assert str(ket) == '|1,0>'
|
||||
assert pretty(ket) == '|1,0>'
|
||||
assert upretty(ket) == '❘1,0⟩'
|
||||
assert latex(ket) == r'{\left|1,0\right\rangle }'
|
||||
sT(ket, "JzKet(Integer(1),Integer(0))")
|
||||
assert str(bra) == '<1,0|'
|
||||
assert pretty(bra) == '<1,0|'
|
||||
assert upretty(bra) == '⟨1,0❘'
|
||||
assert latex(bra) == r'{\left\langle 1,0\right|}'
|
||||
sT(bra, "JzBra(Integer(1),Integer(0))")
|
||||
assert str(cket) == '|1,0,j1=1,j2=2>'
|
||||
assert pretty(cket) == '|1,0,j1=1,j2=2>'
|
||||
assert upretty(cket) == '❘1,0,j₁=1,j₂=2⟩'
|
||||
assert latex(cket) == r'{\left|1,0,j_{1}=1,j_{2}=2\right\rangle }'
|
||||
sT(cket, "JzKetCoupled(Integer(1),Integer(0),Tuple(Integer(1), Integer(2)),Tuple(Tuple(Integer(1), Integer(2), Integer(1))))")
|
||||
assert str(cbra) == '<1,0,j1=1,j2=2|'
|
||||
assert pretty(cbra) == '<1,0,j1=1,j2=2|'
|
||||
assert upretty(cbra) == '⟨1,0,j₁=1,j₂=2❘'
|
||||
assert latex(cbra) == r'{\left\langle 1,0,j_{1}=1,j_{2}=2\right|}'
|
||||
sT(cbra, "JzBraCoupled(Integer(1),Integer(0),Tuple(Integer(1), Integer(2)),Tuple(Tuple(Integer(1), Integer(2), Integer(1))))")
|
||||
assert str(cket_big) == '|1,0,j1=1,j2=2,j3=3,j(1,2)=3>'
|
||||
# TODO: Fix non-unicode pretty printing
|
||||
# i.e. j1,2 -> j(1,2)
|
||||
assert pretty(cket_big) == '|1,0,j1=1,j2=2,j3=3,j1,2=3>'
|
||||
assert upretty(cket_big) == '❘1,0,j₁=1,j₂=2,j₃=3,j₁,₂=3⟩'
|
||||
assert latex(cket_big) == \
|
||||
r'{\left|1,0,j_{1}=1,j_{2}=2,j_{3}=3,j_{1,2}=3\right\rangle }'
|
||||
sT(cket_big, "JzKetCoupled(Integer(1),Integer(0),Tuple(Integer(1), Integer(2), Integer(3)),Tuple(Tuple(Integer(1), Integer(2), Integer(3)), Tuple(Integer(1), Integer(3), Integer(1))))")
|
||||
assert str(cbra_big) == '<1,0,j1=1,j2=2,j3=3,j(1,2)=3|'
|
||||
assert pretty(cbra_big) == '<1,0,j1=1,j2=2,j3=3,j1,2=3|'
|
||||
assert upretty(cbra_big) == '⟨1,0,j₁=1,j₂=2,j₃=3,j₁,₂=3❘'
|
||||
assert latex(cbra_big) == \
|
||||
r'{\left\langle 1,0,j_{1}=1,j_{2}=2,j_{3}=3,j_{1,2}=3\right|}'
|
||||
sT(cbra_big, "JzBraCoupled(Integer(1),Integer(0),Tuple(Integer(1), Integer(2), Integer(3)),Tuple(Tuple(Integer(1), Integer(2), Integer(3)), Tuple(Integer(1), Integer(3), Integer(1))))")
|
||||
assert str(rot) == 'R(1,2,3)'
|
||||
assert pretty(rot) == 'R (1,2,3)'
|
||||
assert upretty(rot) == 'ℛ (1,2,3)'
|
||||
assert latex(rot) == r'\mathcal{R}\left(1,2,3\right)'
|
||||
sT(rot, "Rotation(Integer(1),Integer(2),Integer(3))")
|
||||
assert str(bigd) == 'WignerD(1, 2, 3, 4, 5, 6)'
|
||||
ascii_str = \
|
||||
"""\
|
||||
1 \n\
|
||||
D (4,5,6)\n\
|
||||
2,3 \
|
||||
"""
|
||||
ucode_str = \
|
||||
"""\
|
||||
1 \n\
|
||||
D (4,5,6)\n\
|
||||
2,3 \
|
||||
"""
|
||||
assert pretty(bigd) == ascii_str
|
||||
assert upretty(bigd) == ucode_str
|
||||
assert latex(bigd) == r'D^{1}_{2,3}\left(4,5,6\right)'
|
||||
sT(bigd, "WignerD(Integer(1), Integer(2), Integer(3), Integer(4), Integer(5), Integer(6))")
|
||||
assert str(smalld) == 'WignerD(1, 2, 3, 0, 4, 0)'
|
||||
ascii_str = \
|
||||
"""\
|
||||
1 \n\
|
||||
d (4)\n\
|
||||
2,3 \
|
||||
"""
|
||||
ucode_str = \
|
||||
"""\
|
||||
1 \n\
|
||||
d (4)\n\
|
||||
2,3 \
|
||||
"""
|
||||
assert pretty(smalld) == ascii_str
|
||||
assert upretty(smalld) == ucode_str
|
||||
assert latex(smalld) == r'd^{1}_{2,3}\left(4\right)'
|
||||
sT(smalld, "WignerD(Integer(1), Integer(2), Integer(3), Integer(0), Integer(4), Integer(0))")
|
||||
|
||||
|
||||
def test_state():
|
||||
x = symbols('x')
|
||||
bra = Bra()
|
||||
ket = Ket()
|
||||
bra_tall = Bra(x/2)
|
||||
ket_tall = Ket(x/2)
|
||||
tbra = TimeDepBra()
|
||||
tket = TimeDepKet()
|
||||
assert str(bra) == '<psi|'
|
||||
assert pretty(bra) == '<psi|'
|
||||
assert upretty(bra) == '⟨ψ❘'
|
||||
assert latex(bra) == r'{\left\langle \psi\right|}'
|
||||
sT(bra, "Bra(Symbol('psi'))")
|
||||
assert str(ket) == '|psi>'
|
||||
assert pretty(ket) == '|psi>'
|
||||
assert upretty(ket) == '❘ψ⟩'
|
||||
assert latex(ket) == r'{\left|\psi\right\rangle }'
|
||||
sT(ket, "Ket(Symbol('psi'))")
|
||||
assert str(bra_tall) == '<x/2|'
|
||||
ascii_str = \
|
||||
"""\
|
||||
/ |\n\
|
||||
/ x|\n\
|
||||
\\ -|\n\
|
||||
\\2|\
|
||||
"""
|
||||
ucode_str = \
|
||||
"""\
|
||||
╱ │\n\
|
||||
╱ x│\n\
|
||||
╲ ─│\n\
|
||||
╲2│\
|
||||
"""
|
||||
assert pretty(bra_tall) == ascii_str
|
||||
assert upretty(bra_tall) == ucode_str
|
||||
assert latex(bra_tall) == r'{\left\langle \frac{x}{2}\right|}'
|
||||
sT(bra_tall, "Bra(Mul(Rational(1, 2), Symbol('x')))")
|
||||
assert str(ket_tall) == '|x/2>'
|
||||
ascii_str = \
|
||||
"""\
|
||||
| \\ \n\
|
||||
|x \\\n\
|
||||
|- /\n\
|
||||
|2/ \
|
||||
"""
|
||||
ucode_str = \
|
||||
"""\
|
||||
│ ╲ \n\
|
||||
│x ╲\n\
|
||||
│─ ╱\n\
|
||||
│2╱ \
|
||||
"""
|
||||
assert pretty(ket_tall) == ascii_str
|
||||
assert upretty(ket_tall) == ucode_str
|
||||
assert latex(ket_tall) == r'{\left|\frac{x}{2}\right\rangle }'
|
||||
sT(ket_tall, "Ket(Mul(Rational(1, 2), Symbol('x')))")
|
||||
assert str(tbra) == '<psi;t|'
|
||||
assert pretty(tbra) == '<psi;t|'
|
||||
assert upretty(tbra) == '⟨ψ;t❘'
|
||||
assert latex(tbra) == r'{\left\langle \psi;t\right|}'
|
||||
sT(tbra, "TimeDepBra(Symbol('psi'),Symbol('t'))")
|
||||
assert str(tket) == '|psi;t>'
|
||||
assert pretty(tket) == '|psi;t>'
|
||||
assert upretty(tket) == '❘ψ;t⟩'
|
||||
assert latex(tket) == r'{\left|\psi;t\right\rangle }'
|
||||
sT(tket, "TimeDepKet(Symbol('psi'),Symbol('t'))")
|
||||
|
||||
|
||||
def test_tensorproduct():
|
||||
tp = TensorProduct(JzKet(1, 1), JzKet(1, 0))
|
||||
assert str(tp) == '|1,1>x|1,0>'
|
||||
assert pretty(tp) == '|1,1>x |1,0>'
|
||||
assert upretty(tp) == '❘1,1⟩⨂ ❘1,0⟩'
|
||||
assert latex(tp) == \
|
||||
r'{{\left|1,1\right\rangle }}\otimes {{\left|1,0\right\rangle }}'
|
||||
sT(tp, "TensorProduct(JzKet(Integer(1),Integer(1)), JzKet(Integer(1),Integer(0)))")
|
||||
|
||||
|
||||
def test_big_expr():
|
||||
f = Function('f')
|
||||
x = symbols('x')
|
||||
e1 = Dagger(AntiCommutator(Operator('A') + Operator('B'), Pow(DifferentialOperator(Derivative(f(x), x), f(x)), 3))*TensorProduct(Jz**2, Operator('A') + Operator('B')))*(JzBra(1, 0) + JzBra(1, 1))*(JzKet(0, 0) + JzKet(1, -1))
|
||||
e2 = Commutator(Jz**2, Operator('A') + Operator('B'))*AntiCommutator(Dagger(Operator('C')*Operator('D')), Operator('E').inv()**2)*Dagger(Commutator(Jz, J2))
|
||||
e3 = Wigner3j(1, 2, 3, 4, 5, 6)*TensorProduct(Commutator(Operator('A') + Dagger(Operator('B')), Operator('C') + Operator('D')), Jz - J2)*Dagger(OuterProduct(Dagger(JzBra(1, 1)), JzBra(1, 0)))*TensorProduct(JzKetCoupled(1, 1, (1, 1)) + JzKetCoupled(1, 0, (1, 1)), JzKetCoupled(1, -1, (1, 1)))
|
||||
e4 = (ComplexSpace(1)*ComplexSpace(2) + FockSpace()**2)*(L2(Interval(
|
||||
0, oo)) + HilbertSpace())
|
||||
assert str(e1) == '(Jz**2)x(Dagger(A) + Dagger(B))*{Dagger(DifferentialOperator(Derivative(f(x), x),f(x)))**3,Dagger(A) + Dagger(B)}*(<1,0| + <1,1|)*(|0,0> + |1,-1>)'
|
||||
ascii_str = \
|
||||
"""\
|
||||
/ 3 \\ \n\
|
||||
|/ +\\ | \n\
|
||||
2 / + +\\ <| /d \\ | + +> \n\
|
||||
/J \\ x \\A + B /*||DifferentialOperator|--(f(x)),f(x)| | ,A + B |*(<1,0| + <1,1|)*(|0,0> + |1,-1>)\n\
|
||||
\\ z/ \\\\ \\dx / / / \
|
||||
"""
|
||||
ucode_str = \
|
||||
"""\
|
||||
⎧ 3 ⎫ \n\
|
||||
⎪⎛ †⎞ ⎪ \n\
|
||||
2 ⎛ † †⎞ ⎨⎜ ⎛d ⎞ ⎟ † †⎬ \n\
|
||||
⎛J ⎞ ⨂ ⎝A + B ⎠⋅⎪⎜DifferentialOperator⎜──(f(x)),f(x)⎟ ⎟ ,A + B ⎪⋅(⟨1,0❘ + ⟨1,1❘)⋅(❘0,0⟩ + ❘1,-1⟩)\n\
|
||||
⎝ z⎠ ⎩⎝ ⎝dx ⎠ ⎠ ⎭ \
|
||||
"""
|
||||
assert pretty(e1) == ascii_str
|
||||
assert upretty(e1) == ucode_str
|
||||
assert latex(e1) == \
|
||||
r'{J_z^{2}}\otimes \left({A^{\dagger} + B^{\dagger}}\right) \left\{\left(DifferentialOperator\left(\frac{d}{d x} f{\left(x \right)},f{\left(x \right)}\right)^{\dagger}\right)^{3},A^{\dagger} + B^{\dagger}\right\} \left({\left\langle 1,0\right|} + {\left\langle 1,1\right|}\right) \left({\left|0,0\right\rangle } + {\left|1,-1\right\rangle }\right)'
|
||||
sT(e1, "Mul(TensorProduct(Pow(JzOp(Symbol('J')), Integer(2)), Add(Dagger(Operator(Symbol('A'))), Dagger(Operator(Symbol('B'))))), AntiCommutator(Pow(Dagger(DifferentialOperator(Derivative(Function('f')(Symbol('x')), Tuple(Symbol('x'), Integer(1))),Function('f')(Symbol('x')))), Integer(3)),Add(Dagger(Operator(Symbol('A'))), Dagger(Operator(Symbol('B'))))), Add(JzBra(Integer(1),Integer(0)), JzBra(Integer(1),Integer(1))), Add(JzKet(Integer(0),Integer(0)), JzKet(Integer(1),Integer(-1))))")
|
||||
assert str(e2) == '[Jz**2,A + B]*{E**(-2),Dagger(D)*Dagger(C)}*[J2,Jz]'
|
||||
ascii_str = \
|
||||
"""\
|
||||
[ 2 ] / -2 + +\\ [ 2 ]\n\
|
||||
[/J \\ ,A + B]*<E ,D *C >*[J ,J ]\n\
|
||||
[\\ z/ ] \\ / [ z]\
|
||||
"""
|
||||
ucode_str = \
|
||||
"""\
|
||||
⎡ 2 ⎤ ⎧ -2 † †⎫ ⎡ 2 ⎤\n\
|
||||
⎢⎛J ⎞ ,A + B⎥⋅⎨E ,D ⋅C ⎬⋅⎢J ,J ⎥\n\
|
||||
⎣⎝ z⎠ ⎦ ⎩ ⎭ ⎣ z⎦\
|
||||
"""
|
||||
assert pretty(e2) == ascii_str
|
||||
assert upretty(e2) == ucode_str
|
||||
assert latex(e2) == \
|
||||
r'\left[J_z^{2},A + B\right] \left\{E^{-2},D^{\dagger} C^{\dagger}\right\} \left[J^2,J_z\right]'
|
||||
sT(e2, "Mul(Commutator(Pow(JzOp(Symbol('J')), Integer(2)),Add(Operator(Symbol('A')), Operator(Symbol('B')))), AntiCommutator(Pow(Operator(Symbol('E')), Integer(-2)),Mul(Dagger(Operator(Symbol('D'))), Dagger(Operator(Symbol('C'))))), Commutator(J2Op(Symbol('J')),JzOp(Symbol('J'))))")
|
||||
assert str(e3) == \
|
||||
"Wigner3j(1, 2, 3, 4, 5, 6)*[Dagger(B) + A,C + D]x(-J2 + Jz)*|1,0><1,1|*(|1,0,j1=1,j2=1> + |1,1,j1=1,j2=1>)x|1,-1,j1=1,j2=1>"
|
||||
ascii_str = \
|
||||
"""\
|
||||
[ + ] / 2 \\ \n\
|
||||
/1 3 5\\*[B + A,C + D]x |- J + J |*|1,0><1,1|*(|1,0,j1=1,j2=1> + |1,1,j1=1,j2=1>)x |1,-1,j1=1,j2=1>\n\
|
||||
| | \\ z/ \n\
|
||||
\\2 4 6/ \
|
||||
"""
|
||||
ucode_str = \
|
||||
"""\
|
||||
⎡ † ⎤ ⎛ 2 ⎞ \n\
|
||||
⎛1 3 5⎞⋅⎣B + A,C + D⎦⨂ ⎜- J + J ⎟⋅❘1,0⟩⟨1,1❘⋅(❘1,0,j₁=1,j₂=1⟩ + ❘1,1,j₁=1,j₂=1⟩)⨂ ❘1,-1,j₁=1,j₂=1⟩\n\
|
||||
⎜ ⎟ ⎝ z⎠ \n\
|
||||
⎝2 4 6⎠ \
|
||||
"""
|
||||
assert pretty(e3) == ascii_str
|
||||
assert upretty(e3) == ucode_str
|
||||
assert latex(e3) == \
|
||||
r'\left(\begin{array}{ccc} 1 & 3 & 5 \\ 2 & 4 & 6 \end{array}\right) {\left[B^{\dagger} + A,C + D\right]}\otimes \left({- J^2 + J_z}\right) {\left|1,0\right\rangle }{\left\langle 1,1\right|} \left({{\left|1,0,j_{1}=1,j_{2}=1\right\rangle } + {\left|1,1,j_{1}=1,j_{2}=1\right\rangle }}\right)\otimes {{\left|1,-1,j_{1}=1,j_{2}=1\right\rangle }}'
|
||||
sT(e3, "Mul(Wigner3j(Integer(1), Integer(2), Integer(3), Integer(4), Integer(5), Integer(6)), TensorProduct(Commutator(Add(Dagger(Operator(Symbol('B'))), Operator(Symbol('A'))),Add(Operator(Symbol('C')), Operator(Symbol('D')))), Add(Mul(Integer(-1), J2Op(Symbol('J'))), JzOp(Symbol('J')))), OuterProduct(JzKet(Integer(1),Integer(0)),JzBra(Integer(1),Integer(1))), TensorProduct(Add(JzKetCoupled(Integer(1),Integer(0),Tuple(Integer(1), Integer(1)),Tuple(Tuple(Integer(1), Integer(2), Integer(1)))), JzKetCoupled(Integer(1),Integer(1),Tuple(Integer(1), Integer(1)),Tuple(Tuple(Integer(1), Integer(2), Integer(1))))), JzKetCoupled(Integer(1),Integer(-1),Tuple(Integer(1), Integer(1)),Tuple(Tuple(Integer(1), Integer(2), Integer(1))))))")
|
||||
assert str(e4) == '(C(1)*C(2)+F**2)*(L2(Interval(0, oo))+H)'
|
||||
ascii_str = \
|
||||
"""\
|
||||
// 1 2\\ x2\\ / 2 \\\n\
|
||||
\\\\C x C / + F / x \\L + H/\
|
||||
"""
|
||||
ucode_str = \
|
||||
"""\
|
||||
⎛⎛ 1 2⎞ ⨂2⎞ ⎛ 2 ⎞\n\
|
||||
⎝⎝C ⨂ C ⎠ ⊕ F ⎠ ⨂ ⎝L ⊕ H⎠\
|
||||
"""
|
||||
assert pretty(e4) == ascii_str
|
||||
assert upretty(e4) == ucode_str
|
||||
assert latex(e4) == \
|
||||
r'\left(\left(\mathcal{C}^{1}\otimes \mathcal{C}^{2}\right)\oplus {\mathcal{F}}^{\otimes 2}\right)\otimes \left({\mathcal{L}^2}\left( \left[0, \infty\right) \right)\oplus \mathcal{H}\right)'
|
||||
sT(e4, "TensorProductHilbertSpace((DirectSumHilbertSpace(TensorProductHilbertSpace(ComplexSpace(Integer(1)),ComplexSpace(Integer(2))),TensorPowerHilbertSpace(FockSpace(),Integer(2)))),(DirectSumHilbertSpace(L2(Interval(Integer(0), oo, false, true)),HilbertSpace())))")
|
||||
|
||||
|
||||
def _test_sho1d():
|
||||
ad = RaisingOp('a')
|
||||
assert pretty(ad) == ' \N{DAGGER}\na '
|
||||
assert latex(ad) == 'a^{\\dagger}'
|
||||
@@ -0,0 +1,152 @@
|
||||
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
|
||||
from sympy.testing.pytest import warns_deprecated_sympy
|
||||
|
||||
|
||||
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() == S.One
|
||||
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 P2 == QubitBra(1) # qapply(P1) -> 0 before fix
|
||||
# Pull Request 24237: IdentityOperator from the right without dagger=True option
|
||||
with warns_deprecated_sympy():
|
||||
assert qapply(QubitBra(1)*IdentityOperator()) == QubitBra(1)
|
||||
assert qapply(IdentityGate(0)*(Qubit(0) + Qubit(1))) == Qubit(0) + Qubit(1)
|
||||
@@ -0,0 +1,89 @@
|
||||
from sympy.physics.quantum.qasm import Qasm, flip_index, trim,\
|
||||
get_index, nonblank, fullsplit, fixcommand, stripquotes, read_qasm
|
||||
from sympy.physics.quantum.gate import X, Z, H, S, T
|
||||
from sympy.physics.quantum.gate import CNOT, SWAP, CPHASE, CGate, CGateS
|
||||
from sympy.physics.quantum.circuitplot import Mz
|
||||
|
||||
def test_qasm_readqasm():
|
||||
qasm_lines = """\
|
||||
qubit q_0
|
||||
qubit q_1
|
||||
h q_0
|
||||
cnot q_0,q_1
|
||||
"""
|
||||
q = read_qasm(qasm_lines)
|
||||
assert q.get_circuit() == CNOT(1,0)*H(1)
|
||||
|
||||
def test_qasm_ex1():
|
||||
q = Qasm('qubit q0', 'qubit q1', 'h q0', 'cnot q0,q1')
|
||||
assert q.get_circuit() == CNOT(1,0)*H(1)
|
||||
|
||||
def test_qasm_ex1_methodcalls():
|
||||
q = Qasm()
|
||||
q.qubit('q_0')
|
||||
q.qubit('q_1')
|
||||
q.h('q_0')
|
||||
q.cnot('q_0', 'q_1')
|
||||
assert q.get_circuit() == CNOT(1,0)*H(1)
|
||||
|
||||
def test_qasm_swap():
|
||||
q = Qasm('qubit q0', 'qubit q1', 'cnot q0,q1', 'cnot q1,q0', 'cnot q0,q1')
|
||||
assert q.get_circuit() == CNOT(1,0)*CNOT(0,1)*CNOT(1,0)
|
||||
|
||||
|
||||
def test_qasm_ex2():
|
||||
q = Qasm('qubit q_0', 'qubit q_1', 'qubit q_2', 'h q_1',
|
||||
'cnot q_1,q_2', 'cnot q_0,q_1', 'h q_0',
|
||||
'measure q_1', 'measure q_0',
|
||||
'c-x q_1,q_2', 'c-z q_0,q_2')
|
||||
assert q.get_circuit() == CGate(2,Z(0))*CGate(1,X(0))*Mz(2)*Mz(1)*H(2)*CNOT(2,1)*CNOT(1,0)*H(1)
|
||||
|
||||
def test_qasm_1q():
|
||||
for symbol, gate in [('x', X), ('z', Z), ('h', H), ('s', S), ('t', T), ('measure', Mz)]:
|
||||
q = Qasm('qubit q_0', '%s q_0' % symbol)
|
||||
assert q.get_circuit() == gate(0)
|
||||
|
||||
def test_qasm_2q():
|
||||
for symbol, gate in [('cnot', CNOT), ('swap', SWAP), ('cphase', CPHASE)]:
|
||||
q = Qasm('qubit q_0', 'qubit q_1', '%s q_0,q_1' % symbol)
|
||||
assert q.get_circuit() == gate(1,0)
|
||||
|
||||
def test_qasm_3q():
|
||||
q = Qasm('qubit q0', 'qubit q1', 'qubit q2', 'toffoli q2,q1,q0')
|
||||
assert q.get_circuit() == CGateS((0,1),X(2))
|
||||
|
||||
def test_qasm_flip_index():
|
||||
assert flip_index(0, 2) == 1
|
||||
assert flip_index(1, 2) == 0
|
||||
|
||||
def test_qasm_trim():
|
||||
assert trim('nothing happens here') == 'nothing happens here'
|
||||
assert trim("Something #happens here") == "Something "
|
||||
|
||||
def test_qasm_get_index():
|
||||
assert get_index('q0', ['q0', 'q1']) == 1
|
||||
assert get_index('q1', ['q0', 'q1']) == 0
|
||||
|
||||
def test_qasm_nonblank():
|
||||
assert list(nonblank('abcd')) == list('abcd')
|
||||
assert list(nonblank('abc ')) == list('abc')
|
||||
|
||||
def test_qasm_fullsplit():
|
||||
assert fullsplit('g q0,q1,q2, q3') == ('g', ['q0', 'q1', 'q2', 'q3'])
|
||||
|
||||
def test_qasm_fixcommand():
|
||||
assert fixcommand('foo') == 'foo'
|
||||
assert fixcommand('def') == 'qdef'
|
||||
|
||||
def test_qasm_stripquotes():
|
||||
assert stripquotes("'S'") == 'S'
|
||||
assert stripquotes('"S"') == 'S'
|
||||
assert stripquotes('S') == 'S'
|
||||
|
||||
def test_qasm_qdef():
|
||||
# weaker test condition (str) since we don't have access to the actual class
|
||||
q = Qasm("def Q,0,Q",'qubit q0','Q q0')
|
||||
assert str(q.get_circuit()) == 'Q(0)'
|
||||
|
||||
q = Qasm("def CQ,1,Q", 'qubit q0', 'qubit q1', 'CQ q0,q1')
|
||||
assert str(q.get_circuit()) == 'C((1),Q(0))'
|
||||
@@ -0,0 +1,64 @@
|
||||
from sympy.core.numbers import Integer
|
||||
from sympy.core.symbol import Symbol
|
||||
from sympy.concrete import Sum
|
||||
from sympy.physics.quantum.qexpr import QExpr, _qsympify_sequence
|
||||
from sympy.physics.quantum.hilbert import HilbertSpace
|
||||
from sympy.core.containers import Tuple
|
||||
|
||||
x = Symbol('x')
|
||||
y = Symbol('y')
|
||||
n = Symbol('n', integer=True)
|
||||
m = Symbol('m', integer=True)
|
||||
|
||||
|
||||
def test_qexpr_new():
|
||||
q = QExpr(0)
|
||||
assert q.label == (0,)
|
||||
assert q.hilbert_space == HilbertSpace()
|
||||
assert q.is_commutative is False
|
||||
|
||||
q = QExpr(0, 1)
|
||||
assert q.label == (Integer(0), Integer(1))
|
||||
|
||||
q = QExpr._new_rawargs(HilbertSpace(), Integer(0), Integer(1))
|
||||
assert q.label == (Integer(0), Integer(1))
|
||||
assert q.hilbert_space == HilbertSpace()
|
||||
|
||||
|
||||
def test_qexpr_commutative():
|
||||
q1 = QExpr(x)
|
||||
q2 = QExpr(y)
|
||||
assert q1.is_commutative is False
|
||||
assert q2.is_commutative is False
|
||||
assert q1*q2 != q2*q1
|
||||
|
||||
q = QExpr._new_rawargs(Integer(0), Integer(1), HilbertSpace())
|
||||
assert q.is_commutative is False
|
||||
|
||||
|
||||
def test_qexpr_free_symbols():
|
||||
q1 = QExpr(x, y)
|
||||
assert q1.free_symbols == {x, y}
|
||||
|
||||
|
||||
def test_qexpr_sum():
|
||||
q1 = Sum(QExpr(n), (n,0,2))
|
||||
assert q1.doit() == QExpr(0) + QExpr(1) + QExpr(2)
|
||||
|
||||
q2 = Sum(QExpr(n, m), (n, 0, 2), (m, 0, 2))
|
||||
assert q2.doit() == QExpr(0, 0) + QExpr(0, 1) + QExpr(0, 2) + \
|
||||
QExpr(1, 0) + QExpr(1, 1) + QExpr(1, 2) + \
|
||||
QExpr(2, 0) + QExpr(2, 1) + QExpr(2, 2)
|
||||
|
||||
|
||||
def test_qexpr_subs():
|
||||
q1 = QExpr(x, y)
|
||||
assert q1.subs(x, y) == QExpr(y, y)
|
||||
assert q1.subs({x: 1, y: 2}) == QExpr(1, 2)
|
||||
|
||||
|
||||
def test_qsympify():
|
||||
assert _qsympify_sequence([[1, 2], [1, 3]]) == (Tuple(1, 2), Tuple(1, 3))
|
||||
assert _qsympify_sequence(([1, 2, [3, 4, [2, ]], 1], 3)) == \
|
||||
(Tuple(1, 2, Tuple(3, 4, Tuple(2,)), 1), 3)
|
||||
assert _qsympify_sequence((1,)) == (1,)
|
||||
@@ -0,0 +1,52 @@
|
||||
from sympy.core.numbers import (I, pi)
|
||||
from sympy.core.symbol import Symbol
|
||||
from sympy.functions.elementary.exponential import exp
|
||||
from sympy.functions.elementary.miscellaneous import sqrt
|
||||
from sympy.matrices.dense import Matrix
|
||||
|
||||
from sympy.physics.quantum.qft import QFT, IQFT, RkGate
|
||||
from sympy.physics.quantum.gate import (ZGate, SwapGate, HadamardGate, CGate,
|
||||
PhaseGate, TGate)
|
||||
from sympy.physics.quantum.qubit import Qubit
|
||||
from sympy.physics.quantum.qapply import qapply
|
||||
from sympy.physics.quantum.represent import represent
|
||||
|
||||
from sympy.functions.elementary.complexes import sign
|
||||
|
||||
|
||||
def test_RkGate():
|
||||
x = Symbol('x')
|
||||
assert RkGate(1, x).k == x
|
||||
assert RkGate(1, x).targets == (1,)
|
||||
assert RkGate(1, 1) == ZGate(1)
|
||||
assert RkGate(2, 2) == PhaseGate(2)
|
||||
assert RkGate(3, 3) == TGate(3)
|
||||
|
||||
assert represent(
|
||||
RkGate(0, x), nqubits=1) == Matrix([[1, 0], [0, exp(sign(x)*2*pi*I/(2**abs(x)))]])
|
||||
|
||||
|
||||
def test_quantum_fourier():
|
||||
assert QFT(0, 3).decompose() == \
|
||||
SwapGate(0, 2)*HadamardGate(0)*CGate((0,), PhaseGate(1)) * \
|
||||
HadamardGate(1)*CGate((0,), TGate(2))*CGate((1,), PhaseGate(2)) * \
|
||||
HadamardGate(2)
|
||||
|
||||
assert IQFT(0, 3).decompose() == \
|
||||
HadamardGate(2)*CGate((1,), RkGate(2, -2))*CGate((0,), RkGate(2, -3)) * \
|
||||
HadamardGate(1)*CGate((0,), RkGate(1, -2))*HadamardGate(0)*SwapGate(0, 2)
|
||||
|
||||
assert represent(QFT(0, 3), nqubits=3) == \
|
||||
Matrix([[exp(2*pi*I/8)**(i*j % 8)/sqrt(8) for i in range(8)] for j in range(8)])
|
||||
|
||||
assert QFT(0, 4).decompose() # non-trivial decomposition
|
||||
assert qapply(QFT(0, 3).decompose()*Qubit(0, 0, 0)).expand() == qapply(
|
||||
HadamardGate(0)*HadamardGate(1)*HadamardGate(2)*Qubit(0, 0, 0)
|
||||
).expand()
|
||||
|
||||
|
||||
def test_qft_represent():
|
||||
c = QFT(0, 3)
|
||||
a = represent(c, nqubits=3)
|
||||
b = represent(c.decompose(), nqubits=3)
|
||||
assert a.evalf(n=10) == b.evalf(n=10)
|
||||
@@ -0,0 +1,264 @@
|
||||
import random
|
||||
|
||||
from sympy.core.numbers import (Integer, Rational)
|
||||
from sympy.core.singleton import S
|
||||
from sympy.core.symbol import symbols
|
||||
from sympy.functions.elementary.miscellaneous import sqrt
|
||||
from sympy.matrices.dense import Matrix
|
||||
from sympy.physics.quantum.qubit import (measure_all, measure_all_oneshot, measure_partial,
|
||||
matrix_to_qubit, matrix_to_density,
|
||||
qubit_to_matrix, IntQubit,
|
||||
IntQubitBra, QubitBra)
|
||||
from sympy.physics.quantum.gate import (HadamardGate, CNOT, XGate, YGate,
|
||||
ZGate, PhaseGate)
|
||||
from sympy.physics.quantum.qapply import qapply
|
||||
from sympy.physics.quantum.represent import represent
|
||||
from sympy.physics.quantum.shor import Qubit
|
||||
from sympy.testing.pytest import raises
|
||||
from sympy.physics.quantum.density import Density
|
||||
from sympy.physics.quantum.trace import Tr
|
||||
|
||||
x, y = symbols('x,y')
|
||||
|
||||
epsilon = .000001
|
||||
|
||||
|
||||
def test_Qubit():
|
||||
array = [0, 0, 1, 1, 0]
|
||||
qb = Qubit('00110')
|
||||
assert qb.flip(0) == Qubit('00111')
|
||||
assert qb.flip(1) == Qubit('00100')
|
||||
assert qb.flip(4) == Qubit('10110')
|
||||
assert qb.qubit_values == (0, 0, 1, 1, 0)
|
||||
assert qb.dimension == 5
|
||||
for i in range(5):
|
||||
assert qb[i] == array[4 - i]
|
||||
assert len(qb) == 5
|
||||
qb = Qubit('110')
|
||||
|
||||
|
||||
def test_QubitBra():
|
||||
qb = Qubit(0)
|
||||
qb_bra = QubitBra(0)
|
||||
assert qb.dual_class() == QubitBra
|
||||
assert qb_bra.dual_class() == Qubit
|
||||
|
||||
qb = Qubit(1, 1, 0)
|
||||
qb_bra = QubitBra(1, 1, 0)
|
||||
assert represent(qb, nqubits=3).H == represent(qb_bra, nqubits=3)
|
||||
|
||||
qb = Qubit(0, 1)
|
||||
qb_bra = QubitBra(1,0)
|
||||
assert qb._eval_innerproduct_QubitBra(qb_bra) == Integer(0)
|
||||
|
||||
qb_bra = QubitBra(0, 1)
|
||||
assert qb._eval_innerproduct_QubitBra(qb_bra) == Integer(1)
|
||||
|
||||
|
||||
def test_IntQubit():
|
||||
# issue 9136
|
||||
iqb = IntQubit(0, nqubits=1)
|
||||
assert qubit_to_matrix(Qubit('0')) == qubit_to_matrix(iqb)
|
||||
|
||||
qb = Qubit('1010')
|
||||
assert qubit_to_matrix(IntQubit(qb)) == qubit_to_matrix(qb)
|
||||
|
||||
iqb = IntQubit(1, nqubits=1)
|
||||
assert qubit_to_matrix(Qubit('1')) == qubit_to_matrix(iqb)
|
||||
assert qubit_to_matrix(IntQubit(1)) == qubit_to_matrix(iqb)
|
||||
|
||||
iqb = IntQubit(7, nqubits=4)
|
||||
assert qubit_to_matrix(Qubit('0111')) == qubit_to_matrix(iqb)
|
||||
assert qubit_to_matrix(IntQubit(7, 4)) == qubit_to_matrix(iqb)
|
||||
|
||||
iqb = IntQubit(8)
|
||||
assert iqb.as_int() == 8
|
||||
assert iqb.qubit_values == (1, 0, 0, 0)
|
||||
|
||||
iqb = IntQubit(7, 4)
|
||||
assert iqb.qubit_values == (0, 1, 1, 1)
|
||||
assert IntQubit(3) == IntQubit(3, 2)
|
||||
|
||||
#test Dual Classes
|
||||
iqb = IntQubit(3)
|
||||
iqb_bra = IntQubitBra(3)
|
||||
assert iqb.dual_class() == IntQubitBra
|
||||
assert iqb_bra.dual_class() == IntQubit
|
||||
|
||||
iqb = IntQubit(5)
|
||||
iqb_bra = IntQubitBra(5)
|
||||
assert iqb._eval_innerproduct_IntQubitBra(iqb_bra) == Integer(1)
|
||||
|
||||
iqb = IntQubit(4)
|
||||
iqb_bra = IntQubitBra(5)
|
||||
assert iqb._eval_innerproduct_IntQubitBra(iqb_bra) == Integer(0)
|
||||
raises(ValueError, lambda: IntQubit(4, 1))
|
||||
|
||||
raises(ValueError, lambda: IntQubit('5'))
|
||||
raises(ValueError, lambda: IntQubit(5, '5'))
|
||||
raises(ValueError, lambda: IntQubit(5, nqubits='5'))
|
||||
raises(TypeError, lambda: IntQubit(5, bad_arg=True))
|
||||
|
||||
def test_superposition_of_states():
|
||||
state = 1/sqrt(2)*Qubit('01') + 1/sqrt(2)*Qubit('10')
|
||||
state_gate = CNOT(0, 1)*HadamardGate(0)*state
|
||||
state_expanded = Qubit('01')/2 + Qubit('00')/2 - Qubit('11')/2 + Qubit('10')/2
|
||||
assert qapply(state_gate).expand() == state_expanded
|
||||
assert matrix_to_qubit(represent(state_gate, nqubits=2)) == state_expanded
|
||||
|
||||
|
||||
#test apply methods
|
||||
def test_apply_represent_equality():
|
||||
gates = [HadamardGate(int(3*random.random())),
|
||||
XGate(int(3*random.random())), ZGate(int(3*random.random())),
|
||||
YGate(int(3*random.random())), ZGate(int(3*random.random())),
|
||||
PhaseGate(int(3*random.random()))]
|
||||
|
||||
circuit = Qubit(int(random.random()*2), int(random.random()*2),
|
||||
int(random.random()*2), int(random.random()*2), int(random.random()*2),
|
||||
int(random.random()*2))
|
||||
for i in range(int(random.random()*6)):
|
||||
circuit = gates[int(random.random()*6)]*circuit
|
||||
|
||||
mat = represent(circuit, nqubits=6)
|
||||
states = qapply(circuit)
|
||||
state_rep = matrix_to_qubit(mat)
|
||||
states = states.expand()
|
||||
state_rep = state_rep.expand()
|
||||
assert state_rep == states
|
||||
|
||||
|
||||
def test_matrix_to_qubits():
|
||||
qb = Qubit(0, 0, 0, 0)
|
||||
mat = Matrix([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
|
||||
assert matrix_to_qubit(mat) == qb
|
||||
assert qubit_to_matrix(qb) == mat
|
||||
|
||||
state = 2*sqrt(2)*(Qubit(0, 0, 0) + Qubit(0, 0, 1) + Qubit(0, 1, 0) +
|
||||
Qubit(0, 1, 1) + Qubit(1, 0, 0) + Qubit(1, 0, 1) +
|
||||
Qubit(1, 1, 0) + Qubit(1, 1, 1))
|
||||
ones = sqrt(2)*2*Matrix([1, 1, 1, 1, 1, 1, 1, 1])
|
||||
assert matrix_to_qubit(ones) == state.expand()
|
||||
assert qubit_to_matrix(state) == ones
|
||||
|
||||
|
||||
def test_measure_normalize():
|
||||
a, b = symbols('a b')
|
||||
state = a*Qubit('110') + b*Qubit('111')
|
||||
assert measure_partial(state, (0,), normalize=False) == \
|
||||
[(a*Qubit('110'), a*a.conjugate()), (b*Qubit('111'), b*b.conjugate())]
|
||||
assert measure_all(state, normalize=False) == \
|
||||
[(Qubit('110'), a*a.conjugate()), (Qubit('111'), b*b.conjugate())]
|
||||
|
||||
|
||||
def test_measure_partial():
|
||||
#Basic test of collapse of entangled two qubits (Bell States)
|
||||
state = Qubit('01') + Qubit('10')
|
||||
assert measure_partial(state, (0,)) == \
|
||||
[(Qubit('10'), S.Half), (Qubit('01'), S.Half)]
|
||||
assert measure_partial(state, int(0)) == \
|
||||
[(Qubit('10'), S.Half), (Qubit('01'), S.Half)]
|
||||
assert measure_partial(state, (0,)) == \
|
||||
measure_partial(state, (1,))[::-1]
|
||||
|
||||
#Test of more complex collapse and probability calculation
|
||||
state1 = sqrt(2)/sqrt(3)*Qubit('00001') + 1/sqrt(3)*Qubit('11111')
|
||||
assert measure_partial(state1, (0,)) == \
|
||||
[(sqrt(2)/sqrt(3)*Qubit('00001') + 1/sqrt(3)*Qubit('11111'), 1)]
|
||||
assert measure_partial(state1, (1, 2)) == measure_partial(state1, (3, 4))
|
||||
assert measure_partial(state1, (1, 2, 3)) == \
|
||||
[(Qubit('00001'), Rational(2, 3)), (Qubit('11111'), Rational(1, 3))]
|
||||
|
||||
#test of measuring multiple bits at once
|
||||
state2 = Qubit('1111') + Qubit('1101') + Qubit('1011') + Qubit('1000')
|
||||
assert measure_partial(state2, (0, 1, 3)) == \
|
||||
[(Qubit('1000'), Rational(1, 4)), (Qubit('1101'), Rational(1, 4)),
|
||||
(Qubit('1011')/sqrt(2) + Qubit('1111')/sqrt(2), S.Half)]
|
||||
assert measure_partial(state2, (0,)) == \
|
||||
[(Qubit('1000'), Rational(1, 4)),
|
||||
(Qubit('1111')/sqrt(3) + Qubit('1101')/sqrt(3) +
|
||||
Qubit('1011')/sqrt(3), Rational(3, 4))]
|
||||
|
||||
|
||||
def test_measure_all():
|
||||
assert measure_all(Qubit('11')) == [(Qubit('11'), 1)]
|
||||
state = Qubit('11') + Qubit('10')
|
||||
assert measure_all(state) == [(Qubit('10'), S.Half),
|
||||
(Qubit('11'), S.Half)]
|
||||
state2 = Qubit('11')/sqrt(5) + 2*Qubit('00')/sqrt(5)
|
||||
assert measure_all(state2) == \
|
||||
[(Qubit('00'), Rational(4, 5)), (Qubit('11'), Rational(1, 5))]
|
||||
|
||||
# from issue #12585
|
||||
assert measure_all(qapply(Qubit('0'))) == [(Qubit('0'), 1)]
|
||||
|
||||
|
||||
def test_measure_all_oneshot():
|
||||
random.seed(42)
|
||||
# for issue #27092
|
||||
assert measure_all_oneshot(Qubit('11')) == Qubit('11')
|
||||
assert measure_all_oneshot(Qubit('1')) == Qubit('1')
|
||||
assert measure_all_oneshot(Qubit('0')/sqrt(2) + Qubit('1')/sqrt(2)) == \
|
||||
Qubit('0')
|
||||
|
||||
|
||||
def test_eval_trace():
|
||||
q1 = Qubit('10110')
|
||||
q2 = Qubit('01010')
|
||||
d = Density([q1, 0.6], [q2, 0.4])
|
||||
|
||||
t = Tr(d)
|
||||
assert t.doit() == 1.0
|
||||
|
||||
# extreme bits
|
||||
t = Tr(d, 0)
|
||||
assert t.doit() == (0.4*Density([Qubit('0101'), 1]) +
|
||||
0.6*Density([Qubit('1011'), 1]))
|
||||
t = Tr(d, 4)
|
||||
assert t.doit() == (0.4*Density([Qubit('1010'), 1]) +
|
||||
0.6*Density([Qubit('0110'), 1]))
|
||||
# index somewhere in between
|
||||
t = Tr(d, 2)
|
||||
assert t.doit() == (0.4*Density([Qubit('0110'), 1]) +
|
||||
0.6*Density([Qubit('1010'), 1]))
|
||||
#trace all indices
|
||||
t = Tr(d, [0, 1, 2, 3, 4])
|
||||
assert t.doit() == 1.0
|
||||
|
||||
# trace some indices, initialized in
|
||||
# non-canonical order
|
||||
t = Tr(d, [2, 1, 3])
|
||||
assert t.doit() == (0.4*Density([Qubit('00'), 1]) +
|
||||
0.6*Density([Qubit('10'), 1]))
|
||||
|
||||
# mixed states
|
||||
q = (1/sqrt(2)) * (Qubit('00') + Qubit('11'))
|
||||
d = Density( [q, 1.0] )
|
||||
t = Tr(d, 0)
|
||||
assert t.doit() == (0.5*Density([Qubit('0'), 1]) +
|
||||
0.5*Density([Qubit('1'), 1]))
|
||||
|
||||
|
||||
def test_matrix_to_density():
|
||||
mat = Matrix([[0, 0], [0, 1]])
|
||||
assert matrix_to_density(mat) == Density([Qubit('1'), 1])
|
||||
|
||||
mat = Matrix([[1, 0], [0, 0]])
|
||||
assert matrix_to_density(mat) == Density([Qubit('0'), 1])
|
||||
|
||||
mat = Matrix([[0, 0], [0, 0]])
|
||||
assert matrix_to_density(mat) == 0
|
||||
|
||||
mat = Matrix([[0, 0, 0, 0],
|
||||
[0, 0, 0, 0],
|
||||
[0, 0, 1, 0],
|
||||
[0, 0, 0, 0]])
|
||||
|
||||
assert matrix_to_density(mat) == Density([Qubit('10'), 1])
|
||||
|
||||
mat = Matrix([[1, 0, 0, 0],
|
||||
[0, 0, 0, 0],
|
||||
[0, 0, 0, 0],
|
||||
[0, 0, 0, 0]])
|
||||
|
||||
assert matrix_to_density(mat) == Density([Qubit('00'), 1])
|
||||
@@ -0,0 +1,186 @@
|
||||
from sympy.core.numbers import (Float, I, Integer)
|
||||
from sympy.matrices.dense import Matrix
|
||||
from sympy.external import import_module
|
||||
from sympy.testing.pytest import skip
|
||||
|
||||
from sympy.physics.quantum.dagger import Dagger
|
||||
from sympy.physics.quantum.represent import (represent, rep_innerproduct,
|
||||
rep_expectation, enumerate_states)
|
||||
from sympy.physics.quantum.state import Bra, Ket
|
||||
from sympy.physics.quantum.operator import Operator, OuterProduct
|
||||
from sympy.physics.quantum.tensorproduct import TensorProduct
|
||||
from sympy.physics.quantum.tensorproduct import matrix_tensor_product
|
||||
from sympy.physics.quantum.commutator import Commutator
|
||||
from sympy.physics.quantum.anticommutator import AntiCommutator
|
||||
from sympy.physics.quantum.innerproduct import InnerProduct
|
||||
from sympy.physics.quantum.matrixutils import (numpy_ndarray,
|
||||
scipy_sparse_matrix, to_numpy,
|
||||
to_scipy_sparse, to_sympy)
|
||||
from sympy.physics.quantum.cartesian import XKet, XOp, XBra
|
||||
from sympy.physics.quantum.qapply import qapply
|
||||
from sympy.physics.quantum.operatorset import operators_to_state
|
||||
from sympy.testing.pytest import raises
|
||||
|
||||
Amat = Matrix([[1, I], [-I, 1]])
|
||||
Bmat = Matrix([[1, 2], [3, 4]])
|
||||
Avec = Matrix([[1], [I]])
|
||||
|
||||
|
||||
class AKet(Ket):
|
||||
|
||||
@classmethod
|
||||
def dual_class(self):
|
||||
return ABra
|
||||
|
||||
def _represent_default_basis(self, **options):
|
||||
return self._represent_AOp(None, **options)
|
||||
|
||||
def _represent_AOp(self, basis, **options):
|
||||
return Avec
|
||||
|
||||
|
||||
class ABra(Bra):
|
||||
|
||||
@classmethod
|
||||
def dual_class(self):
|
||||
return AKet
|
||||
|
||||
|
||||
class AOp(Operator):
|
||||
|
||||
def _represent_default_basis(self, **options):
|
||||
return self._represent_AOp(None, **options)
|
||||
|
||||
def _represent_AOp(self, basis, **options):
|
||||
return Amat
|
||||
|
||||
|
||||
class BOp(Operator):
|
||||
|
||||
def _represent_default_basis(self, **options):
|
||||
return self._represent_AOp(None, **options)
|
||||
|
||||
def _represent_AOp(self, basis, **options):
|
||||
return Bmat
|
||||
|
||||
|
||||
k = AKet('a')
|
||||
b = ABra('a')
|
||||
A = AOp('A')
|
||||
B = BOp('B')
|
||||
|
||||
_tests = [
|
||||
# Bra
|
||||
(b, Dagger(Avec)),
|
||||
(Dagger(b), Avec),
|
||||
# Ket
|
||||
(k, Avec),
|
||||
(Dagger(k), Dagger(Avec)),
|
||||
# Operator
|
||||
(A, Amat),
|
||||
(Dagger(A), Dagger(Amat)),
|
||||
# OuterProduct
|
||||
(OuterProduct(k, b), Avec*Avec.H),
|
||||
# TensorProduct
|
||||
(TensorProduct(A, B), matrix_tensor_product(Amat, Bmat)),
|
||||
# Pow
|
||||
(A**2, Amat**2),
|
||||
# Add/Mul
|
||||
(A*B + 2*A, Amat*Bmat + 2*Amat),
|
||||
# Commutator
|
||||
(Commutator(A, B), Amat*Bmat - Bmat*Amat),
|
||||
# AntiCommutator
|
||||
(AntiCommutator(A, B), Amat*Bmat + Bmat*Amat),
|
||||
# InnerProduct
|
||||
(InnerProduct(b, k), (Avec.H*Avec)[0])
|
||||
]
|
||||
|
||||
|
||||
def test_format_sympy():
|
||||
for test in _tests:
|
||||
lhs = represent(test[0], basis=A, format='sympy')
|
||||
rhs = to_sympy(test[1])
|
||||
assert lhs == rhs
|
||||
|
||||
|
||||
def test_scalar_sympy():
|
||||
assert represent(Integer(1)) == Integer(1)
|
||||
assert represent(Float(1.0)) == Float(1.0)
|
||||
assert represent(1.0 + I) == 1.0 + I
|
||||
|
||||
|
||||
np = import_module('numpy')
|
||||
|
||||
|
||||
def test_format_numpy():
|
||||
if not np:
|
||||
skip("numpy not installed.")
|
||||
|
||||
for test in _tests:
|
||||
lhs = represent(test[0], basis=A, format='numpy')
|
||||
rhs = to_numpy(test[1])
|
||||
if isinstance(lhs, numpy_ndarray):
|
||||
assert (lhs == rhs).all()
|
||||
else:
|
||||
assert lhs == rhs
|
||||
|
||||
|
||||
def test_scalar_numpy():
|
||||
if not np:
|
||||
skip("numpy not installed.")
|
||||
|
||||
assert represent(Integer(1), format='numpy') == 1
|
||||
assert represent(Float(1.0), format='numpy') == 1.0
|
||||
assert represent(1.0 + I, format='numpy') == 1.0 + 1.0j
|
||||
|
||||
|
||||
scipy = import_module('scipy', import_kwargs={'fromlist': ['sparse']})
|
||||
|
||||
|
||||
def test_format_scipy_sparse():
|
||||
if not np:
|
||||
skip("numpy not installed.")
|
||||
if not scipy:
|
||||
skip("scipy not installed.")
|
||||
|
||||
for test in _tests:
|
||||
lhs = represent(test[0], basis=A, format='scipy.sparse')
|
||||
rhs = to_scipy_sparse(test[1])
|
||||
if isinstance(lhs, scipy_sparse_matrix):
|
||||
assert np.linalg.norm((lhs - rhs).todense()) == 0.0
|
||||
else:
|
||||
assert lhs == rhs
|
||||
|
||||
|
||||
def test_scalar_scipy_sparse():
|
||||
if not np:
|
||||
skip("numpy not installed.")
|
||||
if not scipy:
|
||||
skip("scipy not installed.")
|
||||
|
||||
assert represent(Integer(1), format='scipy.sparse') == 1
|
||||
assert represent(Float(1.0), format='scipy.sparse') == 1.0
|
||||
assert represent(1.0 + I, format='scipy.sparse') == 1.0 + 1.0j
|
||||
|
||||
x_ket = XKet('x')
|
||||
x_bra = XBra('x')
|
||||
x_op = XOp('X')
|
||||
|
||||
|
||||
def test_innerprod_represent():
|
||||
assert rep_innerproduct(x_ket) == InnerProduct(XBra("x_1"), x_ket).doit()
|
||||
assert rep_innerproduct(x_bra) == InnerProduct(x_bra, XKet("x_1")).doit()
|
||||
raises(TypeError, lambda: rep_innerproduct(x_op))
|
||||
|
||||
|
||||
def test_operator_represent():
|
||||
basis_kets = enumerate_states(operators_to_state(x_op), 1, 2)
|
||||
assert rep_expectation(
|
||||
x_op) == qapply(basis_kets[1].dual*x_op*basis_kets[0])
|
||||
|
||||
|
||||
def test_enumerate_states():
|
||||
test = XKet("foo")
|
||||
assert enumerate_states(test, 1, 1) == [XKet("foo_1")]
|
||||
assert enumerate_states(
|
||||
test, [1, 2, 4]) == [XKet("foo_1"), XKet("foo_2"), XKet("foo_4")]
|
||||
@@ -0,0 +1,176 @@
|
||||
"""Tests for sho1d.py"""
|
||||
|
||||
from sympy.concrete import Sum
|
||||
from sympy.core import oo
|
||||
from sympy.core.numbers import (I, Integer)
|
||||
from sympy.core.singleton import S
|
||||
from sympy.core.symbol import Symbol, symbols
|
||||
from sympy.functions.combinatorial.factorials import factorial
|
||||
from sympy.functions.elementary.exponential import exp
|
||||
from sympy.functions.elementary.miscellaneous import sqrt
|
||||
from sympy.functions.elementary.complexes import Abs
|
||||
from sympy.functions.special.tensor_functions import KroneckerDelta
|
||||
from sympy.physics.quantum import Dagger
|
||||
from sympy.physics.quantum.constants import hbar
|
||||
from sympy.physics.quantum import Commutator
|
||||
from sympy.physics.quantum.qapply import qapply
|
||||
from sympy.physics.quantum.innerproduct import InnerProduct
|
||||
from sympy.physics.quantum.cartesian import X, Px
|
||||
from sympy.physics.quantum.hilbert import ComplexSpace
|
||||
from sympy.physics.quantum.represent import represent
|
||||
from sympy.simplify import simplify
|
||||
from sympy.external import import_module
|
||||
from sympy.tensor import IndexedBase, Idx
|
||||
from sympy.testing.pytest import skip, raises
|
||||
|
||||
from sympy.physics.quantum.sho1d import (RaisingOp, LoweringOp,
|
||||
SHOKet, SHOBra,
|
||||
Hamiltonian, NumberOp)
|
||||
|
||||
ad = RaisingOp('a')
|
||||
a = LoweringOp('a')
|
||||
k = SHOKet('k')
|
||||
kz = SHOKet(0)
|
||||
kf = SHOKet(1)
|
||||
k3 = SHOKet(3)
|
||||
b = SHOBra('b')
|
||||
b3 = SHOBra(3)
|
||||
H = Hamiltonian('H')
|
||||
N = NumberOp('N')
|
||||
omega = Symbol('omega')
|
||||
m = Symbol('m')
|
||||
ndim = Integer(4)
|
||||
p = Symbol('p', integer=True)
|
||||
q = Symbol('q', nonnegative=True, integer=True)
|
||||
|
||||
|
||||
np = import_module('numpy')
|
||||
scipy = import_module('scipy', import_kwargs={'fromlist': ['sparse']})
|
||||
|
||||
ad_rep_sympy = represent(ad, basis=N, ndim=4, format='sympy')
|
||||
a_rep = represent(a, basis=N, ndim=4, format='sympy')
|
||||
N_rep = represent(N, basis=N, ndim=4, format='sympy')
|
||||
H_rep = represent(H, basis=N, ndim=4, format='sympy')
|
||||
k3_rep = represent(k3, basis=N, ndim=4, format='sympy')
|
||||
b3_rep = represent(b3, basis=N, ndim=4, format='sympy')
|
||||
|
||||
def test_RaisingOp():
|
||||
assert Dagger(ad) == a
|
||||
assert Commutator(ad, a).doit() == Integer(-1)
|
||||
assert Commutator(ad, N).doit() == Integer(-1)*ad
|
||||
assert qapply(ad*k) == (sqrt(k.n + 1)*SHOKet(k.n + 1)).expand()
|
||||
assert qapply(ad*kz) == (sqrt(kz.n + 1)*SHOKet(kz.n + 1)).expand()
|
||||
assert qapply(ad*kf) == (sqrt(kf.n + 1)*SHOKet(kf.n + 1)).expand()
|
||||
assert ad.rewrite('xp').doit() == \
|
||||
(Integer(1)/sqrt(Integer(2)*hbar*m*omega))*(Integer(-1)*I*Px + m*omega*X)
|
||||
assert ad.hilbert_space == ComplexSpace(S.Infinity)
|
||||
for i in range(ndim - 1):
|
||||
assert ad_rep_sympy[i + 1,i] == sqrt(i + 1)
|
||||
|
||||
if not np:
|
||||
skip("numpy not installed.")
|
||||
|
||||
ad_rep_numpy = represent(ad, basis=N, ndim=4, format='numpy')
|
||||
for i in range(ndim - 1):
|
||||
assert ad_rep_numpy[i + 1,i] == float(sqrt(i + 1))
|
||||
|
||||
if not np:
|
||||
skip("numpy not installed.")
|
||||
if not scipy:
|
||||
skip("scipy not installed.")
|
||||
|
||||
ad_rep_scipy = represent(ad, basis=N, ndim=4, format='scipy.sparse', spmatrix='lil')
|
||||
for i in range(ndim - 1):
|
||||
assert ad_rep_scipy[i + 1,i] == float(sqrt(i + 1))
|
||||
|
||||
assert ad_rep_numpy.dtype == 'float64'
|
||||
assert ad_rep_scipy.dtype == 'float64'
|
||||
|
||||
def test_LoweringOp():
|
||||
assert Dagger(a) == ad
|
||||
assert Commutator(a, ad).doit() == Integer(1)
|
||||
assert Commutator(a, N).doit() == a
|
||||
assert qapply(a*k) == (sqrt(k.n)*SHOKet(k.n-Integer(1))).expand()
|
||||
assert qapply(a*kz) == Integer(0)
|
||||
assert qapply(a*kf) == (sqrt(kf.n)*SHOKet(kf.n-Integer(1))).expand()
|
||||
assert a.rewrite('xp').doit() == \
|
||||
(Integer(1)/sqrt(Integer(2)*hbar*m*omega))*(I*Px + m*omega*X)
|
||||
for i in range(ndim - 1):
|
||||
assert a_rep[i,i + 1] == sqrt(i + 1)
|
||||
|
||||
def test_NumberOp():
|
||||
assert Commutator(N, ad).doit() == ad
|
||||
assert Commutator(N, a).doit() == Integer(-1)*a
|
||||
assert Commutator(N, H).doit() == Integer(0)
|
||||
assert qapply(N*k) == (k.n*k).expand()
|
||||
assert N.rewrite('a').doit() == ad*a
|
||||
assert N.rewrite('xp').doit() == (Integer(1)/(Integer(2)*m*hbar*omega))*(
|
||||
Px**2 + (m*omega*X)**2) - Integer(1)/Integer(2)
|
||||
assert N.rewrite('H').doit() == H/(hbar*omega) - Integer(1)/Integer(2)
|
||||
for i in range(ndim):
|
||||
assert N_rep[i,i] == i
|
||||
assert N_rep == ad_rep_sympy*a_rep
|
||||
|
||||
def test_Hamiltonian():
|
||||
assert Commutator(H, N).doit() == Integer(0)
|
||||
assert qapply(H*k) == ((hbar*omega*(k.n + Integer(1)/Integer(2)))*k).expand()
|
||||
assert H.rewrite('a').doit() == hbar*omega*(ad*a + Integer(1)/Integer(2))
|
||||
assert H.rewrite('xp').doit() == \
|
||||
(Integer(1)/(Integer(2)*m))*(Px**2 + (m*omega*X)**2)
|
||||
assert H.rewrite('N').doit() == hbar*omega*(N + Integer(1)/Integer(2))
|
||||
for i in range(ndim):
|
||||
assert H_rep[i,i] == hbar*omega*(i + Integer(1)/Integer(2))
|
||||
|
||||
def test_SHOKet():
|
||||
assert SHOKet('k').dual_class() == SHOBra
|
||||
assert SHOBra('b').dual_class() == SHOKet
|
||||
assert InnerProduct(b,k).doit() == KroneckerDelta(k.n, b.n)
|
||||
assert k.hilbert_space == ComplexSpace(S.Infinity)
|
||||
assert k3_rep[k3.n, 0] == Integer(1)
|
||||
assert b3_rep[0, b3.n] == Integer(1)
|
||||
|
||||
def test_sho_sums():
|
||||
e1 = Sum(SHOKet(p)*SHOBra(p), (p, 0, 1))
|
||||
assert e1.doit() == SHOKet(0)*SHOBra(0) + SHOKet(1)*SHOBra(1)
|
||||
|
||||
# Test qapply with Sum on the left
|
||||
assert qapply(
|
||||
Sum(SHOKet(p)*SHOBra(p), (p, 0, oo))*SHOKet(q),
|
||||
sum_doit=True
|
||||
) == SHOKet(q)
|
||||
|
||||
# Test qapply with Sum on the right
|
||||
a = IndexedBase('a')
|
||||
n = symbols('n', cls=Idx)
|
||||
result = qapply(SHOBra(q)*Sum(a[n]*SHOKet(n), (n,0,oo)), sum_doit=True)
|
||||
assert result == a[q]
|
||||
|
||||
# Test qapply with a product of Sums
|
||||
result = qapply(
|
||||
SHOBra(q)*Sum(SHOKet(p)*SHOBra(p), (p, 0, oo))*Sum(a[n]*SHOKet(n), (n,0,oo)),
|
||||
sum_doit=True
|
||||
)
|
||||
assert result == a[q]
|
||||
|
||||
with raises(ValueError):
|
||||
result = qapply(
|
||||
SHOBra(q)*Sum(SHOKet(p)*SHOBra(p), (p, 0, oo))*Sum(a[p]*SHOKet(p), (p,0,oo)),
|
||||
sum_doit=True
|
||||
)
|
||||
|
||||
def test_sho_coherant_state():
|
||||
alpha = Symbol('alpha', is_complex=True)
|
||||
cstate = exp(-Abs(alpha)**2/S(2))*Sum(((alpha**p)/sqrt(factorial(p)))*SHOKet(p), (p,0,oo))
|
||||
# Projection onto the number eigenstate
|
||||
assert qapply(SHOBra(q)*cstate, sum_doit=True) == exp(-Abs(alpha)**2/S(2))*alpha**q/sqrt(factorial(q))
|
||||
# Ensure that the coherent state is an eigenstate of annihilation operator
|
||||
assert simplify(qapply(SHOBra(q)*a*cstate, sum_doit=True)) == simplify(qapply(SHOBra(q)*alpha*cstate, sum_doit=True))
|
||||
|
||||
def test_issue_26495():
|
||||
nbar = Symbol('nbar', real=True, nonnegative=True)
|
||||
n = Symbol('n', integer=True)
|
||||
i = Symbol('i', integer=True, nonnegative=True)
|
||||
j = Symbol('j', integer=True, nonnegative=True)
|
||||
rho = Sum((nbar/(1+nbar))**n*SHOKet(n)*SHOBra(n), (n,0,oo))
|
||||
result = qapply(SHOBra(i)*rho*SHOKet(j), sum_doit=True)
|
||||
assert simplify(result) == (nbar/(nbar+1))**i*KroneckerDelta(i,j)
|
||||
@@ -0,0 +1,21 @@
|
||||
from sympy.testing.pytest import XFAIL
|
||||
|
||||
from sympy.physics.quantum.qapply import qapply
|
||||
from sympy.physics.quantum.qubit import Qubit
|
||||
from sympy.physics.quantum.shor import CMod, getr
|
||||
|
||||
|
||||
@XFAIL
|
||||
def test_CMod():
|
||||
assert qapply(CMod(4, 2, 2)*Qubit(0, 0, 1, 0, 0, 0, 0, 0)) == \
|
||||
Qubit(0, 0, 1, 0, 0, 0, 0, 0)
|
||||
assert qapply(CMod(5, 5, 7)*Qubit(0, 0, 1, 0, 0, 0, 0, 0, 0, 0)) == \
|
||||
Qubit(0, 0, 1, 0, 0, 0, 0, 0, 1, 0)
|
||||
assert qapply(CMod(3, 2, 3)*Qubit(0, 1, 0, 0, 0, 0)) == \
|
||||
Qubit(0, 1, 0, 0, 0, 1)
|
||||
|
||||
|
||||
def test_continued_frac():
|
||||
assert getr(513, 1024, 10) == 2
|
||||
assert getr(169, 1024, 11) == 6
|
||||
assert getr(314, 4096, 16) == 13
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,248 @@
|
||||
from sympy.core.add import Add
|
||||
from sympy.core.function import diff
|
||||
from sympy.core.mul import Mul
|
||||
from sympy.core.numbers import (I, Integer, Rational, oo, pi)
|
||||
from sympy.core.power import Pow
|
||||
from sympy.core.singleton import S
|
||||
from sympy.core.symbol import (Symbol, symbols)
|
||||
from sympy.core.sympify import sympify
|
||||
from sympy.functions.elementary.complexes import conjugate
|
||||
from sympy.functions.elementary.miscellaneous import sqrt
|
||||
from sympy.functions.elementary.trigonometric import sin
|
||||
from sympy.testing.pytest import raises
|
||||
|
||||
from sympy.physics.quantum.dagger import Dagger
|
||||
from sympy.physics.quantum.qexpr import QExpr
|
||||
from sympy.physics.quantum.state import (
|
||||
Ket, Bra, TimeDepKet, TimeDepBra,
|
||||
KetBase, BraBase, StateBase, Wavefunction,
|
||||
OrthogonalKet, OrthogonalBra
|
||||
)
|
||||
from sympy.physics.quantum.hilbert import HilbertSpace
|
||||
|
||||
x, y, t = symbols('x,y,t')
|
||||
|
||||
|
||||
class CustomKet(Ket):
|
||||
@classmethod
|
||||
def default_args(self):
|
||||
return ("test",)
|
||||
|
||||
|
||||
class CustomKetMultipleLabels(Ket):
|
||||
@classmethod
|
||||
def default_args(self):
|
||||
return ("r", "theta", "phi")
|
||||
|
||||
|
||||
class CustomTimeDepKet(TimeDepKet):
|
||||
@classmethod
|
||||
def default_args(self):
|
||||
return ("test", "t")
|
||||
|
||||
|
||||
class CustomTimeDepKetMultipleLabels(TimeDepKet):
|
||||
@classmethod
|
||||
def default_args(self):
|
||||
return ("r", "theta", "phi", "t")
|
||||
|
||||
|
||||
def test_ket():
|
||||
k = Ket('0')
|
||||
|
||||
assert isinstance(k, Ket)
|
||||
assert isinstance(k, KetBase)
|
||||
assert isinstance(k, StateBase)
|
||||
assert isinstance(k, QExpr)
|
||||
|
||||
assert k.label == (Symbol('0'),)
|
||||
assert k.hilbert_space == HilbertSpace()
|
||||
assert k.is_commutative is False
|
||||
|
||||
# Make sure this doesn't get converted to the number pi.
|
||||
k = Ket('pi')
|
||||
assert k.label == (Symbol('pi'),)
|
||||
|
||||
k = Ket(x, y)
|
||||
assert k.label == (x, y)
|
||||
assert k.hilbert_space == HilbertSpace()
|
||||
assert k.is_commutative is False
|
||||
|
||||
assert k.dual_class() == Bra
|
||||
assert k.dual == Bra(x, y)
|
||||
assert k.subs(x, y) == Ket(y, y)
|
||||
|
||||
k = CustomKet()
|
||||
assert k == CustomKet("test")
|
||||
|
||||
k = CustomKetMultipleLabels()
|
||||
assert k == CustomKetMultipleLabels("r", "theta", "phi")
|
||||
|
||||
assert Ket() == Ket('psi')
|
||||
|
||||
|
||||
def test_bra():
|
||||
b = Bra('0')
|
||||
|
||||
assert isinstance(b, Bra)
|
||||
assert isinstance(b, BraBase)
|
||||
assert isinstance(b, StateBase)
|
||||
assert isinstance(b, QExpr)
|
||||
|
||||
assert b.label == (Symbol('0'),)
|
||||
assert b.hilbert_space == HilbertSpace()
|
||||
assert b.is_commutative is False
|
||||
|
||||
# Make sure this doesn't get converted to the number pi.
|
||||
b = Bra('pi')
|
||||
assert b.label == (Symbol('pi'),)
|
||||
|
||||
b = Bra(x, y)
|
||||
assert b.label == (x, y)
|
||||
assert b.hilbert_space == HilbertSpace()
|
||||
assert b.is_commutative is False
|
||||
|
||||
assert b.dual_class() == Ket
|
||||
assert b.dual == Ket(x, y)
|
||||
assert b.subs(x, y) == Bra(y, y)
|
||||
|
||||
assert Bra() == Bra('psi')
|
||||
|
||||
|
||||
def test_ops():
|
||||
k0 = Ket(0)
|
||||
k1 = Ket(1)
|
||||
k = 2*I*k0 - (x/sqrt(2))*k1
|
||||
assert k == Add(Mul(2, I, k0),
|
||||
Mul(Rational(-1, 2), x, Pow(2, S.Half), k1))
|
||||
|
||||
|
||||
def test_time_dep_ket():
|
||||
k = TimeDepKet(0, t)
|
||||
|
||||
assert isinstance(k, TimeDepKet)
|
||||
assert isinstance(k, KetBase)
|
||||
assert isinstance(k, StateBase)
|
||||
assert isinstance(k, QExpr)
|
||||
|
||||
assert k.label == (Integer(0),)
|
||||
assert k.args == (Integer(0), t)
|
||||
assert k.time == t
|
||||
|
||||
assert k.dual_class() == TimeDepBra
|
||||
assert k.dual == TimeDepBra(0, t)
|
||||
|
||||
assert k.subs(t, 2) == TimeDepKet(0, 2)
|
||||
|
||||
k = TimeDepKet(x, 0.5)
|
||||
assert k.label == (x,)
|
||||
assert k.args == (x, sympify(0.5))
|
||||
|
||||
k = CustomTimeDepKet()
|
||||
assert k.label == (Symbol("test"),)
|
||||
assert k.time == Symbol("t")
|
||||
assert k == CustomTimeDepKet("test", "t")
|
||||
|
||||
k = CustomTimeDepKetMultipleLabels()
|
||||
assert k.label == (Symbol("r"), Symbol("theta"), Symbol("phi"))
|
||||
assert k.time == Symbol("t")
|
||||
assert k == CustomTimeDepKetMultipleLabels("r", "theta", "phi", "t")
|
||||
|
||||
assert TimeDepKet() == TimeDepKet("psi", "t")
|
||||
|
||||
|
||||
def test_time_dep_bra():
|
||||
b = TimeDepBra(0, t)
|
||||
|
||||
assert isinstance(b, TimeDepBra)
|
||||
assert isinstance(b, BraBase)
|
||||
assert isinstance(b, StateBase)
|
||||
assert isinstance(b, QExpr)
|
||||
|
||||
assert b.label == (Integer(0),)
|
||||
assert b.args == (Integer(0), t)
|
||||
assert b.time == t
|
||||
|
||||
assert b.dual_class() == TimeDepKet
|
||||
assert b.dual == TimeDepKet(0, t)
|
||||
|
||||
k = TimeDepBra(x, 0.5)
|
||||
assert k.label == (x,)
|
||||
assert k.args == (x, sympify(0.5))
|
||||
|
||||
assert TimeDepBra() == TimeDepBra("psi", "t")
|
||||
|
||||
|
||||
def test_bra_ket_dagger():
|
||||
x = symbols('x', complex=True)
|
||||
k = Ket('k')
|
||||
b = Bra('b')
|
||||
assert Dagger(k) == Bra('k')
|
||||
assert Dagger(b) == Ket('b')
|
||||
assert Dagger(k).is_commutative is False
|
||||
|
||||
k2 = Ket('k2')
|
||||
e = 2*I*k + x*k2
|
||||
assert Dagger(e) == conjugate(x)*Dagger(k2) - 2*I*Dagger(k)
|
||||
|
||||
|
||||
def test_wavefunction():
|
||||
x, y = symbols('x y', real=True)
|
||||
L = symbols('L', positive=True)
|
||||
n = symbols('n', integer=True, positive=True)
|
||||
|
||||
f = Wavefunction(x**2, x)
|
||||
p = f.prob()
|
||||
lims = f.limits
|
||||
|
||||
assert f.is_normalized is False
|
||||
assert f.norm is oo
|
||||
assert f(10) == 100
|
||||
assert p(10) == 10000
|
||||
assert lims[x] == (-oo, oo)
|
||||
assert diff(f, x) == Wavefunction(2*x, x)
|
||||
raises(NotImplementedError, lambda: f.normalize())
|
||||
assert conjugate(f) == Wavefunction(conjugate(f.expr), x)
|
||||
assert conjugate(f) == Dagger(f)
|
||||
|
||||
g = Wavefunction(x**2*y + y**2*x, (x, 0, 1), (y, 0, 2))
|
||||
lims_g = g.limits
|
||||
|
||||
assert lims_g[x] == (0, 1)
|
||||
assert lims_g[y] == (0, 2)
|
||||
assert g.is_normalized is False
|
||||
assert g.norm == sqrt(42)/3
|
||||
assert g(2, 4) == 0
|
||||
assert g(1, 1) == 2
|
||||
assert diff(diff(g, x), y) == Wavefunction(2*x + 2*y, (x, 0, 1), (y, 0, 2))
|
||||
assert conjugate(g) == Wavefunction(conjugate(g.expr), *g.args[1:])
|
||||
assert conjugate(g) == Dagger(g)
|
||||
|
||||
h = Wavefunction(sqrt(5)*x**2, (x, 0, 1))
|
||||
assert h.is_normalized is True
|
||||
assert h.normalize() == h
|
||||
assert conjugate(h) == Wavefunction(conjugate(h.expr), (x, 0, 1))
|
||||
assert conjugate(h) == Dagger(h)
|
||||
|
||||
piab = Wavefunction(sin(n*pi*x/L), (x, 0, L))
|
||||
assert piab.norm == sqrt(L/2)
|
||||
assert piab(L + 1) == 0
|
||||
assert piab(0.5) == sin(0.5*n*pi/L)
|
||||
assert piab(0.5, n=1, L=1) == sin(0.5*pi)
|
||||
assert piab.normalize() == \
|
||||
Wavefunction(sqrt(2)/sqrt(L)*sin(n*pi*x/L), (x, 0, L))
|
||||
assert conjugate(piab) == Wavefunction(conjugate(piab.expr), (x, 0, L))
|
||||
assert conjugate(piab) == Dagger(piab)
|
||||
|
||||
k = Wavefunction(x**2, 'x')
|
||||
assert type(k.variables[0]) == Symbol
|
||||
|
||||
def test_orthogonal_states():
|
||||
bracket = OrthogonalBra(x) * OrthogonalKet(x)
|
||||
assert bracket.doit() == 1
|
||||
|
||||
bracket = OrthogonalBra(x) * OrthogonalKet(x+1)
|
||||
assert bracket.doit() == 0
|
||||
|
||||
bracket = OrthogonalBra(x) * OrthogonalKet(y)
|
||||
assert bracket.doit() == bracket
|
||||
@@ -0,0 +1,142 @@
|
||||
from sympy.core.numbers import I
|
||||
from sympy.core.symbol import symbols
|
||||
from sympy.core.expr import unchanged
|
||||
from sympy.matrices import Matrix, SparseMatrix, ImmutableMatrix
|
||||
from sympy.testing.pytest import warns_deprecated_sympy
|
||||
|
||||
from sympy.physics.quantum.commutator import Commutator as Comm
|
||||
from sympy.physics.quantum.tensorproduct import TensorProduct
|
||||
from sympy.physics.quantum.tensorproduct import TensorProduct as TP
|
||||
from sympy.physics.quantum.tensorproduct import tensor_product_simp
|
||||
from sympy.physics.quantum.dagger import Dagger
|
||||
from sympy.physics.quantum.qubit import Qubit, QubitBra
|
||||
from sympy.physics.quantum.operator import OuterProduct, Operator
|
||||
from sympy.physics.quantum.density import Density
|
||||
from sympy.physics.quantum.trace import Tr
|
||||
|
||||
A = Operator('A')
|
||||
B = Operator('B')
|
||||
C = Operator('C')
|
||||
D = Operator('D')
|
||||
x = symbols('x')
|
||||
y = symbols('y', integer=True, positive=True)
|
||||
|
||||
mat1 = Matrix([[1, 2*I], [1 + I, 3]])
|
||||
mat2 = Matrix([[2*I, 3], [4*I, 2]])
|
||||
|
||||
|
||||
def test_sparse_matrices():
|
||||
spm = SparseMatrix.diag(1, 0)
|
||||
assert unchanged(TensorProduct, spm, spm)
|
||||
|
||||
|
||||
def test_tensor_product_dagger():
|
||||
assert Dagger(TensorProduct(I*A, B)) == \
|
||||
-I*TensorProduct(Dagger(A), Dagger(B))
|
||||
assert Dagger(TensorProduct(mat1, mat2)) == \
|
||||
TensorProduct(Dagger(mat1), Dagger(mat2))
|
||||
|
||||
|
||||
def test_tensor_product_abstract():
|
||||
|
||||
assert TP(x*A, 2*B) == x*2*TP(A, B)
|
||||
assert TP(A, B) != TP(B, A)
|
||||
assert TP(A, B).is_commutative is False
|
||||
assert isinstance(TP(A, B), TP)
|
||||
assert TP(A, B).subs(A, C) == TP(C, B)
|
||||
|
||||
|
||||
def test_tensor_product_expand():
|
||||
assert TP(A + B, B + C).expand(tensorproduct=True) == \
|
||||
TP(A, B) + TP(A, C) + TP(B, B) + TP(B, C)
|
||||
#Tests for fix of issue #24142
|
||||
assert TP(A-B, B-A).expand(tensorproduct=True) == \
|
||||
TP(A, B) - TP(A, A) - TP(B, B) + TP(B, A)
|
||||
assert TP(2*A + B, A + B).expand(tensorproduct=True) == \
|
||||
2 * TP(A, A) + 2 * TP(A, B) + TP(B, A) + TP(B, B)
|
||||
assert TP(2 * A * B + A, A + B).expand(tensorproduct=True) == \
|
||||
2 * TP(A*B, A) + 2 * TP(A*B, B) + TP(A, A) + TP(A, B)
|
||||
|
||||
|
||||
def test_tensor_product_commutator():
|
||||
assert TP(Comm(A, B), C).doit().expand(tensorproduct=True) == \
|
||||
TP(A*B, C) - TP(B*A, C)
|
||||
assert Comm(TP(A, B), TP(B, C)).doit() == \
|
||||
TP(A, B)*TP(B, C) - TP(B, C)*TP(A, B)
|
||||
|
||||
|
||||
def test_tensor_product_simp():
|
||||
with warns_deprecated_sympy():
|
||||
assert tensor_product_simp(TP(A, B)*TP(B, C)) == TP(A*B, B*C)
|
||||
# tests for Pow-expressions
|
||||
assert TP(A, B)**y == TP(A**y, B**y)
|
||||
assert tensor_product_simp(TP(A, B)**y) == TP(A**y, B**y)
|
||||
assert tensor_product_simp(x*TP(A, B)**2) == x*TP(A**2,B**2)
|
||||
assert tensor_product_simp(x*(TP(A, B)**2)*TP(C,D)) == x*TP(A**2*C,B**2*D)
|
||||
assert tensor_product_simp(TP(A,B)-TP(C,D)**y) == TP(A,B)-TP(C**y,D**y)
|
||||
|
||||
|
||||
def test_issue_5923():
|
||||
# most of the issue regarding sympification of args has been handled
|
||||
# and is tested internally by the use of args_cnc through the quantum
|
||||
# module, but the following is a test from the issue that used to raise.
|
||||
assert TensorProduct(1, Qubit('1')*Qubit('1').dual) == \
|
||||
TensorProduct(1, OuterProduct(Qubit(1), QubitBra(1)))
|
||||
|
||||
|
||||
def test_eval_trace():
|
||||
# This test includes tests with dependencies between TensorProducts
|
||||
#and density operators. Since, the test is more to test the behavior of
|
||||
#TensorProducts it remains here
|
||||
|
||||
# Density with simple tensor products as args
|
||||
t = TensorProduct(A, B)
|
||||
d = Density([t, 1.0])
|
||||
tr = Tr(d)
|
||||
assert tr.doit() == 1.0*Tr(A*Dagger(A))*Tr(B*Dagger(B))
|
||||
|
||||
## partial trace with simple tensor products as args
|
||||
t = TensorProduct(A, B, C)
|
||||
d = Density([t, 1.0])
|
||||
tr = Tr(d, [1])
|
||||
assert tr.doit() == 1.0*A*Dagger(A)*Tr(B*Dagger(B))*C*Dagger(C)
|
||||
|
||||
tr = Tr(d, [0, 2])
|
||||
assert tr.doit() == 1.0*Tr(A*Dagger(A))*B*Dagger(B)*Tr(C*Dagger(C))
|
||||
|
||||
# Density with multiple Tensorproducts as states
|
||||
t2 = TensorProduct(A, B)
|
||||
t3 = TensorProduct(C, D)
|
||||
|
||||
d = Density([t2, 0.5], [t3, 0.5])
|
||||
t = Tr(d)
|
||||
assert t.doit() == (0.5*Tr(A*Dagger(A))*Tr(B*Dagger(B)) +
|
||||
0.5*Tr(C*Dagger(C))*Tr(D*Dagger(D)))
|
||||
|
||||
t = Tr(d, [0])
|
||||
assert t.doit() == (0.5*Tr(A*Dagger(A))*B*Dagger(B) +
|
||||
0.5*Tr(C*Dagger(C))*D*Dagger(D))
|
||||
|
||||
#Density with mixed states
|
||||
d = Density([t2 + t3, 1.0])
|
||||
t = Tr(d)
|
||||
assert t.doit() == ( 1.0*Tr(A*Dagger(A))*Tr(B*Dagger(B)) +
|
||||
1.0*Tr(A*Dagger(C))*Tr(B*Dagger(D)) +
|
||||
1.0*Tr(C*Dagger(A))*Tr(D*Dagger(B)) +
|
||||
1.0*Tr(C*Dagger(C))*Tr(D*Dagger(D)))
|
||||
|
||||
t = Tr(d, [1] )
|
||||
assert t.doit() == ( 1.0*A*Dagger(A)*Tr(B*Dagger(B)) +
|
||||
1.0*A*Dagger(C)*Tr(B*Dagger(D)) +
|
||||
1.0*C*Dagger(A)*Tr(D*Dagger(B)) +
|
||||
1.0*C*Dagger(C)*Tr(D*Dagger(D)))
|
||||
|
||||
|
||||
def test_pr24993():
|
||||
from sympy.matrices.expressions.kronecker import matrix_kronecker_product
|
||||
from sympy.physics.quantum.matrixutils import matrix_tensor_product
|
||||
X = Matrix([[0, 1], [1, 0]])
|
||||
Xi = ImmutableMatrix(X)
|
||||
assert TensorProduct(Xi, Xi) == TensorProduct(X, X)
|
||||
assert TensorProduct(Xi, Xi) == matrix_tensor_product(X, X)
|
||||
assert TensorProduct(Xi, Xi) == matrix_kronecker_product(X, X)
|
||||
@@ -0,0 +1,109 @@
|
||||
from sympy.core.containers import Tuple
|
||||
from sympy.core.symbol import symbols
|
||||
from sympy.matrices.dense import Matrix
|
||||
from sympy.physics.quantum.trace import Tr
|
||||
from sympy.testing.pytest import raises, warns_deprecated_sympy
|
||||
|
||||
|
||||
def test_trace_new():
|
||||
a, b, c, d, Y = symbols('a b c d Y')
|
||||
A, B, C, D = symbols('A B C D', commutative=False)
|
||||
|
||||
assert Tr(a + b) == a + b
|
||||
assert Tr(A + B) == Tr(A) + Tr(B)
|
||||
|
||||
#check trace args not implicitly permuted
|
||||
assert Tr(C*D*A*B).args[0].args == (C, D, A, B)
|
||||
|
||||
# check for mul and adds
|
||||
assert Tr((a*b) + ( c*d)) == (a*b) + (c*d)
|
||||
# Tr(scalar*A) = scalar*Tr(A)
|
||||
assert Tr(a*A) == a*Tr(A)
|
||||
assert Tr(a*A*B*b) == a*b*Tr(A*B)
|
||||
|
||||
# since A is symbol and not commutative
|
||||
assert isinstance(Tr(A), Tr)
|
||||
|
||||
#POW
|
||||
assert Tr(pow(a, b)) == a**b
|
||||
assert isinstance(Tr(pow(A, a)), Tr)
|
||||
|
||||
#Matrix
|
||||
M = Matrix([[1, 1], [2, 2]])
|
||||
assert Tr(M) == 3
|
||||
|
||||
##test indices in different forms
|
||||
#no index
|
||||
t = Tr(A)
|
||||
assert t.args[1] == Tuple()
|
||||
|
||||
#single index
|
||||
t = Tr(A, 0)
|
||||
assert t.args[1] == Tuple(0)
|
||||
|
||||
#index in a list
|
||||
t = Tr(A, [0])
|
||||
assert t.args[1] == Tuple(0)
|
||||
|
||||
t = Tr(A, [0, 1, 2])
|
||||
assert t.args[1] == Tuple(0, 1, 2)
|
||||
|
||||
#index is tuple
|
||||
t = Tr(A, (0))
|
||||
assert t.args[1] == Tuple(0)
|
||||
|
||||
t = Tr(A, (1, 2))
|
||||
assert t.args[1] == Tuple(1, 2)
|
||||
|
||||
#trace indices test
|
||||
t = Tr((A + B), [2])
|
||||
assert t.args[0].args[1] == Tuple(2) and t.args[1].args[1] == Tuple(2)
|
||||
|
||||
t = Tr(a*A, [2, 3])
|
||||
assert t.args[1].args[1] == Tuple(2, 3)
|
||||
|
||||
#class with trace method defined
|
||||
#to simulate numpy objects
|
||||
class Foo:
|
||||
def trace(self):
|
||||
return 1
|
||||
assert Tr(Foo()) == 1
|
||||
|
||||
#argument test
|
||||
# check for value error, when either/both arguments are not provided
|
||||
raises(ValueError, lambda: Tr())
|
||||
raises(ValueError, lambda: Tr(A, 1, 2))
|
||||
|
||||
|
||||
def test_trace_doit():
|
||||
a, b, c, d = symbols('a b c d')
|
||||
A, B, C, D = symbols('A B C D', commutative=False)
|
||||
|
||||
#TODO: needed while testing reduced density operations, etc.
|
||||
|
||||
|
||||
def test_permute():
|
||||
A, B, C, D, E, F, G = symbols('A B C D E F G', commutative=False)
|
||||
t = Tr(A*B*C*D*E*F*G)
|
||||
|
||||
assert t.permute(0).args[0].args == (A, B, C, D, E, F, G)
|
||||
assert t.permute(2).args[0].args == (F, G, A, B, C, D, E)
|
||||
assert t.permute(4).args[0].args == (D, E, F, G, A, B, C)
|
||||
assert t.permute(6).args[0].args == (B, C, D, E, F, G, A)
|
||||
assert t.permute(8).args[0].args == t.permute(1).args[0].args
|
||||
|
||||
assert t.permute(-1).args[0].args == (B, C, D, E, F, G, A)
|
||||
assert t.permute(-3).args[0].args == (D, E, F, G, A, B, C)
|
||||
assert t.permute(-5).args[0].args == (F, G, A, B, C, D, E)
|
||||
assert t.permute(-8).args[0].args == t.permute(-1).args[0].args
|
||||
|
||||
t = Tr((A + B)*(B*B)*C*D)
|
||||
assert t.permute(2).args[0].args == (C, D, (A + B), (B**2))
|
||||
|
||||
t1 = Tr(A*B)
|
||||
t2 = t1.permute(1)
|
||||
assert id(t1) != id(t2) and t1 == t2
|
||||
|
||||
def test_deprecated_core_trace():
|
||||
with warns_deprecated_sympy():
|
||||
from sympy.core.trace import Tr # noqa:F401
|
||||
@@ -0,0 +1,75 @@
|
||||
"""Tests of transforms of quantum expressions for Mul and Pow."""
|
||||
|
||||
from sympy.core.symbol import symbols
|
||||
from sympy.testing.pytest import raises
|
||||
|
||||
from sympy.physics.quantum.operator import (
|
||||
Operator, OuterProduct
|
||||
)
|
||||
from sympy.physics.quantum.state import Ket, Bra
|
||||
from sympy.physics.quantum.innerproduct import InnerProduct
|
||||
from sympy.physics.quantum.tensorproduct import TensorProduct
|
||||
|
||||
|
||||
k1 = Ket('k1')
|
||||
k2 = Ket('k2')
|
||||
k3 = Ket('k3')
|
||||
b1 = Bra('b1')
|
||||
b2 = Bra('b2')
|
||||
b3 = Bra('b3')
|
||||
A = Operator('A')
|
||||
B = Operator('B')
|
||||
C = Operator('C')
|
||||
x, y, z = symbols('x y z')
|
||||
|
||||
|
||||
def test_bra_ket():
|
||||
assert b1*k1 == InnerProduct(b1, k1)
|
||||
assert k1*b1 == OuterProduct(k1, b1)
|
||||
# Test priority of inner product
|
||||
assert OuterProduct(k1, b1)*k2 == InnerProduct(b1, k2)*k1
|
||||
assert b1*OuterProduct(k1, b2) == InnerProduct(b1, k1)*b2
|
||||
|
||||
|
||||
def test_tensor_product():
|
||||
# We are attempting to be rigourous and raise TypeError when a user tries
|
||||
# to combine bras, kets, and operators in a manner that doesn't make sense.
|
||||
# In particular, we are not trying to interpret regular ``*`` multiplication
|
||||
# as a tensor product.
|
||||
with raises(TypeError):
|
||||
k1*k1
|
||||
with raises(TypeError):
|
||||
b1*b1
|
||||
with raises(TypeError):
|
||||
k1*TensorProduct(k2, k3)
|
||||
with raises(TypeError):
|
||||
b1*TensorProduct(b2, b3)
|
||||
with raises(TypeError):
|
||||
TensorProduct(k2, k3)*k1
|
||||
with raises(TypeError):
|
||||
TensorProduct(b2, b3)*b1
|
||||
|
||||
assert TensorProduct(A, B, C)*TensorProduct(k1, k2, k3) == \
|
||||
TensorProduct(A*k1, B*k2, C*k3)
|
||||
assert TensorProduct(b1, b2, b3)*TensorProduct(A, B, C) == \
|
||||
TensorProduct(b1*A, b2*B, b3*C)
|
||||
assert TensorProduct(b1, b2, b3)*TensorProduct(k1, k2, k3) == \
|
||||
InnerProduct(b1, k1)*InnerProduct(b2, k2)*InnerProduct(b3, k3)
|
||||
assert TensorProduct(b1, b2, b3)*TensorProduct(A, B, C)*TensorProduct(k1, k2, k3) == \
|
||||
TensorProduct(b1*A*k1, b2*B*k2, b3*C*k3)
|
||||
|
||||
|
||||
def test_outer_product():
|
||||
assert OuterProduct(k1, b1)*OuterProduct(k2, b2) == \
|
||||
InnerProduct(b1, k2)*OuterProduct(k1, b2)
|
||||
|
||||
|
||||
def test_compound():
|
||||
e1 = b1*A*B*k1*b2*k2*b3
|
||||
assert e1 == InnerProduct(b2, k2)*b1*A*B*OuterProduct(k1, b3)
|
||||
|
||||
e2 = TensorProduct(k1, k2)*TensorProduct(b1, b2)
|
||||
assert e2 == TensorProduct(
|
||||
OuterProduct(k1, b1),
|
||||
OuterProduct(k2, b2)
|
||||
)
|
||||
Reference in New Issue
Block a user