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