From 76203d4189e604959accc267d7f098384f88c0d4 Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Mon, 22 Jul 2024 17:28:26 +0200 Subject: [PATCH 01/52] some changes --- patata.py | 8 + pennylane/ops/qubit/state_preparation.py | 94 +++++++++--- pennylane/templates/embeddings/basis.py | 144 +----------------- tests/ops/qubit/test_state_prep.py | 20 +-- tests/templates/test_embeddings/test_basis.py | 6 +- 5 files changed, 96 insertions(+), 176 deletions(-) create mode 100644 patata.py diff --git a/patata.py b/patata.py new file mode 100644 index 00000000000..eba2e2211d4 --- /dev/null +++ b/patata.py @@ -0,0 +1,8 @@ +import pennylane as qml +import jax + +print("input", type(jax.numpy.array([1,0,0]))) +op = qml.BasisState(jax.numpy.array([1,0,0]), wires=range(3)) +print("output", type(op.state_vector())) + + diff --git a/pennylane/ops/qubit/state_preparation.py b/pennylane/ops/qubit/state_preparation.py index d7ae589e067..f971b21d9fc 100644 --- a/pennylane/ops/qubit/state_preparation.py +++ b/pennylane/ops/qubit/state_preparation.py @@ -17,7 +17,7 @@ """ # pylint:disable=abstract-method,arguments-differ,protected-access,no-member import numpy as np - +import pennylane as qml from pennylane import math from pennylane.operation import AnyWires, Operation, StatePrepBase from pennylane.templates.state_preparations import BasisStatePreparation, MottonenStatePreparation @@ -66,15 +66,46 @@ class BasisState(StatePrepBase): [0.+0.j 0.+0.j 0.+0.j 1.+0.j] """ - num_wires = AnyWires - num_params = 1 - """int: Number of trainable parameters that the operator depends on.""" - ndim_params = (1,) - """int: Number of dimensions per trainable parameter of the operator.""" + def __init__(self, features, wires, id=None): + if isinstance(features, list): + features = qml.math.stack(features) + + tracing = qml.math.is_abstract(features) + + if qml.math.shape(features) == (): + if not tracing and features >= 2 ** len(wires): + raise ValueError( + f"Features must be of length {len(wires)}, got features={features} which is >= {2 ** len(wires)}" + ) + bin = 2 ** math.arange(len(wires))[::-1] + features = qml.math.where((features & bin) > 0, 1, 0) + + wires = Wires(wires) + shape = qml.math.shape(features) + + if len(shape) != 1: + raise ValueError(f"Features must be one-dimensional; got shape {shape}.") + + n_features = shape[0] + if n_features != len(wires): + raise ValueError( + f"Features must be of length {len(wires)}; got length {n_features} (features={features})." + ) + + super().__init__(features, wires=wires, id=id) + + def _flatten(self): + features = self.parameters[0] + features = tuple(features) if isinstance(features, list) else features + return (features, ), (self.wires, ) + + @classmethod + def _unflatten(cls, data, metadata) -> "BasisState": + return cls(data[0], wires=metadata[0]) @staticmethod - def compute_decomposition(n, wires): + def compute_decomposition(features, wires): r"""Representation of the operator as a product of other operators (static method). : .. math:: O = O_1 O_2 \dots O_n. @@ -96,30 +127,58 @@ def compute_decomposition(n, wires): [BasisStatePreparation([1, 0], wires=[0, 1])] """ - return [BasisStatePreparation(n, wires)] + + if len(qml.math.shape(features)) > 1: + raise ValueError( + "Broadcasting with BasisStatePreparation is not supported. Please use the " + "qml.transforms.broadcast_expand transform to use broadcasting with " + "BasisStatePreparation." + ) + + if not qml.math.is_abstract(features): + op_list = [] + for wire, state in zip(wires, features): + if state == 1: + op_list.append(qml.X(wire)) + return op_list + + op_list = [] + for wire, state in zip(wires, features): + op_list.append(qml.PhaseShift(state * math.pi / 2, wire)) + op_list.append(qml.RX(state * math.pi, wire)) + op_list.append(qml.PhaseShift(state * math.pi / 2, wire)) + + return op_list def state_vector(self, wire_order=None): """Returns a statevector of shape ``(2,) * num_wires``.""" prep_vals = self.parameters[0] - if any(i not in [0, 1] for i in prep_vals): - raise ValueError("BasisState parameter must consist of 0 or 1 integers.") + if qml.math.shape(prep_vals) == (): + bin = 2 ** math.arange(len(self.wires))[::-1] + prep_vals = qml.math.where((prep_vals & bin) > 0, 1, 0) + + prep_vals_int = math.cast(prep_vals, int) - if (num_wires := len(self.wires)) != len(prep_vals): - raise ValueError("BasisState parameter and wires must be of equal length.") - prep_vals = math.cast(prep_vals, int) if wire_order is None: - indices = prep_vals + indices = prep_vals_int + num_wires = len(indices) else: if not Wires(wire_order).contains_wires(self.wires): raise WireError("Custom wire_order must contain all BasisState wires") num_wires = len(wire_order) indices = [0] * num_wires - for base_wire_label, value in zip(self.wires, prep_vals): + for base_wire_label, value in zip(self.wires, prep_vals_int): indices[wire_order.index(base_wire_label)] = value - ket = np.zeros((2,) * num_wires) - ket[tuple(indices)] = 1 + if qml.math.get_interface(prep_vals_int) == "jax": + ket = math.array(math.zeros((2,) * num_wires), like = "jax") + ket = ket.at[tuple(indices)].set(1) + + else: + ket = math.zeros((2,) * num_wires) + ket[tuple(indices)] = 1 + return math.convert_like(ket, prep_vals) @@ -184,6 +243,7 @@ def __init__(self, state, wires, id=None): if not math.allclose(norm, 1.0, atol=1e-10): raise ValueError("Sum of amplitudes-squared does not equal one.") + @staticmethod def compute_decomposition(state, wires): r"""Representation of the operator as a product of other operators (static method). : diff --git a/pennylane/templates/embeddings/basis.py b/pennylane/templates/embeddings/basis.py index 18175a8fd6a..38293881bc8 100644 --- a/pennylane/templates/embeddings/basis.py +++ b/pennylane/templates/embeddings/basis.py @@ -15,146 +15,10 @@ Contains the BasisEmbedding template. """ # pylint: disable-msg=too-many-branches,too-many-arguments,protected-access -import numpy as np -import pennylane as qml -from pennylane.operation import AnyWires, Operation -from pennylane.wires import Wires +from pennylane.ops.qubit.state_preparation import BasisState +# pylint: disable=missing-class-docstring +class BasisEmbedding(BasisState): + pass # BasisEmbedding is still available -class BasisEmbedding(Operation): - r"""Encodes :math:`n` binary features into a basis state of :math:`n` qubits. - - For example, for ``features=np.array([0, 1, 0])`` or ``features=2`` (binary 10), the - quantum system will be prepared in state :math:`|010 \rangle`. - - .. warning:: - - ``BasisEmbedding`` calls a circuit whose architecture depends on the binary features. - The ``features`` argument is therefore not differentiable when using the template, and - gradients with respect to the argument cannot be computed by PennyLane. - - Args: - features (tensor_like): binary input of shape ``(len(wires), )`` - wires (Any or Iterable[Any]): wires that the template acts on - - Example: - - Basis embedding encodes the binary feature vector into a basis state. - - .. code-block:: python - - dev = qml.device('default.qubit', wires=3) - - @qml.qnode(dev) - def circuit(feature_vector): - qml.BasisEmbedding(features=feature_vector, wires=range(3)) - return qml.state() - - X = [1,1,1] - - The resulting circuit is: - - >>> print(qml.draw(circuit, level="device")(X)) - 0: ──X─┤ State - 1: ──X─┤ State - 2: ──X─┤ State - - And, the output state is: - - >>> print(circuit(X)) - [0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 1.+0.j] - - Thus, ``[1,1,1]`` is mapped to :math:`|111 \rangle`. - - """ - - num_wires = AnyWires - grad_method = None - - def _flatten(self): - basis_state = self.hyperparameters["basis_state"] - basis_state = tuple(basis_state) if isinstance(basis_state, list) else basis_state - return tuple(), (self.wires, basis_state) - - @classmethod - def _unflatten(cls, _, metadata) -> "BasisEmbedding": - return cls(features=metadata[1], wires=metadata[0]) - - def __init__(self, features, wires, id=None): - if isinstance(features, list): - features = qml.math.stack(features) - - tracing = qml.math.is_abstract(features) - - if qml.math.shape(features) == (): - if not tracing and features >= 2 ** len(wires): - raise ValueError( - f"Features must be of length {len(wires)}, got features={features} which is >= {2 ** len(wires)}" - ) - bin = 2 ** np.arange(len(wires))[::-1] - features = qml.math.where((features & bin) > 0, 1, 0) - - wires = Wires(wires) - shape = qml.math.shape(features) - - if len(shape) != 1: - raise ValueError(f"Features must be one-dimensional; got shape {shape}.") - - n_features = shape[0] - if n_features != len(wires): - raise ValueError( - f"Features must be of length {len(wires)}; got length {n_features} (features={features})." - ) - - if not tracing: - features = list(qml.math.toarray(features)) - if not set(features).issubset({0, 1}): - raise ValueError(f"Basis state must only consist of 0s and 1s; got {features}") - - self._hyperparameters = {"basis_state": features} - - super().__init__(wires=wires, id=id) - - @property - def num_params(self): - return 0 - - @staticmethod - def compute_decomposition(wires, basis_state): # pylint: disable=arguments-differ - r"""Representation of the operator as a product of other operators. - - .. math:: O = O_1 O_2 \dots O_n. - - - - .. seealso:: :meth:`~.BasisEmbedding.decomposition`. - - Args: - features (tensor-like): binary input of shape ``(len(wires), )`` - wires (Any or Iterable[Any]): wires that the operator acts on - - Returns: - list[.Operator]: decomposition of the operator - - **Example** - - >>> features = torch.tensor([1, 0, 1]) - >>> qml.BasisEmbedding.compute_decomposition(features, wires=["a", "b", "c"]) - [X('a'), - X('c')] - """ - if not qml.math.is_abstract(basis_state): - ops_list = [] - for wire, bit in zip(wires, basis_state): - if bit == 1: - ops_list.append(qml.X(wire)) - return ops_list - - ops_list = [] - for wire, state in zip(wires, basis_state): - ops_list.append(qml.PhaseShift(state * np.pi / 2, wire)) - ops_list.append(qml.RX(state * np.pi, wire)) - ops_list.append(qml.PhaseShift(state * np.pi / 2, wire)) - - return ops_list diff --git a/tests/ops/qubit/test_state_prep.py b/tests/ops/qubit/test_state_prep.py index 3dfc49a0d43..621e9419e16 100644 --- a/tests/ops/qubit/test_state_prep.py +++ b/tests/ops/qubit/test_state_prep.py @@ -26,7 +26,7 @@ @pytest.mark.parametrize( "op", [ - qml.BasisState(np.array([0, 1]), wires=0), + qml.BasisState(np.array([0, 1]), wires=[0,1]), qml.StatePrep(np.array([1.0, 0.0]), wires=0), qml.QubitDensityMatrix(densitymat0, wires=0), ], @@ -34,6 +34,7 @@ def test_adjoint_error_exception(op): with pytest.raises(qml.operation.AdjointUndefinedError): op.adjoint() + @pytest.mark.parametrize( @@ -66,8 +67,6 @@ def test_BasisState_decomposition(self): ops2 = qml.BasisState(n, wires=wires).decomposition() assert len(ops1) == len(ops2) == 1 - assert isinstance(ops1[0], qml.BasisStatePreparation) - assert isinstance(ops2[0], qml.BasisStatePreparation) def test_StatePrep_decomposition(self): """Test the decomposition for StatePrep.""" @@ -351,18 +350,9 @@ def test_BasisState_state_vector_bad_wire_order(self): with pytest.raises(WireError, match="wire_order must contain all BasisState wires"): basis_op.state_vector(wire_order=[1, 2]) - def test_BasisState_explicitly_checks_0_1(self): - """Tests that BasisState gives a clear error if a value other than 0 or 1 is given.""" - op = qml.BasisState([2, 1], wires=[0, 1]) - with pytest.raises( - ValueError, match="BasisState parameter must consist of 0 or 1 integers." - ): - _ = op.state_vector() def test_BasisState_wrong_param_size(self): """Tests that the parameter must be of length num_wires.""" - op = qml.BasisState([0], wires=[0, 1]) - with pytest.raises( - ValueError, match="BasisState parameter and wires must be of equal length." - ): - _ = op.state_vector() + + with pytest.raises(ValueError, match="The state parameter must be of length 2\*\*num_wires"): + _ = qml.BasisState([0], wires=[0, 1]) diff --git a/tests/templates/test_embeddings/test_basis.py b/tests/templates/test_embeddings/test_basis.py index 31bc736cff6..48461386ee9 100644 --- a/tests/templates/test_embeddings/test_basis.py +++ b/tests/templates/test_embeddings/test_basis.py @@ -34,9 +34,8 @@ def test_flatten_unflatten(): wires = qml.wires.Wires((0, 1, 2)) op = qml.BasisEmbedding(features=[1, 1, 1], wires=wires) data, metadata = op._flatten() - assert data == tuple() + assert np.allclose(data[0], [1, 1, 1]) assert metadata[0] == wires - assert metadata[1] == (1, 1, 1) # make sure metadata hashable assert hash(metadata) @@ -112,8 +111,7 @@ def test_features_as_int_conversion(self, feat, wires, expected): with length = len(wires)""" assert ( - qml.BasisEmbedding(features=feat, wires=wires).hyperparameters["basis_state"] - == expected + np.allclose(qml.BasisEmbedding(features=feat, wires=wires).parameters[0], expected) ) @pytest.mark.parametrize("x", [[0], [0, 1, 1], 4]) From d18d9ddc43299e4fc57ace34825a6ed564a2bdbc Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Mon, 22 Jul 2024 17:43:39 +0200 Subject: [PATCH 02/52] black --- pennylane/ops/qubit/state_preparation.py | 12 +++++++----- pennylane/templates/embeddings/basis.py | 4 ++-- tests/ops/qubit/test_state_prep.py | 9 ++++----- tests/templates/test_embeddings/test_basis.py | 4 +--- 4 files changed, 14 insertions(+), 15 deletions(-) diff --git a/pennylane/ops/qubit/state_preparation.py b/pennylane/ops/qubit/state_preparation.py index f971b21d9fc..cce5811ba5c 100644 --- a/pennylane/ops/qubit/state_preparation.py +++ b/pennylane/ops/qubit/state_preparation.py @@ -66,7 +66,6 @@ class BasisState(StatePrepBase): [0.+0.j 0.+0.j 0.+0.j 1.+0.j] """ - def __init__(self, features, wires, id=None): if isinstance(features, list): features = qml.math.stack(features) @@ -93,12 +92,17 @@ def __init__(self, features, wires, id=None): f"Features must be of length {len(wires)}; got length {n_features} (features={features})." ) + if not tracing: + features_list = list(qml.math.toarray(features)) + if not set(features_list).issubset({0, 1}): + raise ValueError(f"Basis state must only consist of 0s and 1s; got {features_list}") + super().__init__(features, wires=wires, id=id) def _flatten(self): features = self.parameters[0] features = tuple(features) if isinstance(features, list) else features - return (features, ), (self.wires, ) + return (features,), (self.wires,) @classmethod def _unflatten(cls, data, metadata) -> "BasisState": @@ -159,7 +163,6 @@ def state_vector(self, wire_order=None): prep_vals_int = math.cast(prep_vals, int) - if wire_order is None: indices = prep_vals_int num_wires = len(indices) @@ -172,7 +175,7 @@ def state_vector(self, wire_order=None): indices[wire_order.index(base_wire_label)] = value if qml.math.get_interface(prep_vals_int) == "jax": - ket = math.array(math.zeros((2,) * num_wires), like = "jax") + ket = math.array(math.zeros((2,) * num_wires), like="jax") ket = ket.at[tuple(indices)].set(1) else: @@ -243,7 +246,6 @@ def __init__(self, state, wires, id=None): if not math.allclose(norm, 1.0, atol=1e-10): raise ValueError("Sum of amplitudes-squared does not equal one.") - @staticmethod def compute_decomposition(state, wires): r"""Representation of the operator as a product of other operators (static method). : diff --git a/pennylane/templates/embeddings/basis.py b/pennylane/templates/embeddings/basis.py index 38293881bc8..d1bd1d30b3f 100644 --- a/pennylane/templates/embeddings/basis.py +++ b/pennylane/templates/embeddings/basis.py @@ -18,7 +18,7 @@ from pennylane.ops.qubit.state_preparation import BasisState + # pylint: disable=missing-class-docstring class BasisEmbedding(BasisState): - pass # BasisEmbedding is still available - + pass # BasisEmbedding is still available diff --git a/tests/ops/qubit/test_state_prep.py b/tests/ops/qubit/test_state_prep.py index 621e9419e16..670c60bd495 100644 --- a/tests/ops/qubit/test_state_prep.py +++ b/tests/ops/qubit/test_state_prep.py @@ -26,7 +26,7 @@ @pytest.mark.parametrize( "op", [ - qml.BasisState(np.array([0, 1]), wires=[0,1]), + qml.BasisState(np.array([0, 1]), wires=[0, 1]), qml.StatePrep(np.array([1.0, 0.0]), wires=0), qml.QubitDensityMatrix(densitymat0, wires=0), ], @@ -34,7 +34,6 @@ def test_adjoint_error_exception(op): with pytest.raises(qml.operation.AdjointUndefinedError): op.adjoint() - @pytest.mark.parametrize( @@ -350,9 +349,9 @@ def test_BasisState_state_vector_bad_wire_order(self): with pytest.raises(WireError, match="wire_order must contain all BasisState wires"): basis_op.state_vector(wire_order=[1, 2]) - def test_BasisState_wrong_param_size(self): """Tests that the parameter must be of length num_wires.""" - - with pytest.raises(ValueError, match="The state parameter must be of length 2\*\*num_wires"): + with pytest.raises( + ValueError, match="Features must be of length 2; got length 1 \(features=\[0\]\)." + ): _ = qml.BasisState([0], wires=[0, 1]) diff --git a/tests/templates/test_embeddings/test_basis.py b/tests/templates/test_embeddings/test_basis.py index 48461386ee9..de84de18a10 100644 --- a/tests/templates/test_embeddings/test_basis.py +++ b/tests/templates/test_embeddings/test_basis.py @@ -110,9 +110,7 @@ def test_features_as_int_conversion(self, feat, wires, expected): """checks conversion from features as int to a list of binary digits with length = len(wires)""" - assert ( - np.allclose(qml.BasisEmbedding(features=feat, wires=wires).parameters[0], expected) - ) + assert np.allclose(qml.BasisEmbedding(features=feat, wires=wires).parameters[0], expected) @pytest.mark.parametrize("x", [[0], [0, 1, 1], 4]) def test_wrong_input_bits_exception(self, x): From 63d219be882140b2ef78b882a6bb4c39bec10017 Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Mon, 22 Jul 2024 17:47:01 +0200 Subject: [PATCH 03/52] remove patata.py --- patata.py | 8 -------- pennylane/ops/qubit/state_preparation.py | 2 +- 2 files changed, 1 insertion(+), 9 deletions(-) delete mode 100644 patata.py diff --git a/patata.py b/patata.py deleted file mode 100644 index eba2e2211d4..00000000000 --- a/patata.py +++ /dev/null @@ -1,8 +0,0 @@ -import pennylane as qml -import jax - -print("input", type(jax.numpy.array([1,0,0]))) -op = qml.BasisState(jax.numpy.array([1,0,0]), wires=range(3)) -print("output", type(op.state_vector())) - - diff --git a/pennylane/ops/qubit/state_preparation.py b/pennylane/ops/qubit/state_preparation.py index cce5811ba5c..30bc732e988 100644 --- a/pennylane/ops/qubit/state_preparation.py +++ b/pennylane/ops/qubit/state_preparation.py @@ -20,7 +20,7 @@ import pennylane as qml from pennylane import math from pennylane.operation import AnyWires, Operation, StatePrepBase -from pennylane.templates.state_preparations import BasisStatePreparation, MottonenStatePreparation +from pennylane.templates.state_preparations import MottonenStatePreparation from pennylane.wires import WireError, Wires state_prep_ops = {"BasisState", "StatePrep", "QubitDensityMatrix"} From 16d039e4e29cb06fc737cc98d348c93af69ca727 Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Mon, 22 Jul 2024 18:56:42 +0200 Subject: [PATCH 04/52] updating some tests --- tests/devices/test_default_qubit_tf.py | 5 +++-- tests/devices/test_default_qubit_torch.py | 5 +++-- tests/tape/test_qscript.py | 2 +- tests/tape/test_tape.py | 13 ++++++------- 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/tests/devices/test_default_qubit_tf.py b/tests/devices/test_default_qubit_tf.py index 6c4ef169e23..468c5979e53 100644 --- a/tests/devices/test_default_qubit_tf.py +++ b/tests/devices/test_default_qubit_tf.py @@ -295,7 +295,8 @@ def test_invalid_basis_state_length(self): state = np.array([0, 0, 1, 0]) with pytest.raises( - ValueError, match=r"BasisState parameter and wires must be of equal length" + ValueError, + match=r"Features must be of length 3; got length 4 \(features=tensor\(\[0, 0, 1, 0\]\)\)", ): dev.apply([qml.BasisState(state, wires=[0, 1, 2])]) @@ -305,7 +306,7 @@ def test_invalid_basis_state(self): state = np.array([0, 0, 1, 2]) with pytest.raises( - ValueError, match=r"BasisState parameter must consist of 0 or 1 integers" + ValueError, match=r"Basis state must only consist of 0s and 1s; got \[0, 0, 1, 2\]" ): dev.apply([qml.BasisState(state, wires=[0, 1, 2, 3])]) diff --git a/tests/devices/test_default_qubit_torch.py b/tests/devices/test_default_qubit_torch.py index 3a132070038..91f9b810ce9 100644 --- a/tests/devices/test_default_qubit_torch.py +++ b/tests/devices/test_default_qubit_torch.py @@ -258,7 +258,8 @@ def test_invalid_basis_state_length(self, device, torch_device): state = torch.tensor([0, 0, 1, 0]) with pytest.raises( - ValueError, match=r"BasisState parameter and wires must be of equal length" + ValueError, + match=r"Features must be of length 3; got length 4 \(features=tensor\(\[0, 0, 1, 0\]\)\)", ): dev.apply([qml.BasisState(state, wires=[0, 1, 2])]) @@ -268,7 +269,7 @@ def test_invalid_basis_state(self, device, torch_device): state = torch.tensor([0, 0, 1, 2]) with pytest.raises( - ValueError, match=r"BasisState parameter must consist of 0 or 1 integers" + ValueError, match=r"Basis state must only consist of 0s and 1s; got \[0, 0, 1, 2\]" ): dev.apply([qml.BasisState(state, wires=[0, 1, 2, 3])]) diff --git a/tests/tape/test_qscript.py b/tests/tape/test_qscript.py index f72b9f98651..bcafc1da65d 100644 --- a/tests/tape/test_qscript.py +++ b/tests/tape/test_qscript.py @@ -641,7 +641,7 @@ def test_deep_copy(self): def test_adjoint(): """Tests taking the adjoint of a quantum script.""" ops = [ - qml.BasisState([1, 1], wires=0), + qml.BasisState([1, 1], wires=[0, 1]), qml.RX(1.2, wires=0), qml.S(0), qml.CNOT((0, 1)), diff --git a/tests/tape/test_tape.py b/tests/tape/test_tape.py index b2c70265b91..9873f545bff 100644 --- a/tests/tape/test_tape.py +++ b/tests/tape/test_tape.py @@ -896,8 +896,7 @@ def test_decomposition_removing_parameters(self): with QuantumTape() as tape: qml.BasisState(np.array([1]), wires=0) - # since expansion calls `BasisStatePreparation` we have to expand twice - new_tape = tape.expand(depth=2) + new_tape = tape.expand(depth=1) assert len(new_tape.operations) == 1 assert new_tape.operations[0].name == "PauliX" @@ -958,7 +957,8 @@ def test_nesting_and_decomposition(self): qml.probs(wires="a") new_tape = tape.expand() - assert len(new_tape.operations) == 4 + + assert len(new_tape.operations) == 5 assert new_tape.shots is tape.shots def test_stopping_criterion(self): @@ -991,7 +991,7 @@ def test_depth_expansion(self): qml.probs(wires=0) qml.probs(wires="a") - new_tape = tape.expand(depth=3) + new_tape = tape.expand(depth=2) assert len(new_tape.operations) == 11 @pytest.mark.parametrize("skip_first", (True, False)) @@ -1005,7 +1005,7 @@ def test_depth_expansion(self): qml.PauliZ(0), ], [ - qml.BasisStatePreparation([1, 0], wires=[0, 1]), + qml.PauliX(0), qml.MottonenStatePreparation([0, 1, 0, 0], wires=[0, 1]), qml.StatePrep([0, 1, 0, 0], wires=[0, 1]), # still a StatePrepBase :/ qml.PauliZ(0), @@ -1034,7 +1034,6 @@ def test_expansion_state_prep(self, skip_first, op, decomp): true_decomposition += [ qml.PauliZ(wires=0), qml.Rot(0.1, 0.2, 0.3, wires=0), - qml.BasisStatePreparation([0], wires=[1]), qml.MottonenStatePreparation([0, 1], wires=[0]), ] @@ -1079,7 +1078,7 @@ def test_measurement_expansion(self): new_tape = tape.expand(expand_measurements=True) - assert len(new_tape.operations) == 5 + assert len(new_tape.operations) == 6 expected = [ qml.measurements.Probability, From 8127a7a03caf76d66c8903f9ac6d9bab4f67ff83 Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Mon, 22 Jul 2024 19:52:01 +0200 Subject: [PATCH 05/52] some changes --- tests/devices/test_default_qubit_tf.py | 2 +- tests/optimize/test_spsa.py | 5 ++++- tests/templates/test_subroutines/test_all_singles_doubles.py | 2 +- tests/templates/test_subroutines/test_uccsd.py | 2 +- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/tests/devices/test_default_qubit_tf.py b/tests/devices/test_default_qubit_tf.py index 468c5979e53..7cbc3356480 100644 --- a/tests/devices/test_default_qubit_tf.py +++ b/tests/devices/test_default_qubit_tf.py @@ -296,7 +296,7 @@ def test_invalid_basis_state_length(self): with pytest.raises( ValueError, - match=r"Features must be of length 3; got length 4 \(features=tensor\(\[0, 0, 1, 0\]\)\)", + match=r"Features must be of length 3; got length 4 \(features=\[0 0 1 0\]\)", ): dev.apply([qml.BasisState(state, wires=[0, 1, 2])]) diff --git a/tests/optimize/test_spsa.py b/tests/optimize/test_spsa.py index 01726f843f1..e1d7e9ae2cb 100644 --- a/tests/optimize/test_spsa.py +++ b/tests/optimize/test_spsa.py @@ -457,7 +457,8 @@ def test_lighting_device_legacy_opmath(self): @qml.qnode(dev) def cost_fun(params, num_qubits=1): - qml.BasisState([1, 1, 0, 0], wires=range(num_qubits)) + print(num_qubits, "1111") + qml.BasisState([1, 1, 0, 0], wires=range(4)) for i in range(num_qubits): qml.Rot(*params[i], wires=0) qml.CNOT(wires=[2, 3]) @@ -473,7 +474,9 @@ def cost_fun(params, num_qubits=1): max_iterations = 100 opt = qml.SPSAOptimizer(maxiter=max_iterations) for _ in range(max_iterations): + print("dentro") params, energy = opt.step_and_cost(cost_fun, params, num_qubits=num_qubits) + print("fuera") assert np.all(params != init_params) assert energy < init_energy diff --git a/tests/templates/test_subroutines/test_all_singles_doubles.py b/tests/templates/test_subroutines/test_all_singles_doubles.py index 7d20863135d..cefd663d2a8 100644 --- a/tests/templates/test_subroutines/test_all_singles_doubles.py +++ b/tests/templates/test_subroutines/test_all_singles_doubles.py @@ -206,7 +206,7 @@ class TestInputs: [[0, 2]], [[0, 1, 2, 3]], np.array([1, 1, 0, 0, 0]), - "Basis states must be of length 4", + "Features must be of length 4", ), ( np.array([-2.8, 1.6]), diff --git a/tests/templates/test_subroutines/test_uccsd.py b/tests/templates/test_subroutines/test_uccsd.py index f335851bdd6..6a28d3f29fc 100644 --- a/tests/templates/test_subroutines/test_uccsd.py +++ b/tests/templates/test_subroutines/test_uccsd.py @@ -291,7 +291,7 @@ class TestInputs: [], np.array([1, 1, 0, 0, 0]), 1, - "Basis states must be of length 4", + "Features must be of length 4", ), ( np.array([-2.8, 1.6]), From 049f3a359bab9ab319bf37a462c328af04e8e5eb Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Tue, 23 Jul 2024 10:11:37 +0200 Subject: [PATCH 06/52] check tets --- pennylane/optimize/spsa.py | 2 +- tests/optimize/test_spsa.py | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/pennylane/optimize/spsa.py b/pennylane/optimize/spsa.py index e44784f7245..5a29c3b3884 100644 --- a/pennylane/optimize/spsa.py +++ b/pennylane/optimize/spsa.py @@ -270,7 +270,7 @@ def compute_grad(self, objective_fn, args, kwargs): shots = Shots(objective_fn.device._raw_shot_sequence) # pragma: no cover else: shots = Shots(None) - if np.prod(objective_fn.func(*args).shape(objective_fn.device, shots)) > 1: + if np.prod(objective_fn.func(*args, **kwargs).shape(objective_fn.device, shots)) > 1: raise ValueError( "The objective function must be a scalar function for the gradient " "to be computed." diff --git a/tests/optimize/test_spsa.py b/tests/optimize/test_spsa.py index e1d7e9ae2cb..01726f843f1 100644 --- a/tests/optimize/test_spsa.py +++ b/tests/optimize/test_spsa.py @@ -457,8 +457,7 @@ def test_lighting_device_legacy_opmath(self): @qml.qnode(dev) def cost_fun(params, num_qubits=1): - print(num_qubits, "1111") - qml.BasisState([1, 1, 0, 0], wires=range(4)) + qml.BasisState([1, 1, 0, 0], wires=range(num_qubits)) for i in range(num_qubits): qml.Rot(*params[i], wires=0) qml.CNOT(wires=[2, 3]) @@ -474,9 +473,7 @@ def cost_fun(params, num_qubits=1): max_iterations = 100 opt = qml.SPSAOptimizer(maxiter=max_iterations) for _ in range(max_iterations): - print("dentro") params, energy = opt.step_and_cost(cost_fun, params, num_qubits=num_qubits) - print("fuera") assert np.all(params != init_params) assert energy < init_energy From db9e453c5e1aa7a4db36a6a85a0f803c56b75c95 Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Tue, 23 Jul 2024 12:34:55 +0200 Subject: [PATCH 07/52] Update test_default_qubit_legacy.py --- tests/devices/test_default_qubit_legacy.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/devices/test_default_qubit_legacy.py b/tests/devices/test_default_qubit_legacy.py index ec9fd6e65f5..9cf9c51c11a 100644 --- a/tests/devices/test_default_qubit_legacy.py +++ b/tests/devices/test_default_qubit_legacy.py @@ -650,13 +650,14 @@ def test_apply_errors_qubit_state_vector(self, qubit_device_2_wires): ) def test_apply_errors_basis_state(self, qubit_device_2_wires): + with pytest.raises( - ValueError, match="BasisState parameter must consist of 0 or 1 integers." + ValueError, match=r"Basis state must only consist of 0s and 1s; got \[-0\.2, 4\.2\]" ): qubit_device_2_wires.apply([qml.BasisState(np.array([-0.2, 4.2]), wires=[0, 1])]) with pytest.raises( - ValueError, match="BasisState parameter and wires must be of equal length." + ValueError, match=r"Features must be of length 1; got length 2 \(features=\[0 1\]\)\." ): qubit_device_2_wires.apply([qml.BasisState(np.array([0, 1]), wires=[0])]) From 773e459676d77907142d3c916d7118c94bb0439d Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Tue, 23 Jul 2024 12:37:01 +0200 Subject: [PATCH 08/52] Update test_state_prep.py --- tests/ops/qubit/test_state_prep.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ops/qubit/test_state_prep.py b/tests/ops/qubit/test_state_prep.py index 670c60bd495..1ab7632c353 100644 --- a/tests/ops/qubit/test_state_prep.py +++ b/tests/ops/qubit/test_state_prep.py @@ -352,6 +352,6 @@ def test_BasisState_state_vector_bad_wire_order(self): def test_BasisState_wrong_param_size(self): """Tests that the parameter must be of length num_wires.""" with pytest.raises( - ValueError, match="Features must be of length 2; got length 1 \(features=\[0\]\)." + ValueError, match=r"Features must be of length 2; got length 1 \(features=\[0\]\)." ): _ = qml.BasisState([0], wires=[0, 1]) From e60d3f0459fce80f9aaafe30033a886fad6ad804 Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Tue, 23 Jul 2024 14:30:42 +0200 Subject: [PATCH 09/52] solving bugs --- pennylane/ops/qubit/state_preparation.py | 21 ++++++++++--------- tests/templates/test_embeddings/test_basis.py | 19 +++++++++-------- .../test_basis_state_prep.py | 8 ++----- 3 files changed, 23 insertions(+), 25 deletions(-) diff --git a/pennylane/ops/qubit/state_preparation.py b/pennylane/ops/qubit/state_preparation.py index 30bc732e988..74c0bd3cae4 100644 --- a/pennylane/ops/qubit/state_preparation.py +++ b/pennylane/ops/qubit/state_preparation.py @@ -17,6 +17,7 @@ """ # pylint:disable=abstract-method,arguments-differ,protected-access,no-member import numpy as np + import pennylane as qml from pennylane import math from pennylane.operation import AnyWires, Operation, StatePrepBase @@ -97,6 +98,13 @@ def __init__(self, features, wires, id=None): if not set(features_list).issubset({0, 1}): raise ValueError(f"Basis state must only consist of 0s and 1s; got {features_list}") + if len(qml.math.shape(features)) > 1: + raise ValueError( + "Broadcasting with BasisState is not supported. Please use the " + "qml.transforms.broadcast_expand transform to use broadcasting with " + "BasisState." + ) + super().__init__(features, wires=wires, id=id) def _flatten(self): @@ -132,13 +140,6 @@ def compute_decomposition(features, wires): """ - if len(qml.math.shape(features)) > 1: - raise ValueError( - "Broadcasting with BasisStatePreparation is not supported. Please use the " - "qml.transforms.broadcast_expand transform to use broadcasting with " - "BasisStatePreparation." - ) - if not qml.math.is_abstract(features): op_list = [] for wire, state in zip(wires, features): @@ -148,9 +149,9 @@ def compute_decomposition(features, wires): op_list = [] for wire, state in zip(wires, features): - op_list.append(qml.PhaseShift(state * math.pi / 2, wire)) - op_list.append(qml.RX(state * math.pi, wire)) - op_list.append(qml.PhaseShift(state * math.pi / 2, wire)) + op_list.append(qml.PhaseShift(state * np.pi / 2, wire)) + op_list.append(qml.RX(state * np.pi, wire)) + op_list.append(qml.PhaseShift(state * np.pi / 2, wire)) return op_list diff --git a/tests/templates/test_embeddings/test_basis.py b/tests/templates/test_embeddings/test_basis.py index de84de18a10..bd07bd3df0b 100644 --- a/tests/templates/test_embeddings/test_basis.py +++ b/tests/templates/test_embeddings/test_basis.py @@ -241,19 +241,20 @@ def test_jax_jit(self, tol): features = jnp.array([0, 1, 0]) - dev = qml.device("default.qubit", wires=3) + for dev_name in ["default.qubit", "lightning.qubit"]: + dev = qml.device(dev_name, wires=3) - circuit = qml.QNode(circuit_template, dev) - circuit2 = qml.QNode(circuit_decomposed, dev) + circuit = qml.QNode(circuit_template, dev) + circuit2 = qml.QNode(circuit_decomposed, dev) - res = circuit(features) - res2 = circuit2(features) - assert qml.math.allclose(res, res2, atol=tol, rtol=0) + res = circuit(features) + res2 = circuit2(features) + assert qml.math.allclose(res, res2, atol=tol, rtol=0) - circuit = jax.jit(circuit) + circuit = jax.jit(circuit) - res = circuit(jnp.array(2)) - assert qml.math.allclose(res, res2, atol=tol, rtol=0) + res = circuit(jnp.array(2)) + assert qml.math.allclose(res, res2, atol=tol, rtol=0) @pytest.mark.tf def test_tf(self, tol): diff --git a/tests/templates/test_state_preparations/test_basis_state_prep.py b/tests/templates/test_state_preparations/test_basis_state_prep.py index 90b88463a05..63ae247c2f1 100644 --- a/tests/templates/test_state_preparations/test_basis_state_prep.py +++ b/tests/templates/test_state_preparations/test_basis_state_prep.py @@ -171,12 +171,8 @@ def test_batched_decomposition_fails(self): broadcasting raises an error.""" state = np.array([[1, 0], [1, 1]]) - op = qml.BasisStatePreparation(state, wires=[0, 1]) - with pytest.raises(ValueError, match="Broadcasting with BasisStatePreparation"): - _ = op.decomposition() - - with pytest.raises(ValueError, match="Broadcasting with BasisStatePreparation"): - _ = qml.BasisStatePreparation.compute_decomposition(state, qml.wires.Wires([0, 1])) + with pytest.raises(ValueError, match="Broadcasting with BasisState"): + _ = qml.BasisState(state, wires=[0, 1]) class TestInputs: From 8ebf75570b34894304076433eb3f8f35d8e669e0 Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Tue, 23 Jul 2024 16:58:26 +0200 Subject: [PATCH 10/52] spsa from master --- pennylane/ops/qubit/state_preparation.py | 7 ------- pennylane/optimize/spsa.py | 2 +- .../test_state_preparations/test_basis_state_prep.py | 2 +- 3 files changed, 2 insertions(+), 9 deletions(-) diff --git a/pennylane/ops/qubit/state_preparation.py b/pennylane/ops/qubit/state_preparation.py index 74c0bd3cae4..7778cbd6cea 100644 --- a/pennylane/ops/qubit/state_preparation.py +++ b/pennylane/ops/qubit/state_preparation.py @@ -98,13 +98,6 @@ def __init__(self, features, wires, id=None): if not set(features_list).issubset({0, 1}): raise ValueError(f"Basis state must only consist of 0s and 1s; got {features_list}") - if len(qml.math.shape(features)) > 1: - raise ValueError( - "Broadcasting with BasisState is not supported. Please use the " - "qml.transforms.broadcast_expand transform to use broadcasting with " - "BasisState." - ) - super().__init__(features, wires=wires, id=id) def _flatten(self): diff --git a/pennylane/optimize/spsa.py b/pennylane/optimize/spsa.py index 5a29c3b3884..e44784f7245 100644 --- a/pennylane/optimize/spsa.py +++ b/pennylane/optimize/spsa.py @@ -270,7 +270,7 @@ def compute_grad(self, objective_fn, args, kwargs): shots = Shots(objective_fn.device._raw_shot_sequence) # pragma: no cover else: shots = Shots(None) - if np.prod(objective_fn.func(*args, **kwargs).shape(objective_fn.device, shots)) > 1: + if np.prod(objective_fn.func(*args).shape(objective_fn.device, shots)) > 1: raise ValueError( "The objective function must be a scalar function for the gradient " "to be computed." diff --git a/tests/templates/test_state_preparations/test_basis_state_prep.py b/tests/templates/test_state_preparations/test_basis_state_prep.py index 63ae247c2f1..20545da872c 100644 --- a/tests/templates/test_state_preparations/test_basis_state_prep.py +++ b/tests/templates/test_state_preparations/test_basis_state_prep.py @@ -171,7 +171,7 @@ def test_batched_decomposition_fails(self): broadcasting raises an error.""" state = np.array([[1, 0], [1, 1]]) - with pytest.raises(ValueError, match="Broadcasting with BasisState"): + with pytest.raises(ValueError, match="Features must be one-dimensional"): _ = qml.BasisState(state, wires=[0, 1]) From 3c4465ac1f2efb7bd5790bb981b5a6adcb5c9553 Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Tue, 23 Jul 2024 18:32:25 +0200 Subject: [PATCH 11/52] [skip-ci] [skip-ci] --- pennylane/ops/qubit/state_preparation.py | 3 +- pennylane/templates/embeddings/basis.py | 47 +++++++++++++++++++++++- 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/pennylane/ops/qubit/state_preparation.py b/pennylane/ops/qubit/state_preparation.py index 7778cbd6cea..bc2c8f9ea30 100644 --- a/pennylane/ops/qubit/state_preparation.py +++ b/pennylane/ops/qubit/state_preparation.py @@ -28,7 +28,7 @@ class BasisState(StatePrepBase): - r"""BasisState(n, wires) + r"""BasisState(features, wires) Prepares a single computational basis state. **Details:** @@ -68,6 +68,7 @@ class BasisState(StatePrepBase): """ def __init__(self, features, wires, id=None): + if isinstance(features, list): features = qml.math.stack(features) diff --git a/pennylane/templates/embeddings/basis.py b/pennylane/templates/embeddings/basis.py index d1bd1d30b3f..1e9c41eced2 100644 --- a/pennylane/templates/embeddings/basis.py +++ b/pennylane/templates/embeddings/basis.py @@ -21,4 +21,49 @@ # pylint: disable=missing-class-docstring class BasisEmbedding(BasisState): - pass # BasisEmbedding is still available + r"""Encodes :math:`n` binary features into a basis state of :math:`n` qubits. + + For example, for ``features=np.array([0, 1, 0])`` or ``features=2`` (binary 010), the + quantum system will be prepared in state :math:`|010 \rangle`. + + .. warning:: + + ``BasisEmbedding`` calls a circuit whose architecture depends on the binary features. + The ``features`` argument is therefore not differentiable when using the template, and + gradients with respect to the argument cannot be computed by PennyLane. + + Args: + features (tensor_like or int): binary input of shape ``(len(wires), )`` or integer + that represents the binary input. + wires (Any or Iterable[Any]): wires that the template acts on + + Example: + + Basis embedding encodes the binary feature vector into a basis state. + + .. code-block:: python + + dev = qml.device('default.qubit', wires=3) + + @qml.qnode(dev) + def circuit(feature_vector): + qml.BasisEmbedding(features=feature_vector, wires=range(3)) + return qml.state() + + X = [1,1,1] + + The resulting circuit is: + + >>> print(qml.draw(circuit, level="device")(X)) + 0: ──X─┤ State + 1: ──X─┤ State + 2: ──X─┤ State + + And, the output state is: + + >>> print(circuit(X)) + [0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 1.+0.j] + + Thus, ``[1,1,1]`` is mapped to :math:`|111 \rangle`. + + """ From 989aa11c014fecc3d1794b5f4716d9c26bc9d2f2 Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Wed, 24 Jul 2024 12:26:19 +0200 Subject: [PATCH 12/52] fix pylint --- pennylane/ops/qubit/state_preparation.py | 4 ---- pennylane/templates/embeddings/basis.py | 3 ++- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/pennylane/ops/qubit/state_preparation.py b/pennylane/ops/qubit/state_preparation.py index bc2c8f9ea30..2abd5e746b3 100644 --- a/pennylane/ops/qubit/state_preparation.py +++ b/pennylane/ops/qubit/state_preparation.py @@ -152,10 +152,6 @@ def compute_decomposition(features, wires): def state_vector(self, wire_order=None): """Returns a statevector of shape ``(2,) * num_wires``.""" prep_vals = self.parameters[0] - if qml.math.shape(prep_vals) == (): - bin = 2 ** math.arange(len(self.wires))[::-1] - prep_vals = qml.math.where((prep_vals & bin) > 0, 1, 0) - prep_vals_int = math.cast(prep_vals, int) if wire_order is None: diff --git a/pennylane/templates/embeddings/basis.py b/pennylane/templates/embeddings/basis.py index 1e9c41eced2..619a894ab10 100644 --- a/pennylane/templates/embeddings/basis.py +++ b/pennylane/templates/embeddings/basis.py @@ -66,4 +66,5 @@ def circuit(feature_vector): Thus, ``[1,1,1]`` is mapped to :math:`|111 \rangle`. - """ + """ + pass From 99603ec5c6bc5f59a1dfb2dda1e2c72b5c119bb1 Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Wed, 24 Jul 2024 14:46:15 +0200 Subject: [PATCH 13/52] Update basis.py --- pennylane/templates/embeddings/basis.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pennylane/templates/embeddings/basis.py b/pennylane/templates/embeddings/basis.py index 619a894ab10..65fdf8a0342 100644 --- a/pennylane/templates/embeddings/basis.py +++ b/pennylane/templates/embeddings/basis.py @@ -67,4 +67,3 @@ def circuit(feature_vector): Thus, ``[1,1,1]`` is mapped to :math:`|111 \rangle`. """ - pass From fe36eb22050c0f017405964427d281f9822393c9 Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Wed, 24 Jul 2024 15:46:31 +0200 Subject: [PATCH 14/52] Update basis.py --- pennylane/templates/embeddings/basis.py | 56 ++++++++++++------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/pennylane/templates/embeddings/basis.py b/pennylane/templates/embeddings/basis.py index 65fdf8a0342..7688d508c82 100644 --- a/pennylane/templates/embeddings/basis.py +++ b/pennylane/templates/embeddings/basis.py @@ -23,47 +23,47 @@ class BasisEmbedding(BasisState): r"""Encodes :math:`n` binary features into a basis state of :math:`n` qubits. - For example, for ``features=np.array([0, 1, 0])`` or ``features=2`` (binary 010), the - quantum system will be prepared in state :math:`|010 \rangle`. + For example, for ``features=np.array([0, 1, 0])`` or ``features=2`` (binary 010), the + quantum system will be prepared in state :math:`|010 \rangle`. - .. warning:: + .. warning:: - ``BasisEmbedding`` calls a circuit whose architecture depends on the binary features. - The ``features`` argument is therefore not differentiable when using the template, and - gradients with respect to the argument cannot be computed by PennyLane. + ``BasisEmbedding`` calls a circuit whose architecture depends on the binary features. + The ``features`` argument is therefore not differentiable when using the template, and + gradients with respect to the argument cannot be computed by PennyLane. - Args: - features (tensor_like or int): binary input of shape ``(len(wires), )`` or integer - that represents the binary input. - wires (Any or Iterable[Any]): wires that the template acts on + Args: + features (tensor_like or int): binary input of shape ``(len(wires), )`` or integer + that represents the binary input. + wires (Any or Iterable[Any]): wires that the template acts on - Example: + Example: - Basis embedding encodes the binary feature vector into a basis state. + Basis embedding encodes the binary feature vector into a basis state. - .. code-block:: python + .. code-block:: python - dev = qml.device('default.qubit', wires=3) + dev = qml.device('default.qubit', wires=3) - @qml.qnode(dev) - def circuit(feature_vector): - qml.BasisEmbedding(features=feature_vector, wires=range(3)) - return qml.state() + @qml.qnode(dev) + def circuit(feature_vector): + qml.BasisEmbedding(features=feature_vector, wires=range(3)) + return qml.state() - X = [1,1,1] + X = [1,1,1] - The resulting circuit is: + The resulting circuit is: - >>> print(qml.draw(circuit, level="device")(X)) - 0: ──X─┤ State - 1: ──X─┤ State - 2: ──X─┤ State + >>> print(qml.draw(circuit, level="device")(X)) + 0: ──X─┤ State + 1: ──X─┤ State + 2: ──X─┤ State - And, the output state is: + And, the output state is: - >>> print(circuit(X)) - [0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 1.+0.j] + >>> print(circuit(X)) + [0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 1.+0.j] - Thus, ``[1,1,1]`` is mapped to :math:`|111 \rangle`. + Thus, ``[1,1,1]`` is mapped to :math:`|111 \rangle`. """ From 5f8ba56ee47099e353ebbd4dfa9c97baa16a2b34 Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Wed, 24 Jul 2024 18:28:36 +0200 Subject: [PATCH 15/52] deprecating basisstateprep --- doc/development/deprecations.rst | 6 ++++++ doc/releases/changelog-dev.md | 14 +++++++++++++- pennylane/ops/qubit/state_preparation.py | 2 +- pennylane/templates/state_preparations/basis.py | 10 ++++++++++ tests/ops/qubit/test_state_prep.py | 4 ++++ tests/test_qnode.py | 4 ++-- tests/test_qnode_legacy.py | 4 ++-- 7 files changed, 38 insertions(+), 6 deletions(-) diff --git a/doc/development/deprecations.rst b/doc/development/deprecations.rst index b45525a08b4..328e3111cb8 100644 --- a/doc/development/deprecations.rst +++ b/doc/development/deprecations.rst @@ -63,6 +63,12 @@ Pending deprecations - Deprecated in v0.37 - Will be removed in v0.39 +* The ``BasisStatePreparation`` template is deprecated. + Instead, ``BasisState`` can be called on the constructed operator. + + - Deprecated in v0.38 + - Will be removed in v0.39 + New operator arithmetic deprecations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/doc/releases/changelog-dev.md b/doc/releases/changelog-dev.md index b4e808eb0cb..6aee3253cbb 100644 --- a/doc/releases/changelog-dev.md +++ b/doc/releases/changelog-dev.md @@ -122,6 +122,10 @@ Instead, use `pennylane.gradients.classical_fisher` and `pennylane.gradients.quantum_fisher`. [(#5985)](https://github.com/PennyLaneAI/pennylane/pull/5985) +* The ``BasisStatePreparation`` template is deprecated. + Instead, ``BasisState`` can be called on the constructed operator. + [(#6021)](https://github.com/PennyLaneAI/pennylane/pull/6021) +

