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),
],
),