Skip to content
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

add_noise transform for adding noise models #5718

Merged
merged 140 commits into from
Jun 19, 2024
Merged
Show file tree
Hide file tree
Changes from 123 commits
Commits
Show all changes
140 commits
Select commit Hold shift + click to select a range
202c365
init
obliviateandsurrender Apr 26, 2024
4c03e36
init
obliviateandsurrender May 4, 2024
5ff822f
basic structure
obliviateandsurrender May 9, 2024
d49a88b
more versatile support
obliviateandsurrender May 9, 2024
2b8b65d
fix formatting
obliviateandsurrender May 9, 2024
72d25d0
Merge branch 'master' into noise-models-1
obliviateandsurrender May 9, 2024
1892a42
fix `pylint`?
obliviateandsurrender May 9, 2024
3e301a2
more fixes
obliviateandsurrender May 9, 2024
4b6c6b4
format tweaks
obliviateandsurrender May 9, 2024
1317189
add `partial_wires`
obliviateandsurrender May 10, 2024
5332c61
add tests
obliviateandsurrender May 10, 2024
edcb7a4
add repr test
obliviateandsurrender May 10, 2024
59d09de
happy `isort`
obliviateandsurrender May 10, 2024
edb464d
happy `isort`
obliviateandsurrender May 10, 2024
f7465d2
add test
obliviateandsurrender May 10, 2024
09936a6
happy `black`
obliviateandsurrender May 10, 2024
ec1f1c2
happy `isort`
obliviateandsurrender May 10, 2024
d4bfbaf
improve coverage
obliviateandsurrender May 10, 2024
07587a7
improve coverage and simplify bits
obliviateandsurrender May 10, 2024
3d5fe94
Merge branch 'master' into noise-models-1
obliviateandsurrender May 11, 2024
f30501f
happy ci for a while
obliviateandsurrender May 11, 2024
064c6a0
fix test
obliviateandsurrender May 12, 2024
087a007
add docstrings
obliviateandsurrender May 13, 2024
65e158f
add docstrings
obliviateandsurrender May 13, 2024
d806fa3
show in docs
obliviateandsurrender May 13, 2024
72a47e2
tweak
obliviateandsurrender May 13, 2024
75ee072
doc tweak
obliviateandsurrender May 13, 2024
7d92269
doc tweak
obliviateandsurrender May 13, 2024
648ebab
add noise model
obliviateandsurrender May 13, 2024
2a4c7ad
add imports
obliviateandsurrender May 13, 2024
23dee0f
add `repr`
obliviateandsurrender May 13, 2024
299a030
Apply suggestions from code review
obliviateandsurrender May 13, 2024
35b9ce1
add tests
obliviateandsurrender May 13, 2024
e5d481e
Merge branch 'noise-models-1' of https://github.com/PennyLaneAI/penny…
obliviateandsurrender May 13, 2024
4f27312
add support for arithmetic depth
obliviateandsurrender May 14, 2024
2797a53
make lc support robust
obliviateandsurrender May 14, 2024
7fc2dd2
fix coverage
obliviateandsurrender May 14, 2024
d1192b4
simplify doubts
obliviateandsurrender May 14, 2024
9ba793f
Merge branch 'noise-models-1' of https://github.com/PennyLaneAI/penny…
obliviateandsurrender May 14, 2024
26b6719
add model checks
obliviateandsurrender May 16, 2024
2b2c25b
add check test
obliviateandsurrender May 16, 2024
823daad
restructure
obliviateandsurrender May 16, 2024
8a2760d
Merge branch 'master' into noise-models-1
obliviateandsurrender May 16, 2024
6cdfda8
add `changelog`
obliviateandsurrender May 16, 2024
bc755f9
Merge branch 'noise-models-1' of https://github.com/PennyLaneAI/penny…
obliviateandsurrender May 16, 2024
2f0343a
use restructuring
obliviateandsurrender May 16, 2024
9e76f91
changelog
obliviateandsurrender May 16, 2024
0adc86f
add dunder to bitwise
obliviateandsurrender May 17, 2024
f84811e
Merge branch 'master' into noise-models-1
obliviateandsurrender May 17, 2024
ca5adb8
improve coverage
obliviateandsurrender May 17, 2024
4da09b0
Merge branch 'noise-models-1' of https://github.com/PennyLaneAI/penny…
obliviateandsurrender May 17, 2024
19c6fff
add doc page
obliviateandsurrender May 17, 2024
9dcd7d0
add docs
obliviateandsurrender May 17, 2024
242a957
Merge branch 'noise-models-1' of https://github.com/PennyLaneAI/penny…
obliviateandsurrender May 17, 2024
5a9446b
include in docs
obliviateandsurrender May 17, 2024
f5755e6
add transform
obliviateandsurrender May 17, 2024
7eebb48
tweak str output
obliviateandsurrender May 17, 2024
8cd6f24
improve op check
obliviateandsurrender May 20, 2024
fe9ccd7
change arg name
obliviateandsurrender May 20, 2024
fe8c38b
add initial tests
obliviateandsurrender May 22, 2024
1ad2601
fix staticmethod callables?
obliviateandsurrender May 22, 2024
b9d7047
fix coverage?
obliviateandsurrender May 22, 2024
a9cef0c
improve docs
obliviateandsurrender May 22, 2024
e2e7a31
Merge branch 'master' into noise-models-1
Jaybsoni May 22, 2024
f7ba9f3
improve coverage
obliviateandsurrender May 23, 2024
1edcd69
doc fix?
obliviateandsurrender May 23, 2024
c431ce7
CI workaround (for a while)
obliviateandsurrender May 23, 2024
c1f846a
tweak docs
obliviateandsurrender May 23, 2024
6caae2a
apply suggestions
obliviateandsurrender May 23, 2024
caf9def
Merge branch 'noise-models-1' of https://github.com/PennyLaneAI/penny…
obliviateandsurrender May 23, 2024
dd45dcd
Merge branch 'master' into noise-models-1
obliviateandsurrender May 23, 2024
7e6c332
improve LC comparison
obliviateandsurrender May 26, 2024
d3c5fc6
improve docs
obliviateandsurrender May 27, 2024
0979d6d
add exp check
obliviateandsurrender May 27, 2024
6a565e9
tweak fixes
obliviateandsurrender May 27, 2024
4464bf1
tweak docs
obliviateandsurrender May 28, 2024
8fb77a2
tweak docs
obliviateandsurrender May 28, 2024
eb54e04
docs tweaks
obliviateandsurrender May 29, 2024
2f40fa3
improve docs
obliviateandsurrender May 29, 2024
8922964
little tweaks
obliviateandsurrender May 29, 2024
b08b836
Merge branch 'master' into noise-models-1
Jaybsoni May 29, 2024
c7ca37b
add suggestions
obliviateandsurrender May 29, 2024
4a9e787
Merge branch 'noise-models-1' of https://github.com/PennyLaneAI/penny…
obliviateandsurrender May 29, 2024
85b63d1
add suggestions
obliviateandsurrender May 29, 2024
fe011f3
improve docs
obliviateandsurrender May 30, 2024
55ab757
Merge branch 'master' into noise-models-1
obliviateandsurrender May 30, 2024
757dd0c
Merge branch 'noise-models-1' of https://github.com/PennyLaneAI/penny…
obliviateandsurrender May 30, 2024
3f8bc14
improve docs
obliviateandsurrender May 30, 2024
72a28fe
tweak docs
obliviateandsurrender May 30, 2024
e067218
add suggestions
obliviateandsurrender May 30, 2024
f4ea5c7
fix doc?
obliviateandsurrender May 31, 2024
8e5cddf
Merge branch 'master' into noise-models-1
obliviateandsurrender May 31, 2024
1096426
docs?
obliviateandsurrender May 31, 2024
9b1d384
changelog
obliviateandsurrender May 31, 2024
fa573a5
apply suggestions
obliviateandsurrender May 31, 2024
10fffc8
fix coverage
obliviateandsurrender May 31, 2024
636e2d0
Merge branch 'master' into noise-models-1
obliviateandsurrender May 31, 2024
86bd210
apply suggestions
obliviateandsurrender Jun 3, 2024
b1ce904
add `level` wrapper
obliviateandsurrender Jun 4, 2024
baae581
add tests
obliviateandsurrender Jun 4, 2024
259f31b
Merge branch 'noise-models-2' into noise-model-3
obliviateandsurrender Jun 4, 2024
420b845
Merge branch 'master' into noise-models-1
obliviateandsurrender Jun 4, 2024
6d5840d
Merge branch 'noise-models-1' of https://github.com/PennyLaneAI/penny…
obliviateandsurrender Jun 4, 2024
dd2b2f8
Merge branch 'noise-models-2' of https://github.com/PennyLaneAI/penny…
obliviateandsurrender Jun 4, 2024
0e4432c
add `controlled` support
obliviateandsurrender Jun 4, 2024
1a8a4b9
add suggestions
obliviateandsurrender Jun 6, 2024
1eb5d12
Merge branch 'master' of https://github.com/PennyLaneAI/pennylane int…
obliviateandsurrender Jun 6, 2024
832b194
Merge branch 'noise-models-1' of https://github.com/PennyLaneAI/penny…
obliviateandsurrender Jun 6, 2024
5bf3254
Merge branch 'noise-models-2' of https://github.com/PennyLaneAI/penny…
obliviateandsurrender Jun 6, 2024
c793e39
adapt for controlled
obliviateandsurrender Jun 6, 2024
4c2e14e
Merge branch 'noise-models-1' of https://github.com/PennyLaneAI/penny…
obliviateandsurrender Jun 6, 2024
ae1767b
Merge branch 'noise-models-2' of https://github.com/PennyLaneAI/penny…
obliviateandsurrender Jun 6, 2024
ccf02ec
improve docs
obliviateandsurrender Jun 6, 2024
38f51fc
fix warning
obliviateandsurrender Jun 6, 2024
8ed540e
add href?
obliviateandsurrender Jun 6, 2024
7caa142
add suggestions
obliviateandsurrender Jun 6, 2024
9faed8c
doc tweak
obliviateandsurrender Jun 7, 2024
91db373
minor tweak
obliviateandsurrender Jun 7, 2024
7088b9c
minor tweak
obliviateandsurrender Jun 7, 2024
accbeda
Merge branch 'master' into noise-models-1
obliviateandsurrender Jun 10, 2024
f210994
Merge branch 'noise-models-1' of https://github.com/PennyLaneAI/penny…
obliviateandsurrender Jun 10, 2024
b2e131d
Merge branch 'noise-models-2' of https://github.com/PennyLaneAI/penny…
obliviateandsurrender Jun 10, 2024
ba23d59
add classes to test
obliviateandsurrender Jun 10, 2024
378a3e1
use `any` for check
obliviateandsurrender Jun 10, 2024
da1ffb3
add suggestions to docs
obliviateandsurrender Jun 11, 2024
84e3738
minor fixups
obliviateandsurrender Jun 11, 2024
6136e57
Merge branch 'noise-models-1' of https://github.com/PennyLaneAI/penny…
obliviateandsurrender Jun 11, 2024
6a39971
Merge branch 'noise-models-2' of https://github.com/PennyLaneAI/penny…
obliviateandsurrender Jun 11, 2024
d572e6c
Merge branch 'master' of https://github.com/PennyLaneAI/pennylane int…
obliviateandsurrender Jun 12, 2024
e45f9ec
fix test
obliviateandsurrender Jun 12, 2024
7d3b8de
apply suggestions
obliviateandsurrender Jun 12, 2024
fb9365a
minor tweak
obliviateandsurrender Jun 14, 2024
183737e
Merge branch 'master' into noise-model-3
obliviateandsurrender Jun 14, 2024
75bf2b6
Merge branch 'master' into noise-model-3
obliviateandsurrender Jun 17, 2024
aff8cc6
remove advanced examples
obliviateandsurrender Jun 19, 2024
dd3dc1a
Merge branch 'master' into noise-model-3
obliviateandsurrender Jun 19, 2024
7847412
Merge branch 'master' into noise-model-3
obliviateandsurrender Jun 19, 2024
7cd8575
fix ci
obliviateandsurrender Jun 19, 2024
7a9a1ff
minor tweaks
obliviateandsurrender Jun 19, 2024
94862cd
Merge branch 'master' of https://github.com/PennyLaneAI/pennylane int…
obliviateandsurrender Jun 19, 2024
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
109 changes: 109 additions & 0 deletions doc/code/qml_noise.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
qml.noise
=========

