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

qml.evolve: dispatch function #3706

Merged
merged 48 commits into from
Feb 6, 2023
Merged
Show file tree
Hide file tree
Changes from 41 commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
ff6fef4
:test_tube: tests (evolve): Fix tests.
AlbertMitjans Feb 1, 2023
622d1ff
:memo: docs (evolve): Fix docstring.
AlbertMitjans Feb 1, 2023
d1de994
:memo: docs (evolve): Fix docstring.
AlbertMitjans Feb 1, 2023
7548308
:test_tube: tests (evolve): Add tests.
AlbertMitjans Feb 1, 2023
0ad0fe7
:pencil2: chore (changelog): Add changelog entry.
AlbertMitjans Feb 1, 2023
0171402
Merge branch 'master' into refactor-evolve
AlbertMitjans Feb 1, 2023
d8f16ba
:memo: docs (evolve): Fix docstring.
AlbertMitjans Feb 1, 2023
7f8959f
Merge branch 'refactor-evolve' of github.com:PennyLaneAI/pennylane in…
AlbertMitjans Feb 1, 2023
9b16f01
:memo: docs (evolve): Fix docstring.
AlbertMitjans Feb 1, 2023
ca8455d
Merge branch 'master' into refactor-evolve
AlbertMitjans Feb 1, 2023
5656770
:test_tube: tests (evolve): Fix coverage.
AlbertMitjans Feb 1, 2023
8442a92
:wrench: refactor (evolve): Dispatch function.
AlbertMitjans Feb 2, 2023
1bbf4b3
:wrench: refactor (evolve): Dispatch function.
AlbertMitjans Feb 2, 2023
a641f33
:memo: docs (evolve): Fix docstring.
AlbertMitjans Feb 2, 2023
daae413
Merge branch 'master' into refactor-evolve
AlbertMitjans Feb 2, 2023
89daf88
:test_tube: tests (evolve): Fix tests.
AlbertMitjans Feb 2, 2023
8bbb2ab
:memo: docs (evolve): Fix sphinx.
AlbertMitjans Feb 2, 2023
0a992bf
:rewind: revert (evolve): Remove t and dt from parametrized_evolution.
AlbertMitjans Feb 2, 2023
86bc771
:memo: docs (evolve): Fix docstring.
AlbertMitjans Feb 2, 2023
b9903f4
:memo: docs (evolve): Fix docstring.
AlbertMitjans Feb 2, 2023
0ded919
Update pennylane/ops/functions/evolve.py
AlbertMitjans Feb 3, 2023
c964852
Update pennylane/ops/functions/evolve.py
AlbertMitjans Feb 3, 2023
1b3cd1e
Merge branch 'master' into refactor-evolve
AlbertMitjans Feb 3, 2023
c98d411
:memo: docs (evolve): Update evolve docstring.
AlbertMitjans Feb 3, 2023
90099bf
:memo: docs (evolve): Update evolve docstring.
AlbertMitjans Feb 3, 2023
e0529d4
:memo: docs (evolve): Fix sphinx.
AlbertMitjans Feb 3, 2023
072c086
:memo: docs (evolve): Test sphinx.
AlbertMitjans Feb 3, 2023
65bb0d8
:memo: docs (evolve): Test sphinx.
AlbertMitjans Feb 3, 2023
04dbc09
:memo: docs (evolve): Use html.
AlbertMitjans Feb 3, 2023
7c1bbc5
:memo: docs (evolve): Fix docstring.
AlbertMitjans Feb 3, 2023
1740df7
:memo: docs (evolve): Fix docstring.
AlbertMitjans Feb 3, 2023
a863632
:memo: docs (evolve): Test sphinx.
AlbertMitjans Feb 3, 2023
8e5542f
:memo: docs (evolve): Test sphinx.
AlbertMitjans Feb 3, 2023
ad701d4
:memo: docs (evolve): Fix docstring.
AlbertMitjans Feb 3, 2023
d681ee6
:memo: docs (evolve): Fix docstring.
AlbertMitjans Feb 3, 2023
e41fb6d
:bug: fix (evolve): Remove op from initial call.
AlbertMitjans Feb 3, 2023
ef9bf9f
:memo: docs (evolve): Remove docstrings of dispatched functions.
AlbertMitjans Feb 3, 2023
0527537
:memo: docs (evolve): Change docstring.
AlbertMitjans Feb 3, 2023
db0f9fe
Merge branch 'master' into refactor-evolve
AlbertMitjans Feb 3, 2023
c23e653
:wrench: refactor (evolve): Add warning.
AlbertMitjans Feb 3, 2023
43f750b
Merge branch 'refactor-evolve' of github.com:PennyLaneAI/pennylane in…
AlbertMitjans Feb 3, 2023
ac3a992
Update doc/releases/changelog-dev.md
AlbertMitjans Feb 3, 2023
4d67dbe
:pencil2: chore (changelog): Add deprecation entry.
AlbertMitjans Feb 3, 2023
8152ebf
:pencil2: chore (changelog): Add changelog entry.
AlbertMitjans Feb 3, 2023
9514fff
Merge branch 'refactor-evolve' of github.com:PennyLaneAI/pennylane in…
AlbertMitjans Feb 3, 2023
a9eb2ab
:memo: docs (evolve): Change docstring.
AlbertMitjans Feb 3, 2023
b50e546
Update pennylane/ops/functions/evolve.py
AlbertMitjans Feb 3, 2023
eca547f
Merge branch 'master' into refactor-evolve
AlbertMitjans Feb 6, 2023
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
2 changes: 2 additions & 0 deletions doc/releases/changelog-dev.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,11 @@

