ai-content-maker/.venv/Lib/site-packages/sympy/physics/quantum/tests/test_gate.py

361 lines
12 KiB
Python

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)