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

ParametrizedEvolution: Use params in super call #3730

Merged
merged 8 commits into from
Feb 7, 2023
1 change: 1 addition & 0 deletions doc/releases/changelog-dev.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@
* A `ParametrizedHamiltonian` can be time-evolved by using `ParametrizedEvolution`.
[(#3617)](https://github.com/PennyLaneAI/pennylane/pull/3617)
[(#3706)](https://github.com/PennyLaneAI/pennylane/pull/3706)
[(#3730)](https://github.com/PennyLaneAI/pennylane/pull/3730)

* A new function called `qml.evolve` has been added that returns the evolution of an `Operator` or a `ParametrizedHamiltonian`.
[(#3617)](https://github.com/PennyLaneAI/pennylane/pull/3617)
Expand Down
15 changes: 9 additions & 6 deletions pennylane/pulse/parametrized_evolution.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,30 +172,33 @@ def __init__(
raise ValueError(
"All operators inside the parametrized hamiltonian must have a matrix defined."
)
self._has_matrix = params is not None and t is not None
self.H = H
self.params = params
self.odeint_kwargs = odeint_kwargs
if t is None:
self.t = None
else:
self.t = jnp.array([0, t] if qml.math.ndim(t) == 0 else t, dtype=float)
super().__init__(wires=H.wires, do_queue=do_queue, id=id)
params = [] if params is None else params
super().__init__(*params, wires=H.wires, do_queue=do_queue, id=id)

def __call__(self, params, t, **odeint_kwargs):
self.params = params
self.data = [jnp.array(p) if isinstance(p, list) else p for p in params]
self._num_params = len(params)
dwierichs marked this conversation as resolved.
Show resolved Hide resolved
self.t = jnp.array([0, t] if qml.math.ndim(t) == 0 else t, dtype=float)
if odeint_kwargs:
self.odeint_kwargs.update(odeint_kwargs)
self._has_matrix = True
return self

# pylint: disable=arguments-renamed, invalid-overridden-method
@property
def has_matrix(self):
return True
return self._has_matrix
dwierichs marked this conversation as resolved.
Show resolved Hide resolved

# pylint: disable=import-outside-toplevel
def matrix(self, wire_order=None):
if self.params is None or self.t is None:
if not self.has_matrix:
dwierichs marked this conversation as resolved.
Show resolved Hide resolved
raise ValueError(
"The parameters and the time window are required to compute the matrix. "
"You can update its values by calling the class: EV(params, t)."
Expand All @@ -204,7 +207,7 @@ def matrix(self, wire_order=None):

def fun(y, t):
"""dy/dt = -i H(t) y"""
return -1j * qml.matrix(self.H(self.params, t=t)) @ y
return -1j * qml.matrix(self.H(self.data, t=t)) @ y

result = odeint(fun, y0, self.t, **self.odeint_kwargs)
mat = result[-1]
Expand Down
2 changes: 1 addition & 1 deletion tests/ops/qubit/test_matrix_ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -518,7 +518,7 @@ def circuit(x):
loss = circuit(x)

grad = tape.gradient(loss, x)
expected = -tf.math.sin(x)
expected = -tf.math.sin(x) # pylint: disable=invalid-unary-operand-type
dwierichs marked this conversation as resolved.
Show resolved Hide resolved
assert np.allclose(grad, expected)


Expand Down
13 changes: 7 additions & 6 deletions tests/pulse/test_parametrized_evolution.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,17 +89,16 @@ def test_init(self):

assert ev.H is H
assert qml.math.allequal(ev.t, [0, 2])
assert qml.math.allequal(ev.params, [1, 2])

assert ev.wires == H.wires
assert ev.num_wires == AnyWires
assert ev.name == "ParametrizedEvolution"
assert ev.id is None
assert ev.queue_idx is None

assert ev.data == []
assert ev.parameters == []
assert ev.num_params == 0
assert qml.math.allequal(ev.data, [1, 2])
assert qml.math.allequal(ev.parameters, [1, 2])
assert ev.num_params == 2
AlbertMitjans marked this conversation as resolved.
Show resolved Hide resolved

def test_odeint_kwargs(self):
"""Test the initialization with odeint kwargs."""
Expand All @@ -117,14 +116,16 @@ def test_update_attributes(self):
H = ParametrizedHamiltonian(coeffs, ops)
ev = ParametrizedEvolution(H=H, mxstep=10)

assert ev.params is None
assert ev.parameters == []
assert ev.num_params == 0
assert ev.t is None
assert ev.odeint_kwargs == {"mxstep": 10}
params = [1, 2, 3]
t = 6
ev(params, t, atol=1e-6, rtol=1e-4)

assert qml.math.allequal(ev.params, params)
assert qml.math.allequal(ev.parameters, params)
assert ev.num_params == 3
assert qml.math.allequal(ev.t, [0, 6])
assert ev.odeint_kwargs == {"mxstep": 10, "atol": 1e-6, "rtol": 1e-4}

Expand Down