Noisy Simulations
Quantum systems are subject to noise during computations, from the application of gates, imperfect measurements, or interactions with the environment. Being able to simulate and validate quantum algorithms in a noisy setup is crucial for achieving any advantage on current NISQ machines. This section provides an overview of how noise models are instantiated, how target qubits and gates are specified, and the predefined noise models.
We strongly encourage the user to have a look at the dedicated notebook, where all the details of the manipulation, use, and simulation of noise models are presented.
For more details on how to use noise models taken from real hardware, you can look at Simulated Devices.
from mpqp.noise import *
Note
Noisy simulations are supported for IBMDevice
, AtosDevice
and AWSDevice
.
Noise models
In order to represent a general noise model, we introduce the abstract class
NoiseModel
. This class regroups all the
attributes and methods common to all predefined noise models.
While currently abstract, the class is designed with extensibility in mind to support parameterized noise models in the future. This feature will enable users to define noise models with adjustable parameters, offering greater flexibility in simulating and analyzing the effects of noise on quantum circuits.
- class NoiseModel(targets=None, gates=None)[source]
Bases:
ABC
Abstract class used to represent a generic noise model, specifying criteria for applying different noise types to a quantum circuit or some of its qubits.
This class allows one to specify which qubits (targets) and which gates of the circuit will be affected by this noise model. If you do not specify a target, the operation will apply to all qubits.
- Parameters
targets (Optional[list[int]]) – Qubits affected by this noise. Defaults to all qubits.
gates (Optional[list[type[NativeGate]]]) – Gates affected by this noise. Defaults to all gates.
- Raises
ValueError – When the target list is empty, or the target indices are duplicated or negative. When the size of the gate is higher than the number of target qubits.
- info()[source]
For usage of pretty prints, this method displays in a string all information relevant to the noise at matter.
- Returns
The string displaying the noise information in a human readable manner.
- Return type
str
- to_adjusted_kraus_operators(targets, size)[source]
In some cases, you may prefer the Kraus operators to match the size of your circuit, and the targets involved. In particular, the targets of the noise application may not match the noise targets, because the noise targets signifies all the qubits that the noise is applicable on, but if the noise happens at a gate execution, it would only actually impact the targets qubits of the gate.
Note
This generic method considers that the default Kraus operators of the noise are for one qubit noises. If this is not the case, this method should be overloaded in the corresponding class.
- Parameters
targets (set[int]) – Qubits actually affected by the noise.
size (int) – Size of the desired Kraus operators.
- Returns
The Kraus operators adjusted to the targets of the gate on which the noise acts and the size of the circuit.
- Return type
list[npt.NDArray[np.complex64]]
- to_kraus_operators()[source]
Noise models can be represented by Kraus operators. They represent how the state is affected by the noise following the formula
\(\rho \leftarrow \sum_{K \in \mathcal{K}} K \rho K^\dagger\)
Where \(\mathcal{K}\) is the set of Kraus operators corresponding to the noise model and \(\rho\) is the state (as a density matrix).
- Returns
The Kraus operators of the noise. Note that it is not a unique representation.
- Return type
list[npt.NDArray[np.complex64]]
- to_other_language(language)[source]
Transforms this noise model into the corresponding object in the language specified in the
language
arg.In the current version, only Braket and my_QLM are available for conversion.
- Parameters
language (Language) – Enum representing the target language.
- Returns
The corresponding noise model (or channel) in the target language.
- Return type
BraketNoise | QLMNoise | QuantumError
- gates
See parameter description.
- targets
See parameter description.
Depolarizing Noise Model
- class Depolarizing(prob, targets=None, dimension=1, gates=None)[source]
Bases:
DimensionalNoiseModel
Class representing the depolarizing noise channel, which maps a state onto a linear combination of itself and the maximally mixed state. It can be applied to a single or multiple qubits, and depends on a single parameter (probability or error rate).
When the number of qubits in the target is higher than the dimension, the noise will be applied to all possible combinations of indices of size
dimension
.- Parameters
prob (float) – Depolarizing error probability (also called error rate).
targets (Optional[list[int]]) – Qubits affected by this noise. Defaults to all qubits.
dimension (int) – Dimension of the depolarizing channel.
gates (Optional[list[type[NativeGate]]]) – Gates affected by this noise. Defaults to all gates.
- Raises
ValueError – When a wrong dimension (negative) or probability (outside of the expected interval) is input. When the size of the specified gates is not consistent with the number of targets or the dimension.
Examples
>>> circuit = QCircuit([H(i) for i in range(3)]) >>> d1 = Depolarizing(0.32, list(range(circuit.nb_qubits))) >>> d2 = Depolarizing(0.01) >>> d3 = Depolarizing(0.05, [0, 1], dimension=2) >>> d4 = Depolarizing(0.12, [2], gates=[H, Rx, Ry, Rz]) >>> d5 = Depolarizing(0.05, [0, 1, 2], dimension=2, gates=[CNOT, CZ]) >>> circuit.add([d1, d2, d3, d4, d5]) >>> print(circuit) ┌───┐ q_0: ┤ H ├ ├───┤ q_1: ┤ H ├ ├───┤ q_2: ┤ H ├ └───┘ NoiseModel: Depolarizing(0.32, [0, 1, 2]) Depolarizing(0.01) Depolarizing(0.05, [0, 1], dimension=2) Depolarizing(0.12, [2], gates=[H, Rx, Ry, Rz]) Depolarizing(0.05, [0, 1, 2], dimension=2, gates=[CNOT, CZ]) >>> print(circuit.to_other_language(Language.BRAKET)) T : │ 0 │ ┌───┐ ┌────────────┐ ┌────────────┐ q0 : ─┤ H ├─┤ DEPO(0.01) ├─┤ DEPO(0.32) ├──────────────── └───┘ └────────────┘ └────────────┘ ┌───┐ ┌────────────┐ ┌────────────┐ q1 : ─┤ H ├─┤ DEPO(0.01) ├─┤ DEPO(0.32) ├──────────────── └───┘ └────────────┘ └────────────┘ ┌───┐ ┌────────────┐ ┌────────────┐ ┌────────────┐ q2 : ─┤ H ├─┤ DEPO(0.12) ├─┤ DEPO(0.01) ├─┤ DEPO(0.32) ├─ └───┘ └────────────┘ └────────────┘ └────────────┘ T : │ 0 │
- info()[source]
For usage of pretty prints, this method displays in a string all information relevant to the noise at matter.
- Returns
The string displaying the noise information in a human readable manner.
- Return type
str
- to_kraus_operators()[source]
Noise models can be represented by Kraus operators. They represent how the state is affected by the noise following the formula
\(\rho \leftarrow \sum_{K \in \mathcal{K}} K \rho K^\dagger\)
Where \(\mathcal{K}\) is the set of Kraus operators corresponding to the noise model and \(\rho\) is the state (as a density matrix).
- Returns
The Kraus operators of the noise. Note that it is not a unique representation.
- Return type
list[npt.NDArray[np.complex64]]
- to_other_language(language=Language.QISKIT)[source]
See the documentation for this method in the abstract mother class
NoiseModel
.- Parameters
language (Language) – Enum representing the target language.
- Return type
BraketNoise | TwoQubitDepolarizing | QLMNoise | QuantumError
Examples
>>> Depolarizing(0.3, [0,1], dimension=1).to_other_language(Language.BRAKET) Depolarizing('probability': 0.3, 'qubit_count': 1)
>>> Depolarizing(0.3, [0,1], dimension=1).to_other_language(Language.QISKIT).to_quantumchannel() SuperOp([[0.85+0.j, 0. +0.j, 0. +0.j, 0.15+0.j], [0. +0.j, 0.7 +0.j, 0. +0.j, 0. +0.j], [0. +0.j, 0. +0.j, 0.7 +0.j, 0. +0.j], [0.15+0.j, 0. +0.j, 0. +0.j, 0.85+0.j]], input_dims=(2,), output_dims=(2,))
>>> print(Depolarizing(0.3, [0,1], dimension=1).to_other_language(Language.MY_QLM)) Depolarizing channel, p = 0.3: [[0.83666003 0. ] [0. 0.83666003]] [[0. +0.j 0.31622777+0.j] [0.31622777+0.j 0. +0.j]] [[0.+0.j 0.-0.31622777j] [0.+0.31622777j 0.+0.j ]] [[ 0.31622777+0.j 0. +0.j] [ 0. +0.j -0.31622777+0.j]]
- prob
Probability or error rate of the depolarizing noise model.
BitFlip Noise Model
- class BitFlip(prob, targets=None, gates=None)[source]
Bases:
NoiseModel
Class representing the bit flip noise channel, which flips the state of a qubit with a certain probability. It can be applied to single and multi-qubit gates and depends on a single parameter (probability or error rate).
- Parameters
prob (float) – Bit flip error probability or error rate (must be within
[0, 0.5]
).targets (Optional[list[int]]) – Qubits affected by this noise. Defaults to all qubits.
gates (Optional[list[type[NativeGate]]]) – Gates affected by this noise. If multi-qubit gates is passed, single-qubit bitflip will be added for each qubit connected (target, control) with the gates. Defaults to all gates.
- Raises
ValueError – When the probability is outside of the expected interval
[0, 0.5]
.
Examples
>>> circuit = QCircuit( ... [H(i) for i in range(3)] ... + [ ... BitFlip(0.1, [0]), ... BitFlip(0.3, [1, 2]), ... BitFlip(0.05, [0], gates=[H]), ... BitFlip(0.3), ... ] ... ) >>> print(circuit) ┌───┐ q_0: ┤ H ├ ├───┤ q_1: ┤ H ├ ├───┤ q_2: ┤ H ├ └───┘ NoiseModel: BitFlip(0.1, [0]) BitFlip(0.3, [1, 2]) BitFlip(0.05, [0], gates=[H]) BitFlip(0.3) >>> print(circuit.to_other_language(Language.BRAKET)) T : │ 0 │ ┌───┐ ┌─────────┐ ┌──────────┐ ┌─────────┐ q0 : ─┤ H ├─┤ BF(0.3) ├─┤ BF(0.05) ├─┤ BF(0.1) ├─ └───┘ └─────────┘ └──────────┘ └─────────┘ ┌───┐ ┌─────────┐ ┌─────────┐ q1 : ─┤ H ├─┤ BF(0.3) ├─┤ BF(0.3) ├────────────── └───┘ └─────────┘ └─────────┘ ┌───┐ ┌─────────┐ ┌─────────┐ q2 : ─┤ H ├─┤ BF(0.3) ├─┤ BF(0.3) ├────────────── └───┘ └─────────┘ └─────────┘ T : │ 0 │
- info()[source]
For usage of pretty prints, this method displays in a string all information relevant to the noise at matter.
- Returns
The string displaying the noise information in a human readable manner.
- Return type
str
- to_kraus_operators()[source]
Noise models can be represented by Kraus operators. They represent how the state is affected by the noise following the formula
\(\rho \leftarrow \sum_{K \in \mathcal{K}} K \rho K^\dagger\)
Where \(\mathcal{K}\) is the set of Kraus operators corresponding to the noise model and \(\rho\) is the state (as a density matrix).
- Returns
The Kraus operators of the noise. Note that it is not a unique representation.
- Return type
list[npt.NDArray[np.complex64]]
- to_other_language(language=Language.QISKIT)[source]
See documentation of this method in abstract mother class
NoiseModel
.- Parameters
language (Language) – Enum representing the target language.
- Return type
BraketNoise | QLMNoise | QuantumError
Examples
>>> BitFlip(0.3, [0,1]).to_other_language(Language.BRAKET) BitFlip('probability': 0.3, 'qubit_count': 1)
>>> BitFlip(0.3, [0,1]).to_other_language(Language.QISKIT).to_quantumchannel() SuperOp([[0.7+0.j, 0. +0.j, 0. +0.j, 0.3+0.j], [0. +0.j, 0.7+0.j, 0.3+0.j, 0. +0.j], [0. +0.j, 0.3+0.j, 0.7+0.j, 0. +0.j], [0.3+0.j, 0. +0.j, 0. +0.j, 0.7+0.j]], input_dims=(2,), output_dims=(2,))
- prob
See parameter description.
Amplitude Damping Noise Model
- class AmplitudeDamping(gamma, prob=1, targets=None, gates=None)[source]
Bases:
NoiseModel
Class representing the amplitude damping noise channel, which can model both the standard and generalized amplitude damping processes. It can be applied to a single qubit and depends on two parameters: the decay rate
gamma
and the probability of excitationprob
.We recall below the associated representation, in terms of Kraus operators, where we denote by \(\gamma\) the decay rate
gamma
, and by \(p\) the excitation probabilityprob
:\(E_0=\sqrt{p}\begin{pmatrix}1&0\\0&\sqrt{1-\gamma}\end{pmatrix}\), \(~ ~ E_1=\sqrt{p}\begin{pmatrix}0&\sqrt{\gamma}\\0&0\end{pmatrix}\), \(~ ~ E_2=\sqrt{1-p}\begin{pmatrix}\sqrt{1-\gamma}&0\\0&1\end{pmatrix}\) and \(~ E_3=\sqrt{1-p}\begin{pmatrix}0&0\\\sqrt{\gamma}&0\end{pmatrix}\).
- Parameters
gamma (float) – Decaying rate of the amplitude damping noise channel.
prob (float) – Probability of excitation in the generalized amplitude damping noise channel. A value of 1, corresponds to the standard amplitude damping. It must be in the
[0, 1]
interval.targets (Optional[list[int]]) – Qubits affected by this noise. Defaults to all qubits.
gates (Optional[list[type[NativeGate]]]) – Gates affected by this noise. Defaults to all gates.
- Raises
ValueError – When the gamma or prob parameters are outside of the expected interval
[0, 1]
.
Examples
>>> circuit = QCircuit( ... [H(i) for i in range(3)] ... + [ ... AmplitudeDamping(0.2, 0, [0]), ... AmplitudeDamping(0.4, 0.1, [1, 2]), ... AmplitudeDamping(0.1, 1, [0, 1, 2]), ... AmplitudeDamping(0.1, 1), ... AmplitudeDamping(0.7, targets=[0, 1]), ... ] ... ) >>> print(circuit) ┌───┐ q_0: ┤ H ├ ├───┤ q_1: ┤ H ├ ├───┤ q_2: ┤ H ├ └───┘ NoiseModel: AmplitudeDamping(0.2, 0, targets=[0]) AmplitudeDamping(0.4, 0.1, targets=[1, 2]) AmplitudeDamping(0.1, targets=[0, 1, 2]) AmplitudeDamping(0.1) AmplitudeDamping(0.7, targets=[0, 1]) >>> print(circuit.to_other_language(Language.BRAKET)) T : │ 0 │ ┌───┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌────────────┐ q0 : ─┤ H ├─┤ AD(0.7) ├─┤ AD(0.1) ├───┤ AD(0.1) ├─────┤ GAD(0.2,0) ├── └───┘ └─────────┘ └─────────┘ └─────────┘ └────────────┘ ┌───┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌──────────────┐ q1 : ─┤ H ├─┤ AD(0.7) ├─┤ AD(0.1) ├───┤ AD(0.1) ├────┤ GAD(0.4,0.1) ├─ └───┘ └─────────┘ └─────────┘ └─────────┘ └──────────────┘ ┌───┐ ┌─────────┐ ┌─────────┐ ┌──────────────┐ q2 : ─┤ H ├─┤ AD(0.1) ├─┤ AD(0.1) ├─┤ GAD(0.4,0.1) ├────────────────── └───┘ └─────────┘ └─────────┘ └──────────────┘ T : │ 0 │
- info()[source]
For usage of pretty prints, this method displays in a string all information relevant to the noise at matter.
- Returns
The string displaying the noise information in a human readable manner.
- Return type
str
- to_kraus_operators()[source]
Noise models can be represented by Kraus operators. They represent how the state is affected by the noise following the formula
\(\rho \leftarrow \sum_{K \in \mathcal{K}} K \rho K^\dagger\)
Where \(\mathcal{K}\) is the set of Kraus operators corresponding to the noise model and \(\rho\) is the state (as a density matrix).
- Returns
The Kraus operators of the noise. Note that it is not a unique representation.
- Return type
list[npt.NDArray[np.complex64]]
- to_other_language(language=Language.QISKIT)[source]
See documentation of this method in abstract mother class
NoiseModel
.- Parameters
language (Language) – Enum representing the target language.
- Return type
BraketNoise | QLMNoise | QuantumError
Examples
>>> AmplitudeDamping(0.4, targets=[0, 1]).to_other_language(Language.BRAKET) AmplitudeDamping('gamma': 0.4, 'qubit_count': 1)
>>> AmplitudeDamping(0.4, 0.2, [1]).to_other_language(Language.BRAKET) GeneralizedAmplitudeDamping('gamma': 0.4, 'probability': 0.2, 'qubit_count': 1)
>>> AmplitudeDamping(0.2, 0.4, [0, 1]).to_other_language(Language.QISKIT).to_quantumchannel() SuperOp([[0.88 +0.j, 0. +0.j, 0. +0.j, 0.08 +0.j], [0. +0.j, 0.89442719+0.j, 0. +0.j, 0. +0.j], [0. +0.j, 0. +0.j, 0.89442719+0.j, 0. +0.j], [0.12 +0.j, 0. +0.j, 0. +0.j, 0.92 +0.j]], input_dims=(2,), output_dims=(2,))
- gamma
See parameter description.
- prob
See parameter description.
Phase Damping Noise Model
- class PhaseDamping(gamma, targets=None, gates=None)[source]
Bases:
NoiseModel
Class representing the phase damping noise channel. It can be applied to a single qubit and depends on the phase damping parameter
gamma
. Phase damping happens when a quantum system loses its phase information due to interactions with the environment, leading to decoherence.- Parameters
gamma (float) – Probability of phase damping.
targets (Optional[list[int]]) – Qubits affected by this noise. Defaults to all qubits.
gates (Optional[list[type[NativeGate]]]) – Gates affected by this noise. Defaults to all gates.
- Raises
ValueError – When the gamma parameter is outside of the expected interval
[0, 1]
.
Examples
>>> circuit = QCircuit( ... [H(i) for i in range(3)] ... + [ ... PhaseDamping(0.32, list(range(3))), ... PhaseDamping(0.01), ... PhaseDamping(0.45, [0, 1]), ... ] ... ) >>> print(circuit) ┌───┐ q_0: ┤ H ├ ├───┤ q_1: ┤ H ├ ├───┤ q_2: ┤ H ├ └───┘ NoiseModel: PhaseDamping(0.32, [0, 1, 2]) PhaseDamping(0.01) PhaseDamping(0.45, [0, 1]) >>> print(circuit.to_other_language(Language.BRAKET)) T : │ 0 │ ┌───┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ q0 : ─┤ H ├─┤ PD(0.45) ├─┤ PD(0.01) ├─┤ PD(0.32) ├─ └───┘ └──────────┘ └──────────┘ └──────────┘ ┌───┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ q1 : ─┤ H ├─┤ PD(0.45) ├─┤ PD(0.01) ├─┤ PD(0.32) ├─ └───┘ └──────────┘ └──────────┘ └──────────┘ ┌───┐ ┌──────────┐ ┌──────────┐ q2 : ─┤ H ├─┤ PD(0.01) ├─┤ PD(0.32) ├────────────── └───┘ └──────────┘ └──────────┘ T : │ 0 │
- info()[source]
For usage of pretty prints, this method displays in a string all information relevant to the noise at matter.
- Returns
The string displaying the noise information in a human readable manner.
- Return type
str
- to_kraus_operators()[source]
Noise models can be represented by Kraus operators. They represent how the state is affected by the noise following the formula
\(\rho \leftarrow \sum_{K \in \mathcal{K}} K \rho K^\dagger\)
Where \(\mathcal{K}\) is the set of Kraus operators corresponding to the noise model and \(\rho\) is the state (as a density matrix).
- Returns
The Kraus operators of the noise. Note that it is not a unique representation.
- Return type
list[npt.NDArray[np.complex64]]
- to_other_language(language=Language.QISKIT)[source]
See documentation of this method in abstract mother class
NoiseModel
.- Parameters
language (Language) – Enum representing the target language.
- Return type
BraketNoise | QLMNoise | QuantumError
Examples
>>> PhaseDamping(0.4, [0, 1]).to_other_language(Language.BRAKET) PhaseDamping('gamma': 0.4, 'qubit_count': 1)
>>> PhaseDamping(0.4, [0, 1]).to_other_language(Language.QISKIT).to_quantumchannel() SuperOp([[1. +0.j, 0. +0.j, 0. +0.j, 0. +0.j], [0. +0.j, 0.77459667+0.j, 0. +0.j, 0. +0.j], [0. +0.j, 0. +0.j, 0.77459667+0.j, 0. +0.j], [0. +0.j, 0. +0.j, 0. +0.j, 1. +0.j]], input_dims=(2,), output_dims=(2,))
>>> print(PhaseDamping(0.4, [0, 1]).to_other_language(Language.MY_QLM)) Phase Damping channel, gamma = 0.4: [[1. 0. ] [0. 0.77459667]] [[0. 0. ] [0. 0.77459667]]
- gamma
Probability of phase damping.