switching to high quality piper tts and added label translations
This commit is contained in:
+56
@@ -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)
|
||||
+113
@@ -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
|
||||
+69
@@ -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']
|
||||
+402
@@ -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
|
||||
+81
@@ -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)
|
||||
+492
@@ -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
|
||||
+71
@@ -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
|
||||
+136
@@ -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
|
||||
+50
@@ -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)
|
||||
+68
@@ -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])
|
||||
+186
@@ -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
|
||||
+142
@@ -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
|
||||
+75
@@ -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