Skip to content

Commit

Permalink
Merge branch 'atomic-numbers-upgrade' of https://github.com/PennyLane…
Browse files Browse the repository at this point in the history
…AI/pennylane into atomic-numbers-upgrade
  • Loading branch information
obliviateandsurrender committed Jul 18, 2024
2 parents a0f282a + 3a62e27 commit be0ecf5
Show file tree
Hide file tree
Showing 13 changed files with 939 additions and 136 deletions.
15 changes: 7 additions & 8 deletions doc/development/deprecations.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,6 @@ Pending deprecations
- Deprecated in v0.37
- Will be removed in v0.39

* ``qml.from_qasm`` will no longer remove measurements from the QASM code. Calling ``qml.from_qasm``
on a circuit containing measurements without specifying ``measurements`` will raise a deprecation
warning in v0.37, and in v0.38, the default behaviour will be changed to keeping measurements. Use
``measurements=[]`` to remove measurements from the original circuit.

- Deprecated in v0.37
- Default behaviour will be changed in v0.38

New operator arithmetic deprecations
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Expand Down Expand Up @@ -73,6 +65,13 @@ Other deprecations
Completed deprecation cycles
----------------------------


* ``qml.from_qasm`` no longer removes measurements from the QASM code. Use
``measurements=[]`` to remove measurements from the original circuit.

- Deprecated in v0.37
- Default behaviour changed in v0.38

* ``qml.transforms.map_batch_transform`` has been removed, since transforms can be applied directly to a batch of tapes.
See :func:`~.pennylane.transform` for more information.

Expand Down
33 changes: 27 additions & 6 deletions doc/releases/changelog-dev.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,29 @@

<h3>New features since last release</h3>

