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

Make parametric controlled operators inherit from ControlledOp #5069

Merged
merged 42 commits into from
Jan 23, 2024
Merged
Show file tree
Hide file tree
Changes from 32 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
3500582
Move parametric ops to op_math and make them inherit ControlledOp
astralcai Jan 15, 2024
eabc450
Update test cases for non parametric controlled ops
astralcai Jan 15, 2024
67d2b45
Fix imports
astralcai Jan 15, 2024
018aa45
Handle custom parametric ops in ctrl
astralcai Jan 16, 2024
c714a0b
Reorganize testcases for non parametric controlled ops
astralcai Jan 16, 2024
247ee2e
Add bind_new_parameter logic for parametric controlled ops
astralcai Jan 16, 2024
88e0094
Merge branch 'master' of https://github.com/PennyLaneAI/pennylane int…
astralcai Jan 16, 2024
96816e4
Update name property of parametric operators
astralcai Jan 16, 2024
f8ca665
Fix decomposition of controlled parametric operators
astralcai Jan 16, 2024
ce5313c
Split test_parametric_ops
astralcai Jan 16, 2024
8a9d867
Minor bug fixes
astralcai Jan 16, 2024
55c0995
remove qubit/parametric_ops_controlled.py
astralcai Jan 16, 2024
ad75db8
Merge branch 'master' of https://github.com/PennyLaneAI/pennylane int…
astralcai Jan 16, 2024
a2709b7
Fix test_controlled.py
astralcai Jan 16, 2024
1d39290
Fix test_controlled_sequence
astralcai Jan 16, 2024
8a43c4d
Merge branch 'master' into ctrl-par-ops
astralcai Jan 16, 2024
446090e
Minor bug fix
astralcai Jan 16, 2024
2c7864b
Update changelog entry
astralcai Jan 17, 2024
0698766
Merge branch 'master' of https://github.com/PennyLaneAI/pennylane int…
astralcai Jan 17, 2024
5be151d
Merge branch 'master' into ctrl-par-ops
astralcai Jan 17, 2024
6edfc89
Update op_math package docstring
astralcai Jan 17, 2024
911bfd5
Merge parametric and non parametric controlled ops
astralcai Jan 17, 2024
d67a2ce
Merge branch 'master' into ctrl-par-ops
astralcai Jan 17, 2024
3eb7906
Remove unused hashing logic
astralcai Jan 17, 2024
c207de4
Remove duplicate property definitions in subclasses
astralcai Jan 18, 2024
d5f036f
Merge branch 'master' of https://github.com/PennyLaneAI/pennylane int…
astralcai Jan 18, 2024
4ad26d5
Remove duplicated grad_method definition in CY, CZ
astralcai Jan 18, 2024
91d5822
Remove unused imports
astralcai Jan 18, 2024
6ffef30
Cleans up tests for controlled operators
astralcai Jan 18, 2024
05362bb
Merge branch 'master' of https://github.com/PennyLaneAI/pennylane int…
astralcai Jan 18, 2024
ef14179
Simplify logic for ctrl with custom operations
astralcai Jan 18, 2024
f808dde
revert change to gate name in gate_data
astralcai Jan 18, 2024
dceee94
Update doc/releases/changelog-dev.md
astralcai Jan 19, 2024
ab18840
Minor doc update
astralcai Jan 19, 2024
a397034
Simplify test code for comparing decomposed operators
astralcai Jan 19, 2024
79faf6d
Merge branch 'master' into ctrl-par-ops
astralcai Jan 19, 2024
33e05b7
Merge branch 'master' of https://github.com/PennyLaneAI/pennylane int…
astralcai Jan 22, 2024
c8d176c
Update hash logic for controlled rotations
astralcai Jan 22, 2024
1d3c9aa
Merge branch 'master' into ctrl-par-ops
astralcai Jan 22, 2024
7a82516
Merge branch 'master' into ctrl-par-ops
astralcai Jan 22, 2024
16f67c6
Merge branch 'master' into ctrl-par-ops
astralcai Jan 22, 2024
c6694a8
Merge branch 'master' into ctrl-par-ops
astralcai Jan 23, 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
22 changes: 22 additions & 0 deletions doc/releases/changelog-dev.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@
* Raise a more informative error when calling `adjoint_jacobian` with trainable state-prep operations.
[(#5026)](https://github.com/PennyLaneAI/pennylane/pull/5026)

* `CRX`, `CRY`, `CRZ`, `CROT`, and `ControlledPhaseShift` (i.e. `CPhaseShift`) now inherit from `ControlledOp`, giving them additional properties such as `control_wire` and `control_values`. Calling `qml.ctrl` on `RX`, `RY`, `RZ`, `Rot`, and `PhaseShift` with a single control wire will return gates of types `CRX`, `CRY`, etc. as opposed to a general `Controlled` operator.
[(#5069)](https://github.com/PennyLaneAI/pennylane/pull/5069)

<h4>Community contributions 🥳</h4>

* The transform `split_non_commuting` now accepts measurements of type `probs`, `sample` and `counts` which accept both wires and observables.
Expand All @@ -73,6 +76,25 @@
(with potentially negative eigenvalues) has been implemented.
[(#5048)](https://github.com/PennyLaneAI/pennylane/pull/5048)

* The decomposition of an operator created with calling `qml.ctrl` on a parametric operator (specifically `RX`, `RY`, `RZ`, `Rot`, `PhaseShift`) with a single control wire will now be the full decomposition instead of a single controlled gate. For example:
```
>>> qml.ctrl(qml.RX(0.123, wires=1), control=0).decomposition()
[CRX(0.123, wires=[0, 1])]
```
Will become:
astralcai marked this conversation as resolved.
Show resolved Hide resolved
```
>>> qml.ctrl(qml.RX(0.123, wires=1), control=0).decomposition()
[
RZ(1.5707963267948966, wires=[1]),
RY(0.0615, wires=[1]),
CNOT(wires=[0, 1]),
RY(-0.0615, wires=[1]),
CNOT(wires=[0, 1]),
RZ(-1.5707963267948966, wires=[1])
]
```
[(#5069)](https://github.com/PennyLaneAI/pennylane/pull/5069)

* `QuantumScript.is_sampled` and `QuantumScript.all_sampled` have been removed. Users should now
validate these properties manually.
[(#5072)](https://github.com/PennyLaneAI/pennylane/pull/5072)
Expand Down
23 changes: 12 additions & 11 deletions pennylane/data/attributes/operator/operator.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,6 @@ def consumes_types(cls) -> FrozenSet[Type[Operator]]:
qml.S,
qml.SX,
qml.CNOT,
qml.CZ,
qml.CY,
qml.CH,
qml.SWAP,
qml.ECR,
Expand All @@ -87,22 +85,16 @@ def consumes_types(cls) -> FrozenSet[Type[Operator]]:
# pennylane/ops/qubit/observables.py
qml.Hermitian,
qml.Projector,
# pennylane/ops/qubit/parametric_ops_controlled.py
qml.ControlledPhaseShift,
qml.CPhaseShift00,
qml.CPhaseShift01,
qml.CPhaseShift10,
qml.CRX,
qml.CRY,
qml.CRZ,
qml.CRot,
# pennylane/ops/qubit/parametric_ops_multi_qubit.py
qml.MultiRZ,
qml.IsingXX,
qml.IsingYY,
qml.IsingZZ,
qml.IsingXY,
qml.PSWAP,
qml.CPhaseShift00,
qml.CPhaseShift01,
qml.CPhaseShift10,
# pennylane/ops/qubit/parametric_ops_single_qubit.py
qml.RX,
qml.RY,
Expand Down Expand Up @@ -177,6 +169,15 @@ def consumes_types(cls) -> FrozenSet[Type[Operator]]:
qml.FockStateProjector,
# pennylane/ops/identity.py
qml.Identity,
# pennylane/ops/op_math/controlled_ops.py
qml.ControlledQubitUnitary,
qml.ControlledPhaseShift,
qml.CRX,
qml.CRY,
qml.CRZ,
qml.CRot,
qml.CZ,
qml.CY,
)
)

Expand Down
3 changes: 0 additions & 3 deletions pennylane/operation.py
Original file line number Diff line number Diff line change
Expand Up @@ -393,9 +393,6 @@ def _process_data(op):
if op.name in ("RX", "RY", "RZ", "PhaseShift", "Rot"):
return str([qml.math.round(qml.math.real(d) % (2 * np.pi), 10) for d in op.data])

if op.name in ("CRX", "CRY", "CRZ", "CRot"):
astralcai marked this conversation as resolved.
Show resolved Hide resolved
return str([qml.math.round(qml.math.real(d) % (4 * np.pi), 10) for d in op.data])

return str(op.data)


Expand Down
24 changes: 15 additions & 9 deletions pennylane/ops/functions/bind_new_parameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"""
# pylint: disable=missing-docstring

from typing import Sequence
from typing import Sequence, Union
import copy
from functools import singledispatch

Expand Down Expand Up @@ -111,18 +111,24 @@ def bind_new_parameters_composite_op(op: CompositeOp, params: Sequence[TensorLik
return op.__class__(*new_operands)


@bind_new_parameters.register
def bind_new_parameters_cy(
op: qml.CY, params: Sequence[TensorLike]
@bind_new_parameters.register(qml.CY)
@bind_new_parameters.register(qml.CZ)
def bind_new_parameters_copy(
op: Union[qml.CY, qml.CZ], params: Sequence[TensorLike]
): # pylint:disable=unused-argument
return copy.copy(op)


@bind_new_parameters.register
def bind_new_parameters_cz(
op: qml.CZ, params: Sequence[TensorLike]
): # pylint:disable=unused-argument
return copy.copy(op)
@bind_new_parameters.register(qml.CRX)
@bind_new_parameters.register(qml.CRY)
@bind_new_parameters.register(qml.CRZ)
@bind_new_parameters.register(qml.CRot)
@bind_new_parameters.register(qml.ControlledPhaseShift)
def bind_new_parameters_parametric_controlled_ops(
op: Union[qml.CRX, qml.CRY, qml.CRZ, qml.CRot, qml.ControlledPhaseShift],
params: Sequence[TensorLike],
):
return op.__class__(*params, wires=op.wires)


@bind_new_parameters.register
Expand Down
29 changes: 27 additions & 2 deletions pennylane/ops/op_math/__init__.py
astralcai marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@
~ControlledQubitUnitary
~CY
~CZ
~CRX
~CRY
~CRZ
~CRot
~ControlledPhaseShift

Decompositions
~~~~~~~~~~~~~~
Expand Down Expand Up @@ -94,7 +99,17 @@
from .composite import CompositeOp
from .condition import cond, Conditional
from .controlled import Controlled, ControlledOp, ctrl
from .controlled_ops import ControlledQubitUnitary, CY, CZ
from .controlled_ops import (
ControlledQubitUnitary,
ControlledPhaseShift,
CPhase,
CRot,
CRX,
CRY,
CRZ,
CY,
CZ,
)
from .decompositions import one_qubit_decomposition, two_qubit_decomposition, sk_decomposition
from .evolution import Evolution
from .exp import Exp, exp
Expand All @@ -105,4 +120,14 @@
from .symbolicop import ScalarSymbolicOp, SymbolicOp
from .controlled_decompositions import ctrl_decomp_zyz, ctrl_decomp_bisect

controlled_qubit_ops = {"ControlledQubitUnitary", "CY", "CZ"}
controlled_qubit_ops = {
astralcai marked this conversation as resolved.
Show resolved Hide resolved
"ControlledQubitUnitary",
"CY",
"CZ",
"CRX",
"CRY",
"CRZ",
"CRot",
"ControlledPhaseShift",
"CPhase",
}
19 changes: 14 additions & 5 deletions pennylane/ops/op_math/controlled.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,19 +127,24 @@ def cond_fn():
ops_loader = available_eps[active_jit]["ops"].load()
return ops_loader.ctrl(op, control, control_values=control_values, work_wires=work_wires)

custom_controlled_ops = {
custom_ops = {
(qml.PauliZ, 1): qml.CZ,
(qml.PauliY, 1): qml.CY,
(qml.PauliX, 1): qml.CNOT,
(qml.PauliX, 2): qml.Toffoli,
(qml.RX, 1): qml.CRX,
(qml.RY, 1): qml.CRY,
(qml.RZ, 1): qml.CRZ,
(qml.Rot, 1): qml.CRot,
(qml.PhaseShift, 1): qml.ControlledPhaseShift,
}
control_values = [control_values] if isinstance(control_values, (int, bool)) else control_values
control = qml.wires.Wires(control)
custom_key = (type(op), len(control))

if custom_key in custom_controlled_ops and (control_values is None or all(control_values)):
if custom_key in custom_ops and (control_values is None or all(control_values)):
qml.QueuingManager.remove(op)
return custom_controlled_ops[custom_key](control + op.wires)
return custom_ops[custom_key](*op.data, control + op.wires)
if isinstance(op, qml.PauliX):
qml.QueuingManager.remove(op)
control_string = (
Expand Down Expand Up @@ -589,7 +594,7 @@ def pow(self, z):
for op in base_pow
]

def simplify(self) -> "Controlled":
def simplify(self) -> "Operator":
astralcai marked this conversation as resolved.
Show resolved Hide resolved
if isinstance(self.base, Controlled):
base = self.base.base.simplify()
return ctrl(
Expand All @@ -599,8 +604,12 @@ def simplify(self) -> "Controlled":
work_wires=self.work_wires + self.base.work_wires,
)

simplified_base = self.base.simplify()
if isinstance(simplified_base, qml.Identity):
return simplified_base

return ctrl(
op=self.base.simplify(),
op=simplified_base,
control=self.control_wires,
control_values=self.control_values,
work_wires=self.work_wires,
Expand Down
Loading
Loading