Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adapting generators to opmath enabled/disabled #5415

Merged
merged 37 commits into from
Mar 21, 2024
Merged
Show file tree
Hide file tree
Changes from 31 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
09359fe
Update getattr in init file
mudit2812 Mar 15, 2024
bf36746
Added test and changelog entry
mudit2812 Mar 15, 2024
419a150
Update doc/releases/changelog-dev.md
mudit2812 Mar 15, 2024
53207fc
Add deprecation warning
mudit2812 Mar 18, 2024
e8b25c3
Removing mocking implementation of the aliasing
mudit2812 Mar 18, 2024
f650568
[skip-ci] Formatting and linting
mudit2812 Mar 18, 2024
0a37fd7
Added test
mudit2812 Mar 18, 2024
20f52fb
Merge branch 'ham-tests' into getattr-ham-lc-aliasing
lillian542 Mar 18, 2024
3b604e4
Merge branch 'ham-tests' of https://github.com/PennyLaneAI/pennylane …
Qottmann Mar 18, 2024
35a72cd
remove failing parameterization for now
lillian542 Mar 18, 2024
13e12d9
Added fixture to tests
mudit2812 Mar 18, 2024
28f55c6
Merge branch 'ham-tests' into getattr-ham-lc-aliasing
Alex-Preciado Mar 19, 2024
7f15187
Merge branch 'ham-tests' of https://github.com/PennyLaneAI/pennylane …
Qottmann Mar 19, 2024
51921fc
Merge branch 'getattr-ham-lc-aliasing' of https://github.com/PennyLan…
Qottmann Mar 19, 2024
8c7d77f
black formatting
Qottmann Mar 19, 2024
c1c9b57
remove unused import
Qottmann Mar 19, 2024
25a019f
Updated deprecation docs
mudit2812 Mar 19, 2024
1c7ccc4
Update instance check in hamiltonian_expand
mudit2812 Mar 19, 2024
0e92dce
Moved changelog entry to breaking changes section
mudit2812 Mar 19, 2024
3405777
empty commit
PietropaoloFrisoni Mar 19, 2024
00414bb
Replacing first bunch of generators
PietropaoloFrisoni Mar 19, 2024
0c8053b
Replacing gens in `param_ops_multi_qubit`
PietropaoloFrisoni Mar 19, 2024
d604efc
Satisfying pylint
PietropaoloFrisoni Mar 19, 2024
8f57c47
using `simplify` as argument
PietropaoloFrisoni Mar 19, 2024
88ff4f6
replacing `simplify` as argument in favour of `qml.simplify`
PietropaoloFrisoni Mar 20, 2024
77b8109
modify things so that everything works with opmath disabled as well
PietropaoloFrisoni Mar 20, 2024
dd3c693
Merge branch 'ham-tests' into Adapting-generators-to-opmath
PietropaoloFrisoni Mar 20, 2024
8abb192
Using `@pytest.mark.usefixtures("use_legacy_and_new_opmath")` in test…
PietropaoloFrisoni Mar 20, 2024
b699b93
replacing return statements
PietropaoloFrisoni Mar 20, 2024
4a45c2b
avoiding `(0.25) [Hamiltonian0,1]` in parametric_ops
PietropaoloFrisoni Mar 20, 2024
223002b
fixing bug in previous commit
PietropaoloFrisoni Mar 20, 2024
9d7ba94
removing one line from `adjoint` and `pow` operators
PietropaoloFrisoni Mar 21, 2024
853d0d1
Merge branch 'ham-tests' of https://github.com/PennyLaneAI/pennylane …
PietropaoloFrisoni Mar 21, 2024
febc83c
Removing additional test
PietropaoloFrisoni Mar 21, 2024
78936f3
Merge branch 'ham-tests' of https://github.com/PennyLaneAI/pennylane …
PietropaoloFrisoni Mar 21, 2024
0eb3a7d
Merge branch 'ham-tests' of https://github.com/PennyLaneAI/pennylane …
PietropaoloFrisoni Mar 21, 2024
83526bb
Merge branch 'ham-tests' of https://github.com/PennyLaneAI/pennylane …
PietropaoloFrisoni Mar 21, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions pennylane/gradients/hadamard_gradient.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion pennylane/ops/op_math/adjoint.py
PietropaoloFrisoni marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,8 @@ def has_generator(self):
return self.base.has_generator

def generator(self):
return qml.s_prod(-1.0, self.base.generator())
gen = -1 * self.base.generator()
return qml.Hamiltonian(gen.coeffs, gen.ops)


class AdjointObs(Adjoint, Observable):
Expand Down
3 changes: 2 additions & 1 deletion pennylane/ops/op_math/pow.py
PietropaoloFrisoni marked this conversation as resolved.
Show resolved Hide resolved
PietropaoloFrisoni marked this conversation as resolved.
Show resolved Hide resolved
PietropaoloFrisoni marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,8 @@ def generator(self):

See also :func:`~.generator`
"""
return qml.s_prod(self.z, self.base.generator(), lazy=False)
gen = self.z * self.base.generator()
return qml.Hamiltonian(gen.coeffs, gen.ops)
PietropaoloFrisoni marked this conversation as resolved.
Show resolved Hide resolved

def pow(self, z):
return [Pow(base=self.base, z=self.z * z)]
Expand Down
26 changes: 15 additions & 11 deletions pennylane/ops/qubit/parametric_ops_multi_qubit.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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]),
],
PietropaoloFrisoni marked this conversation as resolved.
Show resolved Hide resolved
)

def __init__(self, phi, wires, id=None):
Expand Down
6 changes: 3 additions & 3 deletions pennylane/ops/qubit/parametric_ops_single_qubit.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
10 changes: 9 additions & 1 deletion tests/ops/op_math/test_adjoint.py
PietropaoloFrisoni marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -489,12 +489,20 @@ def test_has_generator_false(self):

assert op.has_generator is False

@pytest.mark.usefixtures("use_legacy_opmath")
def test_generator_legacy(self):
"""Assert that the generator of an Adjoint is -1.0 times the base generator with opmath disabled."""
PietropaoloFrisoni marked this conversation as resolved.
Show resolved Hide resolved
base = qml.RX(1.23, wires=0)
op = Adjoint(base)

assert qml.equal(base.generator(), -1.0 * op.generator())

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(), qml.Hamiltonian([-1.0], [op.generator()]))

def test_no_generator(self):
"""Test that an adjointed non-Operation raises a GeneratorUndefinedError."""
Expand Down
13 changes: 7 additions & 6 deletions tests/ops/qubit/test_parametric_ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@
MultiRZ as old_loc_MultiRZ,
)

from pennylane.ops.op_math.sprod import SProd

from pennylane.wires import Wires

PARAMETRIZED_OPERATIONS = [
Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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")

Expand Down
Loading