def circuit(weights): qml.RX(weights[0], wires=0) qml.RZ(weights[1], wires=1) return qml.expval(qml.PauliZ(0) @ qml.PauliZ(1))
def circuit(x, w=None): qml.RZ(x, wires=w) return qml.expval(qml.PauliX(w))
def _decomposition_2_cnots(U, wires): r"""If 2 CNOTs are required, we can write the circuit as -╭U- = -A--╭X--RZ(d)--╭X--C- -╰U- = -B--╰C--RX(p)--╰C--D- We need to find the angles for the Z and X rotations such that the inner part has the same spectrum as U, and then we can recover A, B, C, D. """ # Compute the rotation angles u = math.dot(Edag, math.dot(U, E)) gammaU = math.dot(u, math.T(u)) evs, _ = math.linalg.eig(gammaU) # These choices are based on Proposition III.3 of # https://arxiv.org/abs/quant-ph/0308045 # There is, however, a special case where the circuit has the form # -╭U- = -A--╭C--╭X--C- # -╰U- = -B--╰X--╰C--D- # # or some variant of this, where the two CNOTs are adjacent. # # What happens here is that the set of evs is -1, -1, 1, 1 and we can write # -╭U- = -A--╭X--SZ--╭X--C- # -╰U- = -B--╰C--SX--╰C--D- # where SZ and SX are square roots of Z and X respectively. (This # decomposition comes from using Hadamards to flip the direction of the # first CNOT, and then decomposing them and merging single-qubit gates.) For # some reason this case is not handled properly with the full algorithm, so # we treat it separately. sorted_evs = math.sort(math.real(evs)) if math.allclose(sorted_evs, [-1, -1, 1, 1]): interior_decomp = [ qml.CNOT(wires=[wires[1], wires[0]]), qml.S(wires=wires[0]), qml.SX(wires=wires[1]), qml.CNOT(wires=[wires[1], wires[0]]), ] # S \otimes SX inner_matrix = S_SX else: # For the non-special case, the eigenvalues come in conjugate pairs. # We need to find two non-conjugate eigenvalues to extract the angles. x = math.angle(evs[0]) y = math.angle(evs[1]) # If it was the conjugate, grab a different eigenvalue. if math.allclose(x, -y): y = math.angle(evs[2]) delta = (x + y) / 2 phi = (x - y) / 2 interior_decomp = [ qml.CNOT(wires=[wires[1], wires[0]]), qml.RZ(delta, wires=wires[0]), qml.RX(phi, wires=wires[1]), qml.CNOT(wires=[wires[1], wires[0]]), ] RZd = qml.RZ(math.cast_like(delta, 1j), wires=0).matrix RXp = qml.RX(phi, wires=0).matrix inner_matrix = math.kron(RZd, RXp) # We need the matrix representation of this interior part, V, in order to # decompose U = (A \otimes B) V (C \otimes D) V = math.dot(math.cast_like(CNOT10, U), math.dot(inner_matrix, math.cast_like(CNOT10, U))) # Now we find the A, B, C, D in SU(2), and return the decomposition A, B, C, D = _extract_su2su2_prefactors(U, V) A_ops = zyz_decomposition(A, wires[0]) B_ops = zyz_decomposition(B, wires[1]) C_ops = zyz_decomposition(C, wires[0]) D_ops = zyz_decomposition(D, wires[1]) return C_ops + D_ops + interior_decomp + A_ops + B_ops
def circuit(reused_param, other_param): qml.RX(extra_param, wires=[0]) qml.RY(reused_param, wires=[0]) qml.RZ(other_param, wires=[0]) qml.RX(reused_param, wires=[0]) return qml.expval(qml.PauliZ(0))
def circuit(x): qml.RZ(x, wires=[1]).inv() qml.RZ(x, wires=[1]).inv().inv() return qml.expval(qml.PauliX(0)), qml.expval(qml.PauliZ(1))
class TestRepresentationResolver: """Test the RepresentationResolver class.""" @pytest.mark.parametrize( "list,element,index,list_after", [ ([1, 2, 3], 2, 1, [1, 2, 3]), ([1, 2, 2, 3], 2, 1, [1, 2, 2, 3]), ([1, 2, 3], 4, 3, [1, 2, 3, 4]), ], ) def test_index_of_array_or_append(self, list, element, index, list_after): """Test the method index_of_array_or_append.""" assert RepresentationResolver.index_of_array_or_append(element, list) == index assert list == list_after @pytest.mark.parametrize("par,expected", [ (3, "3"), (5.236422, "5.236"), ]) def test_single_parameter_representation(self, unicode_representation_resolver, par, expected): """Test that single parameters are properly resolved.""" assert unicode_representation_resolver.single_parameter_representation( par) == expected def test_single_parameter_representation_variable( self, unicode_representation_resolver, variable): """Test that variables are properly resolved.""" assert unicode_representation_resolver.single_parameter_representation( variable) == "2" def test_single_parameter_representation_kwarg_variable( self, unicode_representation_resolver, kwarg_variable): """Test that kwarg variables are properly resolved.""" assert (unicode_representation_resolver. single_parameter_representation(kwarg_variable) == "1") @pytest.mark.parametrize("par,expected", [ (3, "3"), (5.236422, "5.236"), ]) def test_single_parameter_representation_varnames( self, unicode_representation_resolver_varnames, par, expected): """Test that single parameters are properly resolved when show_variable_names is True.""" assert (unicode_representation_resolver_varnames. single_parameter_representation(par) == expected) def test_single_parameter_representation_variable_varnames( self, unicode_representation_resolver_varnames, variable): """Test that variables are properly resolved when show_variable_names is True.""" assert (unicode_representation_resolver_varnames. single_parameter_representation(variable) == "test") def test_single_parameter_representation_kwarg_variable_varnames( self, unicode_representation_resolver_varnames, kwarg_variable): """Test that kwarg variables are properly resolved when show_variable_names is True.""" assert ( unicode_representation_resolver_varnames. single_parameter_representation(kwarg_variable) == "kwarg_test") @pytest.mark.parametrize( "op,wire,target", [ (qml.PauliX(wires=[1]), 1, "X"), (qml.CNOT(wires=[0, 1]), 1, "X"), (qml.CNOT(wires=[0, 1]), 0, "C"), (qml.Toffoli(wires=[0, 2, 1]), 1, "X"), (qml.Toffoli(wires=[0, 2, 1]), 0, "C"), (qml.Toffoli(wires=[0, 2, 1]), 2, "C"), (qml.CSWAP(wires=[0, 2, 1]), 1, "SWAP"), (qml.CSWAP(wires=[0, 2, 1]), 2, "SWAP"), (qml.CSWAP(wires=[0, 2, 1]), 0, "C"), (qml.PauliY(wires=[1]), 1, "Y"), (qml.PauliZ(wires=[1]), 1, "Z"), (qml.CZ(wires=[0, 1]), 1, "Z"), (qml.CZ(wires=[0, 1]), 0, "C"), (qml.Identity(wires=[1]), 1, "I"), (qml.Hadamard(wires=[1]), 1, "H"), (qml.PauliRot(3.14, "XX", wires=[0, 1]), 1, "RX(3.14)"), (qml.PauliRot(3.14, "YZ", wires=[0, 1]), 1, "RZ(3.14)"), (qml.PauliRot(3.14, "IXYZI", wires=[0, 1, 2, 3, 4 ]), 0, "RI(3.14)"), (qml.PauliRot(3.14, "IXYZI", wires=[0, 1, 2, 3, 4 ]), 1, "RX(3.14)"), (qml.PauliRot(3.14, "IXYZI", wires=[0, 1, 2, 3, 4 ]), 2, "RY(3.14)"), (qml.PauliRot(3.14, "IXYZI", wires=[0, 1, 2, 3, 4 ]), 3, "RZ(3.14)"), (qml.PauliRot(3.14, "IXYZI", wires=[0, 1, 2, 3, 4 ]), 4, "RI(3.14)"), (qml.MultiRZ(3.14, wires=[0, 1]), 0, "RZ(3.14)"), (qml.MultiRZ(3.14, wires=[0, 1]), 1, "RZ(3.14)"), (qml.CRX(3.14, wires=[0, 1]), 1, "RX(3.14)"), (qml.CRX(3.14, wires=[0, 1]), 0, "C"), (qml.CRY(3.14, wires=[0, 1]), 1, "RY(3.14)"), (qml.CRY(3.14, wires=[0, 1]), 0, "C"), (qml.CRZ(3.14, wires=[0, 1]), 1, "RZ(3.14)"), (qml.CRZ(3.14, wires=[0, 1]), 0, "C"), (qml.CRot(3.14, 2.14, 1.14, wires=[0, 1 ]), 1, "Rot(3.14, 2.14, 1.14)"), (qml.CRot(3.14, 2.14, 1.14, wires=[0, 1]), 0, "C"), (qml.PhaseShift(3.14, wires=[0]), 0, "Rϕ(3.14)"), (qml.Beamsplitter(1, 2, wires=[0, 1]), 1, "BS(1, 2)"), (qml.Beamsplitter(1, 2, wires=[0, 1]), 0, "BS(1, 2)"), (qml.Squeezing(1, 2, wires=[1]), 1, "S(1, 2)"), (qml.TwoModeSqueezing(1, 2, wires=[0, 1]), 1, "S(1, 2)"), (qml.TwoModeSqueezing(1, 2, wires=[0, 1]), 0, "S(1, 2)"), (qml.Displacement(1, 2, wires=[1]), 1, "D(1, 2)"), (qml.NumberOperator(wires=[1]), 1, "n"), (qml.Rotation(3.14, wires=[1]), 1, "R(3.14)"), (qml.ControlledAddition(3.14, wires=[0, 1]), 1, "X(3.14)"), (qml.ControlledAddition(3.14, wires=[0, 1]), 0, "C"), (qml.ControlledPhase(3.14, wires=[0, 1]), 1, "Z(3.14)"), (qml.ControlledPhase(3.14, wires=[0, 1]), 0, "C"), (qml.ThermalState(3, wires=[1]), 1, "Thermal(3)"), ( qml.GaussianState( np.array([1, 2]), np.array([[2, 0], [0, 2]]), wires=[1]), 1, "Gaussian(M0,M1)", ), (qml.QuadraticPhase(3.14, wires=[1]), 1, "P(3.14)"), (qml.RX(3.14, wires=[1]), 1, "RX(3.14)"), (qml.S(wires=[2]), 2, "S"), (qml.T(wires=[2]), 2, "T"), (qml.RX(3.14, wires=[1]), 1, "RX(3.14)"), (qml.RY(3.14, wires=[1]), 1, "RY(3.14)"), (qml.RZ(3.14, wires=[1]), 1, "RZ(3.14)"), (qml.Rot(3.14, 2.14, 1.14, wires=[1]), 1, "Rot(3.14, 2.14, 1.14)"), (qml.U1(3.14, wires=[1]), 1, "U1(3.14)"), (qml.U2(3.14, 2.14, wires=[1]), 1, "U2(3.14, 2.14)"), (qml.U3(3.14, 2.14, 1.14, wires=[1]), 1, "U3(3.14, 2.14, 1.14)"), (qml.BasisState(np.array([0, 1, 0]), wires=[1, 2, 3]), 1, "|0⟩"), (qml.BasisState(np.array([0, 1, 0]), wires=[1, 2, 3]), 2, "|1⟩"), (qml.BasisState(np.array([0, 1, 0]), wires=[1, 2, 3]), 3, "|0⟩"), (qml.QubitStateVector(np.array([0, 1, 0, 0]), wires=[1, 2]), 1, "QubitStateVector(M0)"), (qml.QubitStateVector(np.array([0, 1, 0, 0]), wires=[1, 2]), 2, "QubitStateVector(M0)"), (qml.QubitUnitary(np.eye(2), wires=[1]), 1, "U0"), (qml.QubitUnitary(np.eye(4), wires=[1, 2]), 2, "U0"), (qml.Kerr(3.14, wires=[1]), 1, "Kerr(3.14)"), (qml.CrossKerr(3.14, wires=[1, 2]), 1, "CrossKerr(3.14)"), (qml.CrossKerr(3.14, wires=[1, 2]), 2, "CrossKerr(3.14)"), (qml.CubicPhase(3.14, wires=[1]), 1, "V(3.14)"), (qml.Interferometer(np.eye(4), wires=[1, 3 ]), 1, "Interferometer(M0)"), (qml.Interferometer(np.eye(4), wires=[1, 3 ]), 3, "Interferometer(M0)"), (qml.CatState(3.14, 2.14, 1, wires=[1]), 1, "CatState(3.14, 2.14, 1)"), (qml.CoherentState(3.14, 2.14, wires=[1]), 1, "CoherentState(3.14, 2.14)"), ( qml.FockDensityMatrix(np.kron(np.eye(4), np.eye(4)), wires=[1, 2]), 1, "FockDensityMatrix(M0)", ), ( qml.FockDensityMatrix(np.kron(np.eye(4), np.eye(4)), wires=[1, 2]), 2, "FockDensityMatrix(M0)", ), ( qml.DisplacedSqueezedState(3.14, 2.14, 1.14, 0.14, wires=[1]), 1, "DisplacedSqueezedState(3.14, 2.14, 1.14, 0.14)", ), (qml.FockState(7, wires=[1]), 1, "|7⟩"), (qml.FockStateVector(np.array([4, 5, 7]), wires=[1, 2, 3 ]), 1, "|4⟩"), (qml.FockStateVector(np.array([4, 5, 7]), wires=[1, 2, 3 ]), 2, "|5⟩"), (qml.FockStateVector(np.array([4, 5, 7]), wires=[1, 2, 3 ]), 3, "|7⟩"), (qml.SqueezedState(3.14, 2.14, wires=[1]), 1, "SqueezedState(3.14, 2.14)"), (qml.Hermitian(np.eye(4), wires=[1, 2]), 1, "H0"), (qml.Hermitian(np.eye(4), wires=[1, 2]), 2, "H0"), (qml.X(wires=[1]), 1, "x"), (qml.P(wires=[1]), 1, "p"), (qml.FockStateProjector(np.array([4, 5, 7]), wires=[1, 2, 3]), 1, "|4,5,7╳4,5,7|"), ( qml.PolyXP(np.array([1, 2, 0, -1.3, 6]), wires=[1]), 2, "1+2x₀-1.3x₁+6p₁", ), ( qml.PolyXP(np.array([[1.2, 2.3, 4.5], [-1.2, 1.2, -1.5], [-1.3, 4.5, 2.3]]), wires=[1]), 1, "1.2+1.1x₀+3.2p₀+1.2x₀²+2.3p₀²+3x₀p₀", ), ( qml.PolyXP( np.array([ [1.2, 2.3, 4.5, 0, 0], [-1.2, 1.2, -1.5, 0, 0], [-1.3, 4.5, 2.3, 0, 0], [0, 2.6, 0, 0, 0], [0, 0, 0, -4.7, -1.0], ]), wires=[1], ), 1, "1.2+1.1x₀+3.2p₀+1.2x₀²+2.3p₀²+3x₀p₀+2.6x₀x₁-p₁²-4.7x₁p₁", ), (qml.QuadOperator(3.14, wires=[1]), 1, "cos(3.14)x+sin(3.14)p"), (qml.PauliX(wires=[1]).inv(), 1, "X⁻¹"), (qml.CNOT(wires=[0, 1]).inv(), 1, "X⁻¹"), (qml.CNOT(wires=[0, 1]).inv(), 0, "C"), (qml.Toffoli(wires=[0, 2, 1]).inv(), 1, "X⁻¹"), (qml.Toffoli(wires=[0, 2, 1]).inv(), 0, "C"), (qml.Toffoli(wires=[0, 2, 1]).inv(), 2, "C"), ], ) def test_operator_representation_unicode(self, unicode_representation_resolver, op, wire, target): """Test that an Operator instance is properly resolved.""" assert unicode_representation_resolver.operator_representation( op, wire) == target @pytest.mark.parametrize( "op,wire,target", [ (qml.PauliX(wires=[1]), 1, "X"), (qml.CNOT(wires=[0, 1]), 1, "X"), (qml.CNOT(wires=[0, 1]), 0, "C"), (qml.Toffoli(wires=[0, 2, 1]), 1, "X"), (qml.Toffoli(wires=[0, 2, 1]), 0, "C"), (qml.Toffoli(wires=[0, 2, 1]), 2, "C"), (qml.CSWAP(wires=[0, 2, 1]), 1, "SWAP"), (qml.CSWAP(wires=[0, 2, 1]), 2, "SWAP"), (qml.CSWAP(wires=[0, 2, 1]), 0, "C"), (qml.PauliY(wires=[1]), 1, "Y"), (qml.PauliZ(wires=[1]), 1, "Z"), (qml.CZ(wires=[0, 1]), 1, "Z"), (qml.CZ(wires=[0, 1]), 0, "C"), (qml.Identity(wires=[1]), 1, "I"), (qml.Hadamard(wires=[1]), 1, "H"), (qml.CRX(3.14, wires=[0, 1]), 1, "RX(3.14)"), (qml.CRX(3.14, wires=[0, 1]), 0, "C"), (qml.CRY(3.14, wires=[0, 1]), 1, "RY(3.14)"), (qml.CRY(3.14, wires=[0, 1]), 0, "C"), (qml.CRZ(3.14, wires=[0, 1]), 1, "RZ(3.14)"), (qml.CRZ(3.14, wires=[0, 1]), 0, "C"), (qml.CRot(3.14, 2.14, 1.14, wires=[0, 1 ]), 1, "Rot(3.14, 2.14, 1.14)"), (qml.CRot(3.14, 2.14, 1.14, wires=[0, 1]), 0, "C"), (qml.PhaseShift(3.14, wires=[0]), 0, "Rϕ(3.14)"), (qml.Beamsplitter(1, 2, wires=[0, 1]), 1, "BS(1, 2)"), (qml.Beamsplitter(1, 2, wires=[0, 1]), 0, "BS(1, 2)"), (qml.Squeezing(1, 2, wires=[1]), 1, "S(1, 2)"), (qml.TwoModeSqueezing(1, 2, wires=[0, 1]), 1, "S(1, 2)"), (qml.TwoModeSqueezing(1, 2, wires=[0, 1]), 0, "S(1, 2)"), (qml.Displacement(1, 2, wires=[1]), 1, "D(1, 2)"), (qml.NumberOperator(wires=[1]), 1, "n"), (qml.Rotation(3.14, wires=[1]), 1, "R(3.14)"), (qml.ControlledAddition(3.14, wires=[0, 1]), 1, "X(3.14)"), (qml.ControlledAddition(3.14, wires=[0, 1]), 0, "C"), (qml.ControlledPhase(3.14, wires=[0, 1]), 1, "Z(3.14)"), (qml.ControlledPhase(3.14, wires=[0, 1]), 0, "C"), (qml.ThermalState(3, wires=[1]), 1, "Thermal(3)"), ( qml.GaussianState( np.array([1, 2]), np.array([[2, 0], [0, 2]]), wires=[1]), 1, "Gaussian(M0,M1)", ), (qml.QuadraticPhase(3.14, wires=[1]), 1, "P(3.14)"), (qml.RX(3.14, wires=[1]), 1, "RX(3.14)"), (qml.S(wires=[2]), 2, "S"), (qml.T(wires=[2]), 2, "T"), (qml.RX(3.14, wires=[1]), 1, "RX(3.14)"), (qml.RY(3.14, wires=[1]), 1, "RY(3.14)"), (qml.RZ(3.14, wires=[1]), 1, "RZ(3.14)"), (qml.Rot(3.14, 2.14, 1.14, wires=[1]), 1, "Rot(3.14, 2.14, 1.14)"), (qml.U1(3.14, wires=[1]), 1, "U1(3.14)"), (qml.U2(3.14, 2.14, wires=[1]), 1, "U2(3.14, 2.14)"), (qml.U3(3.14, 2.14, 1.14, wires=[1]), 1, "U3(3.14, 2.14, 1.14)"), (qml.BasisState(np.array([0, 1, 0]), wires=[1, 2, 3]), 1, "|0>"), (qml.BasisState(np.array([0, 1, 0]), wires=[1, 2, 3]), 2, "|1>"), (qml.BasisState(np.array([0, 1, 0]), wires=[1, 2, 3]), 3, "|0>"), (qml.QubitStateVector(np.array([0, 1, 0, 0]), wires=[1, 2]), 1, "QubitStateVector(M0)"), (qml.QubitStateVector(np.array([0, 1, 0, 0]), wires=[1, 2]), 2, "QubitStateVector(M0)"), (qml.QubitUnitary(np.eye(2), wires=[1]), 1, "U0"), (qml.QubitUnitary(np.eye(4), wires=[1, 2]), 2, "U0"), (qml.Kerr(3.14, wires=[1]), 1, "Kerr(3.14)"), (qml.CrossKerr(3.14, wires=[1, 2]), 1, "CrossKerr(3.14)"), (qml.CrossKerr(3.14, wires=[1, 2]), 2, "CrossKerr(3.14)"), (qml.CubicPhase(3.14, wires=[1]), 1, "V(3.14)"), (qml.Interferometer(np.eye(4), wires=[1, 3 ]), 1, "Interferometer(M0)"), (qml.Interferometer(np.eye(4), wires=[1, 3 ]), 3, "Interferometer(M0)"), (qml.CatState(3.14, 2.14, 1, wires=[1]), 1, "CatState(3.14, 2.14, 1)"), (qml.CoherentState(3.14, 2.14, wires=[1]), 1, "CoherentState(3.14, 2.14)"), ( qml.FockDensityMatrix(np.kron(np.eye(4), np.eye(4)), wires=[1, 2]), 1, "FockDensityMatrix(M0)", ), ( qml.FockDensityMatrix(np.kron(np.eye(4), np.eye(4)), wires=[1, 2]), 2, "FockDensityMatrix(M0)", ), ( qml.DisplacedSqueezedState(3.14, 2.14, 1.14, 0.14, wires=[1]), 1, "DisplacedSqueezedState(3.14, 2.14, 1.14, 0.14)", ), (qml.FockState(7, wires=[1]), 1, "|7>"), (qml.FockStateVector(np.array([4, 5, 7]), wires=[1, 2, 3 ]), 1, "|4>"), (qml.FockStateVector(np.array([4, 5, 7]), wires=[1, 2, 3 ]), 2, "|5>"), (qml.FockStateVector(np.array([4, 5, 7]), wires=[1, 2, 3 ]), 3, "|7>"), (qml.SqueezedState(3.14, 2.14, wires=[1]), 1, "SqueezedState(3.14, 2.14)"), (qml.Hermitian(np.eye(4), wires=[1, 2]), 1, "H0"), (qml.Hermitian(np.eye(4), wires=[1, 2]), 2, "H0"), (qml.X(wires=[1]), 1, "x"), (qml.P(wires=[1]), 1, "p"), (qml.FockStateProjector(np.array([4, 5, 7]), wires=[1, 2, 3]), 1, "|4,5,7X4,5,7|"), ( qml.PolyXP(np.array([1, 2, 0, -1.3, 6]), wires=[1]), 2, "1+2x_0-1.3x_1+6p_1", ), ( qml.PolyXP(np.array([[1.2, 2.3, 4.5], [-1.2, 1.2, -1.5], [-1.3, 4.5, 2.3]]), wires=[1]), 1, "1.2+1.1x_0+3.2p_0+1.2x_0^2+2.3p_0^2+3x_0p_0", ), ( qml.PolyXP( np.array([ [1.2, 2.3, 4.5, 0, 0], [-1.2, 1.2, -1.5, 0, 0], [-1.3, 4.5, 2.3, 0, 0], [0, 2.6, 0, 0, 0], [0, 0, 0, -4.7, 0], ]), wires=[1], ), 1, "1.2+1.1x_0+3.2p_0+1.2x_0^2+2.3p_0^2+3x_0p_0+2.6x_0x_1-4.7x_1p_1", ), (qml.QuadOperator(3.14, wires=[1]), 1, "cos(3.14)x+sin(3.14)p"), (qml.QuadOperator(3.14, wires=[1]), 1, "cos(3.14)x+sin(3.14)p"), (qml.PauliX(wires=[1]).inv(), 1, "X^-1"), (qml.CNOT(wires=[0, 1]).inv(), 1, "X^-1"), (qml.CNOT(wires=[0, 1]).inv(), 0, "C"), (qml.Toffoli(wires=[0, 2, 1]).inv(), 1, "X^-1"), (qml.Toffoli(wires=[0, 2, 1]).inv(), 0, "C"), (qml.Toffoli(wires=[0, 2, 1]).inv(), 2, "C"), ], ) def test_operator_representation_ascii(self, ascii_representation_resolver, op, wire, target): """Test that an Operator instance is properly resolved.""" assert ascii_representation_resolver.operator_representation( op, wire) == target @pytest.mark.parametrize( "obs,wire,target", [ (qml.expval(qml.PauliX(wires=[1])), 1, "⟨X⟩"), (qml.expval(qml.PauliY(wires=[1])), 1, "⟨Y⟩"), (qml.expval(qml.PauliZ(wires=[1])), 1, "⟨Z⟩"), (qml.expval(qml.Hadamard(wires=[1])), 1, "⟨H⟩"), (qml.expval(qml.Hermitian(np.eye(4), wires=[1, 2])), 1, "⟨H0⟩"), (qml.expval(qml.Hermitian(np.eye(4), wires=[1, 2])), 2, "⟨H0⟩"), (qml.expval(qml.NumberOperator(wires=[1])), 1, "⟨n⟩"), (qml.expval(qml.X(wires=[1])), 1, "⟨x⟩"), (qml.expval(qml.P(wires=[1])), 1, "⟨p⟩"), ( qml.expval( qml.FockStateProjector(np.array([4, 5, 7]), wires=[1, 2, 3])), 1, "⟨|4,5,7╳4,5,7|⟩", ), ( qml.expval(qml.PolyXP(np.array([1, 2, 0, -1.3, 6]), wires=[1 ])), 2, "⟨1+2x₀-1.3x₁+6p₁⟩", ), ( qml.expval( qml.PolyXP(np.array([[1.2, 2.3, 4.5], [-1.2, 1.2, -1.5], [-1.3, 4.5, 2.3]]), wires=[1])), 1, "⟨1.2+1.1x₀+3.2p₀+1.2x₀²+2.3p₀²+3x₀p₀⟩", ), (qml.expval(qml.QuadOperator( 3.14, wires=[1])), 1, "⟨cos(3.14)x+sin(3.14)p⟩"), (qml.var(qml.PauliX(wires=[1])), 1, "Var[X]"), (qml.var(qml.PauliY(wires=[1])), 1, "Var[Y]"), (qml.var(qml.PauliZ(wires=[1])), 1, "Var[Z]"), (qml.var(qml.Hadamard(wires=[1])), 1, "Var[H]"), (qml.var(qml.Hermitian(np.eye(4), wires=[1, 2])), 1, "Var[H0]"), (qml.var(qml.Hermitian(np.eye(4), wires=[1, 2])), 2, "Var[H0]"), (qml.var(qml.NumberOperator(wires=[1])), 1, "Var[n]"), (qml.var(qml.X(wires=[1])), 1, "Var[x]"), (qml.var(qml.P(wires=[1])), 1, "Var[p]"), ( qml.var( qml.FockStateProjector(np.array([4, 5, 7]), wires=[1, 2, 3])), 1, "Var[|4,5,7╳4,5,7|]", ), ( qml.var(qml.PolyXP(np.array([1, 2, 0, -1.3, 6]), wires=[1])), 2, "Var[1+2x₀-1.3x₁+6p₁]", ), ( qml.var( qml.PolyXP(np.array([[1.2, 2.3, 4.5], [-1.2, 1.2, -1.5], [-1.3, 4.5, 2.3]]), wires=[1])), 1, "Var[1.2+1.1x₀+3.2p₀+1.2x₀²+2.3p₀²+3x₀p₀]", ), (qml.var(qml.QuadOperator( 3.14, wires=[1])), 1, "Var[cos(3.14)x+sin(3.14)p]"), (qml.sample(qml.PauliX(wires=[1])), 1, "Sample[X]"), (qml.sample(qml.PauliY(wires=[1])), 1, "Sample[Y]"), (qml.sample(qml.PauliZ(wires=[1])), 1, "Sample[Z]"), (qml.sample(qml.Hadamard(wires=[1])), 1, "Sample[H]"), (qml.sample(qml.Hermitian(np.eye(4), wires=[1, 2 ])), 1, "Sample[H0]"), (qml.sample(qml.Hermitian(np.eye(4), wires=[1, 2 ])), 2, "Sample[H0]"), (qml.sample(qml.NumberOperator(wires=[1])), 1, "Sample[n]"), (qml.sample(qml.X(wires=[1])), 1, "Sample[x]"), (qml.sample(qml.P(wires=[1])), 1, "Sample[p]"), ( qml.sample( qml.FockStateProjector(np.array([4, 5, 7]), wires=[1, 2, 3])), 1, "Sample[|4,5,7╳4,5,7|]", ), ( qml.sample(qml.PolyXP(np.array([1, 2, 0, -1.3, 6]), wires=[1 ])), 2, "Sample[1+2x₀-1.3x₁+6p₁]", ), ( qml.sample( qml.PolyXP(np.array([[1.2, 2.3, 4.5], [-1.2, 1.2, -1.5], [-1.3, 4.5, 2.3]]), wires=[1])), 1, "Sample[1.2+1.1x₀+3.2p₀+1.2x₀²+2.3p₀²+3x₀p₀]", ), (qml.sample(qml.QuadOperator( 3.14, wires=[1])), 1, "Sample[cos(3.14)x+sin(3.14)p]"), ( qml.expval( qml.PauliX(wires=[1]) @ qml.PauliY(wires=[2]) @ qml.PauliZ(wires=[3])), 1, "⟨X ⊗ Y ⊗ Z⟩", ), ( qml.expval( qml.FockStateProjector(np.array([4, 5, 7]), wires=[1, 2, 3]) @ qml.X(wires=[4])), 1, "⟨|4,5,7╳4,5,7| ⊗ x⟩", ), ( qml.expval( qml.FockStateProjector(np.array([4, 5, 7]), wires=[1, 2, 3]) @ qml.X(wires=[4])), 2, "⟨|4,5,7╳4,5,7| ⊗ x⟩", ), ( qml.expval( qml.FockStateProjector(np.array([4, 5, 7]), wires=[1, 2, 3]) @ qml.X(wires=[4])), 3, "⟨|4,5,7╳4,5,7| ⊗ x⟩", ), ( qml.expval( qml.FockStateProjector(np.array([4, 5, 7]), wires=[1, 2, 3]) @ qml.X(wires=[4])), 4, "⟨|4,5,7╳4,5,7| ⊗ x⟩", ), ( qml.sample( qml.Hermitian(np.eye(4), wires=[1, 2]) @ qml.Hermitian( np.eye(4), wires=[0, 3])), 0, "Sample[H0 ⊗ H0]", ), ( qml.sample( qml.Hermitian(np.eye(4), wires=[1, 2]) @ qml.Hermitian( 2 * np.eye(4), wires=[0, 3])), 0, "Sample[H0 ⊗ H1]", ), (qml.probs([0]), 0, "Probs"), ], ) def test_output_representation_unicode(self, unicode_representation_resolver, obs, wire, target): """Test that an Observable instance with return type is properly resolved.""" assert unicode_representation_resolver.output_representation( obs, wire) == target def test_fallback_output_representation_unicode( self, unicode_representation_resolver): """Test that an Observable instance with return type is properly resolved.""" obs = qml.PauliZ(0) obs.return_type = "TestReturnType" assert unicode_representation_resolver.output_representation( obs, 0) == "TestReturnType[Z]" @pytest.mark.parametrize( "obs,wire,target", [ (qml.expval(qml.PauliX(wires=[1])), 1, "<X>"), (qml.expval(qml.PauliY(wires=[1])), 1, "<Y>"), (qml.expval(qml.PauliZ(wires=[1])), 1, "<Z>"), (qml.expval(qml.Hadamard(wires=[1])), 1, "<H>"), (qml.expval(qml.Hermitian(np.eye(4), wires=[1, 2])), 1, "<H0>"), (qml.expval(qml.Hermitian(np.eye(4), wires=[1, 2])), 2, "<H0>"), (qml.expval(qml.NumberOperator(wires=[1])), 1, "<n>"), (qml.expval(qml.X(wires=[1])), 1, "<x>"), (qml.expval(qml.P(wires=[1])), 1, "<p>"), ( qml.expval( qml.FockStateProjector(np.array([4, 5, 7]), wires=[1, 2, 3])), 1, "<|4,5,7X4,5,7|>", ), ( qml.expval(qml.PolyXP(np.array([1, 2, 0, -1.3, 6]), wires=[1 ])), 2, "<1+2x_0-1.3x_1+6p_1>", ), ( qml.expval( qml.PolyXP(np.array([[1.2, 2.3, 4.5], [-1.2, 1.2, -1.5], [-1.3, 4.5, 2.3]]), wires=[1])), 1, "<1.2+1.1x_0+3.2p_0+1.2x_0^2+2.3p_0^2+3x_0p_0>", ), (qml.expval(qml.QuadOperator( 3.14, wires=[1])), 1, "<cos(3.14)x+sin(3.14)p>"), (qml.var(qml.PauliX(wires=[1])), 1, "Var[X]"), (qml.var(qml.PauliY(wires=[1])), 1, "Var[Y]"), (qml.var(qml.PauliZ(wires=[1])), 1, "Var[Z]"), (qml.var(qml.Hadamard(wires=[1])), 1, "Var[H]"), (qml.var(qml.Hermitian(np.eye(4), wires=[1, 2])), 1, "Var[H0]"), (qml.var(qml.Hermitian(np.eye(4), wires=[1, 2])), 2, "Var[H0]"), (qml.var(qml.NumberOperator(wires=[1])), 1, "Var[n]"), (qml.var(qml.X(wires=[1])), 1, "Var[x]"), (qml.var(qml.P(wires=[1])), 1, "Var[p]"), ( qml.var( qml.FockStateProjector(np.array([4, 5, 7]), wires=[1, 2, 3])), 1, "Var[|4,5,7X4,5,7|]", ), ( qml.var(qml.PolyXP(np.array([1, 2, 0, -1.3, 6]), wires=[1])), 2, "Var[1+2x_0-1.3x_1+6p_1]", ), ( qml.var( qml.PolyXP(np.array([[1.2, 2.3, 4.5], [-1.2, 1.2, -1.5], [-1.3, 4.5, 2.3]]), wires=[1])), 1, "Var[1.2+1.1x_0+3.2p_0+1.2x_0^2+2.3p_0^2+3x_0p_0]", ), (qml.var(qml.QuadOperator( 3.14, wires=[1])), 1, "Var[cos(3.14)x+sin(3.14)p]"), (qml.sample(qml.PauliX(wires=[1])), 1, "Sample[X]"), (qml.sample(qml.PauliY(wires=[1])), 1, "Sample[Y]"), (qml.sample(qml.PauliZ(wires=[1])), 1, "Sample[Z]"), (qml.sample(qml.Hadamard(wires=[1])), 1, "Sample[H]"), (qml.sample(qml.Hermitian(np.eye(4), wires=[1, 2 ])), 1, "Sample[H0]"), (qml.sample(qml.Hermitian(np.eye(4), wires=[1, 2 ])), 2, "Sample[H0]"), (qml.sample(qml.NumberOperator(wires=[1])), 1, "Sample[n]"), (qml.sample(qml.X(wires=[1])), 1, "Sample[x]"), (qml.sample(qml.P(wires=[1])), 1, "Sample[p]"), ( qml.sample( qml.FockStateProjector(np.array([4, 5, 7]), wires=[1, 2, 3])), 1, "Sample[|4,5,7X4,5,7|]", ), ( qml.sample(qml.PolyXP(np.array([1, 2, 0, -1.3, 6]), wires=[1 ])), 2, "Sample[1+2x_0-1.3x_1+6p_1]", ), ( qml.sample( qml.PolyXP(np.array([[1.2, 2.3, 4.5], [-1.2, 1.2, -1.5], [-1.3, 4.5, 2.3]]), wires=[1])), 1, "Sample[1.2+1.1x_0+3.2p_0+1.2x_0^2+2.3p_0^2+3x_0p_0]", ), (qml.sample(qml.QuadOperator( 3.14, wires=[1])), 1, "Sample[cos(3.14)x+sin(3.14)p]"), ( qml.expval( qml.PauliX(wires=[1]) @ qml.PauliY(wires=[2]) @ qml.PauliZ(wires=[3])), 1, "<X @ Y @ Z>", ), ( qml.expval( qml.FockStateProjector(np.array([4, 5, 7]), wires=[1, 2, 3]) @ qml.X(wires=[4])), 1, "<|4,5,7X4,5,7| @ x>", ), ( qml.expval( qml.FockStateProjector(np.array([4, 5, 7]), wires=[1, 2, 3]) @ qml.X(wires=[4])), 2, "<|4,5,7X4,5,7| @ x>", ), ( qml.expval( qml.FockStateProjector(np.array([4, 5, 7]), wires=[1, 2, 3]) @ qml.X(wires=[4])), 3, "<|4,5,7X4,5,7| @ x>", ), ( qml.expval( qml.FockStateProjector(np.array([4, 5, 7]), wires=[1, 2, 3]) @ qml.X(wires=[4])), 4, "<|4,5,7X4,5,7| @ x>", ), ( qml.sample( qml.Hermitian(np.eye(4), wires=[1, 2]) @ qml.Hermitian( np.eye(4), wires=[0, 3])), 0, "Sample[H0 @ H0]", ), ( qml.sample( qml.Hermitian(np.eye(4), wires=[1, 2]) @ qml.Hermitian( 2 * np.eye(4), wires=[0, 3])), 0, "Sample[H0 @ H1]", ), (qml.probs([0]), 0, "Probs"), ], ) def test_output_representation_ascii(self, ascii_representation_resolver, obs, wire, target): """Test that an Observable instance with return type is properly resolved.""" assert ascii_representation_resolver.output_representation( obs, wire) == target def test_element_representation_none(self, unicode_representation_resolver): """Test that element_representation properly handles None.""" assert unicode_representation_resolver.element_representation(None, 0) == "" def test_element_representation_str(self, unicode_representation_resolver): """Test that element_representation properly handles strings.""" assert unicode_representation_resolver.element_representation( "Test", 0) == "Test" def test_element_representation_calls_output( self, unicode_representation_resolver): """Test that element_representation calls output_representation for returned observables.""" unicode_representation_resolver.output_representation = Mock() obs = qml.sample(qml.PauliX(3)) wire = 3 unicode_representation_resolver.element_representation(obs, wire) assert unicode_representation_resolver.output_representation.call_args[ 0] == (obs, wire) def test_element_representation_calls_operator( self, unicode_representation_resolver): """Test that element_representation calls operator_representation for all operators that are not returned.""" unicode_representation_resolver.operator_representation = Mock() op = qml.PauliX(3) wire = 3 unicode_representation_resolver.element_representation(op, wire) assert unicode_representation_resolver.operator_representation.call_args[ 0] == (op, wire)
def circuit(a, b, c): qml.RY(a * c, wires=0) qml.RZ(b, wires=0) qml.RX(c + c**2 + torch.sin(a), wires=0) return expval(qml.PauliZ(0))
def f(params1, params2): qml.RX(0.4, wires=[0]) qml.RZ(params1 * torch.sqrt(params2), wires=[0]) qml.RY(torch.cos(params2), wires=[0]) return qml.expval(qml.PauliZ(0))
def f(params1, params2): qml.RX(0.4, wires=[0]) qml.RZ(params1 * jax.numpy.sqrt(params2), wires=[0]) qml.RY(jax.numpy.cos(params2), wires=[0]) return qml.expval(qml.PauliZ(0))
def circuit(x, y): qml.RX(x, wires=[0]) qml.RZ(y, wires=[0]) qml.RX(x, wires=[0]) return qml.expval(qml.PauliZ(0))
def circuit(w, *, x=None): qml.RX(x[0], wires=[0]) qml.RX(x[1], wires=[1]) qml.RZ(w, wires=[0]) return qml.expval(qml.PauliZ(0)), qml.expval(qml.PauliZ(1))
def circuit(x): qml._current_context._append_op(CNOT) qml.RY(0.4, wires=[0]) qml.RZ(-0.2, wires=[1]) return qml.expval(qml.PauliX(0)), qml.expval(qml.PauliZ(1))
def template(x): for i in range(5): qml.RZ(i * x, wires=0) return qml.var(qml.PauliZ(0)), qml.sample(qml.PauliX(1))
def template(x): for i in range(5): qml.RZ(i * x, wires=0)
def my_op(a, b, c): qml.RX(a, wires=2) qml.RY(b, wires=3) qml.RZ(c, wires=0)
def circuit_native_pennylane(angle): qml.RZ(angle, wires=0) return qml.expval(qml.PauliZ(0))
class TestOperations: """Tests that the CirqDevice correctly handles the requested operations.""" def test_reset_on_empty_circuit(self, cirq_device_1_wire): """Tests that reset resets the internal circuit when it is not initialized.""" assert cirq_device_1_wire.circuit is None cirq_device_1_wire.reset() # Check if circuit is an empty cirq.Circuit assert cirq_device_1_wire.circuit == cirq.Circuit() def test_reset_on_full_circuit(self, cirq_device_1_wire): """Tests that reset resets the internal circuit when it is filled.""" cirq_device_1_wire.reset() cirq_device_1_wire.apply([qml.PauliX(0)]) # Assert that the queue is filled assert list(cirq_device_1_wire.circuit.all_operations()) cirq_device_1_wire.reset() # Assert that the queue is empty assert not list(cirq_device_1_wire.circuit.all_operations()) @pytest.mark.parametrize( "gate,expected_cirq_gates", [ (qml.PauliX(wires=[0]), [cirq.X]), (qml.PauliY(wires=[0]), [cirq.Y]), (qml.PauliZ(wires=[0]), [cirq.Z]), (qml.PauliX(wires=[0]).inv(), [cirq.X ** -1]), (qml.PauliY(wires=[0]).inv(), [cirq.Y ** -1]), (qml.PauliZ(wires=[0]).inv(), [cirq.Z ** -1]), (qml.Hadamard(wires=[0]), [cirq.H]), (qml.Hadamard(wires=[0]).inv(), [cirq.H ** -1]), (qml.S(wires=[0]), [cirq.S]), (qml.S(wires=[0]).inv(), [cirq.S ** -1]), (qml.PhaseShift(1.4, wires=[0]), [cirq.ZPowGate(exponent=1.4 / np.pi)]), (qml.PhaseShift(-1.2, wires=[0]), [cirq.ZPowGate(exponent=-1.2 / np.pi)]), (qml.PhaseShift(2, wires=[0]), [cirq.ZPowGate(exponent=2 / np.pi)]), (qml.PhaseShift(1.4, wires=[0]).inv(), [cirq.ZPowGate(exponent=-1.4 / np.pi)],), (qml.PhaseShift(-1.2, wires=[0]).inv(), [cirq.ZPowGate(exponent=1.2 / np.pi)],), (qml.PhaseShift(2, wires=[0]).inv(), [cirq.ZPowGate(exponent=-2 / np.pi)]), (qml.RX(1.4, wires=[0]), [cirq.rx(1.4)]), (qml.RX(-1.2, wires=[0]), [cirq.rx(-1.2)]), (qml.RX(2, wires=[0]), [cirq.rx(2)]), (qml.RX(1.4, wires=[0]).inv(), [cirq.rx(-1.4)]), (qml.RX(-1.2, wires=[0]).inv(), [cirq.rx(1.2)]), (qml.RX(2, wires=[0]).inv(), [cirq.rx(-2)]), (qml.RY(1.4, wires=[0]), [cirq.ry(1.4)]), (qml.RY(0, wires=[0]), [cirq.ry(0)]), (qml.RY(-1.3, wires=[0]), [cirq.ry(-1.3)]), (qml.RY(1.4, wires=[0]).inv(), [cirq.ry(-1.4)]), (qml.RY(0, wires=[0]).inv(), [cirq.ry(0)]), (qml.RY(-1.3, wires=[0]).inv(), [cirq.ry(+1.3)]), (qml.RZ(1.4, wires=[0]), [cirq.rz(1.4)]), (qml.RZ(-1.1, wires=[0]), [cirq.rz(-1.1)]), (qml.RZ(1, wires=[0]), [cirq.rz(1)]), (qml.RZ(1.4, wires=[0]).inv(), [cirq.rz(-1.4)]), (qml.RZ(-1.1, wires=[0]).inv(), [cirq.rz(1.1)]), (qml.RZ(1, wires=[0]).inv(), [cirq.rz(-1)]), (qml.Rot(1.4, 2.3, -1.2, wires=[0]), [cirq.rz(1.4), cirq.ry(2.3), cirq.rz(-1.2)],), (qml.Rot(1, 2, -1, wires=[0]), [cirq.rz(1), cirq.ry(2), cirq.rz(-1)]), (qml.Rot(-1.1, 0.2, -1, wires=[0]), [cirq.rz(-1.1), cirq.ry(0.2), cirq.rz(-1)],), ( qml.Rot(1.4, 2.3, -1.2, wires=[0]).inv(), [cirq.rz(1.2), cirq.ry(-2.3), cirq.rz(-1.4)], ), (qml.Rot(1, 2, -1, wires=[0]).inv(), [cirq.rz(1), cirq.ry(-2), cirq.rz(-1)],), (qml.Rot(-1.1, 0.2, -1, wires=[0]).inv(), [cirq.rz(1), cirq.ry(-0.2), cirq.rz(1.1)],), ( qml.QubitUnitary(np.array([[1, 0], [0, 1]]), wires=[0]), [cirq.MatrixGate(np.array([[1, 0], [0, 1]]))], ), ( qml.QubitUnitary(np.array([[1, 0], [0, -1]]), wires=[0]), [cirq.MatrixGate(np.array([[1, 0], [0, -1]]))], ), ( qml.QubitUnitary(np.array([[-1, 1], [1, 1]]) / math.sqrt(2), wires=[0]), [cirq.MatrixGate(np.array([[-1, 1], [1, 1]]) / math.sqrt(2))], ), ( qml.QubitUnitary(np.array([[1, 0], [0, 1]]), wires=[0]).inv(), [cirq.MatrixGate(np.array([[1, 0], [0, 1]])) ** -1], ), ( qml.QubitUnitary(np.array([[1, 0], [0, -1]]), wires=[0]).inv(), [cirq.MatrixGate(np.array([[1, 0], [0, -1]])) ** -1], ), ( qml.QubitUnitary(np.array([[-1, 1], [1, 1]]) / math.sqrt(2), wires=[0]).inv(), [cirq.MatrixGate(np.array([[-1, 1], [1, 1]]) / math.sqrt(2)) ** -1], ), ], ) def test_apply_single_wire(self, cirq_device_1_wire, gate, expected_cirq_gates): """Tests that apply adds the correct gates to the circuit for single-qubit gates.""" cirq_device_1_wire.reset() cirq_device_1_wire.apply([gate]) ops = list(cirq_device_1_wire.circuit.all_operations()) assert len(ops) == len(expected_cirq_gates) for i in range(len(ops)): assert ops[i]._gate == expected_cirq_gates[i] @pytest.mark.parametrize( "gate,expected_cirq_gates", [ (qml.CNOT(wires=[0, 1]), [cirq.CNOT]), (qml.CNOT(wires=[0, 1]).inv(), [cirq.CNOT ** -1]), (qml.SWAP(wires=[0, 1]), [cirq.SWAP]), (qml.SWAP(wires=[0, 1]).inv(), [cirq.SWAP ** -1]), (qml.CZ(wires=[0, 1]), [cirq.CZ]), (qml.CZ(wires=[0, 1]).inv(), [cirq.CZ ** -1]), (qml.CRX(1.4, wires=[0, 1]), [cirq.ControlledGate(cirq.rx(1.4))]), (qml.CRX(-1.2, wires=[0, 1]), [cirq.ControlledGate(cirq.rx(-1.2))]), (qml.CRX(2, wires=[0, 1]), [cirq.ControlledGate(cirq.rx(2))]), (qml.CRX(1.4, wires=[0, 1]).inv(), [cirq.ControlledGate(cirq.rx(-1.4))]), (qml.CRX(-1.2, wires=[0, 1]).inv(), [cirq.ControlledGate(cirq.rx(1.2))]), (qml.CRX(2, wires=[0, 1]).inv(), [cirq.ControlledGate(cirq.rx(-2))]), (qml.CRY(1.4, wires=[0, 1]), [cirq.ControlledGate(cirq.ry(1.4))]), (qml.CRY(0, wires=[0, 1]), [cirq.ControlledGate(cirq.ry(0))]), (qml.CRY(-1.3, wires=[0, 1]), [cirq.ControlledGate(cirq.ry(-1.3))]), (qml.CRY(1.4, wires=[0, 1]).inv(), [cirq.ControlledGate(cirq.ry(-1.4))]), (qml.CRY(0, wires=[0, 1]).inv(), [cirq.ControlledGate(cirq.ry(0))]), (qml.CRY(-1.3, wires=[0, 1]).inv(), [cirq.ControlledGate(cirq.ry(1.3))]), (qml.CRZ(1.4, wires=[0, 1]), [cirq.ControlledGate(cirq.rz(1.4))]), (qml.CRZ(-1.1, wires=[0, 1]), [cirq.ControlledGate(cirq.rz(-1.1))]), (qml.CRZ(1, wires=[0, 1]), [cirq.ControlledGate(cirq.rz(1))]), (qml.CRZ(1.4, wires=[0, 1]).inv(), [cirq.ControlledGate(cirq.rz(-1.4))]), (qml.CRZ(-1.1, wires=[0, 1]).inv(), [cirq.ControlledGate(cirq.rz(1.1))]), (qml.CRZ(1, wires=[0, 1]).inv(), [cirq.ControlledGate(cirq.rz(-1))]), ( qml.CRot(1.4, 2.3, -1.2, wires=[0, 1]), [ cirq.ControlledGate(cirq.rz(1.4)), cirq.ControlledGate(cirq.ry(2.3)), cirq.ControlledGate(cirq.rz(-1.2)), ], ), ( qml.CRot(1, 2, -1, wires=[0, 1]), [ cirq.ControlledGate(cirq.rz(1)), cirq.ControlledGate(cirq.ry(2)), cirq.ControlledGate(cirq.rz(-1)), ], ), ( qml.CRot(-1.1, 0.2, -1, wires=[0, 1]), [ cirq.ControlledGate(cirq.rz(-1.1)), cirq.ControlledGate(cirq.ry(0.2)), cirq.ControlledGate(cirq.rz(-1)), ], ), ( qml.CRot(1.4, 2.3, -1.2, wires=[0, 1]).inv(), [ cirq.ControlledGate(cirq.rz(1.2)), cirq.ControlledGate(cirq.ry(-2.3)), cirq.ControlledGate(cirq.rz(-1.4)), ], ), ( qml.CRot(1, 2, -1, wires=[0, 1]).inv(), [ cirq.ControlledGate(cirq.rz(1)), cirq.ControlledGate(cirq.ry(-2)), cirq.ControlledGate(cirq.rz(-1)), ], ), ( qml.CRot(-1.1, 0.2, -1, wires=[0, 1]).inv(), [ cirq.ControlledGate(cirq.rz(1)), cirq.ControlledGate(cirq.ry(-0.2)), cirq.ControlledGate(cirq.rz(1.1)), ], ), (qml.QubitUnitary(np.eye(4), wires=[0, 1]), [cirq.MatrixGate(np.eye(4))]), ( qml.QubitUnitary( np.array([[0, 0, 0, 1], [0, 0, 1, 0], [0, 1, 0, 0], [1, 0, 0, 0]]), wires=[0, 1], ), [ cirq.MatrixGate( np.array([[0, 0, 0, 1], [0, 0, 1, 0], [0, 1, 0, 0], [1, 0, 0, 0]]) ) ], ), ( qml.QubitUnitary( np.array([[1, -1, -1, 1], [-1, -1, 1, 1], [-1, 1, -1, 1], [1, 1, 1, 1]]) / 2, wires=[0, 1], ), [ cirq.MatrixGate( np.array([[1, -1, -1, 1], [-1, -1, 1, 1], [-1, 1, -1, 1], [1, 1, 1, 1],]) / 2 ) ], ), (qml.QubitUnitary(np.eye(4), wires=[0, 1]).inv(), [cirq.MatrixGate(np.eye(4)) ** -1],), ( qml.QubitUnitary( np.array([[0, 0, 0, 1], [0, 0, 1, 0], [0, 1, 0, 0], [1, 0, 0, 0]]), wires=[0, 1], ).inv(), [ cirq.MatrixGate( np.array([[0, 0, 0, 1], [0, 0, 1, 0], [0, 1, 0, 0], [1, 0, 0, 0]]) ) ** -1 ], ), ( qml.QubitUnitary( np.array([[1, -1, -1, 1], [-1, -1, 1, 1], [-1, 1, -1, 1], [1, 1, 1, 1]]) / 2, wires=[0, 1], ).inv(), [ cirq.MatrixGate( np.array([[1, -1, -1, 1], [-1, -1, 1, 1], [-1, 1, -1, 1], [1, 1, 1, 1],]) / 2 ) ** -1 ], ), ], ) def test_apply_two_wires(self, cirq_device_2_wires, gate, expected_cirq_gates): """Tests that apply adds the correct gates to the circuit for two-qubit gates.""" cirq_device_2_wires.reset() cirq_device_2_wires.apply([gate]) ops = list(cirq_device_2_wires.circuit.all_operations()) assert len(ops) == len(expected_cirq_gates) for i in range(len(ops)): assert ops[i].gate == expected_cirq_gates[i]
def cost(p1, p2): qml.RX(extra_param, wires=[0]) qml.RY(p1, wires=[0]) qml.RZ(p2, wires=[0]) qml.RX(p1, wires=[0]) return qml.expval(qml.PauliZ(0))
def decomposition(phi, wires): return [ qml.CNOT(wires=wires), qml.RZ(phi, wires=[wires[1]]), qml.CNOT(wires=wires), ]
def expand_hadamards(tape, x): for op in tape.operations + tape.measurements: if op.name == "Hadamard": qml.RZ(x, wires=op.wires) else: op.queue()
def circuit(x): qml.RZ(x, wires=[0]) return qml.expval(qml.PauliZ(0))
def circuit(): qml.Hadamard(wires=0) qml.RZ(np.pi / 4, wires=0) return qml.expval(qml.PauliZ(0))
def circuit(x): qml.RX(x, wires=[0]) qml.CNOT(wires=[0, 1], do_queue=False) qml.RY(0.4, wires=[0]) qml.RZ(-0.2, wires=[1], do_queue=False) return qml.expval(qml.PauliX(0)), qml.expval(qml.PauliZ(1))
def circuit(x): qml.RX(x[0], wires=0) qml.RY(x[1], wires=1) qml.RZ(x[2], wires=1) qml.CNOT(wires=[0, 1]) return qml.expval(qml.PauliX(0) @ qml.PauliY(1))
(qml.Hadamard(wires=0), H), (qml.S(wires=0), S), (qml.T(wires=0), T), (qml.PauliX(wires=0).inv(), X.conj().T), (qml.PauliY(wires=0).inv(), Y.conj().T), (qml.PauliZ(wires=0).inv(), Z.conj().T), (qml.Hadamard(wires=0).inv(), H.conj().T), (qml.S(wires=0).inv(), S.conj().T), (qml.T(wires=0).inv(), T.conj().T), ] # list of all parametrized single-qubit gates single_qubit_param = [ (qml.RX(0, wires=0), rx), (qml.RY(0, wires=0), ry), (qml.RZ(0, wires=0), rz), (qml.PhaseShift(0, wires=0), phase_shift), (qml.RX(0, wires=0).inv(), lambda theta: rx(-theta)), (qml.RY(0, wires=0).inv(), lambda theta: ry(-theta)), (qml.RZ(0, wires=0).inv(), lambda theta: rz(-theta)), (qml.PhaseShift(0, wires=0).inv(), lambda theta: phase_shift(-theta)), ] # list of all non-parametrized two-qubit gates two_qubit = [ (qml.CNOT(wires=[0, 1]), CNOT), (qml.SWAP(wires=[0, 1]), SWAP), (qml.CZ(wires=[0, 1]), CZ), (qml.CNOT(wires=[0, 1]).inv(), CNOT.conj().T), (qml.SWAP(wires=[0, 1]).inv(), SWAP.conj().T), (qml.CZ(wires=[0, 1]).inv(), CZ.conj().T), ]
def statepreparation(x): # qml.BasisState(x, wires=[0, 1, 2, 3]) for i in range(len(x)): qml.RY(np.pi * x[i] / 2, wires=i) qml.RX(np.pi * x[i] / 2, wires=i) qml.RZ(np.pi * x[i] / 2, wires=i)
"CRot": qml.CRot(0, 0, 0, wires=[0, 1]), "CSWAP": qml.CSWAP(wires=[0, 1, 2]), "CZ": qml.CZ(wires=[0, 1]), "CY": qml.CY(wires=[0, 1]), "DiagonalQubitUnitary": qml.DiagonalQubitUnitary(np.eye(2), wires=[0]), "Hadamard": qml.Hadamard(wires=[0]), "MultiRZ": qml.MultiRZ(0, wires=[0]), "PauliX": qml.PauliX(wires=[0]), "PauliY": qml.PauliY(wires=[0]), "PauliZ": qml.PauliZ(wires=[0]), "PhaseShift": qml.PhaseShift(0, wires=[0]), "QubitStateVector": qml.QubitStateVector(np.array([1.0, 0.0]), wires=[0]), "QubitUnitary": qml.QubitUnitary(np.eye(2), wires=[0]), "RX": qml.RX(0, wires=[0]), "RY": qml.RY(0, wires=[0]), "RZ": qml.RZ(0, wires=[0]), "Rot": qml.Rot(0, 0, 0, wires=[0]), "S": qml.S(wires=[0]), "SWAP": qml.SWAP(wires=[0, 1]), "T": qml.T(wires=[0]), "Toffoli": qml.Toffoli(wires=[0, 1, 2]), } all_ops = ops.keys() # non-parametrized qubit gates I = np.identity(2) X = np.array([[0, 1], [1, 0]]) Y = np.array([[0, -1j], [1j, 0]]) Z = np.array([[1, 0], [0, -1]]) H = np.array([[1, 1], [1, -1]]) / sqrt(2)
def circuit(x, y, z): qml.RX(x, wires=0) qml.RY(y, wires=0) qml.RZ(z, wires=0) return qml.expval(qml.PauliZ(0))
def _decomposition_3_cnots(U, wires): r"""The most general form of this decomposition is U = (A \otimes B) V (C \otimes D), where V is as depicted in the circuit below: -╭U- = -C--╭X--RZ(d)--╭C---------╭X--A- -╰U- = -D--╰C--RY(b)--╰X--RY(a)--╰C--B- """ # First we add a SWAP as per v1 of arXiv:0308033, which helps with some # rearranging of gates in the decomposition (it will cancel out the fact # that we need to add a SWAP to fix the determinant in another part later). swap_U = np.exp(1j * np.pi / 4) * math.dot(math.cast_like(SWAP, U), U) # Choose the rotation angles of RZ, RY in the two-qubit decomposition. # They are chosen as per Proposition V.1 in quant-ph/0308033 and are based # on the phases of the eigenvalues of :math:`E^\dagger \gamma(U) E`, where # \gamma(U) = (E^\dag U E) (E^\dag U E)^T. # The rotation angles can be computed as follows (any three eigenvalues can be used) u = math.dot(Edag, math.dot(swap_U, E)) gammaU = math.dot(u, math.T(u)) evs, _ = math.linalg.eig(gammaU) # We will sort the angles so that results are consistent across interfaces. angles = math.sort([math.angle(ev) for ev in evs]) x, y, z = angles[0], angles[1], angles[2] # Compute functions of the eigenvalues; there are different options in v1 # vs. v3 of the paper, I'm not entirely sure why. This is the version from v3. alpha = (x + y) / 2 beta = (x + z) / 2 delta = (z + y) / 2 # This is the interior portion of the decomposition circuit interior_decomp = [ qml.CNOT(wires=[wires[1], wires[0]]), qml.RZ(delta, wires=wires[0]), qml.RY(beta, wires=wires[1]), qml.CNOT(wires=wires), qml.RY(alpha, wires=wires[1]), qml.CNOT(wires=[wires[1], wires[0]]), ] # We need the matrix representation of this interior part, V, in order to # decompose U = (A \otimes B) V (C \otimes D) # # Looking at the decomposition above, V has determinant -1 (because there # are 3 CNOTs, each with determinant -1). The relationship between U and V # requires that both are in SU(4), so we add a SWAP after to V. We will see # how this gets fixed later. # # -╭V- = -╭X--RZ(d)--╭C---------╭X--╭SWAP- # -╰V- = -╰C--RY(b)--╰X--RY(a)--╰C--╰SWAP- RZd = qml.RZ(math.cast_like(delta, 1j), wires=wires[0]).matrix RYb = qml.RY(beta, wires=wires[0]).matrix RYa = qml.RY(alpha, wires=wires[0]).matrix V_mats = [ CNOT10, math.kron(RZd, RYb), CNOT01, math.kron(math.eye(2), RYa), CNOT10, SWAP ] V = math.convert_like(math.eye(4), U) for mat in V_mats: V = math.dot(math.cast_like(mat, U), V) # Now we need to find the four SU(2) operations A, B, C, D A, B, C, D = _extract_su2su2_prefactors(swap_U, V) # At this point, we have the following: # -╭U-╭SWAP- = --C--╭X-RZ(d)-╭C-------╭X-╭SWAP--A # -╰U-╰SWAP- = --D--╰C-RZ(b)-╰X-RY(a)-╰C-╰SWAP--B # # Using the relationship that SWAP(A \otimes B) SWAP = B \otimes A, # -╭U-╭SWAP- = --C--╭X-RZ(d)-╭C-------╭X--B--╭SWAP- # -╰U-╰SWAP- = --D--╰C-RZ(b)-╰X-RY(a)-╰C--A--╰SWAP- # # Now the SWAPs cancel, giving us the desired decomposition # (up to a global phase). # -╭U- = --C--╭X-RZ(d)-╭C-------╭X--B-- # -╰U- = --D--╰C-RZ(b)-╰X-RY(a)-╰C--A-- A_ops = zyz_decomposition(A, wires[1]) B_ops = zyz_decomposition(B, wires[0]) C_ops = zyz_decomposition(C, wires[0]) D_ops = zyz_decomposition(D, wires[1]) # Return the full decomposition return C_ops + D_ops + interior_decomp + A_ops + B_ops
def circuit(phi, theta): qml.RX(theta, wires=0) qml.RZ(phi, wires=0) return qml.expval(qml.PauliZ(0))