* 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)

* A new function called `qml.evolve` has been added that returns the evolution of an operator or a `ParametrizedHamiltonian`.
AlbertMitjans marked this conversation as resolved.
Show resolved Hide resolved
[(#3617)](https://github.com/PennyLaneAI/pennylane/pull/3617)
[(#3706)](https://github.com/PennyLaneAI/pennylane/pull/3706)

* A new function `dot` has been added to compute the dot product between a vector and a list of operators. `qml.dot` will now target this new function.
[(#3586)](https://github.com/PennyLaneAI/pennylane/pull/3586)
Expand Down
70 changes: 57 additions & 13 deletions pennylane/ops/functions/evolve.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,32 +14,64 @@
"""
This module contains the qml.evolve function.
"""
from typing import Union
import warnings
from functools import singledispatch

from pennylane.operation import Operator
from pennylane.ops import Evolution
from pennylane.pulse import ParametrizedEvolution, ParametrizedHamiltonian


def evolve(op: Union[Operator, ParametrizedHamiltonian]):
"""Returns a new operator that computes the evolution of ``op``.
@singledispatch
def evolve(*args, **kwargs): # pylint: disable=unused-argument
r"""This method is dispatched and its functionality depends on the type of the input ``op``.

.. raw:: html

<html>
<h3>Input: Operator</h3>
<hr>
</html>

Returns a new operator that computes the evolution of ``op``.

.. math::

e^{-i \times \bm{op} \times coeff)}
lillian542 marked this conversation as resolved.
Show resolved Hide resolved

Args:
op (Union[.Operator, .ParametrizedHamiltonian]): operator to evolve
op (.Operator): operator to evolve
coeff (float): coefficient multiplying the exponentiated operator

Returns:
Union[.Evolution, ~pennylane.ops.op_math.evolve.ParametrizedEvolution]: evolution operator
.Evolution: evolution operator

.. seealso:: :class:`.ParametrizedEvolution`
.. seealso:: :class:`.Evolution`
.. seealso:: :class:`~.Evolution`

**Examples**

We can use ``qml.evolve`` to compute the evolution of any PennyLane operator:

>>> op = qml.s_prod(2, qml.PauliX(0))
>>> qml.evolve(op)
Exp(1j 2*(PauliX(wires=[0])))
>>> op = qml.evolve(qml.PauliX(0), coeff=2)
>>> op
Exp(2j PauliX)

.. raw:: html

<html>
<h3>Input: ParametrizedHamiltonian</h3>
<hr>
</html>

Args:
op (.ParametrizedHamiltonian): operator to evolve

Returns:
~pennylane.ops.op_math.evolve.ParametrizedEvolution: evolution operator

.. seealso:: :class:`.ParametrizedEvolution`

**Examples**

When evolving a :class:`.ParametrizedHamiltonian` class, then a :class:`.ParametrizedEvolution`
instance is returned:
Expand All @@ -58,7 +90,19 @@ def evolve(op: Union[Operator, ParametrizedHamiltonian]):

Please check the :class:`.ParametrizedEvolution` class for more information.
"""
if isinstance(op, ParametrizedHamiltonian):
return ParametrizedEvolution(H=op)

return Evolution(generator=op, param=1.0)

# pylint: disable=missing-docstring
@evolve.register
def parametrized_hamiltonian(op: ParametrizedHamiltonian):
return ParametrizedEvolution(H=op)


# pylint: disable=missing-docstring
@evolve.register
def evolution(op: Operator, coeff: float = 1):
with warnings.catch_warnings():
# Ignore the warning raised in `Evolution`
warnings.simplefilter("ignore")
ev = Evolution(op, -1 * coeff)
return ev
6 changes: 5 additions & 1 deletion pennylane/ops/op_math/evolution.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"""
This submodule defines the Evolution class.
"""
import warnings
from warnings import warn

import numpy as np
Expand Down Expand Up @@ -74,7 +75,10 @@ class Evolution(Exp):
_name = "Evolution"
num_params = 1

def __init__(self, generator, param, do_queue=True, id=None):
def __init__(self, generator, param=1, do_queue=True, id=None):
warnings.warn(
"Please use `qml.evolve` to instantiate an `Evolution` operator.", UserWarning
)
super().__init__(generator, coeff=1j * param, do_queue=do_queue, id=id)
self._data = [param]

Expand Down
14 changes: 4 additions & 10 deletions pennylane/pulse/parametrized_evolution.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,6 @@ class ParametrizedEvolution(Operation):
perform intermediate steps if necessary. It is recommended to just provide a start and end time.
Note that such absolute times only have meaning within an instance of
``ParametrizedEvolution`` and will not affect other gates.
time (str, optional): The name of the time-based parameter in the parametrized Hamiltonian.
Defaults to "t".
do_queue (bool): determines if the scalar product operator will be queued. Default is True.
id (str or None): id for the scalar product operator. Default is None.

Expand All @@ -78,11 +76,9 @@ class ParametrizedEvolution(Operation):

.. warning::

The time argument ``t`` corresponds to the time window used to compute the scalar-valued
functions present in the :class:`ParametrizedHamiltonian` class. Consequently, executing
two ``ParametrizedEvolution`` gates using the same time window does not mean both gates
are executed simultaneously, but rather both gates evaluate their respective scalar-valued
functions using the same time window.
Executing two ``ParametrizedEvolution`` gates using the same time values does not mean both
gates are executed simultaneously, but rather both gates evaluate their respective
scalar-valued functions using the same time values.

.. note::

Expand Down Expand Up @@ -158,13 +154,12 @@ class ParametrizedEvolution(Operation):
_name = "ParametrizedEvolution"
num_wires = AnyWires

# pylint: disable=too-many-arguments, super-init-not-called
# pylint: disable=too-many-arguments
def __init__(
self,
H: ParametrizedHamiltonian,
params: list = None,
t: Union[float, List[float]] = None,
time="t",
do_queue=True,
id=None,
**odeint_kwargs
Expand All @@ -178,7 +173,6 @@ def __init__(
"All operators inside the parametrized hamiltonian must have a matrix defined."
)
self.H = H
self.time = time
self.params = params
self.odeint_kwargs = odeint_kwargs
if t is None:
Expand Down
13 changes: 10 additions & 3 deletions tests/ops/functions/test_evolve.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
"""Unit tests for the ``evolve`` function."""
import warnings

import pytest

import pennylane as qml
Expand All @@ -23,6 +25,12 @@
class TestEvolveConstructor:
"""Unit tests for the evolve function"""

def test_evolve_doesnt_raise_any_warning(self):
"""Test that using `qml.evolve`, the warning inside `Evolution.__init__` is not raised."""
with warnings.catch_warnings():
warnings.simplefilter("error")
qml.evolve(qml.PauliX(0))

def test_evolve_returns_evolution_op(self):
"""Test that the evolve function returns the `Evolution` operator when the input is
a generic operator."""
Expand All @@ -32,9 +40,8 @@ def test_evolve_returns_evolution_op(self):

def test_matrix(self):
"""Test that the matrix of the evolved function is correct."""
op = qml.s_prod(2, qml.PauliX(0))
final_op = qml.evolve(op)
mat = qml.math.expm(1j * qml.matrix(op))
final_op = qml.evolve(qml.PauliX(0), coeff=2)
mat = qml.math.expm(-1j * qml.matrix(2 * qml.PauliX(0)))
assert qml.math.allequal(qml.matrix(final_op), mat)

def test_evolve_returns_parametrized_evolution(self):
Expand Down
4 changes: 4 additions & 0 deletions tests/ops/op_math/test_evolution.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,3 +161,7 @@ def test_generator_error_if_not_hermitian(self):
qml.QuantumFunctionError, match="of operation Evolution is not hermitian"
):
qml.generator(op)

def test_warning_is_raised(self):
with pytest.warns(UserWarning, match="Please use `qml.evolve"):
Evolution(qml.PauliX(0))