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.Reflection Operation #5159

Merged
merged 75 commits into from
Mar 5, 2024
Merged
Show file tree
Hide file tree
Changes from 73 commits
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
8c2af6b
Add Reflection
KetpuntoG Feb 5, 2024
da5faae
updating some docs
KetpuntoG Feb 9, 2024
39a18cf
reflection operator tests
KetpuntoG Feb 9, 2024
49d45d2
Merge branch 'master' into ReflectionOperation
KetpuntoG Feb 9, 2024
20e69af
tests
KetpuntoG Feb 9, 2024
ad20cca
Merge branch 'ReflectionOperation' of https://github.com/PennyLaneAI/…
KetpuntoG Feb 9, 2024
378c368
black
KetpuntoG Feb 9, 2024
82d58de
Update test_reflection.py
KetpuntoG Feb 9, 2024
aa40aad
Docs
KetpuntoG Feb 10, 2024
b1a4e41
queeing test
KetpuntoG Feb 12, 2024
9fabf46
Update reflection.py
KetpuntoG Feb 12, 2024
283a82a
Merge branch 'master' into ReflectionOperation
KetpuntoG Feb 12, 2024
4f1c85c
Update reflection.py
KetpuntoG Feb 17, 2024
91cab7b
Update pennylane/templates/subroutines/reflection.py
KetpuntoG Feb 17, 2024
3800fbb
Update pennylane/templates/subroutines/reflection.py
KetpuntoG Feb 17, 2024
c8032ba
Update tests/templates/test_subroutines/test_reflection.py
KetpuntoG Feb 17, 2024
ece1c63
compute_decomposition
KetpuntoG Feb 17, 2024
7729441
Merge branch 'ReflectionOperation' of https://github.com/PennyLaneAI/…
KetpuntoG Feb 17, 2024
1092c3d
test and feedback
KetpuntoG Feb 17, 2024
8d00fe5
fixing test
KetpuntoG Feb 17, 2024
cc50227
Update test_reflection.py
KetpuntoG Feb 17, 2024
f1478e6
Update test_reflection.py
KetpuntoG Feb 17, 2024
477091b
jax jit - not casting - numpy error
KetpuntoG Feb 18, 2024
8509886
Merge branch 'master' into ReflectionOperation
KetpuntoG Feb 18, 2024
de9bedc
Update reflection.py
KetpuntoG Feb 18, 2024
88bd40c
Merge branch 'ReflectionOperation' of https://github.com/PennyLaneAI/…
KetpuntoG Feb 18, 2024
fb1aea0
docs correction
KetpuntoG Feb 18, 2024
a08a6bb
Update reflection.py
KetpuntoG Feb 20, 2024
8c35834
Update reflection.py
KetpuntoG Feb 20, 2024
e502da9
Update reflection.py
KetpuntoG Feb 20, 2024
814a5d2
Update reflection.py
KetpuntoG Feb 20, 2024
dd842ef
fixing things
KetpuntoG Feb 20, 2024
d3c8457
Update doc/releases/changelog-dev.md
KetpuntoG Feb 20, 2024
ae899c1
Update pennylane/templates/subroutines/reflection.py
KetpuntoG Feb 20, 2024
4bf0acb
Update pennylane/templates/subroutines/reflection.py
KetpuntoG Feb 20, 2024
caf2236
Update reflection.py
KetpuntoG Feb 20, 2024
79c26a1
Merge branch 'ReflectionOperation' of https://github.com/PennyLaneAI/…
KetpuntoG Feb 20, 2024
56236b7
fixing issues
KetpuntoG Feb 20, 2024
5263eb1
docs
KetpuntoG Feb 20, 2024
5d00e44
pylint
KetpuntoG Feb 20, 2024
200d093
Update reflection.py
KetpuntoG Feb 20, 2024
5e7fa4f
Update test_reflection.py
KetpuntoG Feb 20, 2024
c2c1377
hyper parameteres
KetpuntoG Feb 20, 2024
ec4dec3
update reflection op
Jaybsoni Feb 21, 2024
93cc201
lint
Jaybsoni Feb 21, 2024
ad28d6c
Merge branch 'master' into ReflectionOperation
Jaybsoni Feb 21, 2024
b5ff2d0
extra test + image
KetpuntoG Feb 21, 2024
e4e8091
jay suggestions
KetpuntoG Feb 21, 2024
b5d1789
Update pennylane/templates/subroutines/reflection.py
KetpuntoG Feb 21, 2024
40a185b
Update pennylane/templates/subroutines/reflection.py
KetpuntoG Feb 21, 2024
4540d2f
Update pennylane/templates/subroutines/reflection.py
KetpuntoG Feb 21, 2024
39992c8
Merge branch 'ReflectionOperation' of https://github.com/PennyLaneAI/…
KetpuntoG Feb 21, 2024
df96942
Merge branch 'master' into ReflectionOperation
KetpuntoG Feb 21, 2024
cf340fe
pylint
KetpuntoG Feb 21, 2024
1f3726f
black
KetpuntoG Feb 21, 2024
938811e
Merge branch 'master' into ReflectionOperation
Jaybsoni Feb 22, 2024
677e4bf
typo
KetpuntoG Feb 22, 2024
b39713e
Merge branch 'master' into ReflectionOperation
KetpuntoG Feb 22, 2024
a7f0c10
Update tests/templates/test_subroutines/test_reflection.py
KetpuntoG Feb 22, 2024
9dbaf0d
Update pennylane/templates/subroutines/reflection.py
KetpuntoG Feb 22, 2024
e3d3168
Update pennylane/templates/subroutines/reflection.py
KetpuntoG Feb 22, 2024
131228a
Update pennylane/templates/subroutines/reflection.py
KetpuntoG Feb 22, 2024
1bbe0f5
Update pennylane/templates/subroutines/reflection.py
KetpuntoG Feb 22, 2024
c9c8412
Update pennylane/templates/subroutines/reflection.py
KetpuntoG Feb 22, 2024
afb800f
Update pennylane/templates/subroutines/reflection.py
KetpuntoG Feb 22, 2024
5b8e232
Soran suggestions
KetpuntoG Feb 22, 2024
4dbe5ce
Merge branch 'master' into ReflectionOperation
KetpuntoG Feb 22, 2024
720cb54
Update pennylane/templates/subroutines/reflection.py
KetpuntoG Feb 27, 2024
cd16af1
Merge branch 'master' into ReflectionOperation
KetpuntoG Feb 27, 2024
542b2dc
Update pennylane/templates/subroutines/reflection.py
KetpuntoG Mar 5, 2024
ffce70d
Update pennylane/templates/subroutines/reflection.py
KetpuntoG Mar 5, 2024
693e979
Update pennylane/templates/subroutines/reflection.py
KetpuntoG Mar 5, 2024
5424f04
docs
KetpuntoG Mar 5, 2024
5771bfa
Merge branch 'master' into ReflectionOperation
KetpuntoG Mar 5, 2024
352d913
Merge branch 'master' into ReflectionOperation
KetpuntoG Mar 5, 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
KetpuntoG marked this conversation as resolved.
Show resolved Hide resolved
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions doc/introduction/templates.rst
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,10 @@ Other useful templates which do not belong to the previous categories can be fou
:description: :doc:`Grover Diffusion Operator <../code/api/pennylane.GroverOperator>`
:figure: _static/templates/subroutines/grover.svg

