diff --git a/pennylane/gradients/hadamard_gradient.py b/pennylane/gradients/hadamard_gradient.py index 014bccd8630..dea644caf71 100644 --- a/pennylane/gradients/hadamard_gradient.py +++ b/pennylane/gradients/hadamard_gradient.py @@ -461,9 +461,6 @@ def _get_generators(trainable_op): elif isinstance(trainable_op, qml.Rot): generators = [qml.Z(trainable_op.wires)] coeffs = [-0.5] - elif isinstance(trainable_op, (qml.RX, qml.RY, qml.RZ)): - generators = [trainable_op.generator().base] - coeffs = [trainable_op.generator().scalar] else: generators = trainable_op.generator().ops coeffs = trainable_op.generator().coeffs diff --git a/pennylane/ops/op_math/adjoint.py b/pennylane/ops/op_math/adjoint.py index d1d45bc8f42..2f896620d53 100644 --- a/pennylane/ops/op_math/adjoint.py +++ b/pennylane/ops/op_math/adjoint.py @@ -401,7 +401,7 @@ def has_generator(self): return self.base.has_generator def generator(self): - return qml.s_prod(-1.0, self.base.generator()) + return -1 * self.base.generator() class AdjointObs(Adjoint, Observable): diff --git a/pennylane/ops/op_math/pow.py b/pennylane/ops/op_math/pow.py index ac0f313235b..011c4309162 100644 --- a/pennylane/ops/op_math/pow.py +++ b/pennylane/ops/op_math/pow.py @@ -329,7 +329,7 @@ def generator(self): See also :func:`~.generator` """ - return qml.s_prod(self.z, self.base.generator(), lazy=False) + return self.z * self.base.generator() def pow(self, z): return [Pow(base=self.base, z=self.z * z)] diff --git a/pennylane/ops/qubit/parametric_ops_multi_qubit.py b/pennylane/ops/qubit/parametric_ops_multi_qubit.py index 1da176c1d6a..e09b29caaae 100644 --- a/pennylane/ops/qubit/parametric_ops_multi_qubit.py +++ b/pennylane/ops/qubit/parametric_ops_multi_qubit.py @@ -115,7 +115,7 @@ def compute_matrix(theta, num_wires): # pylint: disable=arguments-differ ) def generator(self): - return qml.s_prod(-0.5, functools.reduce(matmul, [PauliZ(w) for w in self.wires])) + return qml.Hamiltonian([-0.5], [functools.reduce(matmul, [PauliZ(w) for w in self.wires])]) @staticmethod def compute_eigvals(theta, num_wires): # pylint: disable=arguments-differ @@ -406,7 +406,10 @@ def compute_matrix(theta, pauli_word): # pylint: disable=arguments-differ def generator(self): pauli_word = self.hyperparameters["pauli_word"] wire_map = {w: i for i, w in enumerate(self.wires)} - return qml.s_prod(-0.5, qml.pauli.string_to_pauli_word(pauli_word, wire_map=wire_map)) + + return qml.Hamiltonian( + [-0.5], [qml.pauli.string_to_pauli_word(pauli_word, wire_map=wire_map)] + ) @staticmethod def compute_eigvals(theta, pauli_word): # pylint: disable=arguments-differ @@ -774,7 +777,7 @@ class IsingXX(Operation): parameter_frequencies = [(1,)] def generator(self): - return qml.s_prod(-0.5, qml.prod(PauliX(wires=self.wires[0]), PauliX(wires=self.wires[1]))) + return qml.Hamiltonian([-0.5], [PauliX(wires=self.wires[0]) @ PauliX(wires=self.wires[1])]) def __init__(self, phi, wires, id=None): super().__init__(phi, wires=wires, id=id) @@ -910,7 +913,7 @@ class IsingYY(Operation): parameter_frequencies = [(1,)] def generator(self): - return qml.s_prod(-0.5, qml.prod(PauliY(wires=self.wires[0]), PauliY(wires=self.wires[1]))) + return qml.Hamiltonian([-0.5], [PauliY(wires=self.wires[0]) @ PauliY(wires=self.wires[1])]) def __init__(self, phi, wires, id=None): super().__init__(phi, wires=wires, id=id) @@ -1053,7 +1056,7 @@ class IsingZZ(Operation): parameter_frequencies = [(1,)] def generator(self): - return qml.s_prod(-0.5, qml.prod(PauliZ(wires=self.wires[0]), PauliZ(wires=self.wires[1]))) + return qml.Hamiltonian([-0.5], [PauliZ(wires=self.wires[0]) @ PauliZ(wires=self.wires[1])]) def __init__(self, phi, wires, id=None): super().__init__(phi, wires=wires, id=id) @@ -1236,12 +1239,13 @@ class IsingXY(Operation): parameter_frequencies = [(0.5, 1.0)] def generator(self): - return qml.s_prod( - 0.25, - qml.sum( - qml.prod(PauliX(wires=self.wires[0]), PauliX(wires=self.wires[1])), - qml.prod(PauliY(wires=self.wires[0]), PauliY(wires=self.wires[1])), - ), + + return qml.Hamiltonian( + [0.25, 0.25], + [ + qml.X(wires=self.wires[0]) @ qml.X(wires=self.wires[1]), + qml.Y(wires=self.wires[0]) @ qml.Y(wires=self.wires[1]), + ], ) def __init__(self, phi, wires, id=None): diff --git a/pennylane/ops/qubit/parametric_ops_single_qubit.py b/pennylane/ops/qubit/parametric_ops_single_qubit.py index 02b913cb49b..c38cc550943 100644 --- a/pennylane/ops/qubit/parametric_ops_single_qubit.py +++ b/pennylane/ops/qubit/parametric_ops_single_qubit.py @@ -70,7 +70,7 @@ class RX(Operation): parameter_frequencies = [(1,)] def generator(self): - return qml.s_prod(-0.5, PauliX(wires=self.wires)) + return qml.Hamiltonian([-0.5], [PauliX(wires=self.wires)]) def __init__(self, phi, wires, id=None): super().__init__(phi, wires=wires, id=id) @@ -166,7 +166,7 @@ class RY(Operation): parameter_frequencies = [(1,)] def generator(self): - return qml.s_prod(-0.5, PauliY(wires=self.wires)) + return qml.Hamiltonian([-0.5], [PauliY(wires=self.wires)]) def __init__(self, phi, wires, id=None): super().__init__(phi, wires=wires, id=id) @@ -261,7 +261,7 @@ class RZ(Operation): parameter_frequencies = [(1,)] def generator(self): - return qml.s_prod(-0.5, PauliZ(wires=self.wires)) + return qml.Hamiltonian([-0.5], [PauliZ(wires=self.wires)]) def __init__(self, phi, wires, id=None): super().__init__(phi, wires=wires, id=id) diff --git a/tests/ops/op_math/test_adjoint.py b/tests/ops/op_math/test_adjoint.py index a5a5291a828..73627b09484 100644 --- a/tests/ops/op_math/test_adjoint.py +++ b/tests/ops/op_math/test_adjoint.py @@ -489,12 +489,13 @@ def test_has_generator_false(self): assert op.has_generator is False + @pytest.mark.usefixtures("use_legacy_and_new_opmath") def test_generator(self): """Assert that the generator of an Adjoint is -1.0 times the base generator.""" base = qml.RX(1.23, wires=0) op = Adjoint(base) - assert qml.equal(base.generator(), qml.s_prod(-1.0, op.generator())) + assert qml.equal(base.generator(), -1.0 * op.generator()) def test_no_generator(self): """Test that an adjointed non-Operation raises a GeneratorUndefinedError.""" diff --git a/tests/ops/qubit/test_parametric_ops.py b/tests/ops/qubit/test_parametric_ops.py index 127a882e070..88ead3da971 100644 --- a/tests/ops/qubit/test_parametric_ops.py +++ b/tests/ops/qubit/test_parametric_ops.py @@ -30,8 +30,6 @@ MultiRZ as old_loc_MultiRZ, ) -from pennylane.ops.op_math.sprod import SProd - from pennylane.wires import Wires PARAMETRIZED_OPERATIONS = [ @@ -236,6 +234,7 @@ def test_pcphase_raises_error(self): class TestParameterFrequencies: + @pytest.mark.usefixtures("use_legacy_and_new_opmath") @pytest.mark.parametrize("op", PARAMETRIZED_OPERATIONS) def test_parameter_frequencies_match_generator(self, op, tol): if not qml.operation.has_gen(op): @@ -2974,12 +2973,13 @@ def test_init_incorrect_pauli_word_length_error(self, pauli_word, wires): ("IIIXYZ"), ], ) + @pytest.mark.usefixtures("use_legacy_and_new_opmath") def test_multirz_generator(self, pauli_word): """Test that the generator of the MultiRZ gate is correct.""" op = qml.PauliRot(0.3, pauli_word, wires=range(len(pauli_word))) gen = op.generator() - assert isinstance(gen, SProd) + assert isinstance(gen, qml.Hamiltonian) if pauli_word[0] == "I": # this is the identity @@ -2994,7 +2994,7 @@ def test_multirz_generator(self, pauli_word): else: expected_gen = expected_gen @ getattr(qml, f"Pauli{pauli}")(wires=i) - assert qml.equal(gen, qml.s_prod(-0.5, expected_gen)) + assert qml.equal(gen, qml.Hamiltonian([-0.5], [expected_gen])) @pytest.mark.torch @pytest.mark.gpu @@ -3189,18 +3189,19 @@ def decomp_circuit(theta): assert np.allclose(qml.jacobian(circuit)(angle), qml.jacobian(decomp_circuit)(angle)) @pytest.mark.parametrize("qubits", range(3, 6)) + @pytest.mark.usefixtures("use_legacy_and_new_opmath") def test_multirz_generator(self, qubits, mocker): """Test that the generator of the MultiRZ gate is correct.""" op = qml.MultiRZ(0.3, wires=range(qubits)) gen = op.generator() - assert isinstance(gen, SProd) + assert isinstance(gen, qml.Hamiltonian) expected_gen = qml.PauliZ(wires=0) for i in range(1, qubits): expected_gen = expected_gen @ qml.PauliZ(wires=i) - assert qml.equal(gen, qml.s_prod(-0.5, expected_gen)) + assert qml.equal(gen, qml.Hamiltonian([-0.5], [expected_gen])) spy = mocker.spy(qml.utils, "pauli_eigs")