diff --git a/doc/releases/changelog-dev.md b/doc/releases/changelog-dev.md
index ad48d2cbf1c..d68930812d3 100644
--- a/doc/releases/changelog-dev.md
+++ b/doc/releases/changelog-dev.md
@@ -295,6 +295,9 @@
* `pennylane.collections`, `pennylane.op_sum`, and `pennylane.utils.sparse_hamiltonian` are removed.
+* `Operator.data` now returns a `tuple` instead of a `list`.
+ [(#4222)](https://github.com/PennyLaneAI/pennylane/pull/4222)
+
Deprecations 👋
* `LieAlgebraOptimizer` is renamed. Please use `RiemannianGradientOptimizer` instead.
diff --git a/pennylane/operation.py b/pennylane/operation.py
index 78a1e4cc9a6..6a3919dc9d7 100644
--- a/pennylane/operation.py
+++ b/pennylane/operation.py
@@ -660,7 +660,7 @@ def compute_decomposition(theta, wires):
def __copy__(self):
cls = self.__class__
copied_op = cls.__new__(cls)
- copied_op.data = self.data.copy()
+ copied_op.data = copy.copy(self.data)
for attr, value in vars(self).items():
if attr != "data":
setattr(copied_op, attr, value)
@@ -680,7 +680,7 @@ def __deepcopy__(self, memo):
# Shallow copy the list of parameters. We avoid a deep copy
# here, since PyTorch does not support deep copying of tensors
# within a differentiable computation.
- copied_op.data = value.copy()
+ copied_op.data = copy.copy(value)
else:
# Deep copy everything else.
setattr(copied_op, attribute, copy.deepcopy(value, memo))
@@ -1024,7 +1024,7 @@ def __init__(self, *params, wires=None, do_queue=None, id=None):
self._check_batching(params)
- self.data = [np.array(p) if isinstance(p, (list, tuple)) else p for p in params]
+ self.data = tuple(np.array(p) if isinstance(p, (list, tuple)) else p for p in params)
if do_queue is not None:
do_queue_deprecation_warning = (
@@ -1174,7 +1174,7 @@ def wires(self):
@property
def parameters(self):
"""Trainable parameters that the operator depends on."""
- return self.data.copy()
+ return list(self.data)
@property
def hyperparameters(self):
@@ -2058,9 +2058,9 @@ def data(self):
"""Raw parameters of all constituent observables in the tensor product.
Returns:
- list[Any]: flattened list containing all dependent parameters
+ tuple[Any]: flattened list containing all dependent parameters
"""
- return sum((o.data for o in self.obs), [])
+ return tuple(d for op in self.obs for d in op.data)
@data.setter
def data(self, new_data):
@@ -2081,8 +2081,14 @@ def data(self, new_data):
[array([[5., 0.],
[0., 5.]])]
"""
- for new_entry, op in zip(new_data, self.obs):
- op.data = new_entry
+ if isinstance(new_data, tuple):
+ start = 0
+ for op in self.obs:
+ op.data = new_data[start : start + len(op.data)]
+ start += len(op.data)
+ else:
+ for new_entry, op in zip(new_data, self.obs):
+ op.data = tuple(new_entry)
@property
def num_params(self):
diff --git a/pennylane/ops/op_math/adjoint.py b/pennylane/ops/op_math/adjoint.py
index f61987cc220..85edd82545a 100644
--- a/pennylane/ops/op_math/adjoint.py
+++ b/pennylane/ops/op_math/adjoint.py
@@ -175,7 +175,7 @@ class Adjoint(SymbolicOp):
>>> qml.generator(Adjoint(qml.RX(1.0, wires=0)))
(PauliX(wires=[0]), 0.5)
>>> Adjoint(qml.RX(1.234, wires=0)).data
- [1.234]
+ (1.234,)
.. details::
:title: Developer Details
diff --git a/pennylane/ops/op_math/composite.py b/pennylane/ops/op_math/composite.py
index eb54934d7c7..2535b9a59f1 100644
--- a/pennylane/ops/op_math/composite.py
+++ b/pennylane/ops/op_math/composite.py
@@ -18,6 +18,7 @@
import abc
from typing import Callable, List
import warnings
+import copy
import numpy as np
@@ -122,7 +123,7 @@ def _op_symbol(self) -> str:
@property
def data(self):
"""Create data property"""
- return [d for op in self for d in op.data]
+ return tuple(d for op in self for d in op.data)
@data.setter
def data(self, new_data):
@@ -351,7 +352,7 @@ def map_wires(self, wire_map: dict):
new_op = cls.__new__(cls)
new_op.operands = tuple(op.map_wires(wire_map=wire_map) for op in self)
new_op._wires = Wires([wire_map.get(wire, wire) for wire in self.wires])
- new_op.data = self.data.copy()
+ new_op.data = copy.copy(self.data)
for attr, value in vars(self).items():
if attr not in {"data", "operands", "_wires"}:
setattr(new_op, attr, value)
diff --git a/pennylane/ops/op_math/controlled.py b/pennylane/ops/op_math/controlled.py
index 0715e2b76d3..3a83cf4b0bd 100644
--- a/pennylane/ops/op_math/controlled.py
+++ b/pennylane/ops/op_math/controlled.py
@@ -178,7 +178,7 @@ class Controlled(SymbolicOp):
>>> op.base
RX(1.234, wires=[1])
>>> op.data
- [1.234]
+ (1.234,)
>>> op.wires
>>> op.control_wires
diff --git a/pennylane/ops/op_math/evolution.py b/pennylane/ops/op_math/evolution.py
index cbc67bee349..9b30ec3a9ab 100644
--- a/pennylane/ops/op_math/evolution.py
+++ b/pennylane/ops/op_math/evolution.py
@@ -85,7 +85,7 @@ def __init__(self, generator, param=1, num_steps=None, do_queue=None, id=None):
super().__init__(
generator, coeff=-1j * param, num_steps=num_steps, do_queue=do_queue, id=id
)
- self._data = [param]
+ self._data = (param,)
def __repr__(self):
return (
diff --git a/pennylane/ops/op_math/symbolicop.py b/pennylane/ops/op_math/symbolicop.py
index 2d5575445f8..dafedf0d67c 100644
--- a/pennylane/ops/op_math/symbolicop.py
+++ b/pennylane/ops/op_math/symbolicop.py
@@ -186,7 +186,7 @@ def batch_size(self):
@property
def data(self):
- return [self.scalar, *self.base.data]
+ return (self.scalar, *self.base.data)
@data.setter
def data(self, new_data):
diff --git a/pennylane/ops/qubit/hamiltonian.py b/pennylane/ops/qubit/hamiltonian.py
index 39f23f35b95..e59aadb3d73 100644
--- a/pennylane/ops/qubit/hamiltonian.py
+++ b/pennylane/ops/qubit/hamiltonian.py
@@ -269,7 +269,7 @@ def terms(self):
>>> t[0]
[, ]
"""
- return self.data, self.ops
+ return self.parameters, self.ops
@property
def wires(self):
@@ -475,7 +475,7 @@ def simplify(self):
# hotfix: We `self.data`, since `self.parameters` returns a copy of the data and is now returned in
# self.terms(). To be improved soon.
- self.data = new_coeffs
+ self.data = tuple(new_coeffs)
# hotfix: We overwrite the hyperparameter entry, which is now returned in self.terms().
# To be improved soon.
self.hyperparameters["ops"] = new_ops
@@ -752,7 +752,7 @@ def map_wires(self, wire_map: dict):
"""
cls = self.__class__
new_op = cls.__new__(cls)
- new_op.data = self.data.copy()
+ new_op.data = copy(self.data)
new_op._wires = Wires( # pylint: disable=protected-access
[wire_map.get(wire, wire) for wire in self.wires]
)
diff --git a/pennylane/optimize/adaptive.py b/pennylane/optimize/adaptive.py
index 4676c9fe666..fefb9e2f375 100644
--- a/pennylane/optimize/adaptive.py
+++ b/pennylane/optimize/adaptive.py
@@ -33,7 +33,8 @@ def append_gate(tape, params, gates):
for i, g in enumerate(gates):
g = copy.copy(g)
- g.data[0] = params[i]
+ new_params = (params[i], *g.data[1:])
+ g.data = new_params
qml.apply(g)
for m in tape.measurements:
diff --git a/pennylane/tape/qscript.py b/pennylane/tape/qscript.py
index a0dbb9b8829..eccb8d3c95b 100644
--- a/pennylane/tape/qscript.py
+++ b/pennylane/tape/qscript.py
@@ -729,10 +729,20 @@ def set_parameters(self, params, trainable_only=True):
if len(params) != required_length:
raise ValueError("Number of provided parameters does not match.")
+ op_data = []
+ for pinfo in self._par_info:
+ if pinfo["p_idx"] == 0:
+ op_data.append((pinfo["op"], list(pinfo["op"].data)))
+ else:
+ op_data.append(op_data[-1])
+
for idx, p in iterator:
- op = self._par_info[idx]["op"]
- op.data[self._par_info[idx]["p_idx"]] = p
+ op_data[idx][1][self._par_info[idx]["p_idx"]] = p
+
+ for op, d in op_data:
+ op.data = tuple(d)
op._check_batching(op.data)
+
self._update_batch_size()
self._update_output_dim()
diff --git a/tests/gradients/parameter_shift/test_parameter_shift_cv.py b/tests/gradients/parameter_shift/test_parameter_shift_cv.py
index abc46de23b5..b5e9e213db6 100644
--- a/tests/gradients/parameter_shift/test_parameter_shift_cv.py
+++ b/tests/gradients/parameter_shift/test_parameter_shift_cv.py
@@ -444,7 +444,7 @@ def _mock_transform_observable(obs, Z, device_wires): # pylint: disable=unused-
transformed_obs.parameters[0]`` the condition ``len(A.nonzero()[0])
== 1 and A.ndim == 2 and A[0, 0] != 0`` is ``True``."""
iden = qml.Identity(0)
- iden.data = [np.array([[1, 0], [0, 0]])]
+ iden.data = (np.array([[1, 0], [0, 0]]),)
return iden
monkeypatch.setattr(
diff --git a/tests/legacy/test_hamiltonian_expand_old.py b/tests/legacy/test_hamiltonian_expand_old.py
index 7d2210e9a92..db96ba3e1fc 100644
--- a/tests/legacy/test_hamiltonian_expand_old.py
+++ b/tests/legacy/test_hamiltonian_expand_old.py
@@ -473,8 +473,8 @@ def test_sum_dif_autograd(self, tol):
3.50307411e-01,
-3.41123470e-01,
0.0,
- 0.0,
- 0.0,
+ -4.36578753e-01,
+ 6.41233474e-01,
]
with AnnotatedQueue() as q:
@@ -567,8 +567,8 @@ def test_sum_dif_jax(self, tol):
3.50307411e-01,
-3.41123470e-01,
0.0,
- 0.0,
- 0.0,
+ -4.36578753e-01,
+ 6.41233474e-01,
]
with AnnotatedQueue() as q:
diff --git a/tests/legacy/test_metric_tensor_old.py b/tests/legacy/test_metric_tensor_old.py
index 5b2fc8bbaaf..73294757ea8 100644
--- a/tests/legacy/test_metric_tensor_old.py
+++ b/tests/legacy/test_metric_tensor_old.py
@@ -46,7 +46,7 @@ def test_rot_decomposition(self, diff_method):
# Second parameter subcircuit
assert len(tapes[1].operations) == 4
assert isinstance(tapes[1].operations[0], qml.RZ)
- assert tapes[1].operations[0].data == [1]
+ assert tapes[1].operations[0].data == (1,)
# PauliY decomp
assert isinstance(tapes[1].operations[1], qml.PauliZ)
assert isinstance(tapes[1].operations[2], qml.S)
@@ -56,8 +56,8 @@ def test_rot_decomposition(self, diff_method):
assert len(tapes[2].operations) == 2
assert isinstance(tapes[2].operations[0], qml.RZ)
assert isinstance(tapes[2].operations[1], qml.RY)
- assert tapes[2].operations[0].data == [1]
- assert tapes[2].operations[1].data == [2]
+ assert tapes[2].operations[0].data == (1,)
+ assert tapes[2].operations[1].data == (2,)
@pytest.mark.parametrize("diff_method", ["parameter-shift", "backprop"])
def test_multirz_decomposition(self, diff_method):
diff --git a/tests/legacy/test_qscript_old.py b/tests/legacy/test_qscript_old.py
index d566b29ba11..847afda0661 100644
--- a/tests/legacy/test_qscript_old.py
+++ b/tests/legacy/test_qscript_old.py
@@ -545,7 +545,6 @@ def test_shallow_copy_with_operations(self, copy_fn):
# however, the underlying operation data *is still shared*
assert copied_qs.operations[0].wires is qs.operations[0].wires
# the data list is copied, but the elements of the list remain th same
- assert copied_qs.operations[0].data is not qs.operations[0].data
assert copied_qs.operations[0].data[0] is qs.operations[0].data[0]
assert qs.get_parameters() == copied_qs.get_parameters()
diff --git a/tests/ops/op_math/test_adjoint.py b/tests/ops/op_math/test_adjoint.py
index cee37e600dd..58a9e1ac36b 100644
--- a/tests/ops/op_math/test_adjoint.py
+++ b/tests/ops/op_math/test_adjoint.py
@@ -108,7 +108,7 @@ def test_nonparametric_ops(self):
assert op.num_params == 0
assert op.parameters == []
- assert op.data == []
+ assert op.data == ()
assert op.wires == qml.wires.Wires("a")
@@ -176,18 +176,18 @@ def test_data(self):
base = qml.RX(x, wires="a")
adj = Adjoint(base)
- assert adj.data == [x]
+ assert adj.data == (x,)
# update parameters through adjoint
x_new = np.array(2.3456)
- adj.data = [x_new]
- assert base.data == [x_new]
- assert adj.data == [x_new]
+ adj.data = (x_new,)
+ assert base.data == (x_new,)
+ assert adj.data == (x_new,)
# update base data updates Adjoint data
x_new2 = np.array(3.456)
- base.data = [x_new2]
- assert adj.data == [x_new2]
+ base.data = (x_new2,)
+ assert adj.data == (x_new2,)
def test_has_matrix_true(self):
"""Test `has_matrix` property carries over when base op defines matrix."""
@@ -866,7 +866,7 @@ def test_adjoint_single_op_function(self):
assert out == tape[0]
assert isinstance(out, Adjoint)
assert out.base.__class__ is qml.RX
- assert out.data == [1.234]
+ assert out.data == (1.234,)
assert out.wires == qml.wires.Wires("a")
def test_adjoint_template(self):
@@ -908,9 +908,9 @@ def func(x, y, z):
assert tape[2].base.__class__ is qml.RX
# check parameters assigned correctly
- assert tape[0].data == [z]
- assert tape[1].data == [y]
- assert tape[2].data == [x]
+ assert tape[0].data == (z,)
+ assert tape[1].data == (y,)
+ assert tape[2].data == (x,)
def test_nested_adjoint(self):
"""Test the adjoint transform on an adjoint transform."""
@@ -923,7 +923,7 @@ def test_nested_adjoint(self):
assert isinstance(out, Adjoint)
assert isinstance(out.base, Adjoint)
assert out.base.base.__class__ is qml.RX
- assert out.data == [x]
+ assert out.data == (x,)
assert out.wires == qml.wires.Wires("b")
@@ -942,7 +942,7 @@ def test_single_decomposeable_op(self):
assert q.queue[0] is out
assert isinstance(out, qml.RX)
- assert out.data == [-1.23]
+ assert out.data == (-1.23,)
def test_single_nondecomposable_op(self):
"""Test lazy=false for a single op that can't be decomposed."""
@@ -966,7 +966,7 @@ def test_single_decomposable_op_function(self):
assert out is tape[0]
assert not isinstance(out, Adjoint)
assert isinstance(out, qml.RX)
- assert out.data == [-x]
+ assert out.data == (-x,)
def test_single_nondecomposable_op_function(self):
"""Test lazy=False for a single op function that can't be decomposed."""
@@ -1009,7 +1009,7 @@ def test_single_op(self):
assert isinstance(out, Adjoint)
assert out.base.__class__ is qml.RZ
- assert out.data == [1.234]
+ assert out.data == (1.234,)
assert out.wires == qml.wires.Wires(0)
def test_single_op_eager(self):
@@ -1020,7 +1020,7 @@ def test_single_op_eager(self):
out = adjoint(base, lazy=False)
assert isinstance(out, qml.RX)
- assert out.data == [-x]
+ assert out.data == (-x,)
def test_observable(self):
"""Test providing a preconstructed Observable outside of a queuing context."""
@@ -1039,7 +1039,7 @@ def test_single_op_function(self):
assert isinstance(out, Adjoint)
assert out.base.__class__ is qml.IsingXX
- assert out.data == [1.234]
+ assert out.data == (1.234,)
assert out.wires == qml.wires.Wires((0, 1))
def test_function(self):
diff --git a/tests/ops/op_math/test_composite.py b/tests/ops/op_math/test_composite.py
index d94089e1652..623150bc5e5 100644
--- a/tests/ops/op_math/test_composite.py
+++ b/tests/ops/op_math/test_composite.py
@@ -101,14 +101,14 @@ def test_parameters(self):
def test_data(self):
"""Test that data is initialized correctly."""
op = ValidOp(qml.RX(9.87, wires=0), qml.Rot(1.23, 4.0, 5.67, wires=1), qml.PauliX(0))
- assert op.data == [9.87, 1.23, 4.0, 5.67]
+ assert op.data == (9.87, 1.23, 4.0, 5.67)
def test_data_setter(self):
"""Test the setter method for data"""
op = ValidOp(qml.RX(9.87, wires=0), qml.Rot(1.23, 4.0, 5.67, wires=1), qml.PauliX(0))
- assert op.data == [9.87, 1.23, 4.0, 5.67]
+ assert op.data == (9.87, 1.23, 4.0, 5.67)
- new_data = [1.23, 0.0, -1.0, -2.0]
+ new_data = (1.23, 0.0, -1.0, -2.0)
op.data = new_data # pylint:disable=attribute-defined-outside-init
assert op.data == new_data
diff --git a/tests/ops/op_math/test_controlled.py b/tests/ops/op_math/test_controlled.py
index f1fcefb2b38..c851ea6d93c 100644
--- a/tests/ops/op_math/test_controlled.py
+++ b/tests/ops/op_math/test_controlled.py
@@ -148,7 +148,7 @@ def test_nonparametric_ops(self):
assert op.num_params == 0
assert op.parameters == []
- assert op.data == []
+ assert op.data == ()
assert op.num_wires == 4
@@ -207,16 +207,16 @@ def test_data(self):
base = qml.RX(x, wires="a")
op = Controlled(base, (0, 1))
- assert op.data == [x]
+ assert op.data == (x,)
- x_new = np.array(2.3454)
+ x_new = (np.array(2.3454),)
op.data = x_new
- assert op.data == [x_new]
- assert base.data == [x_new]
+ assert op.data == (x_new,)
+ assert base.data == (x_new,)
- x_new2 = np.array(3.456)
+ x_new2 = (np.array(3.456),)
base.data = x_new2
- assert op.data == [x_new2]
+ assert op.data == (x_new2,)
assert op.parameters == [x_new2]
@pytest.mark.parametrize(
@@ -386,10 +386,10 @@ def test_copy(self):
assert copied_op.__class__ is op.__class__
assert copied_op.control_wires == op.control_wires
assert copied_op.control_values == op.control_values
- assert copied_op.data == [param1]
+ assert copied_op.data == (param1,)
- copied_op.data = [6.54]
- assert op.data == [param1]
+ copied_op.data = (6.54,)
+ assert op.data == (param1,)
def test_label(self):
"""Test that the label method defers to the label of the base."""
@@ -450,7 +450,7 @@ def test_generator(self):
for wire, ob in zip(op.control_wires, gen_tensor.operands):
assert isinstance(ob, qml.Projector)
- assert ob.data == [[1]]
+ assert ob.data == ([1],)
assert ob.wires == qml.wires.Wires(wire)
assert gen_tensor.operands[-1].__class__ is base_gen.__class__
diff --git a/tests/ops/op_math/test_evolution.py b/tests/ops/op_math/test_evolution.py
index 42afa745f64..f707be56f7f 100644
--- a/tests/ops/op_math/test_evolution.py
+++ b/tests/ops/op_math/test_evolution.py
@@ -36,7 +36,7 @@ def test_initialization(self):
assert op.num_params == 1
assert op.parameters == [param]
- assert op.data == [param]
+ assert op.data == (param,)
assert op.wires == qml.wires.Wires(("b", "c"))
@@ -79,14 +79,14 @@ def test_data(self):
base = qml.PauliX(0)
op = Evolution(base, param)
- assert op.data == [param]
+ assert op.data == (param,)
assert op.coeff == -1j * op.data[0]
assert op.param == op.data[0]
new_param = np.array(2.345)
- op.data = [new_param]
+ op.data = (new_param,)
- assert op.data == [new_param]
+ assert op.data == (new_param,)
assert op.coeff == -1j * op.data[0]
assert op.data == op.data[0]
diff --git a/tests/ops/op_math/test_exp.py b/tests/ops/op_math/test_exp.py
index 5579adcb3fb..6e0c8c5606d 100644
--- a/tests/ops/op_math/test_exp.py
+++ b/tests/ops/op_math/test_exp.py
@@ -44,7 +44,7 @@ def test_pauli_base(self, constructor):
assert op.num_params == 1
assert op.parameters == [1]
- assert op.data == [1]
+ assert op.data == (1,)
assert op.wires == qml.wires.Wires("a")
@@ -63,7 +63,7 @@ def test_provided_coeff(self, constructor):
assert op.num_params == 1
assert op.parameters == [coeff]
- assert op.data == [coeff]
+ assert op.data == (coeff,)
assert op.wires == qml.wires.Wires(("b", "c"))
@@ -81,7 +81,7 @@ def test_parametric_base(self, constructor):
assert op.name == "Exp"
assert op.num_params == 2
- assert op.data == [coeff, base_coeff]
+ assert op.data == (coeff, base_coeff)
assert op.wires == qml.wires.Wires(5)
@@ -110,14 +110,14 @@ def test_data(self):
base = qml.RX(phi, wires=0)
op = Exp(base, coeff)
- assert op.data == [coeff, phi]
+ assert op.data == (coeff, phi)
new_phi = np.array(0.1234)
new_coeff = np.array(3.456)
- op.data = [new_coeff, new_phi]
+ op.data = (new_coeff, new_phi)
- assert op.data == [new_coeff, new_phi]
- assert op.base.data == [new_phi]
+ assert op.data == (new_coeff, new_phi)
+ assert op.base.data == (new_phi,)
assert op.scalar == new_coeff
# pylint: disable=protected-access
diff --git a/tests/ops/op_math/test_pow_op.py b/tests/ops/op_math/test_pow_op.py
index 7aa214cd611..ee951011e70 100644
--- a/tests/ops/op_math/test_pow_op.py
+++ b/tests/ops/op_math/test_pow_op.py
@@ -186,7 +186,7 @@ def test_nonparametric_ops(self, power_method):
assert op.num_params == 0
assert op.parameters == []
- assert op.data == []
+ assert op.data == ()
assert op.wires == qml.wires.Wires("a")
assert op.num_wires == 1
@@ -266,18 +266,18 @@ def test_data(self, power_method):
base = qml.RX(x, wires="a")
op: Pow = power_method(base=base, z=3.21)
- assert op.data == [x]
+ assert op.data == (x,)
# update parameters through pow
x_new = np.array(2.3456)
- op.data = [x_new]
- assert base.data == [x_new]
- assert op.data == [x_new]
+ op.data = (x_new,)
+ assert base.data == (x_new,)
+ assert op.data == (x_new,)
# update base data updates pow data
x_new2 = np.array(3.456)
- base.data = [x_new2]
- assert op.data == [x_new2]
+ base.data = (x_new2,)
+ assert op.data == (x_new2,)
def test_has_matrix_true(self, power_method):
"""Test `has_matrix` property carries over when base op defines matrix."""
@@ -503,10 +503,10 @@ def test_copy(self):
assert copied_op.__class__ is op.__class__
assert copied_op.z == op.z
- assert copied_op.data == [param1]
+ assert copied_op.data == (param1,)
- copied_op.data = [6.54]
- assert op.data == [param1]
+ copied_op.data = (6.54,)
+ assert op.data == (param1,)
def test_label(self):
"""Test that the label draws the exponent as superscript."""
diff --git a/tests/ops/op_math/test_prod.py b/tests/ops/op_math/test_prod.py
index 84eb02f1db8..35220e12c40 100644
--- a/tests/ops/op_math/test_prod.py
+++ b/tests/ops/op_math/test_prod.py
@@ -130,7 +130,7 @@ def test_init_prod_op(self, id):
assert prod_op.id == id
assert prod_op.queue_idx is None
- assert prod_op.data == [0.23]
+ assert prod_op.data == (0.23,)
assert prod_op.parameters == [0.23]
assert prod_op.num_params == 1
diff --git a/tests/ops/op_math/test_sprod.py b/tests/ops/op_math/test_sprod.py
index 6688e24a2a2..37b80067222 100644
--- a/tests/ops/op_math/test_sprod.py
+++ b/tests/ops/op_math/test_sprod.py
@@ -112,7 +112,7 @@ def test_init_sprod_op(self, test_id):
assert sprod_op.id == test_id
assert sprod_op.queue_idx is None
- assert sprod_op.data == [3.14, 0.23]
+ assert sprod_op.data == (3.14, 0.23)
assert sprod_op.parameters == [3.14, 0.23]
assert sprod_op.num_params == 2
@@ -122,17 +122,17 @@ def test_parameters(self):
def test_data(self):
sprod_op = s_prod(9.87, qml.Rot(1.23, 4.0, 5.67, wires=1))
- assert sprod_op.data == [9.87, 1.23, 4.0, 5.67]
+ assert sprod_op.data == (9.87, 1.23, 4.0, 5.67)
def test_data_setter(self):
"""Test the setter method for data"""
scalar, angles = (9.87, (1.23, 4.0, 5.67))
- old_data = [9.87, 1.23, 4.0, 5.67]
+ old_data = (9.87, 1.23, 4.0, 5.67)
sprod_op = s_prod(scalar, qml.Rot(*angles, wires=1))
assert sprod_op.data == old_data
- new_data = [1.23, 0.0, -1.0, -2.0]
+ new_data = (1.23, 0.0, -1.0, -2.0)
sprod_op.data = new_data
assert sprod_op.data == new_data
assert sprod_op.scalar == new_data[0]
@@ -141,20 +141,20 @@ def test_data_setter(self):
def test_data_setter_shallow(self):
"""Test the setter method for data with a non-parametric base op."""
op = s_prod(0.1, qml.PauliX(0))
- op.data = [0.2]
- assert op.data == [0.2] == [op.scalar]
+ op.data = (0.2,)
+ assert op.data == (0.2,) == (op.scalar,)
def test_data_setter_deep(self):
"""Test the setter method for data with a deep base operator."""
op = s_prod(0.1, qml.sum(qml.PauliX(0), qml.prod(qml.PauliY(0), qml.RX(0.2, 1))))
- assert op.data == [0.1, 0.2]
+ assert op.data == (0.1, 0.2)
- new_data = [0.3, 0.4]
+ new_data = (0.3, 0.4)
op.data = new_data
assert op.data == new_data
assert op.scalar == 0.3
- assert op.base[1].data == [0.4]
- assert op.base[1][1].data == [0.4]
+ assert op.base[1].data == (0.4,)
+ assert op.base[1][1].data == (0.4,)
@pytest.mark.parametrize("scalar, op", ops)
def test_terms(self, op, scalar):
@@ -208,9 +208,6 @@ def test_copy(self, op_scalar_tup):
assert sprod_op.base.name == copied_op.base.name
assert sprod_op.base.wires == copied_op.base.wires
assert sprod_op.base.data == copied_op.base.data
- assert (
- sprod_op.base.data is not copied_op.base.data
- ) # we want different object with same content
def test_has_matrix_true_via_factor_has_matrix(self):
"""Test that a scalar product with an operator that has `has_matrix=True`
diff --git a/tests/ops/op_math/test_sum.py b/tests/ops/op_math/test_sum.py
index 3eeac1fe593..7c009a62e47 100644
--- a/tests/ops/op_math/test_sum.py
+++ b/tests/ops/op_math/test_sum.py
@@ -126,7 +126,7 @@ def test_init_sum_op(self, id, sum_method):
if sum_method.__name__ == sum.__name__:
assert sum_op.id == id
- assert sum_op.data == [0.23]
+ assert sum_op.data == (0.23,)
assert sum_op.parameters == [0.23]
assert sum_op.num_params == 1
@@ -142,7 +142,7 @@ def test_init_sum_op_with_sum_summands(self, sum_method):
assert sum_op.name == "Sum"
assert sum_op.id is None
- assert sum_op.data == [0.23, 9.87]
+ assert sum_op.data == (0.23, 9.87)
assert sum_op.parameters == [0.23, 9.87]
assert sum_op.num_params == 2
diff --git a/tests/ops/op_math/test_symbolic_op.py b/tests/ops/op_math/test_symbolic_op.py
index ee3c7a0bfa0..04ae2cddea5 100644
--- a/tests/ops/op_math/test_symbolic_op.py
+++ b/tests/ops/op_math/test_symbolic_op.py
@@ -66,10 +66,10 @@ def test_copy():
copied_op = copy(op)
assert copied_op.__class__ is op.__class__
- assert copied_op.data == [param1]
+ assert copied_op.data == (param1,)
- copied_op.data = [6.54]
- assert op.data == [param1]
+ copied_op.data = (6.54,)
+ assert op.data == (param1,)
def test_map_wires():
@@ -101,18 +101,18 @@ def test_data(self):
base = Operator(x, "a")
op = SymbolicOp(base)
- assert op.data == [x]
+ assert op.data == (x,)
# update parameters through op
x_new = np.array(2.345)
- op.data = [x_new]
- assert base.data == [x_new]
- assert op.data == [x_new]
+ op.data = (x_new,)
+ assert base.data == (x_new,)
+ assert op.data == (x_new,)
# update base data updates symbolic data
x_new2 = np.array(3.45)
- base.data = [x_new2]
- assert op.data == [x_new2]
+ base.data = (x_new2,)
+ assert op.data == (x_new2,)
def test_parameters(self):
"""Test parameter property is a list of the base's trainable parameters."""
@@ -232,7 +232,7 @@ def test_init(self):
op = TempScalar(base, scalar)
assert isinstance(op.scalar, float)
assert op.scalar == 2.2
- assert op.data == [2.2, 1.1]
+ assert op.data == (2.2, 1.1)
base = Operator(1.1, wires=[0])
scalar = [2.2, 3.3]
@@ -246,19 +246,19 @@ def test_data(self):
"""Tests the data property."""
op = TempScalar(Operator(1.1, wires=[0]), 2.2)
assert op.scalar == 2.2
- assert op.data == [2.2, 1.1]
+ assert op.data == (2.2, 1.1)
# check setting through ScalarSymbolicOp
- op.data = [3.3, 4.4] # pylint:disable=attribute-defined-outside-init
- assert op.data == [3.3, 4.4]
+ op.data = (3.3, 4.4) # pylint:disable=attribute-defined-outside-init
+ assert op.data == (3.3, 4.4)
assert op.scalar == 3.3
- assert op.base.data == [4.4]
+ assert op.base.data == (4.4,)
# check setting through base
- op.base.data = [5.5]
- assert op.data == [3.3, 5.5]
+ op.base.data = (5.5,)
+ assert op.data == (3.3, 5.5)
assert op.scalar == 3.3
- assert op.base.data == [5.5]
+ assert op.base.data == (5.5,)
def test_hash(self):
"""Test that a hash correctly identifies ScalarSymbolicOps."""
diff --git a/tests/ops/qubit/test_parametric_ops.py b/tests/ops/qubit/test_parametric_ops.py
index 973b5d44a28..fe17dfa4c99 100644
--- a/tests/ops/qubit/test_parametric_ops.py
+++ b/tests/ops/qubit/test_parametric_ops.py
@@ -3912,14 +3912,14 @@ def test_simplify_rot(self):
simplify_rot_x = rot_x.simplify()
assert simplify_rot_x.name == "RX"
- assert simplify_rot_x.data == [0.1]
+ assert simplify_rot_x.data == (0.1,)
assert np.allclose(simplify_rot_x.matrix(), rot_x.matrix())
rot_y = qml.Rot(0, 0.1, 0, wires=0)
simplify_rot_y = rot_y.simplify()
assert simplify_rot_y.name == "RY"
- assert simplify_rot_y.data == [0.1]
+ assert simplify_rot_y.data == (0.1,)
assert np.allclose(simplify_rot_y.matrix(), rot_y.matrix())
rot_z = qml.Rot(0.1, 0, 0.2, wires=0)
@@ -3948,14 +3948,14 @@ def test_simplify_crot(self):
simplify_crot_x = crot_x.simplify()
assert simplify_crot_x.name == "CRX"
- assert simplify_crot_x.data == [0.1]
+ assert simplify_crot_x.data == (0.1,)
assert np.allclose(simplify_crot_x.matrix(), crot_x.matrix())
crot_y = qml.CRot(0, 0.1, 0, wires=[0, 1])
simplify_crot_y = crot_y.simplify()
assert simplify_crot_y.name == "CRY"
- assert simplify_crot_y.data == [0.1]
+ assert simplify_crot_y.data == (0.1,)
assert np.allclose(simplify_crot_y.matrix(), crot_y.matrix())
crot_z = qml.CRot(0.1, 0, 0.2, wires=[0, 1])
@@ -3978,21 +3978,21 @@ def test_simplify_u2(self):
simplify_u2_x = u2_x.simplify()
assert simplify_u2_x.name == "RX"
- assert simplify_u2_x.data == [np.pi / 2]
+ assert simplify_u2_x.data == (np.pi / 2,)
assert np.allclose(simplify_u2_x.matrix(), u2_x.matrix())
u2_y = qml.U2(-2 * np.pi, 2 * np.pi, wires=0)
simplify_u2_y = u2_y.simplify()
assert simplify_u2_y.name == "RY"
- assert simplify_u2_y.data == [np.pi / 2]
+ assert simplify_u2_y.data == (np.pi / 2,)
assert np.allclose(simplify_u2_y.matrix(), u2_y.matrix())
u2 = qml.U2(0.1, 0.2, wires=0)
u2_not_simplified = u2.simplify()
assert u2_not_simplified.name == "U2"
- assert u2_not_simplified.data == [0.1, 0.2]
+ assert u2_not_simplified.data == (0.1, 0.2)
assert np.allclose(u2_not_simplified.matrix(), u2.matrix())
def test_simplify_u3(self):
@@ -4002,28 +4002,28 @@ def test_simplify_u3(self):
simplify_u3_x = u3_x.simplify()
assert simplify_u3_x.name == "RX"
- assert simplify_u3_x.data == [0.1]
+ assert simplify_u3_x.data == (0.1,)
assert np.allclose(simplify_u3_x.matrix(), u3_x.matrix())
u3_y = qml.U3(0.1, 0.0, 0.0, wires=0)
simplify_u3_y = u3_y.simplify()
assert simplify_u3_y.name == "RY"
- assert simplify_u3_y.data == [0.1]
+ assert simplify_u3_y.data == (0.1,)
assert np.allclose(simplify_u3_y.matrix(), u3_y.matrix())
u3_z = qml.U3(0.0, 0.1, 0.0, wires=0)
simplify_u3_z = u3_z.simplify()
assert simplify_u3_z.name == "PhaseShift"
- assert simplify_u3_z.data == [0.1]
+ assert simplify_u3_z.data == (0.1,)
assert np.allclose(simplify_u3_z.matrix(), u3_z.matrix())
u3 = qml.U3(0.1, 0.2, 0.3, wires=0)
u3_not_simplified = u3.simplify()
assert u3_not_simplified.name == "U3"
- assert u3_not_simplified.data == [0.1, 0.2, 0.3]
+ assert u3_not_simplified.data == (0.1, 0.2, 0.3)
assert np.allclose(u3_not_simplified.matrix(), u3.matrix())
diff --git a/tests/tape/test_qscript.py b/tests/tape/test_qscript.py
index 2f0b9036b00..8a5e8d36506 100644
--- a/tests/tape/test_qscript.py
+++ b/tests/tape/test_qscript.py
@@ -572,7 +572,6 @@ def test_shallow_copy_with_operations(self, copy_fn):
# however, the underlying operation data *is still shared*
assert copied_qs.operations[0].wires is qs.operations[0].wires
# the data list is copied, but the elements of the list remain th same
- assert copied_qs.operations[0].data is not qs.operations[0].data
assert copied_qs.operations[0].data[0] is qs.operations[0].data[0]
assert qs.get_parameters() == copied_qs.get_parameters()
diff --git a/tests/tape/test_tape.py b/tests/tape/test_tape.py
index 1d0200c5966..3bb41d0f20c 100644
--- a/tests/tape/test_tape.py
+++ b/tests/tape/test_tape.py
@@ -323,7 +323,7 @@ def f(x):
assert isinstance(tape.circuit[2], qml.transforms.condition.Conditional)
assert isinstance(tape.circuit[2].then_op, qml.RY)
assert tape.circuit[2].then_op.wires == target_wire
- assert tape.circuit[2].then_op.data == [r]
+ assert tape.circuit[2].then_op.data == (r,)
assert isinstance(tape.circuit[3], qml.transforms.condition.Conditional)
assert isinstance(tape.circuit[3].then_op, qml.PauliZ)
@@ -770,13 +770,13 @@ def test_setting_parameters(self, make_tape):
assert tape.get_parameters() == new_params
- new_params = [0.1, -0.2, 1, 5, 0]
+ new_params = (0.1, -0.2, 1, 5, 0)
tape.data = new_params
for pinfo, pval in zip(tape._par_info, new_params):
assert pinfo["op"].data[pinfo["p_idx"]] == pval
- assert tape.get_parameters() == new_params
+ assert tape.get_parameters() == list(new_params)
def test_setting_free_parameters(self, make_tape):
"""Test that free parameters are correctly modified after construction"""
diff --git a/tests/test_operation.py b/tests/test_operation.py
index fe841444bd5..92b16c071dc 100644
--- a/tests/test_operation.py
+++ b/tests/test_operation.py
@@ -235,7 +235,7 @@ class DummyOp(qml.operation.Operator):
op = DummyOp(1.234, "a")
assert op.wires[0] == "a"
- assert op.data == [1.234]
+ assert op.data == (1.234,)
def test_no_wires(self):
"""Test an error is raised if no wires are passed."""
@@ -1373,7 +1373,7 @@ def test_params(self):
X = qml.PauliX(0)
Y = qml.Hermitian(p, wires=[1, 2])
t = Tensor(X, Y)
- assert t.data == [p]
+ assert t.data == (p,)
def test_data_setter(self):
"""Test the data setter"""
@@ -1381,10 +1381,10 @@ def test_data_setter(self):
X = qml.PauliX(0)
Y = qml.Hermitian(p, wires=[1, 2])
t = Tensor(X, Y)
- assert t.data == [p]
+ assert t.data == (p,)
new_data = np.eye(4) * 6
- t.data = [[], [new_data]]
- assert qml.math.allequal(t.data, [new_data])
+ t.data = [(), (new_data,)]
+ assert qml.math.allequal(t.data, (new_data,))
def test_num_params(self):
"""Test that the correct number of parameters is returned"""
diff --git a/tests/transforms/test_condition.py b/tests/transforms/test_condition.py
index 369c1c838de..51279f658f8 100644
--- a/tests/transforms/test_condition.py
+++ b/tests/transforms/test_condition.py
@@ -73,7 +73,7 @@ def f(x):
assert isinstance(ops[2], qml.transforms.condition.Conditional)
assert isinstance(ops[2].then_op, qml.RY)
assert ops[2].then_op.wires == target_wire
- assert ops[2].then_op.data == [r]
+ assert ops[2].then_op.data == (r,)
assert isinstance(ops[3], qml.transforms.condition.Conditional)
assert isinstance(ops[3].then_op, qml.PauliZ)
@@ -135,7 +135,7 @@ def g(x):
assert isinstance(ops[2], qml.transforms.condition.Conditional)
assert isinstance(ops[2].then_op, qml.RY)
assert ops[2].then_op.wires == target_wire
- assert ops[2].then_op.data == [r]
+ assert ops[2].then_op.data == (r,)
assert isinstance(ops[3], qml.transforms.condition.Conditional)
assert isinstance(ops[3].then_op, qml.PauliZ)
@@ -232,7 +232,7 @@ def test_cond_operationss_with_adjoint(self, terminal_measurement):
assert isinstance(ops[2], qml.transforms.condition.Conditional)
assert isinstance(ops[2].then_op, qml.RX)
- assert ops[2].then_op.data == [r]
+ assert ops[2].then_op.data == (r,)
assert ops[2].then_op.wires == target_wire
assert len(tape.measurements) == 1
diff --git a/tests/transforms/test_defer_measurements.py b/tests/transforms/test_defer_measurements.py
index d2df719e182..c44205dc4a9 100644
--- a/tests/transforms/test_defer_measurements.py
+++ b/tests/transforms/test_defer_measurements.py
@@ -334,7 +334,7 @@ def test_quantum_teleportation(self, device, rads):
op1 = tape.operations[0]
assert isinstance(op1, qml.RY)
assert op1.wires == qml.wires.Wires(0)
- assert op1.data == [rads]
+ assert op1.data == (rads,)
op2 = tape.operations[1]
assert isinstance(op2, qml.Hadamard)
diff --git a/tests/transforms/test_hamiltonian_expand.py b/tests/transforms/test_hamiltonian_expand.py
index 04b59329315..f6a3c16b7bd 100644
--- a/tests/transforms/test_hamiltonian_expand.py
+++ b/tests/transforms/test_hamiltonian_expand.py
@@ -289,7 +289,6 @@ def test_hamiltonian_dif_tensorflow(self):
assert np.isclose(res, output)
g = gtape.gradient(res, var)
- print(g)
assert np.allclose(list(g[0]) + list(g[1]), output2)
@@ -505,8 +504,8 @@ def test_sum_dif_autograd(self, tol):
3.50307411e-01,
-3.41123470e-01,
0.0,
- 0.0,
- 0.0,
+ -4.36578753e-01,
+ 6.41233474e-01,
]
with AnnotatedQueue() as q:
@@ -599,8 +598,8 @@ def test_sum_dif_jax(self, tol):
3.50307411e-01,
-3.41123470e-01,
0.0,
- 0.0,
- 0.0,
+ -4.36578753e-01,
+ 6.41233474e-01,
]
with AnnotatedQueue() as q:
diff --git a/tests/transforms/test_metric_tensor.py b/tests/transforms/test_metric_tensor.py
index 482038bb8c5..94fa23d973a 100644
--- a/tests/transforms/test_metric_tensor.py
+++ b/tests/transforms/test_metric_tensor.py
@@ -46,7 +46,7 @@ def test_rot_decomposition(self, diff_method):
# Second parameter subcircuit
assert len(tapes[1].operations) == 4
assert isinstance(tapes[1].operations[0], qml.RZ)
- assert tapes[1].operations[0].data == [1]
+ assert tapes[1].operations[0].data == (1,)
# PauliY decomp
assert isinstance(tapes[1].operations[1], qml.PauliZ)
assert isinstance(tapes[1].operations[2], qml.S)
@@ -56,8 +56,8 @@ def test_rot_decomposition(self, diff_method):
assert len(tapes[2].operations) == 2
assert isinstance(tapes[2].operations[0], qml.RZ)
assert isinstance(tapes[2].operations[1], qml.RY)
- assert tapes[2].operations[0].data == [1]
- assert tapes[2].operations[1].data == [2]
+ assert tapes[2].operations[0].data == (1,)
+ assert tapes[2].operations[1].data == (2,)
@pytest.mark.parametrize("diff_method", ["parameter-shift", "backprop"])
def test_multirz_decomposition(self, diff_method):
diff --git a/tests/transforms/test_tape_expand.py b/tests/transforms/test_tape_expand.py
index d53856bd096..a56eb694c2c 100644
--- a/tests/transforms/test_tape_expand.py
+++ b/tests/transforms/test_tape_expand.py
@@ -228,7 +228,7 @@ def generator(self):
new_tape = qml.transforms.expand_nonunitary_gen(tape)
assert tape.operations[:2] == new_tape.operations[:2]
exp_op = new_tape.operations[2]
- assert exp_op.name == "RZ" and exp_op.data == [2.1] and exp_op.wires == qml.wires.Wires(1)
+ assert exp_op.name == "RZ" and exp_op.data == (2.1,) and exp_op.wires == qml.wires.Wires(1)
assert tape.operations[3:] == new_tape.operations[3:]
def test_expand_nonunitary_generator(self):
@@ -246,7 +246,7 @@ def test_expand_nonunitary_generator(self):
assert tape.operations[:2] == new_tape.operations[:2]
exp_op = new_tape.operations[2]
- assert exp_op.name == "RZ" and exp_op.data == [2.1] and exp_op.wires == qml.wires.Wires(1)
+ assert exp_op.name == "RZ" and exp_op.data == (2.1,) and exp_op.wires == qml.wires.Wires(1)
assert tape.operations[3:] == new_tape.operations[3:]
def test_decompose_all_nonunitary_generator(self):
diff --git a/tests/transforms/test_transpile.py b/tests/transforms/test_transpile.py
index 5873e52bff5..cb926e71f2b 100644
--- a/tests/transforms/test_transpile.py
+++ b/tests/transforms/test_transpile.py
@@ -218,7 +218,7 @@ def circuit(param):
assert transpiled_ops[2].wires == qml.wires.Wires([1, 2])
assert isinstance(transpiled_ops[3], qml.MultiRZ)
- assert transpiled_ops[3].data == [param]
+ assert transpiled_ops[3].data == (param,)
assert transpiled_ops[3].wires == qml.wires.Wires([0, 1])
assert isinstance(transpiled_ops[4], qml.measurements.MeasurementProcess)
@@ -261,7 +261,7 @@ def circuit(param):
assert transpiled_ops[2].wires == qml.wires.Wires([1, 2])
assert isinstance(transpiled_ops[3], qml.MultiRZ)
- assert transpiled_ops[3].data == [param]
+ assert transpiled_ops[3].data == (param,)
assert transpiled_ops[3].wires == qml.wires.Wires([0, 1])
assert isinstance(transpiled_ops[4], qml.measurements.MeasurementProcess)