Source code for pennylane.noise.noise_model
# Copyright 2018-2024 Xanadu Quantum Technologies Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Contains class and methods for noise models"""
import inspect
import pennylane as qml
[docs]class NoiseModel:
"""Builds a noise model based on the mappings of conditionals to callables that
define noise operations using some optional metadata.
Args:
model_map (dict[BooleanFn -> Callable]): Data for applying the gate errors as
a ``{conditional: noise_fn}`` dictionary. The signature of ``noise_fn``
should be ``noise_fn(op: Operation, **kwargs) -> None``, where ``op``
is the operation that the conditional evaluates and ``kwargs`` are
the specified metadata arguments.
meas_map (dict[BooleanFn -> Callable]): Data for adding the readout errors
similar to ``model_map``. The signature of ``noise_fn`` must be
``noise_fn(mp: MeasurementProcess, **kwargs) -> None``, where ``mp`` is
the measurement process that the conditional evaluates and ``kwargs``
are the specified metadata arguments.
**kwargs: Keyword arguments for specifying metadata related to the noise model.
.. note::
For each key-value pair of ``model_map`` and ``meas_map``:
- The ``conditional`` should be either a function decorated with :class:`~.BooleanFn`,
a callable object built via :ref:`constructor functions <intro_boolean_fn>` in
the ``qml.noise`` module, or their bitwise combination.
- The definition of ``noise_fn(Union[op, mp], **kwargs)`` should have the operations
in the same order in which they are to be queued for an operation ``op`` or
measurement process ``mp``, whenever the corresponding ``conditional`` evaluates
to ``True``.
- Each ``conditional`` in ``meas_map`` is evaluated on each measurement process in
the order they are specified. The corresponding noise has to be added `before`
the measurement, i.e., custom queing in ``noise_fn`` should not be done.
**Example**
.. code-block:: python
# Set up the gate noise
c0 = qml.noise.op_eq(qml.PauliX) | qml.noise.op_eq(qml.PauliY)
c1 = qml.noise.op_eq(qml.Hadamard) & qml.noise.wires_in([0, 1])
def n0(op, **kwargs):
qml.ThermalRelaxationError(0.4, kwargs["t1"], 0.2, 0.6, op.wires)
n1 = qml.noise.partial_wires(qml.AmplitudeDamping, 0.4)
# set up the readout noise
m0 = qml.noise.meas_eq(qml.expval) & qml.noise.wires_in([0, 1])
n2 = qml.noise.partial_wires(qml.PhaseFlip, 0.2)
# Set up noise model
noise_model = qml.NoiseModel({c0: n0}, meas_map={m0:n2}, t1=0.04)
noise_model += {c1: n1}
>>> noise_model
NoiseModel({
OpEq(PauliX) | OpEq(PauliY): n0
OpEq(Hadamard) & WiresIn([0, 1]): AmplitudeDamping(0.4, wires),
},
meas_map = {
MeasEq(expval) & WiresIn([0, 1]): PhaseFlip(p=0.2)
}, t1=0.04)
"""
def __init__(self, model_map, meas_map=None, **kwargs):
self.check_model(model_map)
self._model_map = model_map
if meas_map is not None:
self.check_model(meas_map)
self._meas_map = meas_map or {}
self._metadata = kwargs
@property
def model_map(self):
"""Gives the conditional model for the noise model."""
return self._model_map
@property
def meas_map(self):
"""Gives the measurement model for the noise model."""
return self._meas_map
@property
def metadata(self):
"""Gives the metadata for the noise model."""
return self._metadata
def __add__(self, data):
if not isinstance(data, NoiseModel):
ms_ = data.pop("meas_map", {})
mt_ = {key: data.pop(key) for key in list(filter(lambda k: isinstance(k, str), data))}
return NoiseModel(
{**self.model_map, **data},
{**self.meas_map, **ms_},
**{**self.metadata, **mt_},
)
return NoiseModel(
{**self.model_map, **data.model_map},
{**self.meas_map, **data.meas_map},
**{**self.metadata, **data.metadata},
)
def __radd__(self, data):
return self.__add__(data)
def __sub__(self, data):
if not isinstance(data, NoiseModel):
ms_ = data.pop("meas_map", {})
mt_ = {key: data.pop(key) for key in list(filter(lambda k: isinstance(k, str), data))}
return NoiseModel(
{k: v for k, v in self.model_map.items() if k not in data},
meas_map={k: v for k, v in self.meas_map.items() if k not in ms_},
**{k: v for k, v in self.metadata.items() if k not in mt_},
)
return NoiseModel(
{k: v for k, v in self.model_map.items() if k not in data.model_map},
**dict({k: v for k, v in self.metadata.items() if k not in data.metadata}),
)
def __eq__(self, other):
for key in ["model_map", "meas_map"]:
for model1, model2 in zip(getattr(self, key).items(), getattr(other, key).items()):
(func1, noise1), (func2, noise2) = model1, model2
if getattr(func1, "condition", func1.fn) != getattr(func2, "condition", func2.fn):
return False
if noise1 != noise2:
return False
return self.metadata == other.metadata
def __repr__(self):
model_str = "NoiseModel({\n"
for key, val in self.model_map.items():
model_str += " " + f"{key}: {val.__name__}" + "\n"
if self._meas_map:
model_str += "},\nmeas_map = {\n"
for key, val in self.meas_map.items():
model_str += " " + f"{key}: {val.__name__}" + "\n"
model_str += "}, "
for key, val in self._metadata.items():
model_str += f"{key} = {val}, "
model_str = model_str[:-2] + ")"
return model_str
[docs] @staticmethod
def check_model(model: dict) -> None:
"""Method to validate a ``{conditional -> noise_fn}`` map for constructing a noise model."""
for condition, noise in model.items():
if not isinstance(condition, qml.BooleanFn):
raise ValueError(
f"{condition} must be a boolean conditional, i.e., an instance of "
"BooleanFn or one of its subclasses."
)
final_parameter = list(inspect.signature(noise).parameters.values())[-1]
if final_parameter.kind != final_parameter.VAR_KEYWORD:
raise ValueError(
f"{noise} provided for {condition} must accept **kwargs "
"as the last argument in its signature."
)
_modules/pennylane/noise/noise_model
Download Python script
Download Notebook
View on GitHub