.. gallery-item::
:description: :doc:`Reflection Operator <../code/api/pennylane.Reflection>`
:figure: _static/templates/subroutines/reflection.png

.. gallery-item::
:description: :doc:`Interferometer <../code/api/pennylane.Interferometer>`
:figure: _static/templates/subroutines/interferometer.png
Expand Down
32 changes: 31 additions & 1 deletion doc/releases/changelog-dev.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,35 @@

<h3>Improvements 🛠</h3>

* Create the `qml.Reflection` operator, useful for amplitude amplification and its variants.
[(##5159)](https://github.com/PennyLaneAI/pennylane/pull/5159)
KetpuntoG marked this conversation as resolved.
Show resolved Hide resolved

```python
@qml.prod
def generator(wires):
qml.Hadamard(wires=wires)

U = generator(wires=0)

dev = qml.device('default.qubit')
@qml.qnode(dev)
def circuit():

# Initialize to the state |1>
qml.PauliX(wires=0)

# Apply the reflection
qml.Reflection(U)

return qml.state()

```

```pycon
>>> circuit()
tensor([1.+6.123234e-17j, 0.-6.123234e-17j], requires_grad=True)
```

<h3>Breaking changes 💔</h3>

<h3>Deprecations 👋</h3>
Expand All @@ -21,4 +50,5 @@

This release contains contributions from (in alphabetical order):

Korbinian Kottmann
Guillermo Alonso,
Korbinian Kottmann.
1 change: 1 addition & 0 deletions pennylane/templates/subroutines/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,4 @@
from .controlled_sequence import ControlledSequence
from .trotter import TrotterProduct
from .aqft import AQFT
from .reflection import Reflection
166 changes: 166 additions & 0 deletions pennylane/templates/subroutines/reflection.py
KetpuntoG marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
# Copyright 2018-2024 Xanadu Quantum Technologies Inc.

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at

# http://www.apache.org/licenses/LICENSE-2.0

# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""
This submodule contains the template for the Reflection operation.
"""

import numpy as np
import pennylane as qml
from pennylane.operation import Operation
from pennylane.queuing import QueuingManager


class Reflection(Operation):
r"""Apply a reflection about a state :math:`|\Psi\rangle`.

Given an operator :math:`U` such that :math:`|\Psi\rangle = U|0\rangle` and a reflection angle :math:`\alpha`,
this template creates the operation:

.. math::

R(U, \alpha) = -I + (1 - e^{i\alpha}) |\Psi\rangle \langle \Psi|

This operator is an important component of quantum algorithms such as amplitude amplification [`arXiv:quant-ph/0005055 <https://arxiv.org/abs/quant-ph/0005055>`__]
and oblivious amplitude amplification [`arXiv:1312.1414 <https://arxiv.org/abs/1312.1414>`__].
KetpuntoG marked this conversation as resolved.
Show resolved Hide resolved

Args:
U (Operator): the operator that prepares the state :math:`|\Psi\rangle`
alpha (float): the angle of the operator, default is :math:`\pi`
reflection_wires (Any or Iterable[Any]): subsystem of wires on which to reflect, the default is ``None`` and the reflection will be applied on the ``U`` wires

**Example**

This example shows how to apply the reflection :math:`-I + 2|+\rangle \langle +|` to the state :math:`|1\rangle`.

.. code-block::
KetpuntoG marked this conversation as resolved.
Show resolved Hide resolved

@qml.prod
KetpuntoG marked this conversation as resolved.
Show resolved Hide resolved
def generator(wires):
qml.Hadamard(wires=wires)

U = generator(wires=0)

dev = qml.device('default.qubit')
@qml.qnode(dev)
def circuit():

# Initialize to the state |1>
qml.PauliX(wires=0)

# Apply the reflection
qml.Reflection(U)

return qml.state()

>>> circuit()
tensor([1.+6.123234e-17j, 0.-6.123234e-17j], requires_grad=True)



.. details::
:title: Theory

The operator is built as follows:

.. math::

\text{R}(U, \alpha) = -I + (1 - e^{i\alpha}) |\Psi\rangle \langle \Psi| = U(-I + (1 - e^{i\alpha}) |0\rangle \langle 0|)U^{\dagger}.

The central block is obtained through a :class:`~.PhaseShift` controlled operator.

In the case of specifying the reflection wires, the operator would have the following expression.

.. math::

U(-I + (1 - e^{i\alpha}) |0\rangle^{\otimes m} \langle 0|^{\otimes m}\otimes I^{n-m})U^{\dagger},

where :math:`m` is the number of reflection wires and :math:`n` is the total number of wires.

"""

def _flatten(self):
data = (self.hyperparameters["base"], self.parameters[0])
metadata = tuple(value for key, value in self.hyperparameters.items() if key != "base")
return data, metadata

@classmethod
def _unflatten(cls, data, metadata):
U, alpha = (data[0], data[1])
return cls(U, alpha=alpha, reflection_wires=metadata[0])

def __init__(self, U, alpha=np.pi, reflection_wires=None, id=None):
self._name = "Reflection"
wires = U.wires

if reflection_wires is None:
reflection_wires = U.wires

if not set(reflection_wires).issubset(set(U.wires)):
raise ValueError("The reflection wires must be a subset of the operation wires.")

self._hyperparameters = {
"base": U,
"reflection_wires": reflection_wires,
}

super().__init__(alpha, wires=wires, id=id)

@property
def alpha(self):
"""The alpha angle for the operation."""
return self.parameters[0]

@property
def reflection_wires(self):
"""The reflection wires for the operation."""
return self.hyperparameters["reflection_wires"]

def queue(self, context=QueuingManager):
context.remove(self.hyperparameters["base"])
context.append(self)
return self

@staticmethod
def compute_decomposition(*parameters, wires=None, **hyperparameters):
alpha = parameters[0]
U = hyperparameters["base"]
reflection_wires = hyperparameters["reflection_wires"]

wires = qml.wires.Wires(reflection_wires) if reflection_wires is not None else wires

ops = []

ops.append(qml.GlobalPhase(np.pi))
ops.append(qml.adjoint(U))

if len(wires) > 1:
KetpuntoG marked this conversation as resolved.
Show resolved Hide resolved
ops.append(qml.PauliX(wires=wires[-1]))
ops.append(
qml.ctrl(
qml.PhaseShift(alpha, wires=wires[-1]),
control=wires[:-1],
control_values=[0] * (len(wires) - 1),
)
)
ops.append(qml.PauliX(wires=wires[-1]))
KetpuntoG marked this conversation as resolved.
Show resolved Hide resolved

else:
ops.append(qml.PauliX(wires=wires))
ops.append(qml.PhaseShift(alpha, wires=wires))
ops.append(qml.PauliX(wires=wires))
KetpuntoG marked this conversation as resolved.
Show resolved Hide resolved

ops.append(U)

return ops
Loading