I am done

This commit is contained in:
2024-10-30 22:14:35 +01:00
parent 720dc28c09
commit 40e2a747cf
36901 changed files with 5011519 additions and 0 deletions

View File

@ -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

View File

@ -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)

View File

@ -0,0 +1,104 @@
"""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.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(XOp()*XKet()*XBra('y')) == \
x*DiracDelta(x - x_3)*DiracDelta(x_1 - y)
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)
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

View File

@ -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

View File

@ -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']

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -0,0 +1,102 @@
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
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), adjoint)
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')
I = IdentityOperator()
assert Dagger(O)*O == Dagger(O)*O
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")
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)

View File

@ -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))

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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 matricies
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)

View File

@ -0,0 +1,263 @@
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.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
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")
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():
I = IdentityOperator()
O = Operator('O')
x = Symbol("x")
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 isinstance(3 * I, Mul)
assert isinstance(I * x, Mul)
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

View File

@ -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)

View File

@ -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))

View File

@ -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]])

View File

@ -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

View File

@ -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')
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'))")
@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}'

View File

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

View File

@ -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))'

View File

@ -0,0 +1,52 @@
from sympy.core.numbers import Integer
from sympy.core.symbol import Symbol
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')
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_commutative_free_symbols():
q1 = QExpr(x)
assert q1.free_symbols.pop().is_commutative is False
q2 = QExpr('q2')
assert q2.free_symbols.pop().is_commutative is False
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,)

View File

@ -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)

View File

@ -0,0 +1,255 @@
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_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_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])

View File

@ -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")]

View File

@ -0,0 +1,120 @@
"""Tests for sho1d.py"""
from sympy.core.numbers import (I, Integer)
from sympy.core.singleton import S
from sympy.core.symbol import Symbol
from sympy.functions.elementary.miscellaneous import sqrt
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.functions.special.tensor_functions import KroneckerDelta
from sympy.physics.quantum.hilbert import ComplexSpace
from sympy.physics.quantum.represent import represent
from sympy.external import import_module
from sympy.testing.pytest import skip
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)
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)

View File

@ -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

View File

@ -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():
braket = OrthogonalBra(x) * OrthogonalKet(x)
assert braket.doit() == 1
braket = OrthogonalBra(x) * OrthogonalKet(x+1)
assert braket.doit() == 0
braket = OrthogonalBra(x) * OrthogonalKet(y)
assert braket.doit() == braket

View File

@ -0,0 +1,137 @@
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.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
from sympy.physics.quantum.density import Density
from sympy.physics.quantum.trace import Tr
A, B, C, D = symbols('A,B,C,D', commutative=False)
x = symbols('x')
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():
assert tensor_product_simp(TP(A, B)*TP(B, C)) == TP(A*B, B*C)
# tests for Pow-expressions
assert tensor_product_simp(TP(A, B)**x) == TP(A**x, B**x)
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)**x) == TP(A,B)-TP(C**x,D**x)
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
A, B, C, D, E, F = symbols('A B C D E F', commutative=False)
# 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)

View File

@ -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