This module contains the functionality for building and manipulating noise models.

Overview
--------

In PennyLane, noise models are defined via a mapping of conditions defined as ``Conditionals``
to functions specified as ``Callables``, along with some additional noise-related metadata and
can be attached to a circuit or device via :func:`add_noise <pennylane.transforms.add_noise>`:

::

NoiseModel: ({Conditionals --> Callables}, metadata)

Each ``Conditional`` evaluates the gate operations in the quantum circuit based on some
condition of its attributes (e.g., type, parameters, wires, etc.) and use the corresponding
``Callable`` to apply the noise operations, using the user-provided metadata (e.g., hardware
topologies or relaxation times), whenever the condition results true.

Noise Transform
^^^^^^^^^^^^^^^

.. currentmodule:: pennylane.transforms

.. autosummary::
:toctree: api

~add_noise

Noise Model
^^^^^^^^^^^

.. currentmodule:: pennylane.noise.noise_model

.. autosummary::
:toctree: api

~NoiseModel

Conditional Constructors
^^^^^^^^^^^^^^^^^^^^^^^^

.. currentmodule:: pennylane.noise.conditionals

.. autosummary::
:toctree: api

~op_eq
~op_in
~wires_eq
~wires_in

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

.. currentmodule:: pennylane

.. autosummary::
:toctree: api

