-
Notifications
You must be signed in to change notification settings - Fork 622
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adds a convenience prob()
measurement function to return the probabilities of all computational basis states in a single QNode evaluation
#432
Changes from 11 commits
9a0bdc5
7598bcd
f5c5953
773da6a
7f10806
4cc2e53
357a7d2
cabb8f0
e49577d
20401a7
2507599
6dff8c9
df134b4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,7 +18,7 @@ | |
and measurement samples. | ||
""" | ||
import pennylane as qml | ||
from .operation import Observable, Sample, Variance, Expectation, Tensor | ||
from .operation import Observable, Sample, Variance, Expectation, Probability, Tensor | ||
from .qnodes import QuantumFunctionError | ||
|
||
|
||
|
@@ -31,6 +31,24 @@ def _remove_if_in_queue(op): | |
def expval(op): | ||
r"""Expectation value of the supplied observable. | ||
|
||
**Example:** | ||
|
||
.. code-block:: python3 | ||
|
||
dev = qml.device("default.qubit", wires=2) | ||
|
||
@qml.qnode(dev) | ||
def circuit(x): | ||
qml.RX(x, wires=0) | ||
qml.Hadamard(wires=1) | ||
qml.CNOT(wires=[0, 1]) | ||
return qml.expval(qml.PauliY(0)) | ||
|
||
Executing this QNode: | ||
|
||
>>> circuit(0.5) | ||
-0.4794255386042029 | ||
|
||
Args: | ||
op (Observable): a quantum observable object | ||
|
||
|
@@ -63,6 +81,24 @@ def expval(op): | |
def var(op): | ||
r"""Variance of the supplied observable. | ||
|
||
**Example:** | ||
|
||
.. code-block:: python3 | ||
|
||
dev = qml.device("default.qubit", wires=2) | ||
|
||
@qml.qnode(dev) | ||
def circuit(x): | ||
qml.RX(x, wires=0) | ||
qml.Hadamard(wires=1) | ||
qml.CNOT(wires=[0, 1]) | ||
return qml.var(qml.PauliY(0)) | ||
|
||
Executing this QNode: | ||
|
||
>>> circuit(0.5) | ||
0.7701511529340698 | ||
|
||
Args: | ||
op (Observable): a quantum observable object | ||
|
||
|
@@ -96,6 +132,24 @@ def sample(op): | |
r"""Sample from the supplied observable, with the number of shots | ||
determined from the ``dev.shots`` attribute of the corresponding device. | ||
|
||
**Example:** | ||
|
||
.. code-block:: python3 | ||
|
||
dev = qml.device("default.qubit", wires=2, shots=4) | ||
|
||
@qml.qnode(dev) | ||
def circuit(x): | ||
qml.RX(x, wires=0) | ||
qml.Hadamard(wires=1) | ||
qml.CNOT(wires=[0, 1]) | ||
return qml.sample(qml.PauliY(0)) | ||
|
||
Executing this QNode: | ||
|
||
>>> circuit(0.5) | ||
array([ 1., 1., 1., -1.]) | ||
|
||
Args: | ||
op (Observable): a quantum observable object | ||
|
||
|
@@ -123,3 +177,48 @@ def sample(op): | |
qml._current_context._append_op(op) | ||
|
||
return op | ||
|
||
|
||
def probs(wires): | ||
r"""Probability of each computational basis state. | ||
|
||
This measurement function accepts no observables, and instead | ||
instructs the QNode to return a flat array containing the | ||
probabilities of each quantum state. | ||
|
||
Marginal probabilities may also be requested by restricting | ||
the wires to a subset of the full system. | ||
|
||
**Example:** | ||
|
||
.. code-block:: python3 | ||
|
||
dev = qml.device("default.qubit", wires=2) | ||
|
||
@qml.qnode(dev) | ||
def circuit(): | ||
qml.Hadamard(wires=1) | ||
qml.CNOT(wires=[0, 1]) | ||
return qml.probs(wires=[0, 1]) | ||
|
||
Executing this QNode: | ||
|
||
>>> circuit() | ||
array([0.5, 0.5, 0. , 0. ]) | ||
|
||
The returned array is in lexicographic order, so corresponds | ||
to a :math:`50\%` chance of measuring either :math:`|00\rangle` | ||
or :math:`|01\rangle`. | ||
|
||
Args: | ||
wires (Sequence[int] or int): the wire the operation acts on | ||
""" | ||
# pylint: disable=protected-access | ||
op = qml.Identity(wires=wires, do_queue=False) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Currently There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It looks the # True if op is a CV, False if it is a discrete variable (Identity could be either)
are_cvs = [
isinstance(op, CV) for op in self.queue + list(res) if not isinstance(op, qml.Identity)
] |
||
op.return_type = Probability | ||
|
||
if qml._current_context is not None: | ||
# add observable to QNode observable queue | ||
qml._current_context._append_op(op) | ||
|
||
return op |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -521,11 +521,16 @@ def operations(self): | |
def observables(self): | ||
return set(self._observable_map.keys()) | ||
|
||
def probability(self): | ||
def probability(self, wires=None): | ||
if self._state is None: | ||
return None | ||
|
||
states = itertools.product(range(2), repeat=self.num_wires) | ||
probs = np.abs(self._state)**2 | ||
prob = np.abs(self._state.reshape([2] * self.num_wires)) ** 2 | ||
|
||
return OrderedDict(zip(states, probs)) | ||
wires = wires or range(self.num_wires) | ||
wires = np.hstack(wires) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How come this line would be needed? One of the reasons could be flattening There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good question. I can't remember why I needed to add this line 🤔 |
||
|
||
basis_states = itertools.product(range(2), repeat=len(wires)) | ||
inactive_wires = list(set(range(self.num_wires)) - set(wires)) | ||
prob = np.apply_over_axes(np.sum, prob, inactive_wires).flatten() | ||
return OrderedDict(zip(basis_states, prob)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As an extra sentence, it might be worth adding something like the explanation in the example such as
The dimension of the computational basis states is equal to the number of wires specified.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated to say
Marginal probabilities may also be requested by restricting the wires to a subset of the full system; the size of the returned array will be ``[2**len(wires)]``.