Skip to content

Commit edb7545

Browse files
JerryChen97albi3roastralcai
authored
Deprecate control_wires in ControlledQubitUnitary (#6839)
**Context:** We are in favor of `wires`, just like what we did with `MultiControlledX`. !Note: this involves a big user-interface change. With PL version <=0.40, for ControlledQubitUnitary, we have arg wires to be the target_wires, and the arg control_wires is a positional arg. To be consistent with all the other interfaces, we would like to alter this into wires to be positional and to represent control_wires+target_wires Before: ```python mat = np.eye(2) control_wires = [0] wires = [1] ControlledQubitUnitary(mat, control_wires, wires=wires, control_values=...) ``` After: ```python mat = np.eye(2) wires = [0, 1] ControlledQubitUnitary(mat, wires, control_values=...) ``` where the new `wires` should be the concatenate of old `control_wires` and `wires` **Description of the Change:** Besides the modified test files across the whole codebase involving `ControlledQubitUnitary`, we made the following necessary adjustments beyond the `__init__` method: - classmethod `_unflatten`, `_primitive_bind_call` and method `_controlled` were adjusted accordingly following the new interface - move the `TypeError` regarding empty arg `wires` to the beginning. - add a register for `ControlledQubitUnitary` in `bind_new_parameters.py` following the pattern of `CRX` - modified the direct calls of `ControlledQubitUnitary` inside src files `metric_tensor.py`, `controlled.py` and `matrix_ops.py`. ### **Eco-System** This is an inevitable breaking change, so we need to immediately inform the affected repos that depend on latest PennyLane but only apply corresponding changes after this PR gets merged. - [ ] labs - [ ] Catalyst: [frontend/test/pytest/device/test_decomposition.py](https://github.com/PennyLaneAI/catalyst/blob/286e51910a39c55130de8c1c6a806818a2bcb14b/frontend/test/pytest/device/test_decomposition.py#L52) PennyLaneAI/catalyst#1483 - [ ] Lightning: PR to fix it PennyLaneAI/pennylane-lightning#1047 - - [test_gates.py](https://github.com/PennyLaneAI/pennylane-lightning/blob/290c986e7d087e17dbf3f09c6d2dfc8bd738cc08/tests/test_gates.py#L451) - - [test_gates_and_expval.py](https://github.com/PennyLaneAI/pennylane-lightning/blob/290c986e7d087e17dbf3f09c6d2dfc8bd738cc08/tests/lightning_tensor/test_gates_and_expval.py#L72) - - [test_measurements_class.py](https://github.com/PennyLaneAI/pennylane-lightning/blob/290c986e7d087e17dbf3f09c6d2dfc8bd738cc08/tests/lightning_qubit/test_measurements_class.py#L814) - [ ] QML Demos: [tutorial_classically_boosted_vqe.py](https://github.com/PennyLaneAI/qml/blob/c444cec6201338056304d9d5a293f969a3aeec5e/demonstrations/tutorial_classically_boosted_vqe.py#L451); PR to fix it PennyLaneAI/qml#1310 ### **Plugins** - [x] Pennylane-AQT: No instances of deprecated code found. - [x] Pennylane-Qiskit: No instances of deprecated code found. - [x] Pennylane-IonQ: No instances of deprecated code found. - [x] Pennylane-Qrack: No instances of deprecated code found. - [x] Pennylane-Cirq: No instances of deprecated code found. - [x] Pennylane-Qulacs: No instances of deprecated code found. **Benefits:** Unified interfaces with other controlled ops. **Possible Drawbacks:** This is a hard change to deprecate this arg. Would have to introduce errors for testing matrices. **Related GitHub Issues:** [sc-80842] --------- Co-authored-by: Christina Lee <[email protected]> Co-authored-by: Astral Cai <[email protected]>
1 parent 14f6aa0 commit edb7545

22 files changed

+284
-172
lines changed

doc/development/deprecations.rst

+10
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,16 @@ deprecations are listed below.
99
Pending deprecations
1010
--------------------
1111

12+
* The ``ControlledQubitUnitary`` will stop accepting `QubitUnitary` objects as arguments as its ``base``. Instead, use ``qml.ctrl`` to construct a controlled `QubitUnitary`.
13+
14+
- Deprecated in v0.41
15+
- Will be removed in v0.42
16+
17+
* The ``control_wires`` argument in the ``qml.ControlledQubitUnitary`` class is deprecated. Instead, use the ``wires`` argument.
18+
19+
- Deprecated in v0.41
20+
- Will be removed in v0.42
21+
1222
* The property ```MeasurementProcess.return_type``` has been deprecated.
1323
If observable type checking is needed, please use direct ```isinstance```; if other text information is needed, please use class name, or another internal temporary private member ``_shortname``.
1424

doc/releases/changelog-dev.md

+10
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@
7474
[(#6803)](https://github.com/PennyLaneAI/pennylane/pull/6803)
7575

7676
After constructing a `QNode`,
77+
7778
```python
7879
import pennylane as qml
7980

@@ -83,8 +84,10 @@
8384
qml.CNOT([0,1])
8485
return qml.probs()
8586
```
87+
8688
its settings can be modified with `update`, which returns a new `QNode` object. Here is an example
8789
of updating a QNode's `diff_method`:
90+
8891
```pycon
8992
>>> print(circuit.diff_method)
9093
best
@@ -158,6 +161,13 @@
158161

159162
<h3>Deprecations 👋</h3>
160163

164+
* The ``ControlledQubitUnitary`` will stop accepting `QubitUnitary` objects as arguments as its ``base``. Instead, use ``qml.ctrl`` to construct a controlled `QubitUnitary`.
165+
[(#6840)](https://github.com/PennyLaneAI/pennylane/pull/6840)
166+
167+
* The `control_wires` argument in `qml.ControlledQubitUnitary` has been deprecated.
168+
Instead, use the `wires` argument as the second positional argument.
169+
[(#6839)](https://github.com/PennyLaneAI/pennylane/pull/6839)
170+
161171
* The `mcm_method` keyword in `qml.execute` has been deprecated.
162172
Instead, use the ``mcm_method`` and ``postselect_mode`` arguments.
163173
[(#6807)](https://github.com/PennyLaneAI/pennylane/pull/6807)

pennylane/devices/tests/test_gates.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@
7272
"QubitDensityMatrix": qml.QubitDensityMatrix(np.array([[0.5, 0.0], [0, 0.5]]), wires=[0]),
7373
"QubitUnitary": qml.QubitUnitary(np.eye(2), wires=[0]),
7474
"SpecialUnitary": qml.SpecialUnitary(np.array([0.2, -0.1, 2.3]), wires=1),
75-
"ControlledQubitUnitary": qml.ControlledQubitUnitary(np.eye(2), control_wires=[1], wires=[0]),
75+
"ControlledQubitUnitary": qml.ControlledQubitUnitary(np.eye(2), wires=[1, 0]),
7676
"MultiControlledX": qml.MultiControlledX(wires=[1, 2, 0]),
7777
"IntegerComparator": qml.IntegerComparator(1, geq=True, wires=[0, 1, 2]),
7878
"RX": qml.RX(0, wires=[0]),

pennylane/devices/tests/test_templates.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -678,7 +678,7 @@ def func(i):
678678
target_wires = range(m + 1)
679679
estimation_wires = range(m + 1, n + m + 1)
680680
dev = device(wires=n + m + 1)
681-
check_op_supported(qml.ControlledQubitUnitary(np.eye(2), [1], [0]), dev)
681+
check_op_supported(qml.ControlledQubitUnitary(np.eye(2), wires=[1, 0]), dev)
682682

683683
@qml.qnode(dev)
684684
def circuit():

pennylane/gradients/metric_tensor.py

+6-3
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,9 @@ def _expand_metric_tensor(
7373
allow_nonunitary=True,
7474
aux_wire=None,
7575
device_wires=None,
76-
) -> tuple[QuantumScriptBatch, PostprocessingFn]: # pylint: disable=too-many-arguments
76+
) -> tuple[
77+
QuantumScriptBatch, PostprocessingFn
78+
]: # pylint: disable=too-many-arguments, too-many-positional-arguments
7779
"""Set the metric tensor based on whether non-unitary gates are allowed."""
7880
# pylint: disable=unused-argument,too-many-arguments
7981

@@ -88,7 +90,7 @@ def _expand_metric_tensor(
8890
classical_cotransform=_contract_metric_tensor_with_cjac,
8991
final_transform=True,
9092
)
91-
def metric_tensor( # pylint:disable=too-many-arguments
93+
def metric_tensor( # pylint:disable=too-many-arguments, too-many-positional-arguments
9294
tape: QuantumScript,
9395
argnum=None,
9496
approx=None,
@@ -561,7 +563,8 @@ def _get_gen_op(op, allow_nonunitary, aux_wire):
561563
except KeyError as e:
562564
if allow_nonunitary:
563565
mat = qml.matrix(qml.generator(op)[0])
564-
return qml.ControlledQubitUnitary(mat, control_wires=aux_wire, wires=op.wires)
566+
wires = [aux_wire, *op.wires]
567+
return qml.ControlledQubitUnitary(mat, wires=wires)
565568

566569
raise ValueError(
567570
f"Generator for operation {op} not known and non-unitary operations "

pennylane/ops/functions/bind_new_parameters.py

+1
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ def bind_new_parameters_copy(op, params: Sequence[TensorLike]): # pylint:disabl
163163
@bind_new_parameters.register(qml.CRZ)
164164
@bind_new_parameters.register(qml.CRot)
165165
@bind_new_parameters.register(qml.ControlledPhaseShift)
166+
@bind_new_parameters.register(qml.ControlledQubitUnitary)
166167
def bind_new_parameters_parametric_controlled_ops(
167168
op: Union[qml.CRX, qml.CRY, qml.CRZ, qml.CRot, qml.ControlledPhaseShift],
168169
params: Sequence[TensorLike],

pennylane/ops/op_math/controlled.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,10 @@ def _try_wrap_in_custom_ctrl_op(op, control, control_values=None, work_wires=Non
339339

340340
if isinstance(op, qml.QubitUnitary):
341341
return qml.ControlledQubitUnitary(
342-
op, control_wires=control, control_values=control_values, work_wires=work_wires
342+
op.matrix(),
343+
wires=control + op.wires,
344+
control_values=control_values,
345+
work_wires=work_wires,
343346
)
344347

345348
return None

pennylane/ops/op_math/controlled_ops.py

+96-51
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,31 @@
3434
INV_SQRT2 = 1 / qml.math.sqrt(2)
3535

3636

37+
def _deprecate_control_wires(control_wires):
38+
if control_wires != "unset":
39+
warnings.warn(
40+
"The control_wires input to ControlledQubitUnitary is deprecated and will be removed in v0.42. "
41+
"Please note that the second positional arg of your input is going to be the new wires, following wires=controlled_wires+target_wires, where target_wires is the optional arg wires in the legacy interface.",
42+
qml.PennyLaneDeprecationWarning,
43+
)
44+
45+
3746
# pylint: disable=too-few-public-methods
3847
class ControlledQubitUnitary(ControlledOp):
39-
r"""ControlledQubitUnitary(U, control_wires, wires, control_values)
40-
Apply an arbitrary fixed unitary to ``wires`` with control from the ``control_wires``.
48+
r"""ControlledQubitUnitary(U, wires)
49+
Apply an arbitrary fixed unitary matrix ``U`` to ``wires``. If ``n = len(wires) `` and ``U`` has ``k`` wires, then the first ``n - k`` from ``wires`` serve as control, and ``U`` lives on the last ``k`` wires.
50+
51+
.. warning::
52+
53+
The ``control_wires`` argument is deprecated and will be removed in
54+
v0.42. Please use the ``wires`` argument instead.
4155
4256
In addition to default ``Operation`` instance attributes, the following are
4357
available for ``ControlledQubitUnitary``:
4458
45-
* ``control_wires``: wires that act as control for the operation
59+
* ``control_wires``: (deprecated) wires that act as control for the operation
60+
* ``wires``: wires of the final controlled unitary, consisting of control wires following by target wires
4661
* ``control_values``: the state on which to apply the controlled operation (see below)
47-
* ``target_wires``: the wires the unitary matrix will be applied to
4862
* ``work_wires``: wires made use of during the decomposition of the operation into native operations
4963
5064
**Details:**
@@ -59,9 +73,10 @@ class ControlledQubitUnitary(ControlledOp):
5973
operation. If passing a matrix, this will be used to construct a QubitUnitary
6074
operator that will be used as the base operator. If providing a ``qml.QubitUnitary``,
6175
this will be used as the base directly.
62-
control_wires (Union[Wires, Sequence[int], or int]): the control wire(s)
63-
wires (Union[Wires, Sequence[int], or int]): the wire(s) the unitary acts on
64-
(optional if U is provided as a QubitUnitary)
76+
wires (Union[Wires, Sequence[int], or int]): the wires the full
77+
controlled unitary acts on, composed of the controlled wires followed
78+
by the target wires
79+
control_wires (Union[Wires, Sequence[int], or int]): (deprecated) the control wire(s)
6580
control_values (List[int, bool]): a list providing the state of the control qubits to
6681
control on (default is the all 1s state)
6782
unitary_check (bool): whether to check whether an array U is unitary when creating the
@@ -75,16 +90,9 @@ class ControlledQubitUnitary(ControlledOp):
7590
both wires ``0`` and ``1``:
7691
7792
>>> U = np.array([[ 0.94877869, 0.31594146], [-0.31594146, 0.94877869]])
78-
>>> qml.ControlledQubitUnitary(U, control_wires=[0, 1], wires=2)
93+
>>> qml.ControlledQubitUnitary(U, wires=[0, 1, 2])
7994
Controlled(QubitUnitary(array([[ 0.94877869, 0.31594146],
80-
[-0.31594146, 0.94877869]]), wires=[2]), control_wires=[0, 1])
81-
82-
Alternatively, the same operator can be constructed with a QubitUnitary:
83-
84-
>>> base = qml.QubitUnitary(U, wires=2)
85-
>>> qml.ControlledQubitUnitary(base, control_wires=[0, 1])
86-
Controlled(QubitUnitary(array([[ 0.94877869, 0.31594146],
87-
[-0.31594146, 0.94877869]]), wires=[2]), control_wires=[0, 1])
95+
[-0.31594146, 0.94877869]]), wires=[2]), control_wires=[0, 1])
8896
8997
Typically, controlled operations apply a desired gate if the control qubits
9098
are all in the state :math:`\vert 1\rangle`. However, there are some situations where
@@ -96,11 +104,11 @@ class ControlledQubitUnitary(ControlledOp):
96104
wire ``3`` conditioned on three wires where the first is in state ``0``, the
97105
second is in state ``1``, and the third in state ``1``, we can write:
98106
99-
>>> qml.ControlledQubitUnitary(U, control_wires=[0, 1, 2], wires=3, control_values=[0, 1, 1])
107+
>>> qml.ControlledQubitUnitary(U, wires=[0, 1, 2, 3], control_values=[0, 1, 1])
100108
101109
or
102110
103-
>>> qml.ControlledQubitUnitary(U, control_wires=[0, 1, 2], wires=3, control_values=[False, True, True])
111+
>>> qml.ControlledQubitUnitary(U, wires=[0, 1, 2, 3], control_values=[False, True, True])
104112
"""
105113

106114
num_wires = AnyWires
@@ -115,31 +123,41 @@ class ControlledQubitUnitary(ControlledOp):
115123
grad_method = None
116124
"""Gradient computation method."""
117125

126+
def _flatten(self):
127+
return (self.base.data[0],), (self.wires, tuple(self.control_values), self.work_wires)
128+
118129
@classmethod
119130
def _unflatten(cls, data, metadata):
120-
return cls(
121-
data[0], control_wires=metadata[0], control_values=metadata[1], work_wires=metadata[2]
122-
)
131+
return cls(data[0], wires=metadata[0], control_values=metadata[1], work_wires=metadata[2])
123132

124133
# pylint: disable=arguments-differ, too-many-arguments, unused-argument, too-many-positional-arguments
125134
@classmethod
126135
def _primitive_bind_call(
127136
cls,
128137
base,
129-
control_wires: WiresLike,
130-
wires: WiresLike = (),
138+
control_wires: WiresLike = "unset",
139+
wires: WiresLike = None,
131140
control_values=None,
132141
unitary_check=False,
133142
work_wires: WiresLike = (),
134143
):
135-
wires = Wires(() if wires is None else wires)
144+
_deprecate_control_wires(control_wires)
136145
work_wires = Wires(() if work_wires is None else work_wires)
137-
138-
if hasattr(base, "wires") and len(wires) != 0:
146+
if hasattr(base, "wires"):
139147
warnings.warn(
140-
"base operator already has wires; values specified through wires kwarg will be ignored."
148+
"QubitUnitary input to ControlledQubitUnitary is deprecated and will be removed in v0.42. "
149+
"Instead, please use a full matrix as input, or try qml.ctrl for controlled QubitUnitary.",
150+
qml.PennyLaneDeprecationWarning,
141151
)
142-
wires = Wires(())
152+
base = base.matrix()
153+
154+
if control_wires == "unset":
155+
156+
return cls._primitive.bind(
157+
base, wires=wires, control_values=control_values, work_wires=work_wires
158+
)
159+
# Below is the legacy interface, where control_wires provided
160+
wires = Wires(() if wires is None else wires)
143161

144162
all_wires = control_wires + wires
145163
return cls._primitive.bind(
@@ -150,35 +168,58 @@ def _primitive_bind_call(
150168
def __init__(
151169
self,
152170
base,
153-
control_wires: WiresLike,
154-
wires: WiresLike = (),
171+
control_wires: WiresLike = "unset",
172+
wires: WiresLike = None,
155173
control_values=None,
156174
unitary_check=False,
157175
work_wires: WiresLike = (),
158176
):
159-
wires = Wires(() if wires is None else wires)
177+
_deprecate_control_wires(control_wires)
160178
work_wires = Wires(() if work_wires is None else work_wires)
161-
control_wires = Wires(control_wires)
162179

163-
if hasattr(base, "wires") and len(wires) != 0:
180+
if hasattr(base, "wires"):
164181
warnings.warn(
165-
"base operator already has wires; values specified through wires kwarg will be ignored."
182+
"QubitUnitary input to ControlledQubitUnitary is deprecated and will be removed in v0.42. "
183+
"Instead, please use a full matrix as input.",
184+
qml.PennyLaneDeprecationWarning,
166185
)
167-
wires = Wires(())
168-
169-
if isinstance(base, Iterable):
170-
if len(wires) == 0:
171-
if len(control_wires) > 1:
172-
num_base_wires = int(qml.math.log2(qml.math.shape(base)[-1]))
173-
wires = control_wires[-num_base_wires:]
174-
control_wires = control_wires[:-num_base_wires]
175-
else:
176-
raise TypeError(
177-
"Must specify a set of wires. None is not a valid `wires` label."
178-
)
179-
# We use type.__call__ instead of calling the class directly so that we don't bind the
180-
# operator primitive when new program capture is enabled
181-
base = type.__call__(qml.QubitUnitary, base, wires=wires, unitary_check=unitary_check)
186+
base = base.matrix()
187+
188+
if control_wires == "unset":
189+
if not wires:
190+
raise TypeError("Must specify a set of wires. None is not a valid `wires` label.")
191+
control_wires = wires[:-1] # default
192+
193+
if isinstance(base, Iterable):
194+
num_base_wires = int(qml.math.log2(qml.math.shape(base)[-1]))
195+
target_wires = wires[-num_base_wires:]
196+
control_wires = wires[:-num_base_wires]
197+
# We use type.__call__ instead of calling the class directly so that we don't bind the
198+
# operator primitive when new program capture is enabled
199+
base = type.__call__(
200+
qml.QubitUnitary, base, wires=target_wires, unitary_check=unitary_check
201+
)
202+
else:
203+
raise ValueError("Base must be a matrix.")
204+
else:
205+
# Below is the legacy interface, where control_wires provided
206+
wires = Wires(() if wires is None else wires)
207+
control_wires = Wires(control_wires)
208+
if isinstance(base, Iterable):
209+
if len(wires) == 0:
210+
if len(control_wires) > 1:
211+
num_base_wires = int(qml.math.log2(qml.math.shape(base)[-1]))
212+
wires = control_wires[-num_base_wires:]
213+
control_wires = control_wires[:-num_base_wires]
214+
else:
215+
raise TypeError(
216+
"Must specify a set of wires. None is not a valid `wires` label."
217+
)
218+
# We use type.__call__ instead of calling the class directly so that we don't bind the
219+
# operator primitive when new program capture is enabled
220+
base = type.__call__(
221+
qml.QubitUnitary, base, wires=wires, unitary_check=unitary_check
222+
)
182223

183224
super().__init__(
184225
base,
@@ -191,9 +232,13 @@ def __init__(
191232
def _controlled(self, wire):
192233
ctrl_wires = wire + self.control_wires
193234
values = None if self.control_values is None else [True] + self.control_values
235+
base = self.base
236+
if isinstance(self.base, qml.QubitUnitary):
237+
base = self.base.matrix()
238+
194239
return ControlledQubitUnitary(
195-
self.base,
196-
control_wires=ctrl_wires,
240+
base,
241+
wires=ctrl_wires + self.wires,
197242
control_values=values,
198243
work_wires=self.work_wires,
199244
)

pennylane/ops/qubit/matrix_ops.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ def pow(self, z: Union[int, float]):
249249
return [QubitUnitary(pow_mat, wires=self.wires)]
250250

251251
def _controlled(self, wire):
252-
return qml.ControlledQubitUnitary(*self.parameters, control_wires=wire, wires=self.wires)
252+
return qml.ControlledQubitUnitary(*self.parameters, wires=wire + self.wires)
253253

254254
def label(
255255
self,

tests/devices/default_tensor/test_default_tensor.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@
6565
"CPhaseShift10": qml.CPhaseShift10(1.234, wires=[0, 1]),
6666
"QubitUnitary": qml.QubitUnitary(np.eye(2), wires=[0]),
6767
"SpecialUnitary": qml.SpecialUnitary(np.array([0.2, -0.1, 2.3]), wires=1),
68-
"ControlledQubitUnitary": qml.ControlledQubitUnitary(np.eye(2), control_wires=[1], wires=[0]),
68+
"ControlledQubitUnitary": qml.ControlledQubitUnitary(np.eye(2), wires=[1, 0]),
6969
"MultiControlledX": qml.MultiControlledX(wires=[1, 2, 0]),
7070
"IntegerComparator": qml.IntegerComparator(1, geq=True, wires=[0, 1, 2]),
7171
"RX": qml.RX(1.234, wires=[0]),

tests/ops/functions/conftest.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ def _trotterize_qfunc_dummy(time, theta, phi, wires, flip=False):
4040
(qml.sum(qml.X(0), qml.X(0), qml.Z(0), qml.Z(0)), {}),
4141
(qml.BasisState([1], wires=[0]), {"skip_differentiation": True}),
4242
(
43-
qml.ControlledQubitUnitary(np.eye(2), control_wires=1, wires=0),
43+
qml.ControlledQubitUnitary(np.eye(2), wires=[1, 0]),
4444
{"skip_differentiation": True},
4545
),
4646
(

tests/ops/functions/test_bind_new_parameters.py

+7-3
Original file line numberDiff line numberDiff line change
@@ -156,11 +156,15 @@ def test_scalar_symbolic_ops(op, new_params, expected_op):
156156
[-0.5, 0.456],
157157
qml.ctrl(qml.s_prod(-0.5, qml.RX(0.456, 0)), [1]),
158158
),
159-
(qml.ControlledQubitUnitary(X, [1], [0]), [Y], qml.ControlledQubitUnitary(Y, [1], [0])),
160159
(
161-
qml.ControlledQubitUnitary(qml.QubitUnitary(X, 0), [1]),
160+
qml.ControlledQubitUnitary(X, wires=[1, 0]),
162161
[Y],
163-
qml.ControlledQubitUnitary(qml.QubitUnitary(Y, 0), [1]),
162+
qml.ControlledQubitUnitary(Y, wires=[1, 0]),
163+
),
164+
(
165+
qml.ControlledQubitUnitary(qml.QubitUnitary(X, 0).matrix(), wires=[1, 0]),
166+
[Y],
167+
qml.ControlledQubitUnitary(qml.QubitUnitary(Y, 0).matrix(), wires=[1, 0]),
164168
),
165169
],
166170
)

0 commit comments

Comments
 (0)