Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/code/qp_io.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Functions
~from_qasm
~from_qasm3
~from_qiskit
~from_qiskit_noise
~from_qiskit_op
~from_quil
~from_quil_file
Expand Down
227 changes: 227 additions & 0 deletions doc/code/qp_noise.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
qp.noise
=========

This module contains the functionality for building and manipulating insertion-based noise models,
where noisy gates and channels are inserted based on the target operations and measurements.

.. _intro_noise_model:

Overview
--------

Insertion-based noise models in PennyLane are defined via a mapping from conditionals, specified
as :class:`~.BooleanFn` objects, to :ref:`quantum function <intro_vcirc_qfunc>`-like callables
that contain the noisy operations to be applied, but without any return statements. Additional
noise-related metadata can also be supplied to construct a noise model using:

.. currentmodule:: pennylane

.. autosummary::
:toctree: api

~NoiseModel

Each conditional in the ``model_map`` (and ``meas_map``) evaluates the gate operations
(and terminal measurements) in the quantum circuit based on some condition of its attributes
(e.g., type, parameters, wires, etc.) and uses the corresponding callable to apply the
noise operations, using the user-provided metadata (e.g., hardware topologies or relaxation
times), whenever the condition is true. A noise model, once built, can be attached
to a circuit or device via the following transform:

.. autosummary::
:toctree: api

~add_noise

.. _intro_boolean_fn:

Boolean functions
^^^^^^^^^^^^^^^^^

Each :class:`~.BooleanFn` in the noise model is evaluated on the operations of a given
quantum circuit. One can construct standard Boolean functions using the following helpers:

.. currentmodule:: pennylane.noise

.. autosummary::
:toctree: api

~meas_eq
~op_eq
~op_in
~wires_eq
~wires_in

For example, a Boolean function that checks if an operation is on wire ``0`` can be created
as follows:

>>> fn = qp.noise.wires_eq(0)
>>> op1, op2 = qp.PauliX(0), qp.PauliX(1)
>>> fn(op1)
True
>>> fn(op2)
False

Arbitrary Boolean functions can also be defined by wrapping the functional form
of custom conditions with the following decorator:

.. currentmodule:: pennylane

.. autosummary::
:toctree: api

~BooleanFn

For example, a Boolean function can be created to identify an :class:`~.RX` gate
with a maximum parameter value:

.. code-block:: python

@qp.BooleanFn
def rx_condition(op, **metadata):
return isinstance(op, qp.RX) and op.parameters[0] < 1.0

Boolean functions can be combined using standard bitwise operators, such as
``&``, ``|``, ``^``, or ``~``. The result will be another Boolean function. It
is important to note that as Python will evaluate the expression in the order
of their combination, i.e., left to right, the order of composition could matter,
even though bitwise operations are symmetric by definition.

Noisy quantum functions
^^^^^^^^^^^^^^^^^^^^^^^

If a Boolean function evaluates to ``True`` on a given operation in the quantum circuit,
the corresponding quantum function is evaluated that inserts the noise directly after
the operation. The quantum function should have signature ``fn(op, **metadata)``,
allowing for dependency on both the preceding operation and metadata specified in
the noise model. For example, the following noise model adds an over-rotation
to the ``RX`` gate:

.. code-block:: python

def noisy_rx(op, **metadata):
qp.RX(op.parameters[0] * 0.05, op.wires)

noise_model = qp.NoiseModel({rx_condition: noisy_rx})

A common use case is to have a single-operation :ref:`noise channel <intro_ref_ops_channels>`
whose wires are the same as the preceding operation. This can be constructed using:

.. currentmodule:: pennylane.noise

.. autosummary::
:toctree: api

~partial_wires

For example, a constant-valued over-rotation can be created using:

>>> rx_constant = qp.noise.partial_wires(qp.RX(0.1, wires=[0]))
>>> rx_constant(2)
RX(0.1, 2)

