def test_matrix_parameter(self, U, tol): """Test that the Torch interface works correctly with a matrix parameter""" a_val = 0.1 a = torch.tensor(a_val, requires_grad=True) dev = qml.device("default.qubit", wires=2) with TorchInterface.apply(QuantumTape()) as tape: qml.QubitUnitary(U, wires=0) qml.RY(a, wires=0) qml.expval(qml.PauliZ(0)) assert tape.trainable_params == {1} res = tape.execute(dev) assert np.allclose(res.detach().numpy(), -np.cos(a_val), atol=tol, rtol=0) res.backward() assert np.allclose(a.grad, np.sin(a_val), atol=tol, rtol=0)
def apply_random_su4_layer(num_qubits): for qubit_idx in range(0, num_qubits, 2): if qubit_idx < num_qubits - 1: rand_haar_su4 = random_interferometer(N=4) qml.QubitUnitary(rand_haar_su4, wires=[qubit_idx, qubit_idx + 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.24"), ], ) 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 @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([[2, 0], [0, 2]]), np.array([1, 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.InterferometerUnitary( np.eye(4), wires=[1, 3]), 1, "InterferometerUnitary(M0)"), (qml.InterferometerUnitary( np.eye(4), wires=[1, 3]), 3, "InterferometerUnitary(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"), (qml.measure.sample(wires=[0, 1]), 0, "basis"), # not providing an observable in (qml.measure.sample(wires=[0, 1]), 1, "basis"), # sample gets displayed as raw (two_wire_quantum_tape(), 0, "QuantumTape:T0"), (two_wire_quantum_tape(), 1, "QuantumTape:T0"), ], ) 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([[2, 0], [0, 2]]), np.array([1, 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.InterferometerUnitary( np.eye(4), wires=[1, 3]), 1, "InterferometerUnitary(M0)"), (qml.InterferometerUnitary( np.eye(4), wires=[1, 3]), 3, "InterferometerUnitary(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"), (qml.measure.sample(wires=[0, 1]), 0, "basis"), # not providing an observable in (qml.measure.sample(wires=[0, 1]), 1, "basis"), # sample gets displayed as raw (two_wire_quantum_tape(), 0, "QuantumTape:T0"), (two_wire_quantum_tape(), 1, "QuantumTape:T0"), ], ) 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"), (state(), 0, "State"), ], ) 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"), (state(), 0, "State"), ], ) 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)
# pylint: disable=invalid-name import math import random import numpy as np import pennylane as qml import benchmark_utils as bu CCZ_diag = np.array([1, 1, 1, 1, 1, 1, 1, -1]) CCZ_matrix = np.diag(CCZ_diag) if hasattr(qml, "DiagonalQubitUnitary"): CCZ = lambda wires: qml.DiagonalQubitUnitary(CCZ_diag, wires=wires) else: CCZ = lambda wires: qml.QubitUnitary(CCZ_matrix, wires=wires) def random_iqp_wires(n_wires): """Create a random set of IQP wires. Returns a list of either 1, 2, or 3 distinct integers in the range of n_wires. Args: n_wires (int): Number of wires of the device. Returns: List[int]: The IQP wires. """ # The global seed was fixed during benchmark construction
"CRY": qml.CRY(0, wires=[0, 1]), "CRZ": qml.CRZ(0, wires=[0, 1]), "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.array([1, 1]), 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]), "ControlledPhaseShift": qml.ControlledPhaseShift(0, wires=[0, 1]), "QubitStateVector": qml.QubitStateVector(np.array([1.0, 0.0]), wires=[0]), "QubitUnitary": qml.QubitUnitary(np.eye(2), wires=[0]), "ControlledQubitUnitary": qml.ControlledQubitUnitary(np.eye(2), control_wires=[1], wires=[0]), "MultiControlledX": qml.MultiControlledX(control_wires=[1, 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]), "SX": qml.SX(wires=[0]), "Toffoli": qml.Toffoli(wires=[0, 1, 2]), "QFT": qml.QFT(wires=[0, 1, 2]), "SingleExcitation": qml.SingleExcitation(0, wires=[0, 1]), "SingleExcitationPlus": qml.SingleExcitationPlus(0, wires=[0, 1]), "SingleExcitationMinus": qml.SingleExcitationMinus(0, wires=[0, 1]),
def crossres_circuit(gate_pars): G = Generator(*gate_pars) qml.QubitUnitary(expm(-1j * G), wires=[0, 1]) return qml.expval(qml.PauliZ(0))
def f2(): qml.QubitUnitary(U1, wires=range(3)) qml.Toffoli(wires=control_wires + [target_wire]) qml.QubitUnitary(U2, wires=range(3)) return qml.state()
def qnode(): qml.S(wires=0) qml.QubitUnitary(U, wires=0) return qml.expval(qml.PauliZ(0))
def cost(a, U, device): with QuantumTape() as tape: qml.QubitUnitary(U, wires=0) qml.RY(a, wires=0) expval(qml.PauliZ(0)) return tape.execute(device)
def U0(t, wires): matrix = U0_matrix(t) qml.QubitUnitary(matrix, wires=wires)
def qr_haar_random_unitary(): qml.QubitUnitary(qr_haar(2), wires=0) return qml.state()
def Turing(): # distinct fun names in functional placeholders= # [] qml.Hadamard(0) qml.PauliX(1) qml.PauliY(1) qml.PauliZ(1) qml.CNOT(wires=[0, 1]) qml.CZ(wires=[0, 1]) qml.SWAP(wires=[1, 0]) qml.RX(-6.283185307179586, wires=2) qml.RY(-6.283185307179586, wires=2) qml.RZ(-6.283185307179586, wires=2) qml.PhaseShift(3.141592653589793, wires=1) def rot(rad_ang_x, rad_ang_y, rad_ang_z, lib='np'): """ Returns exp(1j*(rad_ang_x*sig_x + rad_ang_y*sig_y + rad_ang_z*sig_z)) where rad_ang_x is an angle in radians and sig_x is the x Pauli matrix, etc. Parameters ---------- rad_ang_x : float rad_ang_y : float rad_ang_z : float lib : str Returns ------- np.ndarray """ if 'autograd.numpy' in sys.modules: tlist = [0., rad_ang_x, rad_ang_y, rad_ang_z] return pu2(*tlist) mat_dict = OneQubitGate.const_dict(0) vec = [rad_ang_x, rad_ang_y, rad_ang_z] n = OneQubitGate.get_fun(lib, 'sqrt')(vec[0]**2 + vec[1]**2 + vec[2]**2) if abs(n) < 1e-8: mat_dict['00'] = 1 mat_dict['11'] = 1 else: nx = rad_ang_x / n ny = rad_ang_y / n nz = rad_ang_z / n c = OneQubitGate.get_fun(lib, 'cos')(n) s = OneQubitGate.get_fun(lib, 'sin')(n) mat_dict['00'] = c + 1j * s * nz mat_dict['01'] = s * ny + 1j * s * nx mat_dict['10'] = -s * ny + 1j * s * nx mat_dict['11'] = c - 1j * s * nz return OneQubitGate.get_mat(lib, mat_dict) qml.QubitUnitary(rot(-6.283185307179586, -6.283185307179586, -6.283185307179586), wires=0) return qml.expval.Hermitian(hamil)
# # .. math:: # # \frac{1}{\sqrt{2}} # \begin{bmatrix} # 1 & \sqrt{i} \\ # \sqrt{-i} & 1 \\ # \end{bmatrix}. # # The :math:`\sqrt{X}` gate is already implemented in PennyLane, while the # two other gates can be implemented as follows: sqrtYgate = lambda wires: qml.RY(np.pi / 2, wires=wires) sqrtWgate = lambda wires: qml.QubitUnitary( np.array([[1, -np.sqrt(1j)], [np.sqrt(-1j), 1]]) / np.sqrt(2), wires=wires ) single_qubit_gates = [qml.SX, sqrtYgate, sqrtWgate] ###################################################################### # For the two-qubit gates we need the iSWAP gate # # .. math:: # # \begin{bmatrix} # 1 & 0 & 0 & 0 \\ # 0 & 0 & i & 0 \\ # 0 & i & 0 & 0 \\ # 0 & 0 & 0 & 1
def state_evolve(hamiltonian, qubits, time): U = scipy.linalg.expm(-1j * hamiltonian * time) qml.QubitUnitary(U, wires=qubits)
def circuit(phi0, Xdata=None, Y=None): X1 = Xdata[0:, 0] X2 = Xdata[0:, 1] for i in range(4): qml.Hadamard(wires=i) qml.QubitUnitary(U1f, wires=all_wires) featuremap(X1[0], X2[0], Y[0], phi0) qml.QubitUnitary(U1b, wires=all_wires) qml.QubitUnitary(U2f, wires=all_wires) featuremap(X1[1], X2[1], Y[1], phi0) qml.QubitUnitary(U2b, wires=all_wires) qml.QubitUnitary(U3f, wires=all_wires) featuremap(X1[2], X2[2], Y[2], phi0) qml.QubitUnitary(U3b, wires=all_wires) qml.QubitUnitary(U4f, wires=all_wires) featuremap(X1[3], X2[3], Y[3], phi0) qml.QubitUnitary(U4b, wires=all_wires) qml.QubitUnitary(U5f, wires=all_wires) featuremap(X1[4], X2[4], Y[4], phi0) qml.QubitUnitary(U5b, wires=all_wires) qml.QubitUnitary(U6f, wires=all_wires) featuremap(X1[5], X2[5], Y[5], phi0) qml.QubitUnitary(U6b, wires=all_wires) qml.QubitUnitary(U7f, wires=all_wires) featuremap(X1[6], X2[6], Y[6], phi0) qml.QubitUnitary(U7b, wires=all_wires) qml.QubitUnitary(U8f, wires=all_wires) featuremap(X1[7], X2[7], Y[7], phi0) qml.QubitUnitary(U8b, wires=all_wires) qml.Hadamard(wires=0) return qml.expval(qml.Hermitian(np.array([[1, 0], [0, 0]]), wires=0)), qml.expval(qml.PauliZ(wires=5))
def cost(a, U, device): with qml.tape.JacobianTape() as tape: qml.QubitUnitary(U, wires=0) qml.RY(a, wires=0) qml.expval(qml.PauliZ(0)) return execute([tape], device, **execute_kwargs)[0]
def vqe_circuit(params): qml.QubitUnitary(np.array([[1, 0], [0, 1]]), wires=0) qml.RX(params[0], wires=0) qml.RX(params[1], wires=1)
def fn(): qml.QubitUnitary(a_mat, wires=wires[:-1]) qml.QubitUnitary(r_mat, wires=wires)
qml.PauliX(wires=control_wires[wire]) qml.ControlledQubitUnitary(U, control_wires=control_wires, wires=wires) for wire in x_locations: qml.PauliX(wires=control_wires[wire]) return qml.state() mixed_polarity_state = circuit_mixed_polarity() pauli_x_state = circuit_pauli_x() assert np.allclose(mixed_polarity_state, pauli_x_state) label_data = [ (qml.QubitUnitary(X, wires=0), "U"), (qml.DiagonalQubitUnitary([1, 1], wires=1), "U"), (qml.ControlledQubitUnitary(X, control_wires=0, wires=1), "U"), ] @pytest.mark.parametrize("op, label", label_data) def test_label(op, label): assert op.label() == label assert op.label(decimals=5) == label op.inv() assert op.label() == label + "⁻¹"
def apply_r(input_state): qml.QubitStateVector(input_state, wires=range(wires)) qml.QubitUnitary(r, wires=range(wires + 1)) return qml.probs(wires)
def f2(): qml.QubitUnitary(U1, wires=range(4)) qml.QubitUnitary(U_matrix, wires=range(4)) qml.QubitUnitary(U2, wires=range(4)) return qml.state()
def U(): # this may not generate a uniform distribution of states, but certainly can yield any state #random_U = scipy.stats.unitary_group.rvs(3) U = np.kron(pauli_x, pauli_x) qml.QubitUnitary(U, wires=[0, 1])
def circuit(U, a): qml.QubitUnitary(U, wires=0) qml.RY(a, wires=0) return qml.expval(qml.PauliZ(0))
qml.ControlledQubitUnitary(U, control_wires=control_wires, wires=wires) for wire in x_locations: qml.PauliX(wires=control_wires[wire]) return qml.state() mixed_polarity_state = circuit_mixed_polarity() pauli_x_state = circuit_pauli_x() assert np.allclose(mixed_polarity_state, pauli_x_state) label_data = [ (qml.QubitUnitary(X, wires=0), "U"), (qml.DiagonalQubitUnitary([1, 1], wires=1), "U"), (qml.ControlledQubitUnitary(X, control_wires=0, wires=1), "U"), ] @pytest.mark.parametrize("op, label", label_data) def test_label(op, label): assert op.label() == label assert op.label(decimals=5) == label op.inv() assert op.label() == label + "⁻¹" control_data = [ (qml.QubitUnitary(X, wires=0), Wires([])),
def circuit(): qml.QubitStateVector(rnd_state, wires=range(n_wires)) qml.QubitUnitary(mat, wires=list(range(n_wires))).inv() return qml.probs(wires=range(n_wires))
def f1(): qml.QubitUnitary(U1, wires=range(4)) qml.ControlledQubitUnitary(U, control_wires=control_wires, wires=target_wires) qml.QubitUnitary(U2, wires=range(4)) return qml.state()
def metric_tensor(self, args, kwargs=None, *, diag_approx=False, only_construct=False): """Evaluate the value of the metric tensor. Args: args (tuple[Any]): positional (differentiable) arguments kwargs (dict[str, Any]): auxiliary arguments diag_approx (bool): iff True, use the diagonal approximation only_construct (bool): Iff True, construct the circuits used for computing the metric tensor but do not execute them, and return None. Returns: array[float]: metric tensor """ kwargs = kwargs or {} kwargs = self._default_args(kwargs) if self.circuit is None or self.mutable: # construct the circuit self._construct(args, kwargs) if self._metric_tensor_subcircuits is None: self._construct_metric_tensor(diag_approx=diag_approx) if only_construct: return None # temporarily store the parameter values in the Variable class self._set_variables(args, kwargs) tensor = np.zeros([self.num_variables, self.num_variables]) # execute constructed metric tensor subcircuits for params, circuit in self._metric_tensor_subcircuits.items(): self.device.reset() s = np.array(circuit["scale"]) V = circuit["eigenbasis_matrix"] if not diag_approx: # block diagonal approximation unitary_op = qml.QubitUnitary(V, wires=list(range( self.num_wires)), do_queue=False) self.device.execute(circuit["queue"] + [unitary_op], [ qml.expval(qml.PauliZ(wire)) for wire in list(range(self.device.num_wires)) ]) probs = list(self.device.probability()) first_order_ev = np.zeros([len(params)]) second_order_ev = np.zeros([len(params), len(params)]) for idx, ev in circuit["Ki_expectations"]: first_order_ev[idx] = ev @ probs for idx, ev in circuit["KiKj_expectations"]: # idx is a 2-tuple (i, j), representing # generators K_i, K_j second_order_ev[idx] = ev @ probs # since K_i and K_j are assumed to commute, # <psi|K_j K_i|psi> = <psi|K_i K_j|psi>, # and thus the matrix of second-order expectations # is symmetric second_order_ev[idx[1], idx[0]] = second_order_ev[idx] g = np.zeros([len(params), len(params)]) for i, j in itertools.product(range(len(params)), repeat=2): g[i, j] = (s[i] * s[j] * (second_order_ev[i, j] - first_order_ev[i] * first_order_ev[j])) row = np.array(params).reshape(-1, 1) col = np.array(params).reshape(1, -1) circuit["result"] = np.diag(g) tensor[row, col] = g else: # diagonal approximation circuit["result"] = s**2 * self.device.execute( circuit["queue"], circuit["observable"]) tensor[np.array(params), np.array(params)] = circuit["result"] return tensor
def circuit(Umat): """Test QNode""" qml.QubitUnitary(Umat, wires=[0, 1]) return qml.expval(qml.PauliZ(0))
def circuit(): """Reference QNode""" qml.Hadamard(wires=0) qml.CNOT(wires=[0, 1]) qml.QubitUnitary(U2, wires=[0, 1]) 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]