Basic usage

Using M3 involves three steps (steps one and two can usually be done in reverse order if desired).

  1. Select a system and calibrate over the desired set of qubits.

  2. Run the circuit(s) of interest on the system.

  3. Apply the readout correction and post-process.

Simple example

Here we use a noisy simulator to perform the three steps above. First we import the needed modules, and construct a circuit of interest.

import numpy as np
from qiskit import *
from qiskit.providers.fake_provider import FakeCasablanca
import mthree

qc = QuantumCircuit(6)

Next we calibrate an M3 mitigator instance over qubits 0 -> 6 (Step #1):

backend = FakeCasablanca()
mit = mthree.M3Mitigation(backend)

Transpile and execute our circuit (Step #2):

trans_qc = transpile(qc, backend)
raw_counts =

Finally, apply the correction and post-process (Step #3). Here our post-processing is simply computing the expectation value from the returned quasi-probabilities:

quasis = mit.apply_correction(raw_counts, range(6))
print('Expectation value:',quasis.expval())
Expectation value: 0.9152542989652004

Specifying qubits to mitigate over

The circuit above also fits on other systems without SWAP mapping provided that we select the correct layout.

from qiskit.providers.fake_provider import FakeMontreal

backend = FakeMontreal()
mit2 = mthree.M3Mitigation(backend)

In our case, qubits = [10, 12, 15, 13, 11, 14] is an appropriate layout. Importantly, the zeroth entry of the list tells us what physical qubit is readout to generate bit 0 in the output bit-strings. We must pass this list to both the calibration and correction steps of M3.

qubits = [10, 12, 15, 13, 11, 14]

trans_qc = transpile(qc, backend, initial_layout=qubits)
raw_counts2 =

quasis2 = mit2.apply_correction(raw_counts2, qubits)
print('Expectation value:',quasis2.expval())
Expectation value: 0.9270263106855061