>>> qp.NoiseModel({rx_condition: rx_constant})
NoiseModel({
BooleanFn(rx_condition): RX(phi=0.1)
})

Example noise model
^^^^^^^^^^^^^^^^^^^

The following example shows how to set up an artificial noise model in PennyLane:

.. code-block:: python

# Set up the conditions
c0 = qp.noise.op_eq(qp.PauliX) | qp.noise.op_eq(qp.PauliY)
c1 = qp.noise.op_eq(qp.Hadamard) & qp.noise.wires_in([0, 1])
c2 = qp.noise.op_eq(qp.RX)

@qp.BooleanFn
def c3(op, **metadata):
return isinstance(op, qp.RY) and op.parameters[0] >= 0.5

# Set up noisy ops
n0 = qp.noise.partial_wires(qp.AmplitudeDamping, 0.4)

def n1(op, **metadata):
ThermalRelaxationError(0.4, metadata["t1"], 0.2, 0.6, op.wires)

def n2(op, **metadata):
qp.RX(op.parameters[0] * 0.05, op.wires)

n3 = qp.noise.partial_wires(qp.PhaseDamping, 0.9)

# Set up noise model
noise_model = qp.NoiseModel({c0: n0, c1: n1, c2: n2}, t1=0.04)
noise_model += {c3: n3} # One-at-a-time construction

>>> noise_model
NoiseModel({
OpEq(PauliX) | OpEq(PauliY): AmplitudeDamping(gamma=0.4)
OpEq(Hadamard) & WiresIn([0, 1]): n1
OpEq(RX): n2
BooleanFn(c3): PhaseDamping(gamma=0.9)
}, t1 = 0.04)

API overview
^^^^^^^^^^^^

The following are the ``BooleanFn`` objects created by calling the helper functions
above, such as :func:`~.op_eq`. These objects do not need to be instantiated directly

.. currentmodule:: pennylane.noise.conditionals

.. autosummary::
:toctree: api

~MeasEq
~OpEq
~OpIn
~WiresEq
~WiresIn

Bitwise operations like ``And`` and ``Or`` are represented with the following classes in the
:mod:`boolean_fn` module:

.. currentmodule:: pennylane.boolean_fn

.. autosummary::
:toctree: api

~And
~Or
~Xor
~Not

Class Inheritence Diagram
^^^^^^^^^^^^^^^^^^^^^^^^^

Note all child classes inherit from the same parent :class:`~.BooleanFn`,
but are just located in different modules.

**Noise Conditionals:**

.. inheritance-diagram:: pennylane.noise.conditionals
:parts: 1

**Boolean Fn conditionals:**

.. inheritance-diagram:: pennylane.boolean_fn
:parts: 1

Noise transforms
^^^^^^^^^^^^^^^^

.. currentmodule:: pennylane.noise

.. autosummary::
:toctree: api

~add_noise
~insert
~mitigate_with_zne
~fold_global
~poly_extrapolate
~richardson_extrapolate
~exponential_extrapolate
6 changes: 0 additions & 6 deletions doc/development/deprecations.rst
Original file line number Diff line number Diff line change
Expand Up @@ -125,12 +125,6 @@ Completed deprecation cycles

- Removed in releases after v0.45

* The ``pennylane.noise`` module has been removed, including ``NoiseModel``, ``add_noise``,
``insert``, noise mitigation transforms, and ``from_qiskit_noise``. Noise channels such as
:class:`~.AmplitudeDamping` are unaffected.

- Removed in releases after v0.45

* Implementing ``Operator.generator`` as a property is no longer supported. Instead, define a ``generator()`` method for your operator that returns an ``Operator`` instance.

