Skip to content

Commit

Permalink
Rename StatePrep to StatePrepBase and QubitStateVector to `Stat…
Browse files Browse the repository at this point in the history
…ePrep` (#4450)

* Support midcircuit stateprep

* Added tests for code cobv

* changelog

* lint

* fix typo

* fix doc-string

* address code review

* Add support for defaultqubit2

* changelog

* lint

* lint

* ci

* ci

* code review

* renamed StatePrep --> InitialState

* Support `StatePrep` mid-circuit for `DefaultQubit2` (#4444)

* Add support for defaultqubit2

* changelog

* lint

* ci

* code review

* renamed QSV --> StatePrep

* lint

* Fixed test

* lint

* Fix doc

* renamed  --

* fixed bug and pylint

* changelog fix + datasets fix

* Apply suggestions from code review

Co-authored-by: Christina Lee <christina@xanadu.ai>

* fix tests

* fix indent

* Update pennylane/_qubit_device.py

Co-authored-by: Christina Lee <christina@xanadu.ai>

* lijnt

---------

Co-authored-by: Christina Lee <christina@xanadu.ai>
Co-authored-by: Mudit Pandey <mudit.pandey@xanadu.ai>
  • Loading branch information
3 people committed Aug 17, 2023
1 parent 6b46da5 commit 7e0e5af
Show file tree
Hide file tree
Showing 83 changed files with 463 additions and 434 deletions.
2 changes: 1 addition & 1 deletion doc/introduction/operations.rst
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ State preparation
:nosignatures:

~pennylane.BasisState
~pennylane.QubitStateVector
~pennylane.StatePrep
~pennylane.QubitDensityMatrix

:html:`</div>`
Expand Down
4 changes: 4 additions & 0 deletions doc/releases/changelog-dev.md
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,10 @@ array([False, False])
* The gradients module no longer needs shot information passed to it explicitly, as the shots are on the tapes.
[(#4448)](https://github.com/PennyLaneAI/pennylane/pull/4448)

* `StatePrep` is renamed to `StatePrepBase` and `QubitStateVector` is renamed to `StatePrep`.
`qml.operation.StatePrep` and `qml.QubitStateVector` will still be accessible for the time being.
[(#4450)](https://github.com/PennyLaneAI/pennylane/pull/4450)

<h3>Deprecations 👋</h3>

* ``qml.qchem.jordan_wigner`` is deprecated, use ``qml.jordan_wigner`` instead.
Expand Down
6 changes: 3 additions & 3 deletions pennylane/_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
Variance,
)

from pennylane.operation import Observable, Operation, Tensor, Operator, StatePrep
from pennylane.operation import Observable, Operation, Tensor, Operator, StatePrepBase
from pennylane.ops import Hamiltonian, Sum
from pennylane.tape import QuantumScript, QuantumTape, expand_tape_state_prep
from pennylane.wires import WireError, Wires
Expand Down Expand Up @@ -665,9 +665,9 @@ def default_expand_fn(self, circuit, max_expansion=10):
if max_expansion == 0:
return circuit

expand_state_prep = any(isinstance(op, StatePrep) for op in circuit.operations[1:])
expand_state_prep = any(isinstance(op, StatePrepBase) for op in circuit.operations[1:])

if expand_state_prep: # expand mid-circuit StatePrep operations
if expand_state_prep: # expand mid-circuit StatePrepBase operations
circuit = expand_tape_state_prep(circuit)

comp_basis_sampled_multi_measure = (
Expand Down
2 changes: 1 addition & 1 deletion pennylane/_qubit_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -1991,7 +1991,7 @@ def adjoint_jacobian(
)
ops = op.decomposition()
expanded_ops.extend(reversed(ops))
elif op.name not in ("QubitStateVector", "BasisState", "Snapshot"):
elif op.name not in ("StatePrep", "QubitStateVector", "BasisState", "Snapshot"):
expanded_ops.append(op)

trainable_params = []
Expand Down
1 change: 1 addition & 0 deletions pennylane/data/attributes/operator/operator.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ def consumes_types(cls) -> FrozenSet[Type[Operator]]:
# pennylane/ops/state_preparation.py
qml.BasisState,
qml.QubitStateVector,
qml.StatePrep,
qml.QubitDensityMatrix,
# pennylane/ops/qutrit/matrix_obs.py
qml.QutritUnitary,
Expand Down
7 changes: 4 additions & 3 deletions pennylane/devices/default_mixed.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
DeviceError,
QubitDensityMatrix,
QubitDevice,
QubitStateVector,
StatePrep,
Snapshot,
)
from pennylane import numpy as np
Expand Down Expand Up @@ -86,6 +86,7 @@ class DefaultMixed(QubitDevice):
"Snapshot",
"BasisState",
"QubitStateVector",
"StatePrep",
"QubitDensityMatrix",
"QubitUnitary",
"ControlledQubitUnitary",
Expand Down Expand Up @@ -604,7 +605,7 @@ def _apply_operation(self, operation):
if operation.name == "Identity":
return

if isinstance(operation, QubitStateVector):
if isinstance(operation, StatePrep):
self._apply_state_vector(operation.parameters[0], wires)
return

Expand Down Expand Up @@ -755,7 +756,7 @@ def apply(self, operations, rotations=None, **kwargs):

# apply the circuit operations
for i, operation in enumerate(operations):
if i > 0 and isinstance(operation, (QubitStateVector, BasisState)):
if i > 0 and isinstance(operation, (StatePrep, BasisState)):
raise DeviceError(
f"Operation {operation.name} cannot be used after other Operations have already been applied "
f"on a {self.short_name} device."
Expand Down
7 changes: 4 additions & 3 deletions pennylane/devices/default_qubit.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
from scipy.sparse import csr_matrix

import pennylane as qml
from pennylane import BasisState, DeviceError, QubitDevice, QubitStateVector, Snapshot
from pennylane import BasisState, DeviceError, QubitDevice, StatePrep, Snapshot
from pennylane.devices.qubit import measure
from pennylane.operation import Operation
from pennylane.ops import Sum
Expand Down Expand Up @@ -113,6 +113,7 @@ class DefaultQubit(QubitDevice):
"Identity",
"Snapshot",
"BasisState",
"StatePrep",
"QubitStateVector",
"QubitUnitary",
"ControlledQubitUnitary",
Expand Down Expand Up @@ -270,13 +271,13 @@ def apply(self, operations, rotations=None, **kwargs):

# apply the circuit operations
for i, operation in enumerate(operations):
if i > 0 and isinstance(operation, (QubitStateVector, BasisState)):
if i > 0 and isinstance(operation, (StatePrep, BasisState)):
raise DeviceError(
f"Operation {operation.name} cannot be used after other Operations have already been applied "
f"on a {self.short_name} device."
)

if isinstance(operation, QubitStateVector):
if isinstance(operation, StatePrep):
self._apply_state_vector(operation.parameters[0], operation.wires)
elif isinstance(operation, BasisState):
self._apply_basis_state(operation.parameters[0], operation.wires)
Expand Down
1 change: 1 addition & 0 deletions pennylane/devices/null_qubit.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ class NullQubit(QubitDevice):
"Identity",
"Snapshot",
"BasisState",
"StatePrep",
"QubitStateVector",
"QubitUnitary",
"ControlledQubitUnitary",
Expand Down
4 changes: 2 additions & 2 deletions pennylane/devices/qubit/initialize_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,15 @@

def create_initial_state(
wires: Union[qml.wires.Wires, Iterable],
prep_operation: qml.operation.StatePrep = None,
prep_operation: qml.operation.StatePrepBase = None,
like: str = None,
):
r"""
Returns an initial state, defaulting to :math:`\ket{0}` if no state-prep operator is provided.
Args:
wires (Union[Wires, Iterable]): The wires to be present in the initial state
prep_operation (Optional[StatePrep]): An operation to prepare the initial state
prep_operation (Optional[StatePrepBase]): An operation to prepare the initial state
like (Optional[str]): The machine learning interface used to create the initial state.
Defaults to None
Expand Down
6 changes: 3 additions & 3 deletions pennylane/devices/qubit/preprocess.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

import pennylane as qml

from pennylane.operation import Tensor, StatePrep
from pennylane.operation import Tensor, StatePrepBase
from pennylane.measurements import (
MidMeasureMP,
StateMeasurement,
Expand Down Expand Up @@ -250,8 +250,8 @@ def expand_fn(circuit: qml.tape.QuantumScript) -> qml.tape.QuantumScript:

if not all(_accepted_operator(op) for op in circuit.operations):
try:
# don't decompose initial operations if its StatePrep
prep_op = [circuit[0]] if isinstance(circuit[0], StatePrep) else []
# don't decompose initial operations if its StatePrepBase
prep_op = [circuit[0]] if isinstance(circuit[0], StatePrepBase) else []

new_ops = [
final_op
Expand Down
2 changes: 1 addition & 1 deletion pennylane/devices/qubit/simulate.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def get_final_state(circuit, debugger=None):
circuit = qml.map_wires(circuit, wire_map)

prep = None
if len(circuit) > 0 and isinstance(circuit[0], qml.operation.StatePrep):
if len(circuit) > 0 and isinstance(circuit[0], qml.operation.StatePrepBase):
prep = circuit[0]

state = create_initial_state(circuit.wires, prep)
Expand Down
23 changes: 12 additions & 11 deletions pennylane/devices/tests/test_gates.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
"CPhaseShift01": qml.CPhaseShift01(0, wires=[0, 1]),
"CPhaseShift10": qml.CPhaseShift10(0, wires=[0, 1]),
"QubitStateVector": qml.QubitStateVector(np.array([1.0, 0.0]), wires=[0]),
"StatePrep": qml.StatePrep(np.array([1.0, 0.0]), wires=[0]),
"QubitDensityMatrix": qml.QubitDensityMatrix(np.array([[0.5, 0.0], [0, 0.5]]), wires=[0]),
"QubitUnitary": qml.QubitUnitary(np.eye(2), wires=[0]),
"SpecialUnitary": qml.SpecialUnitary(np.array([0.2, -0.1, 2.3]), wires=1),
Expand Down Expand Up @@ -391,8 +392,8 @@ def circuit():
expected[np.ravel_multi_index(basis_state, [2] * n_wires)] = 1
assert np.allclose(res, expected, atol=tol(dev.shots))

def test_qubit_state_vector(self, device, init_state, tol, skip_if):
"""Test QubitStateVector initialisation."""
def test_state_prep(self, device, init_state, tol, skip_if):
"""Test StatePrep initialisation."""
n_wires = 1
dev = device(n_wires)
skip_if(dev, {"returns_probs": False})
Expand All @@ -401,7 +402,7 @@ def test_qubit_state_vector(self, device, init_state, tol, skip_if):

@qml.qnode(dev)
def circuit():
qml.QubitStateVector(rnd_state, wires=range(n_wires))
qml.StatePrep(rnd_state, wires=range(n_wires))
return qml.probs(range(n_wires))

res = circuit()
Expand All @@ -420,7 +421,7 @@ def test_single_qubit_no_parameters(self, device, init_state, op, mat, tol, skip

@qml.qnode(dev)
def circuit():
qml.QubitStateVector(rnd_state, wires=range(n_wires))
qml.StatePrep(rnd_state, wires=range(n_wires))
op(wires=range(n_wires))
return qml.probs(wires=range(n_wires))

Expand All @@ -441,7 +442,7 @@ def test_single_qubit_parameters(self, device, init_state, op, func, gamma, tol,

@qml.qnode(dev)
def circuit():
qml.QubitStateVector(rnd_state, wires=range(n_wires))
qml.StatePrep(rnd_state, wires=range(n_wires))
op(gamma, wires=range(n_wires))
return qml.probs(wires=range(n_wires))

Expand All @@ -463,7 +464,7 @@ def test_rotation(self, device, init_state, tol, skip_if):

@qml.qnode(dev)
def circuit():
qml.QubitStateVector(rnd_state, wires=range(n_wires))
qml.StatePrep(rnd_state, wires=range(n_wires))
qml.Rot(a, b, c, wires=range(n_wires))
return qml.probs(wires=range(n_wires))

Expand All @@ -485,7 +486,7 @@ def test_two_qubit_no_parameters(self, device, init_state, op, mat, tol, skip_if

@qml.qnode(dev)
def circuit():
qml.QubitStateVector(rnd_state, wires=range(n_wires))
qml.StatePrep(rnd_state, wires=range(n_wires))
op(wires=range(n_wires))
return qml.probs(wires=range(n_wires))

Expand All @@ -506,7 +507,7 @@ def test_two_qubit_parameters(self, device, init_state, op, func, param, tol, sk

@qml.qnode(dev)
def circuit():
qml.QubitStateVector(rnd_state, wires=range(n_wires))
qml.StatePrep(rnd_state, wires=range(n_wires))
op(param, wires=range(n_wires))
return qml.probs(wires=range(n_wires))

Expand All @@ -530,7 +531,7 @@ def test_qubit_unitary(self, device, init_state, mat, tol, skip_if):

@qml.qnode(dev)
def circuit():
qml.QubitStateVector(rnd_state, wires=range(n_wires))
qml.StatePrep(rnd_state, wires=range(n_wires))
qml.QubitUnitary(mat, wires=list(range(n_wires)))
return qml.probs(wires=range(n_wires))

Expand All @@ -554,7 +555,7 @@ def test_special_unitary(self, device, init_state, theta_, tol, skip_if):

@qml.qnode(dev)
def circuit():
qml.QubitStateVector(rnd_state, wires=range(n_wires))
qml.StatePrep(rnd_state, wires=range(n_wires))
qml.SpecialUnitary(theta_, wires=list(range(n_wires)))
return qml.probs(wires=range(n_wires))

Expand All @@ -579,7 +580,7 @@ def test_three_qubit_no_parameters(self, device, init_state, op, mat, tol, skip_

@qml.qnode(dev)
def circuit():
qml.QubitStateVector(rnd_state, wires=range(n_wires))
qml.StatePrep(rnd_state, wires=range(n_wires))
op(wires=[0, 1, 2])
return qml.probs(wires=range(n_wires))

Expand Down
6 changes: 3 additions & 3 deletions pennylane/devices/tests/test_gates_with_expval.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ def test_state_vector_3_qubit_subset(self, device, tol, par, wires, expected_out

@qml.qnode(dev)
def circuit():
qml.QubitStateVector(par, wires=wires)
qml.StatePrep(par, wires=wires)
return qml.expval(qml.PauliZ(0)), qml.expval(qml.PauliZ(1)), qml.expval(qml.PauliZ(2))

assert np.allclose(circuit(), expected_output, atol=tol(dev.shots))
Expand Down Expand Up @@ -213,7 +213,7 @@ def test_supported_gate_two_wires_with_parameters(

@qml.qnode(dev)
def circuit():
qml.QubitStateVector(np.array([1 / 2, 0, 0, sqrt(3) / 2]), wires=[0, 1])
qml.StatePrep(np.array([1 / 2, 0, 0, sqrt(3) / 2]), wires=[0, 1])
op(*par, wires=[0, 1])
return qml.expval(qml.PauliZ(0)), qml.expval(qml.PauliZ(1))

Expand Down Expand Up @@ -263,7 +263,7 @@ def test_supported_gate_two_wires_no_parameters(self, device, tol, name, expecte

@qml.qnode(dev)
def circuit():
qml.QubitStateVector(np.array([1 / 2, 0, 0, sqrt(3) / 2]), wires=[0, 1])
qml.StatePrep(np.array([1 / 2, 0, 0, sqrt(3) / 2]), wires=[0, 1])
op(wires=[0, 1])
return qml.expval(qml.PauliZ(0)), qml.expval(qml.PauliZ(1))

Expand Down
13 changes: 10 additions & 3 deletions pennylane/operation.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,11 +121,11 @@
~CVOperation
~Channel
~Tensor
~StatePrep
~StatePrepBase
.. currentmodule:: pennylane.operation
.. inheritance-diagram:: Operator Operation Observable Channel CV CVObservable CVOperation Tensor StatePrep
.. inheritance-diagram:: Operator Operation Observable Channel CV CVObservable CVOperation Tensor StatePrepBase
:parts: 1
Errors
Expand Down Expand Up @@ -2827,7 +2827,7 @@ def heisenberg_obs(self, wire_order):
return self.heisenberg_expand(U, wire_order)


class StatePrep(Operation):
class StatePrepBase(Operation):
"""An interface for state-prep operations."""

grad_method = None
Expand Down Expand Up @@ -3011,3 +3011,10 @@ def active_new_opmath():
True
"""
return __use_new_opmath


def __getattr__(name):
"""To facilitate StatePrep rename"""
if name == "StatePrep":
return StatePrepBase
raise AttributeError(f"module 'pennylane.operation' has no attribute '{name}'")
3 changes: 2 additions & 1 deletion pennylane/ops/functions/is_commuting.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,8 +260,9 @@ def check_commutation_two_non_simplified_rotations(operation1, operation2):
"SProd",
]
non_commuting_operations = [
# State Prep
# StatePrepBase
"QubitStateVector",
"StatePrep",
"BasisState",
# Templates
"ArbitraryStatePreparation",
Expand Down
1 change: 1 addition & 0 deletions pennylane/ops/qubit/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@
"IsingZZ",
"IsingXY",
"BasisState",
"StatePrep",
"QubitStateVector",
"QubitDensityMatrix",
"QubitUnitary",
Expand Down
1 change: 1 addition & 0 deletions pennylane/ops/qubit/attributes.py
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ def __contains__(self, obj):
"OrbitalRotation",
"FermionicSWAP",
"QubitStateVector",
"StatePrep",
"AmplitudeEmbedding",
"AngleEmbedding",
"IQPEmbedding",
Expand Down
Loading

0 comments on commit 7e0e5af

Please sign in to comment.