* Resolved the bug in `qml.ThermalRelaxationError` where there was a typo from `tq` to `tg`.
[(#5988)](https://github.com/PennyLaneAI/pennylane/issues/5988)

* A new method `process_density_matrix` has been added to the `ProbabilityMP` and `DensityMatrixMP` classes, allowing for more efficient handling of quantum density matrices, particularly with batch processing support. This method simplifies the calculation of probabilities from quantum states represented as density matrices.
[(#5830)](https://github.com/PennyLaneAI/pennylane/pull/5830)

* The `qml.PrepSelPrep` template is added. The template implements a block-encoding of a linear
* The `qml.PrepSelPrep` template is added. The template implements a block-encoding of a linear
combination of unitaries.
[(#5756)](https://github.com/PennyLaneAI/pennylane/pull/5756)

* The `split_to_single_terms` transform is added. This transform splits expectation values of sums
into multiple single-term measurements on a single tape, providing better support for simulators
* The `split_to_single_terms` transform is added. This transform splits expectation values of sums
into multiple single-term measurements on a single tape, providing better support for simulators
that can handle non-commuting observables but don't natively support multi-term observables.
[(#5884)](https://github.com/PennyLaneAI/pennylane/pull/5884)

* `SProd.terms` now flattens out the terms if the base is a multi-term observable.
[(#5885)](https://github.com/PennyLaneAI/pennylane/pull/5885)

<h3>Improvements 🛠</h3>

* `StateMP.process_state` defines rules in `cast_to_complex` for complex casting, avoiding a superfluous state vector copy in Lightning simulations
[(#5995)](https://github.com/PennyLaneAI/pennylane/pull/5995)

* Port the fast `apply_operation` implementation of `PauliZ` to `PhaseShift`, `S` and `T`.
[(#5876)](https://github.com/PennyLaneAI/pennylane/pull/5876)

Expand All @@ -34,15 +40,27 @@

* The representation for `Wires` has now changed to be more copy-paste friendly.
[(#5958)](https://github.com/PennyLaneAI/pennylane/pull/5958)

* Observable validation for `default.qubit` is now based on execution mode (analytic vs. finite shots) and measurement type (sample measurement vs. state measurement).
[(#5890)](https://github.com/PennyLaneAI/pennylane/pull/5890)

* Molecules and Hamiltonians can now be constructed for all the elements present in the periodic table.
[(#5821)](https://github.com/PennyLaneAI/pennylane/pull/5821)

<h4>Community contributions 🥳</h4>

* `DefaultQutritMixed` readout error has been added using parameters `readout_relaxation_probs` and
`readout_misclassification_probs` on the `default.qutrit.mixed` device. These parameters add a `~.QutritAmplitudeDamping` and a `~.TritFlip` channel, respectively,
after measurement diagonalization. The amplitude damping error represents the potential for
relaxation to occur during longer measurements. The trit flip error represents misclassification during readout.
[(#5842)](https://github.com/PennyLaneAI/pennylane/pull/5842)

<h3>Breaking changes 💔</h3>

* ``qml.from_qasm`` no longer removes measurements from the QASM code. Use
``measurements=[]`` to remove measurements from the original circuit.
[(#5982)](https://github.com/PennyLaneAI/pennylane/pull/5982)

* ``qml.transforms.map_batch_transform`` has been removed, since transforms can be applied directly to a batch of tapes.
See :func:`~.pennylane.transform` for more information.
[(#5981)](https://github.com/PennyLaneAI/pennylane/pull/5981)
Expand Down Expand Up @@ -77,11 +95,14 @@

This release contains contributions from (in alphabetical order):
Guillermo Alonso,
Ahmed Darwish,
Utkarsh Azad
Astral Cai,
Yushao Chen,
Gabriel Bottrill,
Ahmed Darwish,
Lillian M. A. Frederiksen,
Pietropaolo Frisoni,
Emiliano Godinez,
Christina Lee,
Austin Huang,
William Maxwell,
Expand Down
1 change: 1 addition & 0 deletions pennylane/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
from pennylane.configuration import Configuration
from pennylane.drawer import draw, draw_mpl
from pennylane.tracker import Tracker

from pennylane.io import *
from pennylane.measurements import (
counts,
Expand Down
109 changes: 105 additions & 4 deletions pennylane/devices/default_qutrit_mixed.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
"""The default.qutrit.mixed device is PennyLane's standard qutrit simulator for mixed-state
computations."""
import logging
import warnings
from dataclasses import replace
from functools import partial
from typing import Callable, Optional, Sequence, Tuple, Union

import numpy as np
Expand All @@ -33,6 +35,7 @@
from .preprocess import (
decompose,
no_sampling,
null_postprocessing,
validate_device_wires,
validate_measurements,
validate_observables,
Expand Down Expand Up @@ -85,10 +88,67 @@ def accepted_sample_measurement(m: qml.measurements.MeasurementProcess) -> bool:
return isinstance(m, qml.measurements.SampleMeasurement)


@qml.transform
def warn_readout_error_state(
tape: qml.tape.QuantumTape,
) -> tuple[Sequence[qml.tape.QuantumTape], Callable]:
"""If a measurement in the QNode is an analytic state or density_matrix, and a readout error
parameter is defined, warn that readout error will not be applied.
Args:
tape (QuantumTape, .QNode, Callable): a quantum circuit.
Returns:
qnode (pennylane.QNode) or quantum function (callable) or tuple[List[.QuantumTape], function]:
The unaltered input circuit.
"""
if not tape.shots:
for m in tape.measurements:
if isinstance(m, qml.measurements.StateMP):
warnings.warn(f"Measurement {m} is not affected by readout error.")

return (tape,), null_postprocessing


def get_readout_errors(readout_relaxation_probs, readout_misclassification_probs):
r"""Get the list of readout errors that should be applied to each measured wire.
Args:
readout_relaxation_probs (List[float]): Inputs for :class:`~.QutritAmplitudeDamping` channel
of the form :math:`[\gamma_{10}, \gamma_{20}, \gamma_{21}]`. This error models
amplitude damping associated with longer readout and varying relaxation times of
transmon-based qudits.
readout_misclassification_probs (List[float]): Inputs for :class:`~.TritFlip` channel
of the form :math:`[p_{01}, p_{02}, p_{12}]`. This error models misclassification events
in readout.
Returns:
readout_errors (List[Callable]): List of readout error channels that should be
applied to each measured wire.
"""
measure_funcs = []
if readout_relaxation_probs is not None:
try:
with qml.queuing.QueuingManager.stop_recording():
qml.QutritAmplitudeDamping(*readout_relaxation_probs, wires=0)
except Exception as e:
raise qml.DeviceError("Applying damping readout error results in error:\n" + str(e))
measure_funcs.append(partial(qml.QutritAmplitudeDamping, *readout_relaxation_probs))
if readout_misclassification_probs is not None:
try:
with qml.queuing.QueuingManager.stop_recording():
qml.TritFlip(*readout_misclassification_probs, wires=0)
except Exception as e:
raise qml.DeviceError("Applying trit flip readout error results in error:\n" + str(e))
measure_funcs.append(partial(qml.TritFlip, *readout_misclassification_probs))

return None if len(measure_funcs) == 0 else measure_funcs


@simulator_tracking
@single_tape_support
class DefaultQutritMixed(Device):
"""A PennyLane Python-based device for mixed-state qutrit simulation.
r"""A PennyLane Python-based device for mixed-state qutrit simulation.
Args:
wires (int, Iterable[Number, str]): Number of wires present on the device, or iterable that
Expand All @@ -104,6 +164,12 @@ class DefaultQutritMixed(Device):
If a ``jax.random.PRNGKey`` is passed as the seed, a JAX-specific sampling function using
``jax.random.choice`` and the ``PRNGKey`` will be used for sampling rather than
``numpy.random.default_rng``.
readout_relaxation_probs (List[float]): Input probabilities for relaxation errors implemented
with the :class:`~.QutritAmplitudeDamping` channel. The input defines the
channel's parameters :math:`[\gamma_{10}, \gamma_{20}, \gamma_{21}]`.
readout_misclassification_probs (List[float]): Input probabilities for state readout
misclassification events implemented with the :class:`~.TritFlip` channel. The input defines the
channel's parameters :math:`[p_{01}, p_{02}, p_{12}]`.
**Example:**
Expand Down Expand Up @@ -154,6 +220,33 @@ def f(x):
>>> jax.grad(f)(jax.numpy.array(1.2))
DeviceArray(-0.93203914, dtype=float32, weak_type=True)
.. details::
:title: Readout Error
``DefaultQutritMixed`` includes readout error support. Two input arguments control
the parameters of error channels applied to each measured wire of the state after
it has been diagonalized for measurement:
* ``readout_relaxation_probs``: Input parameters of a :class:`~.QutritAmplitudeDamping` channel.
This error models state relaxation error that occurs during readout of transmon-based qutrits.
The motivation for this readout error is described in [`1 <https://arxiv.org/abs/2003.03307>`_] (Sec II.A).
* ``readout_misclassification_probs``: Input parameters of a :class:`~.TritFlip` channel.
This error models misclassification events in readout. An example of this readout error
can be seen in [`2 <https://arxiv.org/abs/2309.11303>`_] (Fig 1a).
In the case that both parameters are defined, relaxation error is applied first then
misclassification error is applied.
.. note::
The readout errors will be applied to the state after it has been diagonalized for each
measurement. This may give different results depending on how the observable is defined.
This is because diagonalizing gates for the same observable may return eigenvalues in
different orders. For example, measuring :class:`~.THermitian` with a non-diagonal
GellMann matrix will result in a different measurement result then measuring the
equivalent :class:`~.GellMann` observable, as the THermitian eigenvalues are returned
in increasing order when explicitly diagonalized (i.e., ``[-1, 0, 1]``), while non-diagonal GellManns provided
in PennyLane have their eigenvalues hardcoded (i.e., ``[1, -1, 0]``).
.. details::
:title: Tracking
Expand All @@ -166,7 +259,6 @@ def f(x):
* ``batches``: The number of times :meth:`~.execute` is called.
* ``results``: The results of each call of :meth:`~.execute`
"""

_device_options = ("rng", "prng_key") # tuple of string names for all the device options.
Expand All @@ -177,11 +269,13 @@ def name(self):
return "default.qutrit.mixed"

@debug_logger_init
def __init__(
def __init__( # pylint: disable=too-many-arguments
self,
wires=None,
shots=None,
seed="global",
readout_relaxation_probs=None,
readout_misclassification_probs=None,
) -> None:
super().__init__(wires=wires, shots=shots)
seed = np.random.randint(0, high=10000000) if seed == "global" else seed
Expand All @@ -193,6 +287,10 @@ def __init__(
self._rng = np.random.default_rng(seed)
self._debugger = None

self.readout_errors = get_readout_errors(
readout_relaxation_probs, readout_misclassification_probs
)

@debug_logger
def supports_derivatives(
self,
Expand Down Expand Up @@ -284,6 +382,9 @@ def preprocess(
if config.gradient_method == "backprop":
transform_program.add_transform(no_sampling, name="backprop + default.qutrit")

if self.readout_errors is not None:
transform_program.add_transform(warn_readout_error_state)

return transform_program, config

@debug_logger
Expand All @@ -292,7 +393,6 @@ def execute(
circuits: QuantumTape_or_Batch,
execution_config: ExecutionConfig = DefaultExecutionConfig,
) -> Result_or_ResultBatch:

interface = (
execution_config.interface
if execution_config.gradient_method in {"best", "backprop", None}
Expand All @@ -306,6 +406,7 @@ def execute(
prng_key=self._prng_key,
debugger=self._debugger,
interface=interface,
readout_errors=self.readout_errors,
)
for c in circuits
)
Loading

0 comments on commit be0ecf5

Please sign in to comment.