- Deprecated in v0.22
Expand Down
1 change: 1 addition & 0 deletions doc/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@ PennyLane is **free** and **open source**, released under the Apache License, Ve
code/qp_liealg
code/qp_logging
code/qp_math
code/qp_noise
code/qp_numpy
code/qp_ops_op_math
code/qp_pauli
Expand Down
1 change: 1 addition & 0 deletions doc/news/program_capture_sharp_bits.rst
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,7 @@ errors may occur. Currently, this includes:
* :func:`~.pennylane.transforms.zx.push_hadamards`
* :func:`~.pennylane.transforms.zx.reduce_non_clifford`
* :func:`~.pennylane.transforms.zx.todd`
* :func:`~.pennylane.add_noise`
* :func:`~.pennylane.transforms.undo_swaps`
* :func:`~.pennylane.transforms.rowcol`
* :func:`~.pennylane.map_wires`
Expand Down
9 changes: 1 addition & 8 deletions doc/releases/changelog-dev.md
Original file line number Diff line number Diff line change
Expand Up @@ -1051,13 +1051,6 @@

[(#10209)](https://github.com/PennyLaneAI/pennylane/pull/10209)

* The ``pennylane.noise`` module has been removed, including ``NoiseModel``,
``add_noise``, ``insert``, noise mitigation transforms (``mitigate_with_zne``,
``fold_global``, ``poly_extrapolate``, ``richardson_extrapolate``,
``exponential_extrapolate``), and ``from_qiskit_noise``. Noise channels such as
:class:`~.AmplitudeDamping` are unaffected.
[(#10214)](https://github.com/PennyLaneAI/pennylane/pull/10214)

* Removed the ``qp.fourier`` module. This includes ``circuit_spectrum``, ``coefficients``,
``qnode_spectrum``, ``mark``, ``get_spectrum``, ``join_spectra`` and the
``qp.fourier.visualize`` plotting functions. Also, ``qp.fourier.reconstruct`` has moved to
Expand Down Expand Up @@ -1539,7 +1532,7 @@
[(#9753)](https://github.com/PennyLaneAI/pennylane/pull/9753)
- Integration with :func:`pennylane.apply`.
[(#9738)](https://github.com/PennyLaneAI/pennylane/pull/9738)
- Integration with ``pennylane.insert``.
- Integration with :func:`pennylane.insert`.
[(#9685)](https://github.com/PennyLaneAI/pennylane/pull/9685)
- Integration with the graph-based decomposition system.
[(#9723)](https://github.com/PennyLaneAI/pennylane/pull/9723)
Expand Down
13 changes: 13 additions & 0 deletions pennylane/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,15 @@
gridsynth,
CompilePipeline,
)
from pennylane.noise import (
add_noise,
insert,
mitigate_with_zne,
fold_global,
poly_extrapolate,
richardson_extrapolate,
exponential_extrapolate,
)
from pennylane.ops.functions import (
dot,
eigvals,
Expand Down Expand Up @@ -173,6 +182,7 @@
from_qasm,
to_openqasm,
from_qiskit,
from_qiskit_noise,
from_qiskit_op,
from_quil,
from_quil_file,
Expand All @@ -187,6 +197,9 @@

from pennylane import data

from pennylane import noise
from pennylane.noise import NoiseModel

from pennylane.devices import Tracker
from pennylane.devices.device_constructor import device, refresh_devices

Expand Down
4 changes: 1 addition & 3 deletions pennylane/devices/device_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -950,9 +950,7 @@ def _default_mcm_method(capabilities: DeviceCapabilities, shots_present: bool) -
return "deferred"


# NOTE: this api is only the fallback for legacy devices and any other devices
# beyond default.qubit
def _preprocess_device(original_device, transform, targs, tkwargs): # pragma: no cover
def _preprocess_device(original_device, transform, targs, tkwargs):
class TransformedDevice(type(original_device)):
"""A transformed device with updated preprocess method."""

Expand Down
1 change: 1 addition & 0 deletions pennylane/io/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from_pyquil,
from_qasm,
from_qiskit,
from_qiskit_noise,
from_qiskit_op,
from_quil,
from_quil_file,
Expand Down
Loading
Loading