~BooleanFn

.. note::

Conditionals built via these constructors or decorator can be combined using
standard bit-wise operators, such as ``&``, ``|``, ``^``, or ``~``. The resulting
combination will still behave like a single conditional and store the individual
components in the ``operands`` attribute. As Python will evaluate the expression
in the same order, i.e., left to right, the order of composition could matter,
even though bitwise operations are symmetric by definition.

Callable Constructor
^^^^^^^^^^^^^^^^^^^^

.. currentmodule:: pennylane.noise.conditionals

.. autosummary::
:toctree: api

~partial_wires

.. note::

The signature of any user-defined callable must be -
``noise_fn(op: Operation, **kwargs) -> None``, i.e., it accepts
an operation and some metadata-based keyword arguments. It should
then let one queue the noisy gates corresponding to that operation
similar to a quantum function but without returning any measurements.

Conditional Classes
^^^^^^^^^^^^^^^^^^^

.. currentmodule:: pennylane.noise.conditionals

.. autosummary::
:toctree: api

~OpEq
~OpIn
~WiresEq
~WiresIn

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

.. inheritance-diagram:: pennylane.noise.conditionals
:parts: 1
1 change: 1 addition & 0 deletions doc/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ PennyLane is **free** and **open source**, released under the Apache License, Ve
code/qml_kernels
code/qml_logging
code/qml_math
code/qml_noise
code/qml_numpy
code/qml_ops_op_math
code/qml_pauli
Expand Down
37 changes: 37 additions & 0 deletions doc/releases/changelog-dev.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,42 @@
* The `default.tensor` device is introduced to perform tensor network simulation of a quantum circuit.
[(#5699)](https://github.com/PennyLaneAI/pennylane/pull/5699)

* A new `qml.noise` module which contains utililty function for building `NoiseModels`
obliviateandsurrender marked this conversation as resolved.
Show resolved Hide resolved
and an `add_noise` tranform for addding it to quantum circuits.
[(#5674)](https://github.com/PennyLaneAI/pennylane/pull/5674)
[(#5684)](https://github.com/PennyLaneAI/pennylane/pull/5684)
[(#5718)](https://github.com/PennyLaneAI/pennylane/pull/5718)

```pycon
>>> fcond1 = qml.noise.op_eq(qml.RX) & qml.noise.wires_in([0, 1])
>>> noise1 = qml.noise.partial_wires(qml.PhaseDamping, 0.4)
>>> fcond2 = qml.noise.op_in([qml.RY, qml.RZ])
>>> def noise2(op, **kwargs):
... qml.ThermalRelaxationError(op.parameters[0] * 0.05, kwargs["t1"], 0.2, 0.6, op.wires)
>>> noise_model = qml.NoiseModel({fcond1: noise1, fcond2: noise2}, t1=2.0)
>>> noise_model
NoiseModel({
OpEq(RX) & WiresIn([0, 1]) = PhaseDamping(gamma=0.4)
OpIn(['RY', 'RZ']) = noise2
}, t1 = 2.0)
Jaybsoni marked this conversation as resolved.
Show resolved Hide resolved
```

``` pycon
>>> @partial(qml.transforms.add_noise, noise_model=noise_model)
... @qml.qnode(dev)
... def circuit(w, x, y, z):
... qml.RX(w, wires=0)
... qml.RY(x, wires=1)
... qml.CNOT(wires=[0, 1])
... qml.RY(y, wires=0)
... qml.RX(z, wires=1)
... return qml.expval(qml.Z(0) @ qml.Z(1))
>>> print(qml.draw(circuit)(0.9, 0.4, 0.5, 0.6))
0: ──RX(0.90)──PhaseDamping(0.40)──────────────────────────╭●──RY(0.50)
1: ──RY(0.40)──ThermalRelaxationError(0.02,2.00,0.20,0.60)─╰X──RX(0.60)
───ThermalRelaxationError(0.03,2.00,0.20,0.60)─┤ ╭<Z@Z>
───PhaseDamping(0.40)──────────────────────────┤ ╰<Z@Z>
```

<h3>Improvements 🛠</h3>

Expand Down Expand Up @@ -366,6 +402,7 @@
This release contains contributions from (in alphabetical order):

Guillermo Alonso-Linaje,
Utkarsh Azad,
Lillian M. A. Frederiksen,
Gabriel Bottrill,
Astral Cai,
Expand Down
3 changes: 3 additions & 0 deletions pennylane/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,9 @@

import pennylane.data

import pennylane.noise
from pennylane.noise import NoiseModel

from packaging.specifiers import SpecifierSet
from packaging.version import Version

Expand Down
133 changes: 124 additions & 9 deletions pennylane/boolean_fn.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2018-2021 Xanadu Quantum Technologies Inc.
# 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.
Expand All @@ -19,13 +19,14 @@
import functools


# pylint: disable=unnecessary-lambda
class BooleanFn:
r"""Wrapper for simple callables with boolean output that can be
manipulated and combined with bit-wise operators.

Args:
fn (callable): Function to be wrapped. It must accept a single
argument, and must return a boolean.
fn (callable): Function to be wrapped. It can accept any number
of arguments, and must return a boolean.

**Example**

Expand Down Expand Up @@ -77,18 +78,132 @@ class BooleanFn:

"""

def __init__(self, fn):
def __init__(self, fn, name=None):
self.fn = fn
self.name = name or self.fn.__name__
functools.update_wrapper(self, fn)

def __and__(self, other):
return BooleanFn(lambda obj: self.fn(obj) and other.fn(obj))
return And(self, other)

def __or__(self, other):
return BooleanFn(lambda obj: self.fn(obj) or other.fn(obj))
return Or(self, other)

def __xor__(self, other):
return Xor(self, other)

def __invert__(self):
return BooleanFn(lambda obj: not self.fn(obj))
return Not(self)

def __call__(self, *args, **kwargs):
return self.fn(*args, **kwargs)

def __repr__(self):
return f"BooleanFn({self.name})" if not (self.bitwise or self.conditional) else self.name

@property
def bitwise(self):
"""Determine whether wrapped callable performs a bit-wise operation or not.
This checks for the ``operands`` attribute that should be defined by it."""
return bool(getattr(self, "operands", tuple()))

@property
def conditional(self):
"""Determine whether wrapped callable is for a conditional or not.
This checks for the ``condition`` attribute that should be defined by it."""
return bool(getattr(self, "condition", None))


class And(BooleanFn):
"""Developer facing class for implemeting bit-wise ``AND`` for callables
wrapped up with :class:`BooleanFn <pennylane.BooleanFn>`.

Args:
left (~.BooleanFn): Left operand in the bit-wise expression.
right (~.BooleanFn): Right operand in the bit-wise expression.
"""

def __init__(self, left, right):
self.operands = (left, right)

if any(getattr(opr, "condition", None) for opr in self.operands):
self.condition = tuple(getattr(opr, "condition", ()) for opr in self.operands)

super().__init__(
lambda *args, **kwargs: left(*args, **kwargs) and right(*args, **kwargs),
f"And({left.name}, {right.name})",
)

def __str__(self):
return f"{self.operands[0].name} & {self.operands[1].name}"


class Or(BooleanFn):
"""Developer facing class for implemeting bit-wise ``OR`` for callables
wrapped up with :class:`BooleanFn <pennylane.BooleanFn>`.

Args:
left (~.BooleanFn): Left operand in the bit-wise expression.
right (~.BooleanFn): Right operand in the bit-wise expression.
"""

def __init__(self, left, right):
self.operands = (left, right)

if any(getattr(opr, "condition", None) for opr in self.operands):
self.condition = tuple(getattr(opr, "condition", ()) for opr in self.operands)

super().__init__(
lambda *args, **kwargs: left(*args, **kwargs) or right(*args, **kwargs),
f"Or({left.name}, {right.name})",
)

def __str__(self):
return f"{self.operands[0].name} | {self.operands[1].name}"


class Xor(BooleanFn):
"""Developer facing class for implemeting bit-wise ``XOR`` for callables
wrapped up with :class:`BooleanFn <pennylane.BooleanFn>`.

Args:
left (~.BooleanFn): Left operand in the bit-wise expression.
right (~.BooleanFn): Right operand in the bit-wise expression.
"""

def __init__(self, left, right):
self.operands = (left, right)

if any(getattr(opr, "condition", None) for opr in self.operands):
self.condition = tuple(getattr(opr, "condition", ()) for opr in self.operands)

super().__init__(
lambda *args, **kwargs: left(*args, **kwargs) ^ right(*args, **kwargs),
f"Xor({left.name}, {right.name})",
)

def __str__(self):
return f"{self.operands[0].name} ^ {self.operands[1].name}"


class Not(BooleanFn):
"""Developer facing class for implemeting bit-wise ``NOT`` for callables
wrapped up with :class:`BooleanFn <pennylane.BooleanFn>`.

Args:
left (~.BooleanFn): Left operand in the bit-wise expression.
"""

def __init__(self, left):
self.operands = (left,)

if any(getattr(opr, "condition", None) for opr in self.operands):
self.condition = tuple(getattr(opr, "condition", ()) for opr in self.operands)

super().__init__(
lambda *args, **kwargs: not left(*args, **kwargs),
f"Not({left.name})",
)

def __call__(self, obj):
return self.fn(obj)
def __str__(self):
return f"~{self.operands[0].name}"
17 changes: 17 additions & 0 deletions pennylane/noise/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# 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.
"""This module contains the functionality to work with noise models in PennyLane."""

from .conditionals import wires_in, wires_eq, op_in, op_eq, partial_wires
from .noise_model import NoiseModel
Loading
Loading