Documentation 📝

* Improves the docstring for `QuantumScript.expand` and `qml.tape.tape.expand_tape`. @@ -146,8 +150,16 @@ [(#5978)](https://github.com/PennyLaneAI/pennylane/pull/5978) * `qml.AmplitudeEmbedding` has better support for features using low precision integer data types. -[(#5969)](https://github.com/PennyLaneAI/pennylane/pull/5969) + [(#5969)](https://github.com/PennyLaneAI/pennylane/pull/5969) + +* `qml.BasisState` now works with jax.jit. + [(#6021)](https://github.com/PennyLaneAI/pennylane/pull/6021) + +* `qml.BasisEmbedding` now gives the correct decomposition. + [(#6021)](https://github.com/PennyLaneAI/pennylane/pull/6021) +* `qml.BasisEmbedding` now works with lightning.qubit and jax.jit. + [(#6021)](https://github.com/PennyLaneAI/pennylane/pull/6021)

Contributors ✍️

diff --git a/pennylane/ops/qubit/state_preparation.py b/pennylane/ops/qubit/state_preparation.py index 2abd5e746b3..ae1ef379faf 100644 --- a/pennylane/ops/qubit/state_preparation.py +++ b/pennylane/ops/qubit/state_preparation.py @@ -130,7 +130,7 @@ def compute_decomposition(features, wires): **Example:** >>> qml.BasisState.compute_decomposition([1,0], wires=(0,1)) - [BasisStatePreparation([1, 0], wires=[0, 1])] + [X(0)] """ diff --git a/pennylane/templates/state_preparations/basis.py b/pennylane/templates/state_preparations/basis.py index 48211a6d1e8..3109999667d 100644 --- a/pennylane/templates/state_preparations/basis.py +++ b/pennylane/templates/state_preparations/basis.py @@ -16,6 +16,7 @@ """ import numpy as np +import warnings import pennylane as qml from pennylane.operation import AnyWires, Operation @@ -30,6 +31,8 @@ class BasisStatePreparation(Operation): ``basis_state`` influences the circuit architecture and is therefore incompatible with gradient computations. + ``BasisStatePreparation`` is deprecated and will be removed in version 0.39. Instead, please use ``BasisState``." + Args: basis_state (array): Input array of shape ``(n,)``, where n is the number of wires the state preparation acts on. @@ -59,6 +62,13 @@ def circuit(basis_state): ndim_params = (1,) def __init__(self, basis_state, wires, id=None): + + warnings.warn( + "BasisStatePreparation is deprecated and will be removed in version 0.39. " + "Instead, please use BasisState.", + qml.PennyLaneDeprecationWarning, + ) + basis_state = qml.math.stack(basis_state) # check if the `basis_state` param is batched diff --git a/tests/ops/qubit/test_state_prep.py b/tests/ops/qubit/test_state_prep.py index 1ab7632c353..0e87a337ffe 100644 --- a/tests/ops/qubit/test_state_prep.py +++ b/tests/ops/qubit/test_state_prep.py @@ -35,6 +35,10 @@ def test_adjoint_error_exception(op): with pytest.raises(qml.operation.AdjointUndefinedError): op.adjoint() +def test_BasisStatePreparation_is_deprecated(): + """Test that my_feature is deprecated.""" + with pytest.warns(qml.PennyLaneDeprecationWarning, match="BasisStatePreparation is deprecated"): + _ = qml.BasisStatePreparation() @pytest.mark.parametrize( "op, mat, base", diff --git a/tests/test_qnode.py b/tests/test_qnode.py index 71e99e705ac..a3a1f241280 100644 --- a/tests/test_qnode.py +++ b/tests/test_qnode.py @@ -958,7 +958,7 @@ def test_sampling_with_mcm(self, basis_state, mocker): @qml.qnode(dev) def cry_qnode(x): """QNode where we apply a controlled Y-rotation.""" - qml.BasisStatePreparation(basis_state, wires=[0, 1]) + qml.BasisState(basis_state, wires=[0, 1]) qml.CRY(x, wires=[0, 1]) return qml.sample(qml.PauliZ(1)) @@ -966,7 +966,7 @@ def cry_qnode(x): def conditional_ry_qnode(x): """QNode where the defer measurements transform is applied by default under the hood.""" - qml.BasisStatePreparation(basis_state, wires=[0, 1]) + qml.BasisState(basis_state, wires=[0, 1]) m_0 = qml.measure(0) qml.cond(m_0, qml.RY)(x, wires=1) return qml.sample(qml.PauliZ(1)) diff --git a/tests/test_qnode_legacy.py b/tests/test_qnode_legacy.py index 91fa971a430..4cb220cc2be 100644 --- a/tests/test_qnode_legacy.py +++ b/tests/test_qnode_legacy.py @@ -1149,7 +1149,7 @@ def test_sampling_with_mcm(self, basis_state, mocker): @qml.qnode(dev) def cry_qnode(x): """QNode where we apply a controlled Y-rotation.""" - qml.BasisStatePreparation(basis_state, wires=[0, 1]) + qml.BasisState(basis_state, wires=[0, 1]) qml.CRY(x, wires=[0, 1]) return qml.sample(qml.PauliZ(1)) @@ -1157,7 +1157,7 @@ def cry_qnode(x): def conditional_ry_qnode(x): """QNode where the defer measurements transform is applied by default under the hood.""" - qml.BasisStatePreparation(basis_state, wires=[0, 1]) + qml.BasisState(basis_state, wires=[0, 1]) m_0 = qml.measure(0) qml.cond(m_0, qml.RY)(x, wires=1) return qml.sample(qml.PauliZ(1)) From 94ca8bfef5348b8c2549b5e1848724b689cba879 Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Wed, 24 Jul 2024 18:31:27 +0200 Subject: [PATCH 16/52] Update basis.py --- pennylane/templates/state_preparations/basis.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pennylane/templates/state_preparations/basis.py b/pennylane/templates/state_preparations/basis.py index 3109999667d..017d11c5297 100644 --- a/pennylane/templates/state_preparations/basis.py +++ b/pennylane/templates/state_preparations/basis.py @@ -15,8 +15,8 @@ Contains the BasisStatePreparation template. """ -import numpy as np import warnings +import numpy as np import pennylane as qml from pennylane.operation import AnyWires, Operation From 3e5e25026bad6bc2e23bbb78dcc36a15ae3326c6 Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Thu, 25 Jul 2024 09:19:34 +0200 Subject: [PATCH 17/52] warning deprecated --- pennylane/devices/tests/test_templates.py | 8 ++ tests/capture/test_templates.py | 6 +- .../test_basis_state_prep.py | 89 +++++++++++++++++++ tests/transforms/test_batch_input.py | 7 ++ tests/transforms/test_batch_params.py | 7 ++ tests/transforms/test_defer_measurements.py | 8 ++ 6 files changed, 122 insertions(+), 3 deletions(-) diff --git a/pennylane/devices/tests/test_templates.py b/pennylane/devices/tests/test_templates.py index 07b0b56b39c..64e656f2069 100644 --- a/pennylane/devices/tests/test_templates.py +++ b/pennylane/devices/tests/test_templates.py @@ -225,6 +225,14 @@ def circuit(): [math.fidelity_statevector(circuit(), exp_state)], [1.0], atol=tol(dev.shots) ) + @pytest.fixture(scope="function", autouse=True) + def capture_warnings(self, recwarn): + yield + if len(recwarn) > 0: + for w in recwarn: + assert isinstance(w.message, qml.PennyLaneDeprecationWarning) + assert "BasisStatePreparation is deprecated" in str(w.message) + def test_BasisStatePreparation(self, device, tol): """Test the BasisStatePreparation template.""" dev = device(4) diff --git a/tests/capture/test_templates.py b/tests/capture/test_templates.py index afc66e6c5ab..58f8b1ee56c 100644 --- a/tests/capture/test_templates.py +++ b/tests/capture/test_templates.py @@ -116,9 +116,9 @@ def enable_disable_plxpr(): (qml.ArbitraryStatePreparation, (jnp.ones(6), [2, 3]), {}), (qml.ArbitraryStatePreparation, (jnp.zeros(14),), {"wires": [3, 2, 0]}), (qml.ArbitraryStatePreparation, (), {"weights": jnp.ones(2), "wires": [1]}), - (qml.BasisStatePreparation, (jnp.array([0, 1]), [2, 3]), {}), - (qml.BasisStatePreparation, (jnp.ones(3),), {"wires": [3, 2, 0]}), - (qml.BasisStatePreparation, (), {"basis_state": jnp.ones(1), "wires": [1]}), + #(qml.BasisStatePreparation, (jnp.array([0, 1]), [2, 3]), {}), + #(qml.BasisStatePreparation, (jnp.ones(3),), {"wires": [3, 2, 0]}), + #(qml.BasisStatePreparation, (), {"basis_state": jnp.ones(1), "wires": [1]}), (qml.CosineWindow, ([2, 3],), {}), (qml.CosineWindow, (), {"wires": [2, 0, 1]}), (qml.MottonenStatePreparation, (jnp.ones(4) / 2, [2, 3]), {}), diff --git a/tests/templates/test_state_preparations/test_basis_state_prep.py b/tests/templates/test_state_preparations/test_basis_state_prep.py index 20545da872c..4565a8997a8 100644 --- a/tests/templates/test_state_preparations/test_basis_state_prep.py +++ b/tests/templates/test_state_preparations/test_basis_state_prep.py @@ -22,6 +22,15 @@ import pennylane as qml +@pytest.fixture(scope="function", autouse=True) +def capture_warnings(recwarn): + yield + if len(recwarn) > 0: + for w in recwarn: + assert isinstance(w.message, qml.PennyLaneDeprecationWarning) + assert "BasisStatePreparation is deprecated" in str(w.message) + + def test_standard_validity(): """Check the operation using the assert_valid function.""" @@ -36,6 +45,14 @@ def test_standard_validity(): class TestDecomposition: """Tests that the template defines the correct decomposition.""" + @pytest.fixture(scope="function", autouse=True) + def capture_warnings(self, recwarn): + yield + if len(recwarn) > 0: + for w in recwarn: + assert isinstance(w.message, qml.PennyLaneDeprecationWarning) + assert "BasisStatePreparation is deprecated" in str(w.message) + # fmt: off @pytest.mark.parametrize("basis_state,wires,target_wires", [ ([0], [0], []), @@ -61,6 +78,14 @@ def test_correct_pl_gates(self, basis_state, wires, target_wires): assert gate.name == "PauliX" assert gate.wires.tolist() == [target_wires[id]] + @pytest.fixture(scope="function", autouse=True) + def capture_warnings(self, recwarn): + yield + if len(recwarn) > 0: + for w in recwarn: + assert isinstance(w.message, qml.PennyLaneDeprecationWarning) + assert "BasisStatePreparation is deprecated" in str(w.message) + # fmt: off @pytest.mark.parametrize("basis_state,wires,target_state", [ ([0], [0], [0, 0, 0]), @@ -90,6 +115,14 @@ def circuit(): assert np.allclose(output_state, target_state, atol=tol, rtol=0) + @pytest.fixture(scope="function", autouse=True) + def capture_warnings(self, recwarn): + yield + if len(recwarn) > 0: + for w in recwarn: + assert isinstance(w.message, qml.PennyLaneDeprecationWarning) + assert "BasisStatePreparation is deprecated" in str(w.message) + @pytest.mark.jax @pytest.mark.parametrize( "basis_state,wires,target_state", @@ -117,6 +150,14 @@ def circuit(state): assert np.allclose(output_state, target_state, atol=tol, rtol=0) + @pytest.fixture(scope="function", autouse=True) + def capture_warnings(self, recwarn): + yield + if len(recwarn) > 0: + for w in recwarn: + assert isinstance(w.message, qml.PennyLaneDeprecationWarning) + assert "BasisStatePreparation is deprecated" in str(w.message) + @pytest.mark.tf @pytest.mark.parametrize( "basis_state,wires,target_state", @@ -143,6 +184,14 @@ def circuit(state): assert np.allclose(output_state, target_state, atol=tol, rtol=0) + @pytest.fixture(scope="function", autouse=True) + def capture_warnings(self, recwarn): + yield + if len(recwarn) > 0: + for w in recwarn: + assert isinstance(w.message, qml.PennyLaneDeprecationWarning) + assert "BasisStatePreparation is deprecated" in str(w.message) + def test_custom_wire_labels(self, tol): """Test that template can deal with non-numeric, nonconsecutive wire labels.""" basis_state = [0, 1, 0] @@ -166,6 +215,14 @@ def circuit2(): assert np.allclose(res1, res2, atol=tol, rtol=0) assert np.allclose(state1, state2, atol=tol, rtol=0) + @pytest.fixture(scope="function", autouse=True) + def capture_warnings(self, recwarn): + yield + if len(recwarn) > 0: + for w in recwarn: + assert isinstance(w.message, qml.PennyLaneDeprecationWarning) + assert "BasisStatePreparation is deprecated" in str(w.message) + def test_batched_decomposition_fails(self): """Test that attempting to decompose a BasisStatePreparation operation with broadcasting raises an error.""" @@ -178,6 +235,14 @@ def test_batched_decomposition_fails(self): class TestInputs: """Test inputs and pre-processing.""" + @pytest.fixture(scope="function", autouse=True) + def capture_warnings(self, recwarn): + yield + if len(recwarn) > 0: + for w in recwarn: + assert isinstance(w.message, qml.PennyLaneDeprecationWarning) + assert "BasisStatePreparation is deprecated" in str(w.message) + # fmt: off @pytest.mark.parametrize("basis_state,wires", [ ([0], [0, 1]), @@ -191,6 +256,14 @@ def test_error_num_qubits(self, basis_state, wires): with pytest.raises(ValueError, match="Basis states must be of (shape|length)"): qml.BasisStatePreparation(basis_state, wires) + @pytest.fixture(scope="function", autouse=True) + def capture_warnings(self, recwarn): + yield + if len(recwarn) > 0: + for w in recwarn: + assert isinstance(w.message, qml.PennyLaneDeprecationWarning) + assert "BasisStatePreparation is deprecated" in str(w.message) + # fmt: off @pytest.mark.parametrize("basis_state,wires", [ ([3], [0]), @@ -204,6 +277,14 @@ def test_error_basis_state_format(self, basis_state, wires): with pytest.raises(ValueError, match="Basis states must only (contain|consist)"): qml.BasisStatePreparation(basis_state, wires) + @pytest.fixture(scope="function", autouse=True) + def capture_warnings(self, recwarn): + yield + if len(recwarn) > 0: + for w in recwarn: + assert isinstance(w.message, qml.PennyLaneDeprecationWarning) + assert "BasisStatePreparation is deprecated" in str(w.message) + def test_exception_wrong_dim(self): """Verifies that exception is raised if the number of dimensions of features is incorrect.""" @@ -226,6 +307,14 @@ def circuit(basis_state): basis_state = np.array([0, 2]) circuit(basis_state) + @pytest.fixture(scope="function", autouse=True) + def capture_warnings(self, recwarn): + yield + if len(recwarn) > 0: + for w in recwarn: + assert isinstance(w.message, qml.PennyLaneDeprecationWarning) + assert "BasisStatePreparation is deprecated" in str(w.message) + def test_id(self): """Tests that the id attribute can be set.""" template = qml.BasisStatePreparation(np.array([0, 1]), wires=[0, 1], id="a") diff --git a/tests/transforms/test_batch_input.py b/tests/transforms/test_batch_input.py index 3d97e981ed2..b68d2d2a443 100644 --- a/tests/transforms/test_batch_input.py +++ b/tests/transforms/test_batch_input.py @@ -199,6 +199,13 @@ def circuit2(data, weights): indiv_res.append(circuit2(state, weights)) assert np.allclose(res, indiv_res) +@pytest.fixture(scope="function", autouse=True) + def capture_warnings(self, recwarn): + yield + if len(recwarn) > 0: + for w in recwarn: + assert isinstance(w.message, qml.PennyLaneDeprecationWarning) + assert "BasisStatePreparation is deprecated" in str(w.message) def test_basis_state_preparation(mocker): """Test that batching works for BasisStatePreparation""" diff --git a/tests/transforms/test_batch_params.py b/tests/transforms/test_batch_params.py index ad4daddeb69..0a193a4f901 100644 --- a/tests/transforms/test_batch_params.py +++ b/tests/transforms/test_batch_params.py @@ -173,6 +173,13 @@ def circuit2(data, weights): indiv_res.append(circuit2(state, weight)) assert np.allclose(res, indiv_res) +@pytest.fixture(scope="function", autouse=True) + def capture_warnings(self, recwarn): + yield + if len(recwarn) > 0: + for w in recwarn: + assert isinstance(w.message, qml.PennyLaneDeprecationWarning) + assert "BasisStatePreparation is deprecated" in str(w.message) def test_basis_state_preparation(mocker): """Test that batching works for BasisStatePreparation""" diff --git a/tests/transforms/test_defer_measurements.py b/tests/transforms/test_defer_measurements.py index 3d5e98791ea..fb604fb84dc 100644 --- a/tests/transforms/test_defer_measurements.py +++ b/tests/transforms/test_defer_measurements.py @@ -1347,6 +1347,14 @@ def quantum_control_circuit(rads): class TestTemplates: """Tests templates being conditioned on mid-circuit measurement outcomes.""" + @pytest.fixture(scope="function", autouse=True) + def capture_warnings(self, recwarn): + yield + if len(recwarn) > 0: + for w in recwarn: + assert isinstance(w.message, qml.PennyLaneDeprecationWarning) + assert "BasisStatePreparation is deprecated" in str(w.message) + def test_basis_state_prep(self): """Test the basis state prep template conditioned on mid-circuit measurement outcomes.""" From 9ee26bcc9d25640b4b34a745af5e75f661cd9d87 Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Thu, 25 Jul 2024 10:18:34 +0200 Subject: [PATCH 18/52] Update test_templates.py --- pennylane/devices/tests/test_templates.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pennylane/devices/tests/test_templates.py b/pennylane/devices/tests/test_templates.py index 64e656f2069..47dccc97da0 100644 --- a/pennylane/devices/tests/test_templates.py +++ b/pennylane/devices/tests/test_templates.py @@ -227,6 +227,7 @@ def circuit(): @pytest.fixture(scope="function", autouse=True) def capture_warnings(self, recwarn): + """Capture warnings.""" yield if len(recwarn) > 0: for w in recwarn: From 7ed2fd92e813bc8856d2f69557a098dc6f44b864 Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Thu, 25 Jul 2024 10:48:32 +0200 Subject: [PATCH 19/52] test correct --- tests/transforms/test_batch_input.py | 12 ++++++------ tests/transforms/test_batch_params.py | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/tests/transforms/test_batch_input.py b/tests/transforms/test_batch_input.py index b68d2d2a443..6c6bdf1b8c8 100644 --- a/tests/transforms/test_batch_input.py +++ b/tests/transforms/test_batch_input.py @@ -200,12 +200,12 @@ def circuit2(data, weights): assert np.allclose(res, indiv_res) @pytest.fixture(scope="function", autouse=True) - def capture_warnings(self, recwarn): - yield - if len(recwarn) > 0: - for w in recwarn: - assert isinstance(w.message, qml.PennyLaneDeprecationWarning) - assert "BasisStatePreparation is deprecated" in str(w.message) +def capture_warnings(self, recwarn): + yield + if len(recwarn) > 0: + for w in recwarn: + assert isinstance(w.message, qml.PennyLaneDeprecationWarning) + assert "BasisStatePreparation is deprecated" in str(w.message) def test_basis_state_preparation(mocker): """Test that batching works for BasisStatePreparation""" diff --git a/tests/transforms/test_batch_params.py b/tests/transforms/test_batch_params.py index 0a193a4f901..418124ab22d 100644 --- a/tests/transforms/test_batch_params.py +++ b/tests/transforms/test_batch_params.py @@ -174,12 +174,12 @@ def circuit2(data, weights): assert np.allclose(res, indiv_res) @pytest.fixture(scope="function", autouse=True) - def capture_warnings(self, recwarn): - yield - if len(recwarn) > 0: - for w in recwarn: - assert isinstance(w.message, qml.PennyLaneDeprecationWarning) - assert "BasisStatePreparation is deprecated" in str(w.message) +def capture_warnings(recwarn): + yield + if len(recwarn) > 0: + for w in recwarn: + assert isinstance(w.message, qml.PennyLaneDeprecationWarning) + assert "BasisStatePreparation is deprecated" in str(w.message) def test_basis_state_preparation(mocker): """Test that batching works for BasisStatePreparation""" From cc3e25b529f5443101a787a038e9c45217d01a7f Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Thu, 25 Jul 2024 11:07:24 +0200 Subject: [PATCH 20/52] Update test_batch_input.py --- tests/transforms/test_batch_input.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/transforms/test_batch_input.py b/tests/transforms/test_batch_input.py index 6c6bdf1b8c8..c88f50180b0 100644 --- a/tests/transforms/test_batch_input.py +++ b/tests/transforms/test_batch_input.py @@ -200,7 +200,7 @@ def circuit2(data, weights): assert np.allclose(res, indiv_res) @pytest.fixture(scope="function", autouse=True) -def capture_warnings(self, recwarn): +def capture_warnings(recwarn): yield if len(recwarn) > 0: for w in recwarn: From f2f3efc9bb2aa7e6700ee2ab288957b5af037137 Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Thu, 25 Jul 2024 12:15:21 +0200 Subject: [PATCH 21/52] commit --- tests/capture/test_templates.py | 6 +++--- tests/ops/qubit/test_state_prep.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/capture/test_templates.py b/tests/capture/test_templates.py index 58f8b1ee56c..afc66e6c5ab 100644 --- a/tests/capture/test_templates.py +++ b/tests/capture/test_templates.py @@ -116,9 +116,9 @@ def enable_disable_plxpr(): (qml.ArbitraryStatePreparation, (jnp.ones(6), [2, 3]), {}), (qml.ArbitraryStatePreparation, (jnp.zeros(14),), {"wires": [3, 2, 0]}), (qml.ArbitraryStatePreparation, (), {"weights": jnp.ones(2), "wires": [1]}), - #(qml.BasisStatePreparation, (jnp.array([0, 1]), [2, 3]), {}), - #(qml.BasisStatePreparation, (jnp.ones(3),), {"wires": [3, 2, 0]}), - #(qml.BasisStatePreparation, (), {"basis_state": jnp.ones(1), "wires": [1]}), + (qml.BasisStatePreparation, (jnp.array([0, 1]), [2, 3]), {}), + (qml.BasisStatePreparation, (jnp.ones(3),), {"wires": [3, 2, 0]}), + (qml.BasisStatePreparation, (), {"basis_state": jnp.ones(1), "wires": [1]}), (qml.CosineWindow, ([2, 3],), {}), (qml.CosineWindow, (), {"wires": [2, 0, 1]}), (qml.MottonenStatePreparation, (jnp.ones(4) / 2, [2, 3]), {}), diff --git a/tests/ops/qubit/test_state_prep.py b/tests/ops/qubit/test_state_prep.py index 0e87a337ffe..870c2bad8a6 100644 --- a/tests/ops/qubit/test_state_prep.py +++ b/tests/ops/qubit/test_state_prep.py @@ -38,7 +38,7 @@ def test_adjoint_error_exception(op): def test_BasisStatePreparation_is_deprecated(): """Test that my_feature is deprecated.""" with pytest.warns(qml.PennyLaneDeprecationWarning, match="BasisStatePreparation is deprecated"): - _ = qml.BasisStatePreparation() + _ = qml.BasisStatePreparation([1,0], wires = [0,1]) @pytest.mark.parametrize( "op, mat, base", From a7ad726094ea19ce58f62eae78b7c760af0cbad6 Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Thu, 25 Jul 2024 12:49:09 +0200 Subject: [PATCH 22/52] Update test_templates.py --- tests/capture/test_templates.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/capture/test_templates.py b/tests/capture/test_templates.py index afc66e6c5ab..14b15a46415 100644 --- a/tests/capture/test_templates.py +++ b/tests/capture/test_templates.py @@ -189,6 +189,13 @@ def enable_disable_plxpr(): ), ] +@pytest.fixture(scope="function", autouse=True) +def capture_warnings(recwarn): + yield + if len(recwarn) > 0: + for w in recwarn: + assert isinstance(w.message, qml.PennyLaneDeprecationWarning) + assert "BasisStatePreparation is deprecated" in str(w.message) @pytest.mark.parametrize("template, args, kwargs", unmodified_templates_cases) def test_unmodified_templates(template, args, kwargs): From 2b6b670cf3b94c18bde175be11e07940f6101aa8 Mon Sep 17 00:00:00 2001 From: Guillermo Alonso-Linaje <65235481+KetpuntoG@users.noreply.github.com> Date: Mon, 12 Aug 2024 12:55:23 +0200 Subject: [PATCH 23/52] Update doc/development/deprecations.rst Co-authored-by: Isaac De Vlugt <34751083+isaacdevlugt@users.noreply.github.com> --- doc/development/deprecations.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/development/deprecations.rst b/doc/development/deprecations.rst index e69cb20af29..0f78979333e 100644 --- a/doc/development/deprecations.rst +++ b/doc/development/deprecations.rst @@ -80,7 +80,7 @@ Pending deprecations - Will be removed in v0.39 * The ``BasisStatePreparation`` template is deprecated. - Instead, ``BasisState`` can be called on the constructed operator. + Instead, use ``BasisState``. - Deprecated in v0.38 - Will be removed in v0.39 From 461454a9c508197cce0c11d01dcc2e25c37ffa03 Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Mon, 12 Aug 2024 13:30:36 +0200 Subject: [PATCH 24/52] Update test_basis_state_prep.py --- .../test_basis_state_prep.py | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/tests/templates/test_state_preparations/test_basis_state_prep.py b/tests/templates/test_state_preparations/test_basis_state_prep.py index 4565a8997a8..119463775c1 100644 --- a/tests/templates/test_state_preparations/test_basis_state_prep.py +++ b/tests/templates/test_state_preparations/test_basis_state_prep.py @@ -23,7 +23,7 @@ @pytest.fixture(scope="function", autouse=True) -def capture_warnings(recwarn): +def capture_warnings(recwarn): # pylint: disable=function-redefined yield if len(recwarn) > 0: for w in recwarn: @@ -46,7 +46,7 @@ class TestDecomposition: """Tests that the template defines the correct decomposition.""" @pytest.fixture(scope="function", autouse=True) - def capture_warnings(self, recwarn): + def capture_warnings(self, recwarn): # pylint: disable=function-redefined yield if len(recwarn) > 0: for w in recwarn: @@ -79,7 +79,7 @@ def test_correct_pl_gates(self, basis_state, wires, target_wires): assert gate.wires.tolist() == [target_wires[id]] @pytest.fixture(scope="function", autouse=True) - def capture_warnings(self, recwarn): + def capture_warnings(self, recwarn): # pylint: disable=function-redefined yield if len(recwarn) > 0: for w in recwarn: @@ -116,7 +116,7 @@ def circuit(): assert np.allclose(output_state, target_state, atol=tol, rtol=0) @pytest.fixture(scope="function", autouse=True) - def capture_warnings(self, recwarn): + def capture_warnings(self, recwarn): # pylint: disable=function-redefined yield if len(recwarn) > 0: for w in recwarn: @@ -151,7 +151,7 @@ def circuit(state): assert np.allclose(output_state, target_state, atol=tol, rtol=0) @pytest.fixture(scope="function", autouse=True) - def capture_warnings(self, recwarn): + def capture_warnings(self, recwarn): # pylint: disable=function-redefined yield if len(recwarn) > 0: for w in recwarn: @@ -185,7 +185,7 @@ def circuit(state): assert np.allclose(output_state, target_state, atol=tol, rtol=0) @pytest.fixture(scope="function", autouse=True) - def capture_warnings(self, recwarn): + def capture_warnings(self, recwarn): # pylint: disable=function-redefined yield if len(recwarn) > 0: for w in recwarn: @@ -216,7 +216,7 @@ def circuit2(): assert np.allclose(state1, state2, atol=tol, rtol=0) @pytest.fixture(scope="function", autouse=True) - def capture_warnings(self, recwarn): + def capture_warnings(self, recwarn): # pylint: disable=function-redefined yield if len(recwarn) > 0: for w in recwarn: @@ -236,7 +236,7 @@ class TestInputs: """Test inputs and pre-processing.""" @pytest.fixture(scope="function", autouse=True) - def capture_warnings(self, recwarn): + def capture_warnings(self, recwarn): # pylint: disable=function-redefined yield if len(recwarn) > 0: for w in recwarn: @@ -257,7 +257,7 @@ def test_error_num_qubits(self, basis_state, wires): qml.BasisStatePreparation(basis_state, wires) @pytest.fixture(scope="function", autouse=True) - def capture_warnings(self, recwarn): + def capture_warnings(self, recwarn): # pylint: disable=function-redefined yield if len(recwarn) > 0: for w in recwarn: @@ -278,7 +278,7 @@ def test_error_basis_state_format(self, basis_state, wires): qml.BasisStatePreparation(basis_state, wires) @pytest.fixture(scope="function", autouse=True) - def capture_warnings(self, recwarn): + def capture_warnings(self, recwarn): # pylint: disable=function-redefined yield if len(recwarn) > 0: for w in recwarn: @@ -308,7 +308,7 @@ def circuit(basis_state): circuit(basis_state) @pytest.fixture(scope="function", autouse=True) - def capture_warnings(self, recwarn): + def capture_warnings(self, recwarn): # pylint: disable=function-redefined yield if len(recwarn) > 0: for w in recwarn: From 50d80853c0b5a97cb52fa31ebb1dcdbd85544735 Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Mon, 12 Aug 2024 13:41:20 +0200 Subject: [PATCH 25/52] docs --- pennylane/ops/qubit/state_preparation.py | 6 ++---- pennylane/templates/embeddings/basis.py | 2 +- pennylane/templates/state_preparations/basis.py | 2 +- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/pennylane/ops/qubit/state_preparation.py b/pennylane/ops/qubit/state_preparation.py index ae1ef379faf..2e5a0b110b3 100644 --- a/pennylane/ops/qubit/state_preparation.py +++ b/pennylane/ops/qubit/state_preparation.py @@ -35,7 +35,6 @@ class BasisState(StatePrepBase): * Number of wires: Any (the operation can act on any number of wires) * Number of parameters: 1 - * Gradient recipe: None (integer parameters not supported) .. note:: @@ -49,9 +48,8 @@ class BasisState(StatePrepBase): as :math:`U|0\rangle = |\psi\rangle` Args: - n (array): prepares the basis state :math:`\ket{n}`, where ``n`` is an - array of integers from the set :math:`\{0, 1\}`, i.e., - if ``n = np.array([0, 1, 0])``, prepares the state :math:`|010\rangle`. + features (tensor_like): binary input of shape ``(len(wires), )``. For example, for ``features=np.array([0, 1, 0])`` or ``features=2`` (binary 010), the quantum system will be prepared in state :math:`|010 \rangle`. + wires (Sequence[int] or int): the wire(s) the operation acts on id (str): custom label given to an operator instance, can be useful for some applications where the instance has to be identified. diff --git a/pennylane/templates/embeddings/basis.py b/pennylane/templates/embeddings/basis.py index 7688d508c82..5db190746fa 100644 --- a/pennylane/templates/embeddings/basis.py +++ b/pennylane/templates/embeddings/basis.py @@ -35,7 +35,7 @@ class BasisEmbedding(BasisState): Args: features (tensor_like or int): binary input of shape ``(len(wires), )`` or integer that represents the binary input. - wires (Any or Iterable[Any]): wires that the template acts on + wires (Any or Iterable[Any]): wires that the template acts on. Example: diff --git a/pennylane/templates/state_preparations/basis.py b/pennylane/templates/state_preparations/basis.py index 017d11c5297..ac99e26a5a4 100644 --- a/pennylane/templates/state_preparations/basis.py +++ b/pennylane/templates/state_preparations/basis.py @@ -31,7 +31,7 @@ class BasisStatePreparation(Operation): ``basis_state`` influences the circuit architecture and is therefore incompatible with gradient computations. - ``BasisStatePreparation`` is deprecated and will be removed in version 0.39. Instead, please use ``BasisState``." + ``BasisStatePreparation`` is deprecated and will be removed in version 0.39. Instead, please use ``BasisState``. Args: basis_state (array): Input array of shape ``(n,)``, where n is the number of wires From d1787c13a60bdb02ac94328da1e1813bffe10b17 Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Mon, 12 Aug 2024 14:03:52 +0200 Subject: [PATCH 26/52] black --- tests/capture/test_templates.py | 2 ++ tests/ops/qubit/test_state_prep.py | 4 +++- tests/transforms/test_batch_input.py | 2 ++ tests/transforms/test_batch_params.py | 2 ++ 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/tests/capture/test_templates.py b/tests/capture/test_templates.py index 14b15a46415..89b14da090e 100644 --- a/tests/capture/test_templates.py +++ b/tests/capture/test_templates.py @@ -189,6 +189,7 @@ def enable_disable_plxpr(): ), ] + @pytest.fixture(scope="function", autouse=True) def capture_warnings(recwarn): yield @@ -197,6 +198,7 @@ def capture_warnings(recwarn): assert isinstance(w.message, qml.PennyLaneDeprecationWarning) assert "BasisStatePreparation is deprecated" in str(w.message) + @pytest.mark.parametrize("template, args, kwargs", unmodified_templates_cases) def test_unmodified_templates(template, args, kwargs): """Test that templates with unmodified primitive binds are captured as expected.""" diff --git a/tests/ops/qubit/test_state_prep.py b/tests/ops/qubit/test_state_prep.py index 870c2bad8a6..c8465230eb7 100644 --- a/tests/ops/qubit/test_state_prep.py +++ b/tests/ops/qubit/test_state_prep.py @@ -35,10 +35,12 @@ def test_adjoint_error_exception(op): with pytest.raises(qml.operation.AdjointUndefinedError): op.adjoint() + def test_BasisStatePreparation_is_deprecated(): """Test that my_feature is deprecated.""" with pytest.warns(qml.PennyLaneDeprecationWarning, match="BasisStatePreparation is deprecated"): - _ = qml.BasisStatePreparation([1,0], wires = [0,1]) + _ = qml.BasisStatePreparation([1, 0], wires=[0, 1]) + @pytest.mark.parametrize( "op, mat, base", diff --git a/tests/transforms/test_batch_input.py b/tests/transforms/test_batch_input.py index c88f50180b0..ba10a5f1592 100644 --- a/tests/transforms/test_batch_input.py +++ b/tests/transforms/test_batch_input.py @@ -199,6 +199,7 @@ def circuit2(data, weights): indiv_res.append(circuit2(state, weights)) assert np.allclose(res, indiv_res) + @pytest.fixture(scope="function", autouse=True) def capture_warnings(recwarn): yield @@ -207,6 +208,7 @@ def capture_warnings(recwarn): assert isinstance(w.message, qml.PennyLaneDeprecationWarning) assert "BasisStatePreparation is deprecated" in str(w.message) + def test_basis_state_preparation(mocker): """Test that batching works for BasisStatePreparation""" dev = qml.device("default.qubit", wires=3) diff --git a/tests/transforms/test_batch_params.py b/tests/transforms/test_batch_params.py index 418124ab22d..e22c03c210a 100644 --- a/tests/transforms/test_batch_params.py +++ b/tests/transforms/test_batch_params.py @@ -173,6 +173,7 @@ def circuit2(data, weights): indiv_res.append(circuit2(state, weight)) assert np.allclose(res, indiv_res) + @pytest.fixture(scope="function", autouse=True) def capture_warnings(recwarn): yield @@ -181,6 +182,7 @@ def capture_warnings(recwarn): assert isinstance(w.message, qml.PennyLaneDeprecationWarning) assert "BasisStatePreparation is deprecated" in str(w.message) + def test_basis_state_preparation(mocker): """Test that batching works for BasisStatePreparation""" dev = qml.device("default.qubit", wires=4) From 032e0ae6220e33557bb778c4f66d3f0dfe2ccc00 Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Mon, 12 Aug 2024 14:20:01 +0200 Subject: [PATCH 27/52] isort --- patata.py | 3 +++ pennylane/templates/state_preparations/basis.py | 1 + 2 files changed, 4 insertions(+) create mode 100644 patata.py diff --git a/patata.py b/patata.py new file mode 100644 index 00000000000..be26a5f7850 --- /dev/null +++ b/patata.py @@ -0,0 +1,3 @@ +import pennylane as qml + +print(qml.BasisState.compute_decomposition([1,0], wires=(0,1))) \ No newline at end of file diff --git a/pennylane/templates/state_preparations/basis.py b/pennylane/templates/state_preparations/basis.py index ac99e26a5a4..d49a1cc81b9 100644 --- a/pennylane/templates/state_preparations/basis.py +++ b/pennylane/templates/state_preparations/basis.py @@ -16,6 +16,7 @@ """ import warnings + import numpy as np import pennylane as qml From bb65b87c09eebf84617b1873048a08a4eb8810e4 Mon Sep 17 00:00:00 2001 From: Guillermo Alonso-Linaje <65235481+KetpuntoG@users.noreply.github.com> Date: Mon, 12 Aug 2024 16:11:27 +0200 Subject: [PATCH 28/52] Delete patata.py --- patata.py | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 patata.py diff --git a/patata.py b/patata.py deleted file mode 100644 index be26a5f7850..00000000000 --- a/patata.py +++ /dev/null @@ -1,3 +0,0 @@ -import pennylane as qml - -print(qml.BasisState.compute_decomposition([1,0], wires=(0,1))) \ No newline at end of file From b650cbf4d2f9a9b24bc5eff3c0361cf7c5d97741 Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Tue, 13 Aug 2024 09:12:29 +0200 Subject: [PATCH 29/52] autouse False --- pennylane/devices/tests/test_templates.py | 2 +- tests/capture/test_templates.py | 2 +- .../test_basis_state_prep.py | 22 +++++++++---------- tests/transforms/test_batch_input.py | 2 +- tests/transforms/test_batch_params.py | 2 +- tests/transforms/test_defer_measurements.py | 2 +- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/pennylane/devices/tests/test_templates.py b/pennylane/devices/tests/test_templates.py index 47dccc97da0..a1292d1eed6 100644 --- a/pennylane/devices/tests/test_templates.py +++ b/pennylane/devices/tests/test_templates.py @@ -225,7 +225,7 @@ def circuit(): [math.fidelity_statevector(circuit(), exp_state)], [1.0], atol=tol(dev.shots) ) - @pytest.fixture(scope="function", autouse=True) + @pytest.fixture(scope="function", autouse=False) def capture_warnings(self, recwarn): """Capture warnings.""" yield diff --git a/tests/capture/test_templates.py b/tests/capture/test_templates.py index 89b14da090e..b770ebbc5f4 100644 --- a/tests/capture/test_templates.py +++ b/tests/capture/test_templates.py @@ -190,7 +190,7 @@ def enable_disable_plxpr(): ] -@pytest.fixture(scope="function", autouse=True) +@pytest.fixture(scope="function", autouse=False) def capture_warnings(recwarn): yield if len(recwarn) > 0: diff --git a/tests/templates/test_state_preparations/test_basis_state_prep.py b/tests/templates/test_state_preparations/test_basis_state_prep.py index 119463775c1..67d5489fa3b 100644 --- a/tests/templates/test_state_preparations/test_basis_state_prep.py +++ b/tests/templates/test_state_preparations/test_basis_state_prep.py @@ -22,7 +22,7 @@ import pennylane as qml -@pytest.fixture(scope="function", autouse=True) +@pytest.fixture(scope="function", autouse=False) def capture_warnings(recwarn): # pylint: disable=function-redefined yield if len(recwarn) > 0: @@ -45,7 +45,7 @@ def test_standard_validity(): class TestDecomposition: """Tests that the template defines the correct decomposition.""" - @pytest.fixture(scope="function", autouse=True) + @pytest.fixture(scope="function", autouse=False) def capture_warnings(self, recwarn): # pylint: disable=function-redefined yield if len(recwarn) > 0: @@ -78,7 +78,7 @@ def test_correct_pl_gates(self, basis_state, wires, target_wires): assert gate.name == "PauliX" assert gate.wires.tolist() == [target_wires[id]] - @pytest.fixture(scope="function", autouse=True) + @pytest.fixture(scope="function", autouse=False) def capture_warnings(self, recwarn): # pylint: disable=function-redefined yield if len(recwarn) > 0: @@ -115,7 +115,7 @@ def circuit(): assert np.allclose(output_state, target_state, atol=tol, rtol=0) - @pytest.fixture(scope="function", autouse=True) + @pytest.fixture(scope="function", autouse=False) def capture_warnings(self, recwarn): # pylint: disable=function-redefined yield if len(recwarn) > 0: @@ -150,7 +150,7 @@ def circuit(state): assert np.allclose(output_state, target_state, atol=tol, rtol=0) - @pytest.fixture(scope="function", autouse=True) + @pytest.fixture(scope="function", autouse=False) def capture_warnings(self, recwarn): # pylint: disable=function-redefined yield if len(recwarn) > 0: @@ -184,7 +184,7 @@ def circuit(state): assert np.allclose(output_state, target_state, atol=tol, rtol=0) - @pytest.fixture(scope="function", autouse=True) + @pytest.fixture(scope="function", autouse=False) def capture_warnings(self, recwarn): # pylint: disable=function-redefined yield if len(recwarn) > 0: @@ -215,7 +215,7 @@ def circuit2(): assert np.allclose(res1, res2, atol=tol, rtol=0) assert np.allclose(state1, state2, atol=tol, rtol=0) - @pytest.fixture(scope="function", autouse=True) + @pytest.fixture(scope="function", autouse=False) def capture_warnings(self, recwarn): # pylint: disable=function-redefined yield if len(recwarn) > 0: @@ -235,7 +235,7 @@ def test_batched_decomposition_fails(self): class TestInputs: """Test inputs and pre-processing.""" - @pytest.fixture(scope="function", autouse=True) + @pytest.fixture(scope="function", autouse=False) def capture_warnings(self, recwarn): # pylint: disable=function-redefined yield if len(recwarn) > 0: @@ -256,7 +256,7 @@ def test_error_num_qubits(self, basis_state, wires): with pytest.raises(ValueError, match="Basis states must be of (shape|length)"): qml.BasisStatePreparation(basis_state, wires) - @pytest.fixture(scope="function", autouse=True) + @pytest.fixture(scope="function", autouse=False) def capture_warnings(self, recwarn): # pylint: disable=function-redefined yield if len(recwarn) > 0: @@ -277,7 +277,7 @@ def test_error_basis_state_format(self, basis_state, wires): with pytest.raises(ValueError, match="Basis states must only (contain|consist)"): qml.BasisStatePreparation(basis_state, wires) - @pytest.fixture(scope="function", autouse=True) + @pytest.fixture(scope="function", autouse=False) def capture_warnings(self, recwarn): # pylint: disable=function-redefined yield if len(recwarn) > 0: @@ -307,7 +307,7 @@ def circuit(basis_state): basis_state = np.array([0, 2]) circuit(basis_state) - @pytest.fixture(scope="function", autouse=True) + @pytest.fixture(scope="function", autouse=False) def capture_warnings(self, recwarn): # pylint: disable=function-redefined yield if len(recwarn) > 0: diff --git a/tests/transforms/test_batch_input.py b/tests/transforms/test_batch_input.py index ba10a5f1592..369781796df 100644 --- a/tests/transforms/test_batch_input.py +++ b/tests/transforms/test_batch_input.py @@ -200,7 +200,7 @@ def circuit2(data, weights): assert np.allclose(res, indiv_res) -@pytest.fixture(scope="function", autouse=True) +@pytest.fixture(scope="function", autouse=False) def capture_warnings(recwarn): yield if len(recwarn) > 0: diff --git a/tests/transforms/test_batch_params.py b/tests/transforms/test_batch_params.py index e22c03c210a..6bc8411da1f 100644 --- a/tests/transforms/test_batch_params.py +++ b/tests/transforms/test_batch_params.py @@ -174,7 +174,7 @@ def circuit2(data, weights): assert np.allclose(res, indiv_res) -@pytest.fixture(scope="function", autouse=True) +@pytest.fixture(scope="function", autouse=False) def capture_warnings(recwarn): yield if len(recwarn) > 0: diff --git a/tests/transforms/test_defer_measurements.py b/tests/transforms/test_defer_measurements.py index fb604fb84dc..309e3bef85c 100644 --- a/tests/transforms/test_defer_measurements.py +++ b/tests/transforms/test_defer_measurements.py @@ -1347,7 +1347,7 @@ def quantum_control_circuit(rads): class TestTemplates: """Tests templates being conditioned on mid-circuit measurement outcomes.""" - @pytest.fixture(scope="function", autouse=True) + @pytest.fixture(scope="function", autouse=False) def capture_warnings(self, recwarn): yield if len(recwarn) > 0: From 448e36922305c939f4d28aa839ddcd7ed626d7ce Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Tue, 13 Aug 2024 09:42:39 +0200 Subject: [PATCH 30/52] only test_templates --- tests/capture/test_templates.py | 2 +- .../test_basis_state_prep.py | 22 +++++++++---------- tests/transforms/test_batch_input.py | 2 +- tests/transforms/test_batch_params.py | 2 +- tests/transforms/test_defer_measurements.py | 2 +- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/tests/capture/test_templates.py b/tests/capture/test_templates.py index b770ebbc5f4..89b14da090e 100644 --- a/tests/capture/test_templates.py +++ b/tests/capture/test_templates.py @@ -190,7 +190,7 @@ def enable_disable_plxpr(): ] -@pytest.fixture(scope="function", autouse=False) +@pytest.fixture(scope="function", autouse=True) def capture_warnings(recwarn): yield if len(recwarn) > 0: diff --git a/tests/templates/test_state_preparations/test_basis_state_prep.py b/tests/templates/test_state_preparations/test_basis_state_prep.py index 67d5489fa3b..119463775c1 100644 --- a/tests/templates/test_state_preparations/test_basis_state_prep.py +++ b/tests/templates/test_state_preparations/test_basis_state_prep.py @@ -22,7 +22,7 @@ import pennylane as qml -@pytest.fixture(scope="function", autouse=False) +@pytest.fixture(scope="function", autouse=True) def capture_warnings(recwarn): # pylint: disable=function-redefined yield if len(recwarn) > 0: @@ -45,7 +45,7 @@ def test_standard_validity(): class TestDecomposition: """Tests that the template defines the correct decomposition.""" - @pytest.fixture(scope="function", autouse=False) + @pytest.fixture(scope="function", autouse=True) def capture_warnings(self, recwarn): # pylint: disable=function-redefined yield if len(recwarn) > 0: @@ -78,7 +78,7 @@ def test_correct_pl_gates(self, basis_state, wires, target_wires): assert gate.name == "PauliX" assert gate.wires.tolist() == [target_wires[id]] - @pytest.fixture(scope="function", autouse=False) + @pytest.fixture(scope="function", autouse=True) def capture_warnings(self, recwarn): # pylint: disable=function-redefined yield if len(recwarn) > 0: @@ -115,7 +115,7 @@ def circuit(): assert np.allclose(output_state, target_state, atol=tol, rtol=0) - @pytest.fixture(scope="function", autouse=False) + @pytest.fixture(scope="function", autouse=True) def capture_warnings(self, recwarn): # pylint: disable=function-redefined yield if len(recwarn) > 0: @@ -150,7 +150,7 @@ def circuit(state): assert np.allclose(output_state, target_state, atol=tol, rtol=0) - @pytest.fixture(scope="function", autouse=False) + @pytest.fixture(scope="function", autouse=True) def capture_warnings(self, recwarn): # pylint: disable=function-redefined yield if len(recwarn) > 0: @@ -184,7 +184,7 @@ def circuit(state): assert np.allclose(output_state, target_state, atol=tol, rtol=0) - @pytest.fixture(scope="function", autouse=False) + @pytest.fixture(scope="function", autouse=True) def capture_warnings(self, recwarn): # pylint: disable=function-redefined yield if len(recwarn) > 0: @@ -215,7 +215,7 @@ def circuit2(): assert np.allclose(res1, res2, atol=tol, rtol=0) assert np.allclose(state1, state2, atol=tol, rtol=0) - @pytest.fixture(scope="function", autouse=False) + @pytest.fixture(scope="function", autouse=True) def capture_warnings(self, recwarn): # pylint: disable=function-redefined yield if len(recwarn) > 0: @@ -235,7 +235,7 @@ def test_batched_decomposition_fails(self): class TestInputs: """Test inputs and pre-processing.""" - @pytest.fixture(scope="function", autouse=False) + @pytest.fixture(scope="function", autouse=True) def capture_warnings(self, recwarn): # pylint: disable=function-redefined yield if len(recwarn) > 0: @@ -256,7 +256,7 @@ def test_error_num_qubits(self, basis_state, wires): with pytest.raises(ValueError, match="Basis states must be of (shape|length)"): qml.BasisStatePreparation(basis_state, wires) - @pytest.fixture(scope="function", autouse=False) + @pytest.fixture(scope="function", autouse=True) def capture_warnings(self, recwarn): # pylint: disable=function-redefined yield if len(recwarn) > 0: @@ -277,7 +277,7 @@ def test_error_basis_state_format(self, basis_state, wires): with pytest.raises(ValueError, match="Basis states must only (contain|consist)"): qml.BasisStatePreparation(basis_state, wires) - @pytest.fixture(scope="function", autouse=False) + @pytest.fixture(scope="function", autouse=True) def capture_warnings(self, recwarn): # pylint: disable=function-redefined yield if len(recwarn) > 0: @@ -307,7 +307,7 @@ def circuit(basis_state): basis_state = np.array([0, 2]) circuit(basis_state) - @pytest.fixture(scope="function", autouse=False) + @pytest.fixture(scope="function", autouse=True) def capture_warnings(self, recwarn): # pylint: disable=function-redefined yield if len(recwarn) > 0: diff --git a/tests/transforms/test_batch_input.py b/tests/transforms/test_batch_input.py index 369781796df..ba10a5f1592 100644 --- a/tests/transforms/test_batch_input.py +++ b/tests/transforms/test_batch_input.py @@ -200,7 +200,7 @@ def circuit2(data, weights): assert np.allclose(res, indiv_res) -@pytest.fixture(scope="function", autouse=False) +@pytest.fixture(scope="function", autouse=True) def capture_warnings(recwarn): yield if len(recwarn) > 0: diff --git a/tests/transforms/test_batch_params.py b/tests/transforms/test_batch_params.py index 6bc8411da1f..e22c03c210a 100644 --- a/tests/transforms/test_batch_params.py +++ b/tests/transforms/test_batch_params.py @@ -174,7 +174,7 @@ def circuit2(data, weights): assert np.allclose(res, indiv_res) -@pytest.fixture(scope="function", autouse=False) +@pytest.fixture(scope="function", autouse=True) def capture_warnings(recwarn): yield if len(recwarn) > 0: diff --git a/tests/transforms/test_defer_measurements.py b/tests/transforms/test_defer_measurements.py index 309e3bef85c..fb604fb84dc 100644 --- a/tests/transforms/test_defer_measurements.py +++ b/tests/transforms/test_defer_measurements.py @@ -1347,7 +1347,7 @@ def quantum_control_circuit(rads): class TestTemplates: """Tests templates being conditioned on mid-circuit measurement outcomes.""" - @pytest.fixture(scope="function", autouse=False) + @pytest.fixture(scope="function", autouse=True) def capture_warnings(self, recwarn): yield if len(recwarn) > 0: From 0918ac744c6f516557c2ae367a13cf3093e63191 Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Mon, 19 Aug 2024 13:58:31 -0400 Subject: [PATCH 31/52] Update deprecations.rst --- doc/development/deprecations.rst | 6 ------ 1 file changed, 6 deletions(-) diff --git a/doc/development/deprecations.rst b/doc/development/deprecations.rst index 5024cf3be4e..2f05830d4b8 100644 --- a/doc/development/deprecations.rst +++ b/doc/development/deprecations.rst @@ -85,12 +85,6 @@ Pending deprecations - Deprecated in v0.37 - Will be removed in v0.39 -* The ``BasisStatePreparation`` template is deprecated. - Instead, use ``BasisState``. - - - Deprecated in v0.38 - - Will be removed in v0.39 - New operator arithmetic deprecations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From 7165004f6b80fe05c2b8ef0f934ec08dd78f3757 Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Mon, 19 Aug 2024 14:00:46 -0400 Subject: [PATCH 32/52] Update changelog-dev.md --- doc/releases/changelog-dev.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/doc/releases/changelog-dev.md b/doc/releases/changelog-dev.md index ea42c94afe4..e27989ec2dd 100644 --- a/doc/releases/changelog-dev.md +++ b/doc/releases/changelog-dev.md @@ -263,10 +263,6 @@ Instead, use `pennylane.gradients.classical_fisher` and `pennylane.gradients.quantum_fisher`. [(#5985)](https://github.com/PennyLaneAI/pennylane/pull/5985) -* The ``BasisStatePreparation`` template is deprecated. - Instead, ``BasisState`` can be called on the constructed operator. - [(#6021)](https://github.com/PennyLaneAI/pennylane/pull/6021) - * The legacy devices `default.qubit.{autograd,torch,tf,jax,legacy}` are deprecated. Instead, use `default.qubit` as it now supports backpropagation through the several backends. [(#5997)](https://github.com/PennyLaneAI/pennylane/pull/5997) From 8d7c5e0cac3929b62ed8a8a4b80effd54429e682 Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Mon, 19 Aug 2024 14:03:11 -0400 Subject: [PATCH 33/52] Update test_templates.py --- pennylane/devices/tests/test_templates.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/pennylane/devices/tests/test_templates.py b/pennylane/devices/tests/test_templates.py index a1292d1eed6..07b0b56b39c 100644 --- a/pennylane/devices/tests/test_templates.py +++ b/pennylane/devices/tests/test_templates.py @@ -225,15 +225,6 @@ def circuit(): [math.fidelity_statevector(circuit(), exp_state)], [1.0], atol=tol(dev.shots) ) - @pytest.fixture(scope="function", autouse=False) - def capture_warnings(self, recwarn): - """Capture warnings.""" - yield - if len(recwarn) > 0: - for w in recwarn: - assert isinstance(w.message, qml.PennyLaneDeprecationWarning) - assert "BasisStatePreparation is deprecated" in str(w.message) - def test_BasisStatePreparation(self, device, tol): """Test the BasisStatePreparation template.""" dev = device(4) From 3b278be12c8d5a15b285e26c335744b43c883bf8 Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Mon, 19 Aug 2024 14:08:17 -0400 Subject: [PATCH 34/52] Update basis.py --- pennylane/templates/state_preparations/basis.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/pennylane/templates/state_preparations/basis.py b/pennylane/templates/state_preparations/basis.py index d49a1cc81b9..24d9c141a14 100644 --- a/pennylane/templates/state_preparations/basis.py +++ b/pennylane/templates/state_preparations/basis.py @@ -15,8 +15,6 @@ Contains the BasisStatePreparation template. """ -import warnings - import numpy as np import pennylane as qml @@ -32,8 +30,6 @@ class BasisStatePreparation(Operation): ``basis_state`` influences the circuit architecture and is therefore incompatible with gradient computations. - ``BasisStatePreparation`` is deprecated and will be removed in version 0.39. Instead, please use ``BasisState``. - Args: basis_state (array): Input array of shape ``(n,)``, where n is the number of wires the state preparation acts on. From 4fc8b58a205c7903d05946a70d2122967dbeccc6 Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Mon, 19 Aug 2024 14:10:30 -0400 Subject: [PATCH 35/52] Update basis.py --- pennylane/templates/state_preparations/basis.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/pennylane/templates/state_preparations/basis.py b/pennylane/templates/state_preparations/basis.py index 24d9c141a14..48211a6d1e8 100644 --- a/pennylane/templates/state_preparations/basis.py +++ b/pennylane/templates/state_preparations/basis.py @@ -59,13 +59,6 @@ def circuit(basis_state): ndim_params = (1,) def __init__(self, basis_state, wires, id=None): - - warnings.warn( - "BasisStatePreparation is deprecated and will be removed in version 0.39. " - "Instead, please use BasisState.", - qml.PennyLaneDeprecationWarning, - ) - basis_state = qml.math.stack(basis_state) # check if the `basis_state` param is batched From 5cdffeeea1db0d94ff06f4153c7917e9039533d7 Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Mon, 19 Aug 2024 14:12:17 -0400 Subject: [PATCH 36/52] Update test_templates.py --- tests/capture/test_templates.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/tests/capture/test_templates.py b/tests/capture/test_templates.py index 89b14da090e..afc66e6c5ab 100644 --- a/tests/capture/test_templates.py +++ b/tests/capture/test_templates.py @@ -190,15 +190,6 @@ def enable_disable_plxpr(): ] -@pytest.fixture(scope="function", autouse=True) -def capture_warnings(recwarn): - yield - if len(recwarn) > 0: - for w in recwarn: - assert isinstance(w.message, qml.PennyLaneDeprecationWarning) - assert "BasisStatePreparation is deprecated" in str(w.message) - - @pytest.mark.parametrize("template, args, kwargs", unmodified_templates_cases) def test_unmodified_templates(template, args, kwargs): """Test that templates with unmodified primitive binds are captured as expected.""" From a3c6e154ea00634b2ab6bcbdda3b73724f7b56f6 Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Mon, 19 Aug 2024 14:14:07 -0400 Subject: [PATCH 37/52] Update test_state_prep.py --- tests/ops/qubit/test_state_prep.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tests/ops/qubit/test_state_prep.py b/tests/ops/qubit/test_state_prep.py index c8465230eb7..1ab7632c353 100644 --- a/tests/ops/qubit/test_state_prep.py +++ b/tests/ops/qubit/test_state_prep.py @@ -36,12 +36,6 @@ def test_adjoint_error_exception(op): op.adjoint() -def test_BasisStatePreparation_is_deprecated(): - """Test that my_feature is deprecated.""" - with pytest.warns(qml.PennyLaneDeprecationWarning, match="BasisStatePreparation is deprecated"): - _ = qml.BasisStatePreparation([1, 0], wires=[0, 1]) - - @pytest.mark.parametrize( "op, mat, base", [ From cfdd48780f661d73dd52aba43b2bc5fc6ab80656 Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Mon, 19 Aug 2024 14:17:29 -0400 Subject: [PATCH 38/52] Update test_state_prep.py --- tests/ops/qubit/test_state_prep.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/ops/qubit/test_state_prep.py b/tests/ops/qubit/test_state_prep.py index 1ab7632c353..f13fef67d80 100644 --- a/tests/ops/qubit/test_state_prep.py +++ b/tests/ops/qubit/test_state_prep.py @@ -66,6 +66,8 @@ def test_BasisState_decomposition(self): ops2 = qml.BasisState(n, wires=wires).decomposition() assert len(ops1) == len(ops2) == 1 + assert isinstance(ops1[0], qml.BasisStatePreparation) + assert isinstance(ops2[0], qml.BasisStatePreparation) def test_StatePrep_decomposition(self): """Test the decomposition for StatePrep.""" From cb6ba65a17f03e3a8af46538a1fe5a26d87b8c64 Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Mon, 19 Aug 2024 14:23:32 -0400 Subject: [PATCH 39/52] Update test_basis_state_prep.py --- .../test_basis_state_prep.py | 97 ++----------------- 1 file changed, 6 insertions(+), 91 deletions(-) diff --git a/tests/templates/test_state_preparations/test_basis_state_prep.py b/tests/templates/test_state_preparations/test_basis_state_prep.py index 119463775c1..90b88463a05 100644 --- a/tests/templates/test_state_preparations/test_basis_state_prep.py +++ b/tests/templates/test_state_preparations/test_basis_state_prep.py @@ -22,15 +22,6 @@ import pennylane as qml -@pytest.fixture(scope="function", autouse=True) -def capture_warnings(recwarn): # pylint: disable=function-redefined - yield - if len(recwarn) > 0: - for w in recwarn: - assert isinstance(w.message, qml.PennyLaneDeprecationWarning) - assert "BasisStatePreparation is deprecated" in str(w.message) - - def test_standard_validity(): """Check the operation using the assert_valid function.""" @@ -45,14 +36,6 @@ def test_standard_validity(): class TestDecomposition: """Tests that the template defines the correct decomposition.""" - @pytest.fixture(scope="function", autouse=True) - def capture_warnings(self, recwarn): # pylint: disable=function-redefined - yield - if len(recwarn) > 0: - for w in recwarn: - assert isinstance(w.message, qml.PennyLaneDeprecationWarning) - assert "BasisStatePreparation is deprecated" in str(w.message) - # fmt: off @pytest.mark.parametrize("basis_state,wires,target_wires", [ ([0], [0], []), @@ -78,14 +61,6 @@ def test_correct_pl_gates(self, basis_state, wires, target_wires): assert gate.name == "PauliX" assert gate.wires.tolist() == [target_wires[id]] - @pytest.fixture(scope="function", autouse=True) - def capture_warnings(self, recwarn): # pylint: disable=function-redefined - yield - if len(recwarn) > 0: - for w in recwarn: - assert isinstance(w.message, qml.PennyLaneDeprecationWarning) - assert "BasisStatePreparation is deprecated" in str(w.message) - # fmt: off @pytest.mark.parametrize("basis_state,wires,target_state", [ ([0], [0], [0, 0, 0]), @@ -115,14 +90,6 @@ def circuit(): assert np.allclose(output_state, target_state, atol=tol, rtol=0) - @pytest.fixture(scope="function", autouse=True) - def capture_warnings(self, recwarn): # pylint: disable=function-redefined - yield - if len(recwarn) > 0: - for w in recwarn: - assert isinstance(w.message, qml.PennyLaneDeprecationWarning) - assert "BasisStatePreparation is deprecated" in str(w.message) - @pytest.mark.jax @pytest.mark.parametrize( "basis_state,wires,target_state", @@ -150,14 +117,6 @@ def circuit(state): assert np.allclose(output_state, target_state, atol=tol, rtol=0) - @pytest.fixture(scope="function", autouse=True) - def capture_warnings(self, recwarn): # pylint: disable=function-redefined - yield - if len(recwarn) > 0: - for w in recwarn: - assert isinstance(w.message, qml.PennyLaneDeprecationWarning) - assert "BasisStatePreparation is deprecated" in str(w.message) - @pytest.mark.tf @pytest.mark.parametrize( "basis_state,wires,target_state", @@ -184,14 +143,6 @@ def circuit(state): assert np.allclose(output_state, target_state, atol=tol, rtol=0) - @pytest.fixture(scope="function", autouse=True) - def capture_warnings(self, recwarn): # pylint: disable=function-redefined - yield - if len(recwarn) > 0: - for w in recwarn: - assert isinstance(w.message, qml.PennyLaneDeprecationWarning) - assert "BasisStatePreparation is deprecated" in str(w.message) - def test_custom_wire_labels(self, tol): """Test that template can deal with non-numeric, nonconsecutive wire labels.""" basis_state = [0, 1, 0] @@ -215,34 +166,22 @@ def circuit2(): assert np.allclose(res1, res2, atol=tol, rtol=0) assert np.allclose(state1, state2, atol=tol, rtol=0) - @pytest.fixture(scope="function", autouse=True) - def capture_warnings(self, recwarn): # pylint: disable=function-redefined - yield - if len(recwarn) > 0: - for w in recwarn: - assert isinstance(w.message, qml.PennyLaneDeprecationWarning) - assert "BasisStatePreparation is deprecated" in str(w.message) - def test_batched_decomposition_fails(self): """Test that attempting to decompose a BasisStatePreparation operation with broadcasting raises an error.""" state = np.array([[1, 0], [1, 1]]) - with pytest.raises(ValueError, match="Features must be one-dimensional"): - _ = qml.BasisState(state, wires=[0, 1]) + op = qml.BasisStatePreparation(state, wires=[0, 1]) + with pytest.raises(ValueError, match="Broadcasting with BasisStatePreparation"): + _ = op.decomposition() + + with pytest.raises(ValueError, match="Broadcasting with BasisStatePreparation"): + _ = qml.BasisStatePreparation.compute_decomposition(state, qml.wires.Wires([0, 1])) class TestInputs: """Test inputs and pre-processing.""" - @pytest.fixture(scope="function", autouse=True) - def capture_warnings(self, recwarn): # pylint: disable=function-redefined - yield - if len(recwarn) > 0: - for w in recwarn: - assert isinstance(w.message, qml.PennyLaneDeprecationWarning) - assert "BasisStatePreparation is deprecated" in str(w.message) - # fmt: off @pytest.mark.parametrize("basis_state,wires", [ ([0], [0, 1]), @@ -256,14 +195,6 @@ def test_error_num_qubits(self, basis_state, wires): with pytest.raises(ValueError, match="Basis states must be of (shape|length)"): qml.BasisStatePreparation(basis_state, wires) - @pytest.fixture(scope="function", autouse=True) - def capture_warnings(self, recwarn): # pylint: disable=function-redefined - yield - if len(recwarn) > 0: - for w in recwarn: - assert isinstance(w.message, qml.PennyLaneDeprecationWarning) - assert "BasisStatePreparation is deprecated" in str(w.message) - # fmt: off @pytest.mark.parametrize("basis_state,wires", [ ([3], [0]), @@ -277,14 +208,6 @@ def test_error_basis_state_format(self, basis_state, wires): with pytest.raises(ValueError, match="Basis states must only (contain|consist)"): qml.BasisStatePreparation(basis_state, wires) - @pytest.fixture(scope="function", autouse=True) - def capture_warnings(self, recwarn): # pylint: disable=function-redefined - yield - if len(recwarn) > 0: - for w in recwarn: - assert isinstance(w.message, qml.PennyLaneDeprecationWarning) - assert "BasisStatePreparation is deprecated" in str(w.message) - def test_exception_wrong_dim(self): """Verifies that exception is raised if the number of dimensions of features is incorrect.""" @@ -307,14 +230,6 @@ def circuit(basis_state): basis_state = np.array([0, 2]) circuit(basis_state) - @pytest.fixture(scope="function", autouse=True) - def capture_warnings(self, recwarn): # pylint: disable=function-redefined - yield - if len(recwarn) > 0: - for w in recwarn: - assert isinstance(w.message, qml.PennyLaneDeprecationWarning) - assert "BasisStatePreparation is deprecated" in str(w.message) - def test_id(self): """Tests that the id attribute can be set.""" template = qml.BasisStatePreparation(np.array([0, 1]), wires=[0, 1], id="a") From 6531ce6bfd34973a7144e2394873a126afb43579 Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Mon, 19 Aug 2024 14:24:39 -0400 Subject: [PATCH 40/52] Update test_batch_input.py --- tests/transforms/test_batch_input.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/tests/transforms/test_batch_input.py b/tests/transforms/test_batch_input.py index ba10a5f1592..3d97e981ed2 100644 --- a/tests/transforms/test_batch_input.py +++ b/tests/transforms/test_batch_input.py @@ -200,15 +200,6 @@ def circuit2(data, weights): assert np.allclose(res, indiv_res) -@pytest.fixture(scope="function", autouse=True) -def capture_warnings(recwarn): - yield - if len(recwarn) > 0: - for w in recwarn: - assert isinstance(w.message, qml.PennyLaneDeprecationWarning) - assert "BasisStatePreparation is deprecated" in str(w.message) - - def test_basis_state_preparation(mocker): """Test that batching works for BasisStatePreparation""" dev = qml.device("default.qubit", wires=3) From 51a79de264926f0879b31da11c0023368c14be75 Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Mon, 19 Aug 2024 14:25:47 -0400 Subject: [PATCH 41/52] Update test_batch_params.py --- tests/transforms/test_batch_params.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/tests/transforms/test_batch_params.py b/tests/transforms/test_batch_params.py index e22c03c210a..ad4daddeb69 100644 --- a/tests/transforms/test_batch_params.py +++ b/tests/transforms/test_batch_params.py @@ -174,15 +174,6 @@ def circuit2(data, weights): assert np.allclose(res, indiv_res) -@pytest.fixture(scope="function", autouse=True) -def capture_warnings(recwarn): - yield - if len(recwarn) > 0: - for w in recwarn: - assert isinstance(w.message, qml.PennyLaneDeprecationWarning) - assert "BasisStatePreparation is deprecated" in str(w.message) - - def test_basis_state_preparation(mocker): """Test that batching works for BasisStatePreparation""" dev = qml.device("default.qubit", wires=4) From 4c1e2d5aa783ebf0e28e4cf3504526124443bd0f Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Mon, 19 Aug 2024 14:26:45 -0400 Subject: [PATCH 42/52] Update test_defer_measurements.py --- tests/transforms/test_defer_measurements.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/tests/transforms/test_defer_measurements.py b/tests/transforms/test_defer_measurements.py index fb604fb84dc..3d5e98791ea 100644 --- a/tests/transforms/test_defer_measurements.py +++ b/tests/transforms/test_defer_measurements.py @@ -1347,14 +1347,6 @@ def quantum_control_circuit(rads): class TestTemplates: """Tests templates being conditioned on mid-circuit measurement outcomes.""" - @pytest.fixture(scope="function", autouse=True) - def capture_warnings(self, recwarn): - yield - if len(recwarn) > 0: - for w in recwarn: - assert isinstance(w.message, qml.PennyLaneDeprecationWarning) - assert "BasisStatePreparation is deprecated" in str(w.message) - def test_basis_state_prep(self): """Test the basis state prep template conditioned on mid-circuit measurement outcomes.""" From cc7801b3866efc31fa84017a53b14d1bc4653c40 Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Mon, 19 Aug 2024 15:24:01 -0400 Subject: [PATCH 43/52] removing BSP modifications --- tests/test_qnode.py | 4 ++-- tests/test_qnode_legacy.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/test_qnode.py b/tests/test_qnode.py index 88d72d7aebe..9f452bfe853 100644 --- a/tests/test_qnode.py +++ b/tests/test_qnode.py @@ -965,7 +965,7 @@ def test_sampling_with_mcm(self, basis_state, mocker): @qml.qnode(dev) def cry_qnode(x): """QNode where we apply a controlled Y-rotation.""" - qml.BasisState(basis_state, wires=[0, 1]) + qml.BasisStatePreparation(basis_state, wires=[0, 1]) qml.CRY(x, wires=[0, 1]) return qml.sample(qml.PauliZ(1)) @@ -973,7 +973,7 @@ def cry_qnode(x): def conditional_ry_qnode(x): """QNode where the defer measurements transform is applied by default under the hood.""" - qml.BasisState(basis_state, wires=[0, 1]) + qml.BasisStatePreparation(basis_state, wires=[0, 1]) m_0 = qml.measure(0) qml.cond(m_0, qml.RY)(x, wires=1) return qml.sample(qml.PauliZ(1)) diff --git a/tests/test_qnode_legacy.py b/tests/test_qnode_legacy.py index b7d216bc40a..7ea5c331596 100644 --- a/tests/test_qnode_legacy.py +++ b/tests/test_qnode_legacy.py @@ -1191,7 +1191,7 @@ def test_sampling_with_mcm(self, basis_state, mocker): @qml.qnode(dev) def cry_qnode(x): """QNode where we apply a controlled Y-rotation.""" - qml.BasisState(basis_state, wires=[0, 1]) + qml.BasisStatePreparation(basis_state, wires=[0, 1]) qml.CRY(x, wires=[0, 1]) return qml.sample(qml.PauliZ(1)) @@ -1199,7 +1199,7 @@ def cry_qnode(x): def conditional_ry_qnode(x): """QNode where the defer measurements transform is applied by default under the hood.""" - qml.BasisState(basis_state, wires=[0, 1]) + qml.BasisStatePreparation(basis_state, wires=[0, 1]) m_0 = qml.measure(0) qml.cond(m_0, qml.RY)(x, wires=1) return qml.sample(qml.PauliZ(1)) From e9931bc7266f69203dbaa42b07ea1575babc1c02 Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Tue, 20 Aug 2024 08:56:26 -0400 Subject: [PATCH 44/52] Update state_preparation.py --- pennylane/ops/qubit/state_preparation.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pennylane/ops/qubit/state_preparation.py b/pennylane/ops/qubit/state_preparation.py index 9dfb5aaacbc..b4c2c510ae9 100644 --- a/pennylane/ops/qubit/state_preparation.py +++ b/pennylane/ops/qubit/state_preparation.py @@ -22,9 +22,8 @@ import pennylane as qml from pennylane import math - from pennylane.operation import AnyWires, Operation, Operator, StatePrepBase -from pennylane.templates.state_preparations import BasisStatePreparation, MottonenStatePreparation +from pennylane.templates.state_preparations import MottonenStatePreparation from pennylane.typing import TensorLike from pennylane.wires import WireError, Wires, WiresLike From cd64dff076c04bdcd21fe304813f530a719f8cc4 Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Tue, 20 Aug 2024 09:41:49 -0400 Subject: [PATCH 45/52] Update test_state_prep.py --- tests/ops/qubit/test_state_prep.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/ops/qubit/test_state_prep.py b/tests/ops/qubit/test_state_prep.py index f13fef67d80..e9995e65409 100644 --- a/tests/ops/qubit/test_state_prep.py +++ b/tests/ops/qubit/test_state_prep.py @@ -66,8 +66,8 @@ def test_BasisState_decomposition(self): ops2 = qml.BasisState(n, wires=wires).decomposition() assert len(ops1) == len(ops2) == 1 - assert isinstance(ops1[0], qml.BasisStatePreparation) - assert isinstance(ops2[0], qml.BasisStatePreparation) + assert isinstance(ops1[0], qml.PauliX) + assert isinstance(ops2[0], qml.PauliX) def test_StatePrep_decomposition(self): """Test the decomposition for StatePrep.""" From c9e66e9561fabdb12a582c295f0158a558273b0a Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Wed, 21 Aug 2024 09:41:38 -0400 Subject: [PATCH 46/52] code review comments --- pennylane/ops/qubit/state_preparation.py | 66 +++++++++---------- pennylane/templates/embeddings/basis.py | 4 +- tests/devices/test_default_qubit_legacy.py | 2 +- tests/devices/test_default_qubit_tf.py | 2 +- tests/devices/test_default_qubit_torch.py | 2 +- tests/ops/qubit/test_state_prep.py | 6 +- tests/templates/test_embeddings/test_basis.py | 40 ++++++----- .../templates/test_subroutines/test_uccsd.py | 2 +- 8 files changed, 66 insertions(+), 58 deletions(-) diff --git a/pennylane/ops/qubit/state_preparation.py b/pennylane/ops/qubit/state_preparation.py index b4c2c510ae9..70d9c67b1ce 100644 --- a/pennylane/ops/qubit/state_preparation.py +++ b/pennylane/ops/qubit/state_preparation.py @@ -31,7 +31,7 @@ class BasisState(StatePrepBase): - r"""BasisState(features, wires) + r"""BasisState(state, wires) Prepares a single computational basis state. **Details:** @@ -51,7 +51,7 @@ class BasisState(StatePrepBase): as :math:`U|0\rangle = |\psi\rangle` Args: - features (tensor_like): binary input of shape ``(len(wires), )``. For example, for ``features=np.array([0, 1, 0])`` or ``features=2`` (binary 010), the quantum system will be prepared in state :math:`|010 \rangle`. + state (tensor_like): binary input of shape ``(len(wires), )``, e.g., for ``state=np.array([0, 1, 0])`` or ``state=2`` (binary 010), the quantum system will be prepared in state :math:`|010 \rangle`. wires (Sequence[int] or int): the wire(s) the operation acts on id (str): custom label given to an operator instance, @@ -68,51 +68,52 @@ class BasisState(StatePrepBase): [0.+0.j 0.+0.j 0.+0.j 1.+0.j] """ - def __init__(self, features, wires, id=None): + def __init__(self, state, wires, id=None): - if isinstance(features, list): - features = qml.math.stack(features) + if isinstance(state, list): + state = qml.math.stack(state) - tracing = qml.math.is_abstract(features) + tracing = qml.math.is_abstract(state) - if qml.math.shape(features) == (): - if not tracing and features >= 2 ** len(wires): + if not qml.math.shape(state): + if not tracing and state >= 2 ** len(wires): raise ValueError( - f"Features must be of length {len(wires)}, got features={features} which is >= {2 ** len(wires)}" + f"Integer state must be < {2 ** len(wires)} to have a feasible binary representation, got {state}" + f"State must be of length {len(wires)}, got state={state} which is >= {2 ** len(wires)}" ) bin = 2 ** math.arange(len(wires))[::-1] - features = qml.math.where((features & bin) > 0, 1, 0) + state = qml.math.where((state & bin) > 0, 1, 0) wires = Wires(wires) - shape = qml.math.shape(features) + shape = qml.math.shape(state) if len(shape) != 1: - raise ValueError(f"Features must be one-dimensional; got shape {shape}.") + raise ValueError(f"State must be one-dimensional; got shape {shape}.") - n_features = shape[0] - if n_features != len(wires): + n_states = shape[0] + if n_states != len(wires): raise ValueError( - f"Features must be of length {len(wires)}; got length {n_features} (features={features})." + f"State must be of length {len(wires)}; got length {n_states} (state={state})." ) if not tracing: - features_list = list(qml.math.toarray(features)) - if not set(features_list).issubset({0, 1}): - raise ValueError(f"Basis state must only consist of 0s and 1s; got {features_list}") + state_list = list(qml.math.toarray(state)) + if not set(state_list).issubset({0, 1}): + raise ValueError(f"Basis state must only consist of 0s and 1s; got {state_list}") - super().__init__(features, wires=wires, id=id) + super().__init__(state, wires=wires, id=id) def _flatten(self): - features = self.parameters[0] - features = tuple(features) if isinstance(features, list) else features - return (features,), (self.wires,) + state = self.parameters[0] + state = tuple(state) if isinstance(state, list) else state + return (state,), (self.wires,) @classmethod def _unflatten(cls, data, metadata) -> "BasisState": return cls(data[0], wires=metadata[0]) @staticmethod - def compute_decomposition(features: TensorLike, wires: WiresLike) -> list[Operator]: + def compute_decomposition(state: TensorLike, wires: WiresLike) -> list[Operator]: r"""Representation of the operator as a product of other operators (static method). : .. math:: O = O_1 O_2 \dots O_n. @@ -121,8 +122,7 @@ def compute_decomposition(features: TensorLike, wires: WiresLike) -> list[Operat .. seealso:: :meth:`~.BasisState.decomposition`. Args: - n (array): prepares the basis state :math:`\ket{n}`, where ``n`` is an - array of integers from the set :math:`\{0, 1\}` + state (array): the basis state to be prepared wires (Iterable, Wires): the wire(s) the operation acts on Returns: @@ -135,18 +135,14 @@ def compute_decomposition(features: TensorLike, wires: WiresLike) -> list[Operat """ - if not qml.math.is_abstract(features): - op_list = [] - for wire, state in zip(wires, features): - if state == 1: - op_list.append(qml.X(wire)) - return op_list + if not qml.math.is_abstract(state): + return [qml.X(wire) for wire, basis in zip(wires, state) if basis == 1] op_list = [] - for wire, state in zip(wires, features): - op_list.append(qml.PhaseShift(state * np.pi / 2, wire)) - op_list.append(qml.RX(state * np.pi, wire)) - op_list.append(qml.PhaseShift(state * np.pi / 2, wire)) + for wire, basis in zip(wires, state): + op_list.append(qml.PhaseShift(basis * np.pi / 2, wire)) + op_list.append(qml.RX(basis * np.pi, wire)) + op_list.append(qml.PhaseShift(basis * np.pi / 2, wire)) return op_list diff --git a/pennylane/templates/embeddings/basis.py b/pennylane/templates/embeddings/basis.py index 5db190746fa..9c95f7f253a 100644 --- a/pennylane/templates/embeddings/basis.py +++ b/pennylane/templates/embeddings/basis.py @@ -19,7 +19,6 @@ from pennylane.ops.qubit.state_preparation import BasisState -# pylint: disable=missing-class-docstring class BasisEmbedding(BasisState): r"""Encodes :math:`n` binary features into a basis state of :math:`n` qubits. @@ -67,3 +66,6 @@ def circuit(feature_vector): Thus, ``[1,1,1]`` is mapped to :math:`|111 \rangle`. """ + + def __init__(self, features, wires, id=None): + super().__init__(features, wires=wires, id=id) diff --git a/tests/devices/test_default_qubit_legacy.py b/tests/devices/test_default_qubit_legacy.py index f84ab1d0689..a1a86b74ed1 100644 --- a/tests/devices/test_default_qubit_legacy.py +++ b/tests/devices/test_default_qubit_legacy.py @@ -657,7 +657,7 @@ def test_apply_errors_basis_state(self, qubit_device_2_wires): qubit_device_2_wires.apply([qml.BasisState(np.array([-0.2, 4.2]), wires=[0, 1])]) with pytest.raises( - ValueError, match=r"Features must be of length 1; got length 2 \(features=\[0 1\]\)\." + ValueError, match=r"State must be of length 1; got length 2 \(features=\[0 1\]\)\." ): qubit_device_2_wires.apply([qml.BasisState(np.array([0, 1]), wires=[0])]) diff --git a/tests/devices/test_default_qubit_tf.py b/tests/devices/test_default_qubit_tf.py index 7cbc3356480..0016deb97e4 100644 --- a/tests/devices/test_default_qubit_tf.py +++ b/tests/devices/test_default_qubit_tf.py @@ -296,7 +296,7 @@ def test_invalid_basis_state_length(self): with pytest.raises( ValueError, - match=r"Features must be of length 3; got length 4 \(features=\[0 0 1 0\]\)", + match=r"State must be of length 3; got length 4 \(features=\[0 0 1 0\]\)", ): dev.apply([qml.BasisState(state, wires=[0, 1, 2])]) diff --git a/tests/devices/test_default_qubit_torch.py b/tests/devices/test_default_qubit_torch.py index da40ee14ded..77cea2da4d4 100644 --- a/tests/devices/test_default_qubit_torch.py +++ b/tests/devices/test_default_qubit_torch.py @@ -259,7 +259,7 @@ def test_invalid_basis_state_length(self, device, torch_device): with pytest.raises( ValueError, - match=r"Features must be of length 3; got length 4 \(features=tensor\(\[0, 0, 1, 0\]\)\)", + match=r"State must be of length 3; got length 4 \(features=tensor\(\[0, 0, 1, 0\]\)\)", ): dev.apply([qml.BasisState(state, wires=[0, 1, 2])]) diff --git a/tests/ops/qubit/test_state_prep.py b/tests/ops/qubit/test_state_prep.py index e9995e65409..d9c421c6127 100644 --- a/tests/ops/qubit/test_state_prep.py +++ b/tests/ops/qubit/test_state_prep.py @@ -66,8 +66,8 @@ def test_BasisState_decomposition(self): ops2 = qml.BasisState(n, wires=wires).decomposition() assert len(ops1) == len(ops2) == 1 - assert isinstance(ops1[0], qml.PauliX) - assert isinstance(ops2[0], qml.PauliX) + assert isinstance(ops1[0], qml.X) + assert isinstance(ops2[0], qml.X) def test_StatePrep_decomposition(self): """Test the decomposition for StatePrep.""" @@ -354,6 +354,6 @@ def test_BasisState_state_vector_bad_wire_order(self): def test_BasisState_wrong_param_size(self): """Tests that the parameter must be of length num_wires.""" with pytest.raises( - ValueError, match=r"Features must be of length 2; got length 1 \(features=\[0\]\)." + ValueError, match=r"State must be of length 2; got length 1 \(state=\[0\]\)." ): _ = qml.BasisState([0], wires=[0, 1]) diff --git a/tests/templates/test_embeddings/test_basis.py b/tests/templates/test_embeddings/test_basis.py index bd07bd3df0b..3b8b93b79e6 100644 --- a/tests/templates/test_embeddings/test_basis.py +++ b/tests/templates/test_embeddings/test_basis.py @@ -112,8 +112,15 @@ def test_features_as_int_conversion(self, feat, wires, expected): assert np.allclose(qml.BasisEmbedding(features=feat, wires=wires).parameters[0], expected) - @pytest.mark.parametrize("x", [[0], [0, 1, 1], 4]) - def test_wrong_input_bits_exception(self, x): + @pytest.mark.parametrize( + "x, msg", + [ + ([0], "State must be of length"), + ([0, 1, 1], "State must be of length"), + (4, "Integer state must be"), + ], + ) + def test_wrong_input_bits_exception(self, x, msg): """Checks exception if number of features is not same as number of qubits.""" dev = qml.device("default.qubit", wires=2) @@ -123,7 +130,7 @@ def circuit(): qml.BasisEmbedding(features=x, wires=range(2)) return qml.expval(qml.PauliZ(0)) - with pytest.raises(ValueError, match="Features must be of length"): + with pytest.raises(ValueError, match=msg): circuit() def test_input_not_binary_exception(self): @@ -149,7 +156,7 @@ def circuit(x=None): qml.BasisEmbedding(features=x, wires=2) return qml.expval(qml.PauliZ(0)) - with pytest.raises(ValueError, match="Features must be one-dimensional"): + with pytest.raises(ValueError, match="State must be one-dimensional"): circuit(x=[[1], [0]]) def test_id(self): @@ -232,8 +239,12 @@ def test_jax(self, tol): res = circuit(jnp.array(2)) assert qml.math.allclose(res, res2, atol=tol, rtol=0) + @pytest.mark.parametrize( + "device_name", + ["default.qubit", "lightning.qubit"], + ) @pytest.mark.jax - def test_jax_jit(self, tol): + def test_jax_jit(self, tol, device_name): """Tests the jax-jit interface.""" import jax @@ -241,20 +252,19 @@ def test_jax_jit(self, tol): features = jnp.array([0, 1, 0]) - for dev_name in ["default.qubit", "lightning.qubit"]: - dev = qml.device(dev_name, wires=3) + dev = qml.device(device_name, wires=3) - circuit = qml.QNode(circuit_template, dev) - circuit2 = qml.QNode(circuit_decomposed, dev) + circuit = qml.QNode(circuit_template, dev) + circuit2 = qml.QNode(circuit_decomposed, dev) - res = circuit(features) - res2 = circuit2(features) - assert qml.math.allclose(res, res2, atol=tol, rtol=0) + res = circuit(features) + res2 = circuit2(features) + assert qml.math.allclose(res, res2, atol=tol, rtol=0) - circuit = jax.jit(circuit) + circuit = jax.jit(circuit) - res = circuit(jnp.array(2)) - assert qml.math.allclose(res, res2, atol=tol, rtol=0) + res = circuit(jnp.array(2)) + assert qml.math.allclose(res, res2, atol=tol, rtol=0) @pytest.mark.tf def test_tf(self, tol): diff --git a/tests/templates/test_subroutines/test_uccsd.py b/tests/templates/test_subroutines/test_uccsd.py index 6a28d3f29fc..62476ad6ad6 100644 --- a/tests/templates/test_subroutines/test_uccsd.py +++ b/tests/templates/test_subroutines/test_uccsd.py @@ -291,7 +291,7 @@ class TestInputs: [], np.array([1, 1, 0, 0, 0]), 1, - "Features must be of length 4", + "State must be of length 4", ), ( np.array([-2.8, 1.6]), From 05823d338299f680f639cc3fa1b0dbd8710d729c Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Wed, 21 Aug 2024 09:56:33 -0400 Subject: [PATCH 47/52] Update state_preparation.py --- pennylane/ops/qubit/state_preparation.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pennylane/ops/qubit/state_preparation.py b/pennylane/ops/qubit/state_preparation.py index 70d9c67b1ce..1b932692fac 100644 --- a/pennylane/ops/qubit/state_preparation.py +++ b/pennylane/ops/qubit/state_preparation.py @@ -38,6 +38,7 @@ class BasisState(StatePrepBase): * Number of wires: Any (the operation can act on any number of wires) * Number of parameters: 1 + * Gradient recipe: None .. note:: From bf122895087cc778e8c4d654267a908f200eebae Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Wed, 21 Aug 2024 10:38:55 -0400 Subject: [PATCH 48/52] updating test msgs --- tests/devices/test_default_qubit_legacy.py | 2 +- tests/devices/test_default_qubit_tf.py | 2 +- tests/devices/test_default_qubit_torch.py | 2 +- tests/templates/test_subroutines/test_all_singles_doubles.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/devices/test_default_qubit_legacy.py b/tests/devices/test_default_qubit_legacy.py index a1a86b74ed1..17422a4aeb9 100644 --- a/tests/devices/test_default_qubit_legacy.py +++ b/tests/devices/test_default_qubit_legacy.py @@ -657,7 +657,7 @@ def test_apply_errors_basis_state(self, qubit_device_2_wires): qubit_device_2_wires.apply([qml.BasisState(np.array([-0.2, 4.2]), wires=[0, 1])]) with pytest.raises( - ValueError, match=r"State must be of length 1; got length 2 \(features=\[0 1\]\)\." + ValueError, match=r"State must be of length 1; got length 2 \(state=\[0 1\]\)\." ): qubit_device_2_wires.apply([qml.BasisState(np.array([0, 1]), wires=[0])]) diff --git a/tests/devices/test_default_qubit_tf.py b/tests/devices/test_default_qubit_tf.py index 0016deb97e4..ccc38a55364 100644 --- a/tests/devices/test_default_qubit_tf.py +++ b/tests/devices/test_default_qubit_tf.py @@ -296,7 +296,7 @@ def test_invalid_basis_state_length(self): with pytest.raises( ValueError, - match=r"State must be of length 3; got length 4 \(features=\[0 0 1 0\]\)", + match=r"State must be of length 3; got length 4 \(state=\[0 0 1 0\]\)", ): dev.apply([qml.BasisState(state, wires=[0, 1, 2])]) diff --git a/tests/devices/test_default_qubit_torch.py b/tests/devices/test_default_qubit_torch.py index 77cea2da4d4..3f4f55bca17 100644 --- a/tests/devices/test_default_qubit_torch.py +++ b/tests/devices/test_default_qubit_torch.py @@ -259,7 +259,7 @@ def test_invalid_basis_state_length(self, device, torch_device): with pytest.raises( ValueError, - match=r"State must be of length 3; got length 4 \(features=tensor\(\[0, 0, 1, 0\]\)\)", + match=r"State must be of length 3; got length 4 \(state=tensor\(\[0, 0, 1, 0\]\)\)", ): dev.apply([qml.BasisState(state, wires=[0, 1, 2])]) diff --git a/tests/templates/test_subroutines/test_all_singles_doubles.py b/tests/templates/test_subroutines/test_all_singles_doubles.py index cefd663d2a8..f7844dcb807 100644 --- a/tests/templates/test_subroutines/test_all_singles_doubles.py +++ b/tests/templates/test_subroutines/test_all_singles_doubles.py @@ -206,7 +206,7 @@ class TestInputs: [[0, 2]], [[0, 1, 2, 3]], np.array([1, 1, 0, 0, 0]), - "Features must be of length 4", + "State must be of length 4", ), ( np.array([-2.8, 1.6]), From 55f9941a274e636011bdc90b2881183f0174b224 Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Wed, 21 Aug 2024 14:58:13 -0400 Subject: [PATCH 49/52] unify changelog --- doc/releases/changelog-dev.md | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/doc/releases/changelog-dev.md b/doc/releases/changelog-dev.md index eee9a307164..2f16057aaa6 100644 --- a/doc/releases/changelog-dev.md +++ b/doc/releases/changelog-dev.md @@ -356,13 +356,7 @@ * `qml.AmplitudeEmbedding` has better support for features using low precision integer data types. [(#5969)](https://github.com/PennyLaneAI/pennylane/pull/5969) -* `qml.BasisState` now works with jax.jit. - [(#6021)](https://github.com/PennyLaneAI/pennylane/pull/6021) - -* `qml.BasisEmbedding` now gives the correct decomposition. - [(#6021)](https://github.com/PennyLaneAI/pennylane/pull/6021) - -* `qml.BasisEmbedding` now works with lightning.qubit and jax.jit. +* `qml.BasisState` and `qml.BasisEmbedding` now works with jax.jit, lightning.qubit and now gives the correct decomposition. [(#6021)](https://github.com/PennyLaneAI/pennylane/pull/6021) * Jacobian shape is fixed for measurements with dimension in `qml.gradients.vjp.compute_vjp_single`. From 5d5201401078c227917450c69dadf12e70686428 Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Wed, 21 Aug 2024 15:05:48 -0400 Subject: [PATCH 50/52] Update test_tape.py --- tests/tape/test_tape.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/tape/test_tape.py b/tests/tape/test_tape.py index 9873f545bff..adcabff8104 100644 --- a/tests/tape/test_tape.py +++ b/tests/tape/test_tape.py @@ -1007,7 +1007,7 @@ def test_depth_expansion(self): [ qml.PauliX(0), qml.MottonenStatePreparation([0, 1, 0, 0], wires=[0, 1]), - qml.StatePrep([0, 1, 0, 0], wires=[0, 1]), # still a StatePrepBase :/ + qml.StatePrep([0, 1, 0, 0], wires=[0, 1]), qml.PauliZ(0), ], ), From c4cbc98f5e1b4a6f6a0e2b89fb49ca24c15b9a52 Mon Sep 17 00:00:00 2001 From: Guillermo Alonso-Linaje <65235481+KetpuntoG@users.noreply.github.com> Date: Wed, 21 Aug 2024 16:08:13 -0400 Subject: [PATCH 51/52] Apply suggestions from code review Co-authored-by: soranjh <40344468+soranjh@users.noreply.github.com> Co-authored-by: Utkarsh --- doc/releases/changelog-dev.md | 2 +- pennylane/ops/qubit/state_preparation.py | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/doc/releases/changelog-dev.md b/doc/releases/changelog-dev.md index 6c90f794a4b..d9c99616cf3 100644 --- a/doc/releases/changelog-dev.md +++ b/doc/releases/changelog-dev.md @@ -377,7 +377,7 @@ * `qml.AmplitudeEmbedding` has better support for features using low precision integer data types. [(#5969)](https://github.com/PennyLaneAI/pennylane/pull/5969) -* `qml.BasisState` and `qml.BasisEmbedding` now works with jax.jit, lightning.qubit and now gives the correct decomposition. +* `qml.BasisState` and `qml.BasisEmbedding` now works with jax.jit, lightning.qubit and give the correct decomposition. [(#6021)](https://github.com/PennyLaneAI/pennylane/pull/6021) * Jacobian shape is fixed for measurements with dimension in `qml.gradients.vjp.compute_vjp_single`. diff --git a/pennylane/ops/qubit/state_preparation.py b/pennylane/ops/qubit/state_preparation.py index f510993b2d3..a7af56b4e38 100644 --- a/pennylane/ops/qubit/state_preparation.py +++ b/pennylane/ops/qubit/state_preparation.py @@ -80,7 +80,6 @@ def __init__(self, state, wires, id=None): if not tracing and state >= 2 ** len(wires): raise ValueError( f"Integer state must be < {2 ** len(wires)} to have a feasible binary representation, got {state}" - f"State must be of length {len(wires)}, got state={state} which is >= {2 ** len(wires)}" ) bin = 2 ** math.arange(len(wires))[::-1] state = qml.math.where((state & bin) > 0, 1, 0) @@ -150,7 +149,7 @@ def compute_decomposition(state: TensorLike, wires: WiresLike) -> list[Operator] def state_vector(self, wire_order: Optional[WiresLike] = None) -> TensorLike: """Returns a statevector of shape ``(2,) * num_wires``.""" prep_vals = self.parameters[0] - prep_vals_int = math.cast(prep_vals, int) + prep_vals_int = math.cast(self.parameters[0], int) if wire_order is None: indices = prep_vals_int From f79135ac54f8bc50fd3be42ba51b9b6d0c56414f Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Wed, 21 Aug 2024 18:25:30 -0400 Subject: [PATCH 52/52] Update test_tape.py --- tests/tape/test_tape.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/tape/test_tape.py b/tests/tape/test_tape.py index 59ea4a3eeaa..227d4025a3b 100644 --- a/tests/tape/test_tape.py +++ b/tests/tape/test_tape.py @@ -1007,7 +1007,7 @@ def test_depth_expansion(self): [ qml.PauliX(0), qml.MottonenStatePreparation([0, 1, 0, 0], wires=[0, 1]), - qml.StatePrep([0, 1, 0, 0], wires=[0, 1]), + qml.MottonenStatePreparation([0, 1, 0, 0], wires=[0, 1]), qml.PauliZ(0), ], ),