PennyLane
  • Why PennyLane
  • Getting Started
  • Documentation
  • Ecosystem
Install
Install
  1. Blog/
  2. How-to/
  3. How to simulate noise with PennyLane

May 14, 2021

How to simulate noise with PennyLane

David Wakeham

David Wakeham

Quantum technology is still in its infancy. And like any infant, it is small, noisy and lovable, a state of affairs captured by the acronym NISQ (Noisy Intermediate-Scale Quantum). To realistically model the machines our circuits will run on, and the robustness of the algorithms themselves, we need to add noise to our simulations. Thankfully, PennyLane has a variety of ways for doing this! This how-to guide briefly explores three different methods: classical parametric randomness, PennyLane’s built-in default.mixed device, and plugins to Cirq and Qiskit. So, without further ado, let’s make some noise for NISQ!

nisq-baby

Classical randomization

We’ll start with a cheap, direct method for creating noise: classically randomizing parameters. This reflects, for instance, the fact that experimentalists can only twiddle knobs with finite precision. Let’s pause briefly and think about what this does. We know that measurement in quantum mechanics is an intrinsically random process. Even if we have a completely deterministic circuit producing a state U|0\rangle , the outcome of observing O is random. However, the average, or expectation value

\langle O \rangle = \langle 0| U^\dagger O U |0\rangle

over many measurements is well-defined. But if U(\theta) is now a function of a noisy parameter \theta , then the expectation

\langle O \rangle_\theta = \langle 0| U(\theta)^\dagger O U(\theta) |0\rangle

will also fluctuate with \theta ! Here is a single-qubit example. We will perform a noisy X rotation, i.e., a rotation R_x(\theta) = e^{-i\theta X/2} with a random angle \theta . We then measure Z :

import pennylane as qml from pennylane import numpy as np dev1 = qml.device("default.qubit", wires=1) @qml.qnode(dev1) def rot_circuit(prec): rand_angle = np.pi + prec*np.random.rand() # np.random.rand() uniformly samples from [0, 1) qml.RX(rand_angle, wires=0) return qml.expval(qml.PauliZ(0))

Our random angle is \theta = \pi + \epsilon , where \epsilon is a random (uniform) wobble about \pi . For large random rotations, \epsilon \sim \pi , the expectation values of Z should fluctuate wildly. For \epsilon \ll \pi , the state is approximately |1\rangle and the expectation should jitter near \langle Z \rangle = -1 :

>>> print(rot_circuit(4)) 0.8340865579113448 >>> print(rot_circuit(4)) -0.910006272110444 >>> print(rot_circuit(0.1)) -0.9999434937900038 >>> print(rot_circuit(0.1)) -0.9982625520423022

This behaves as we expect! We see that basic classical noise is easy to add by hand.

Density matrices

Instead of working with classical noise, we can wrangle noise quantum-mechanically using the formalism of density matrices. PennyLane lets us describe density matrices using the default.mixed device, invoked as follows:

dev2 = qml.device('default.mixed', wires=1)

Recall that the most general physical operations acting on density matrices are quantum channels \Phi , which can be written in terms of some set of Kraus operators \{K_e\} as

\Phi(\rho) = \sum_e K_e \rho K_e^\dagger, \quad \sum_e K_e^\dagger K_e = I.

Each K_e is associated with a particular outcome (or error) which may occur when applying the channel. For a detailed review of quantum channels and Kraus operators, consult your local quantum information textbook, e.g., chapter 8 of Nielsen and Chuang.

PennyLane provides various standard noise operations. The simplest example is the bit flip channel, which swaps |0\rangle and |1\rangle with some probability. More formally, with probability p this applies an X operation, and otherwise does nothing, so the Kraus operators are

K_0 = \sqrt{1 - p}I, \quad K_1 = \sqrt{p} X.

This may seem too trivial to be of physical interest, but turns out to be very important when considering the effects of cosmic rays on terrestrial computation (sort of). The bit flip channel is implemented by the BitFlip method in PennyLane:

@qml.qnode(dev2) def bitflip_circuit(p): qml.BitFlip(p, wires=0) return qml.expval(qml.PauliZ(0))

As before, we can measure Z and see if the results make sense. Note that default.mixed is initialized to the density |0\rangle\langle 0| :

>>> print(bitflip_circuit(0.01)) 0.98 >>> print(bitflip_circuit(0.99)) -0.98

