qml.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.
Overview¶
Insertion-based noise models in PennyLane are defined via a mapping from conditionals, specified
as BooleanFn
objects, to quantum function-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:
|
Builds a noise model based on the mappings of conditionals to callables that define noise operations using some optional metadata. |
Each conditional in the model_map
(and meas_map
) evaluates the gate operations
(and terminal measurments) 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:
|
Insert operations according to a provided noise model. |
Boolean functions¶
Each 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:
|
Builds a conditional as a |
|
Builds a conditional as a |
|
Builds a conditional as a |
|
Builds a conditional as a |
|
Builds a conditional as a |
For example, a Boolean function that checks if an operation is on wire 0
can be created
as follows:
>>> fn = qml.noise.wires_eq(0)
>>> op1, op2 = qml.PauliX(0), qml.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:
|
Wrapper for simple callables with Boolean output that can be manipulated and combined with bitwise operators. |
For example, a Boolean function can be created to identify an RX
gate
with a maximum parameter value:
@qml.BooleanFn
def rx_condition(op, **metadata):
return isinstance(op, qml.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:
def noisy_rx(op, **metadata):
qml.RX(op.parameters[0] * 0.05, op.wires)
noise_model = qml.NoiseModel({rx_condition: noisy_rx})
A common use case is to have a single-operation noise channel whose wires are the same as the preceding operation. This can be constructed using:
|
Builds a partial function based on the given gate operation or measurement process with all argument frozen except |
For example, a constant-valued over-rotation can be created using:
>>> rx_constant = qml.noise.partial_wires(qml.RX(0.1, wires=[0]))
>>> rx_constant(2)
RX(0.1, 2)
>>> qml.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:
# Set up the conditions
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])
c2 = qml.noise.op_eq(qml.RX)
@qml.BooleanFn
def c3(op, **metadata):
return isinstance(op, qml.RY) and op.parameters[0] >= 0.5
# Set up noisy ops
n0 = qml.noise.partial_wires(qml.AmplitudeDamping, 0.4)
def n1(op, **metadata):
ThermalRelaxationError(0.4, metadata["t1"], 0.2, 0.6, op.wires)
def n2(op, **metadata):
qml.RX(op.parameters[0] * 0.05, op.wires)
n3 = qml.noise.partial_wires(qml.PhaseDamping, 0.9)
# Set up noise model
noise_model = qml.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 op_eq()
. These objects do not need to be instantiated directly
|
A conditional for evaluating if a given measurement process is equal to the specified measurement process. |
|
A conditional for evaluating if a given operation is equal to the specified operation. |
|
A conditional for evaluating if a given operation exist in a specified set of operations. |
|
A conditional for evaluating if a given wire is equal to a specified set of wires. |
|
A conditional for evaluating if the wires of an operation exist in a specified set of wires. |
Bitwise operations like And
and Or
are represented with the following classes in the
boolean_fn
module:
|
Developer facing class for implemeting bitwise |
|
Developer facing class for implemeting bitwise |
|
Developer facing class for implemeting bitwise |
|
Developer facing class for implemeting bitwise |