Skip to content

Commit

Permalink
Bugfix: Cannot initialize ParticleConservingU1/2 with default `init…
Browse files Browse the repository at this point in the history
…_state` (#5535)

**Context:** `qml.ParticleConservingU1` and `qml.ParticleConservingU2`
cannot be initialized with their default value for the `initial_state`
argument (the default value is `None`).

**Description of the Change:** If the `initial_state` argument is not
specified, it is set to a tuple of zeros, which seems a reasonable
choice for an initial state in physics. This modification occurs only if
the initial state is not specified and the information is reported in
the class's docstring.

**Benefits:** The error is no longer raised when the initial state is
not specified, and the class works with the default argument.

**Possible Drawbacks:** As mentioned above, this modification only
occurs if the initial state is not specified and should not cause any
issues.

**Related GitHub Issues:** #5522 

[sc-61431]
  • Loading branch information
PietropaoloFrisoni committed Apr 19, 2024
1 parent 016d2cc commit bb672a3
Show file tree
Hide file tree
Showing 5 changed files with 15 additions and 8 deletions.
3 changes: 3 additions & 0 deletions doc/releases/changelog-dev.md
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,9 @@

<h3>Bug fixes 🐛</h3>

* `qml.ParticleConservingU1` and `qml.ParticleConservingU2` no longer raise an error when the initial state is not specified but default to the all-zeros state.
[(#5535)](https://github.com/PennyLaneAI/pennylane/pull/5535)

* `qml.counts` no longer returns negative samples when measuring 8 or more wires.
[(#5544)](https://github.com/PennyLaneAI/pennylane/pull/5544)

Expand Down
6 changes: 4 additions & 2 deletions pennylane/templates/layers/particle_conserving_u1.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,9 +183,9 @@ class ParticleConservingU1(Operation):
weights (tensor_like): Array of weights of shape ``(D, M, 2)``.
``D`` is the number of entangler block layers and :math:`M=N-1`
is the number of exchange gates :math:`U_{1,\mathrm{ex}}` per layer.
wires (Iterable): wires that the template acts on
wires (Iterable): wires that the template acts on.
init_state (tensor_like): iterable or shape ``(len(wires),)`` tensor representing the Hartree-Fock state
used to initialize the wires
used to initialize the wires. If ``None``, a tuple of zeros is selected as initial state.
.. details::
:title: Usage Details
Expand Down Expand Up @@ -266,6 +266,8 @@ def __init__(self, weights, wires, init_state=None, id=None):
f"Weights tensor must have third dimension of length 2; got {shape[2]}"
)

init_state = tuple(0 for _ in wires) if init_state is None else init_state

self._hyperparameters = {"init_state": tuple(init_state)}

super().__init__(weights, wires=wires, id=id)
Expand Down
6 changes: 4 additions & 2 deletions pennylane/templates/layers/particle_conserving_u2.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,9 @@ class ParticleConservingU2(Operation):
weights (tensor_like): Weight tensor of shape ``(D, M)`` where ``D`` is the number of
layers and ``M`` = ``2N-1`` is the total number of rotation ``(N)`` and exchange
``(N-1)`` gates per layer.
wires (Iterable): wires that the template acts on
wires (Iterable): wires that the template acts on.
init_state (tensor_like): iterable or shape ``(len(wires),)`` tensor representing the Hartree-Fock state
used to initialize the wires.
used to initialize the wires. If ``None``, a tuple of zeros is selected as initial state.
.. details::
:title: Usage Details
Expand Down Expand Up @@ -171,6 +171,8 @@ def __init__(self, weights, wires, init_state=None, id=None):
f"Weights tensor must have a second dimension of length {2 * len(wires) - 1}; got {shape[1]}"
)

init_state = tuple(0 for _ in wires) if init_state is None else init_state

self._hyperparameters = {"init_state": tuple(init_state)}

super().__init__(weights, wires=wires, id=id)
Expand Down
4 changes: 2 additions & 2 deletions tests/templates/test_layers/test_particle_conserving_u1.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@
from pennylane import numpy as pnp


def test_standard_validity():
@pytest.mark.parametrize("init_state", [np.array([1, 1, 0]), None])
def test_standard_validity(init_state):
"""Check the operation using the assert_valid function."""

weights = np.random.random(size=(1, 2, 2))
init_state = np.array([1, 1, 0])
op = qml.ParticleConservingU1(weights, wires=range(3), init_state=init_state)

qml.ops.functions.assert_valid(op)
Expand Down
4 changes: 2 additions & 2 deletions tests/templates/test_layers/test_particle_conserving_u2.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@
from pennylane import numpy as pnp


def test_standard_validity():
@pytest.mark.parametrize("init_state", [np.array([1, 1, 0, 0]), None])
def test_standard_validity(init_state):
"""Run standard checks with the assert_valid function."""

layers = 2
qubits = 4

weights = np.random.normal(0, 2 * np.pi, (layers, 2 * qubits - 1))
init_state = np.array([1, 1, 0, 0])
op = qml.ParticleConservingU2(weights, wires=range(qubits), init_state=init_state)
qml.ops.functions.assert_valid(op)

Expand Down

0 comments on commit bb672a3

Please sign in to comment.