Once again, this is what we expect! Other channels include PhaseFlip (randomly applies Z ), AmplitudeDamping (randomly destroy amplitude information), PhaseDamping (randomly destroy phase information) and the DepolarizingChannel (randomly destroy all information).

Finally, you can use QubitChannel to customize your noise! As a simple example, let’s make the bit phase flip channel, which applies Y with probability p . This has Kraus operators

K_0 = \sqrt{1-p}I, \quad K_1 = \sqrt{p}Y,

which we can input to the QubitChannel method as follows:

@qml.qnode(dev2) def bitphaseflip_circuit(p): K0 = np.sqrt(1-p)*np.eye(2) K1 = np.sqrt(p)*np.array([[0,1j],[1j,0]]) qml.QubitChannel([K0, K1], wires=0) return qml.expval(qml.PauliZ(0))

We get the same results as the bit flip channel, since the effect is the same up to phase (as the name of the channel suggests):

>>> print(bitphaseflip_circuit(0.01)) 0.98 >>> print(bitphaseflip_circuit(0.99)) -0.98

Cirq

Quantum circuits may be run on a variety of backends, some of which have their own associated programming languages and simulators. PennyLane can interface with these other languages via plugins. We will look at two examples: Cirq and Qiskit. Before proceeding, ensure the plugins are installed by running

pip install pennylane-cirq

and

pip install pennylane-qiskit

from the command line. Let’s start with Cirq. We simply import ops, which gives access to Cirq’s quantum channels, and run on the cirq.mixedsimulator device:

from pennylane_cirq import ops as cirq_ops dev3 = qml.device("cirq.mixedsimulator", wires=1) @qml.qnode(dev3) def bitflip_circuit_cirq(p): cirq_ops.BitFlip(p, wires=0) return qml.expval(qml.PauliZ(0))

Let’s try this out:

>>> print(bitflip_circuit_cirq(0.01)) 0.980000008828938 >>> print(bitflip_circuit_cirq(0.99)) -0.980000008828938

See this tutorial for more on Cirq’s noise operations.

Qiskit

The Qiskit simulator Aer is provided by qiskit.aer, with noise operations living in qiskit.providers.aer.noise. Qiskit has a different approach, incorporating a noise model into the device itself. We’ll do a slightly more interesting example, and attach a bit flip error to a Hadamard gate:

import qiskit import qiskit.providers.aer.noise as noise # create a bit flip error with probability p = 0.01 p = 0.01 my_bitflip = noise.pauli_error([('X', p), ('I', 1 - p)]) # create an empty noise model my_noise_model = noise.NoiseModel() # attach the error to the hadamard gate 'h' my_noise_model.add_quantum_error(my_bitflip, ['h'], [0]) dev4 = qml.device('qiskit.aer', wires=1, noise_model = my_noise_model) @qml.qnode(dev4) def bitflip_circuit_aer(): qml.Hadamard(0) return qml.expval(qml.PauliZ(0))

Let’s check the output of our circuit:

>>> print(bitflip_circuit_aer()) -0.080078125

Since the probability of a bit flip is small, and the expectation of Z in the state H|0\rangle = |+\rangle vanishes, our result is sensible! More detailed information can be found in the PennyLane and Qiskit documentation.

This completes our whistlestop tour of noise simulation in PennyLane. You now know how to simulate a jittery knob, a cosmic ray event, or an arbitrary Kraus operator, and how to interface with noisy simulation in Cirq and Qiskit. Time for you to make your own noise!

About the author

David Wakeham
David Wakeham

David Wakeham

Having fun at the intersection of quantum algorithms, symmetry, statistical learning theory and large language models.

Last modified: August 06, 2024

Related Blog Posts

PennyLane

PennyLane is an open-source software framework for quantum machine learning, quantum chemistry, and quantum computing, with the ability to run on all hardware. Built with ❤️ by Xanadu.

Stay updated with our newsletter

For researchers

  • Research
  • Features
  • Demos
  • Compilation
  • Datasets
  • Performance
  • Learn
  • Videos
  • Documentation
  • Teach

For learners

  • Learn
  • Codebook
  • Teach
  • Videos
  • Challenges
  • Demos
  • Compilation
  • Glossary

For developers

  • Features
  • Documentation
  • API
  • GitHub
  • Datasets
  • Demos
  • Compilation
  • Performance
  • Devices
  • Catalyst

© Copyright 2025 | Xanadu | All rights reserved

TensorFlow, the TensorFlow logo and any related marks are trademarks of Google Inc.

Privacy Policy|Terms of Service|Cookie Policy|Code of Conduct