Advanced usage¶
Options for M3Mitigation class¶
iter_threshold
¶
The main mthree.M3Mitigation
class accepts the iter_threshold keyword argument
that determines when the automated method selector pickes the iterative method
over direct LU factorization (selection also depends on free memory).
from qiskit_ibm_runtime.fake_provider import FakeCasablancaV2
import mthree
backend = FakeCasablancaV2()
mit = mthree.M3Mitigation(backend, iter_threshold=4321)
Options for calibration¶
shots
¶
When calibrating the mitigator, it is possible to vary the number of shots per calibration circuit:
mit = mthree.M3Mitigation(backend)
mit.cals_from_system(range(5), shots=4321)
[<qiskit_aer.jobs.aerjob.AerJob at 0x7fbbd83d4fa0>]
method
¶
There are three ways to do the calibration. The default balanced
method executes \(2N\) circuits
with varying bitstring patterns such that the \(|0\rangle\) and \(|1\rangle\) states are each
prepared \(N\) times and averaged over. For example, the balanced bit-strings over four qubits are
mthree.circuits.balanced_cal_strings(4)
['0101', '1010', '0011', '1100', '0001', '1110', '0000', '1111']
The independent
method also sends \(2N\) circuits but measures only a single qubit at a time.
As such, this is a truely uncorrelated calibration process.
Finally, a marginal
calibration can also be done that sends only two circuits,
\(|0\rangle^{\otimes N}\) and \(|1\rangle^{\otimes N}\), and marginalizes over the
results to get the needed \(2N\) error rates. These two states are a sub-set of the balanced
calibrations, and are what Qiskit uses in its readout mitigation. This method is very sensitive to
state preparation errors, and should not be used in practice.
An example setting the method is
mit = mthree.M3Mitigation(backend)
mit.cals_from_system(range(5), method='independent')
[<qiskit_aer.jobs.aerjob.AerJob at 0x7fbbd833a050>]
rep_delay
¶
Caution
Do not set this unless you know what you are doing.
The rep_delay
keyword argument sets the time between calibration circuits on IBM Quantum systems.
This option exists to test and reduce the presence of state prep errors. The calibration circuits
in M3 all contain conditional resets at the beginning so as to minimize the need for setting this
option.
mit = mthree.M3Mitigation(backend)
mit.cals_from_system(range(5), rep_delay=400e-6)
[<qiskit_aer.jobs.aerjob.AerJob at 0x7fbbd83d50f0>]
initial_reset
¶
Caution
Do not set this unless you know what you are doing.
A boolean value that specifies whether reset instructions should be used at the beginning of the
calibration circuits. Ideally this helps to supress any residual state prep errors that occur from
imperfect reset of the qubits. Can be used in concert with, or as an alternative to rep_delay
.
Note that, in order for this to work, the circuits that need to be mitigated must also have reset
instructions at the beginning. Otherwise you are calibrating for no state-prep errors, but the
actual circuits may still suffer from these errors.
Options when applying corrections¶
Here we first calibrate a mitigator and generate raw counts:
from qiskit import *
qc = QuantumCircuit(6)
qc.reset(range(6))
qc.h(3)
qc.cx(3,1)
qc.cx(3,5)
qc.cx(1,0)
qc.cx(5,4)
qc.cx(1,2)
qc.measure_all()
mit = mthree.M3Mitigation(backend)
mit.cals_from_system(range(6))
trans_qc = transpile(qc, backend)
raw_counts = backend.run(trans_qc, shots=8192).result().get_counts()
method
¶
There are two ways to solve the linear system of equations generated by M3. First, the
direct
method uses LU-factorization by constructing the reduced assignment matrix.
Second the iterative
method uses preconditioned iterative solvers to find the
solution vector without explicit matrix construction. By default M3 uses an auto
method that selects the appropriate solution method based on the number of unique
bit-strings and the available free memory on the computer. To override this, one
can simply set the option:
quasis = mit.apply_correction(raw_counts, range(6), method='iterative')
distance
¶
Optionally one may trucate the M3 assignment matrix to only those elements of the matrix that
are transistions between elements less than or equal to a given Hamming distance away from
each other. This does not change the dimensionality of the underlying matrix, but rather
changes the sparsity pattern of the elements. This is done using the distance
keyword argument.
By default, M3 computes the corrections out to the full distance. In practice, including only
up to distance=3
elements yields accurate answers in most cases.
quasis = mit.apply_correction(raw_counts, range(6), distance=3)
details
¶
Allows one to see additional information about the solution. This changes the return of the
:method:mthree.M3Mitigation.apply_correction
method to a tuple of two values:
quasis, details = mit.apply_correction(raw_counts, range(6), details=True)
print(details)
{'method': 'direct', 'time': 0.0001660210000125062, 'dimension': 44, 'col_norms': array([0.9991987 , 0.9628587 , 0.98538595, 0.97123784, 0.98513776,
0.99302775, 0.97786385, 0.9782937 , 0.9859417 , 0.9609599 ,
0.948159 , 0.9786799 , 0.9984028 , 0.9780926 , 0.95648533,
0.92860085, 0.9835394 , 0.9321074 , 0.9581357 , 0.95899475,
0.9598778 , 0.99740773, 0.96948814, 0.9568221 , 0.9568263 ,
0.9758898 , 0.9544127 , 0.9515043 , 0.9508917 , 0.9569788 ,
0.9977843 , 0.9694043 , 0.90190464, 0.90020055, 0.93124384,
0.9951148 , 0.9983702 , 0.9550446 , 0.933478 , 0.99592066,
0.95833814, 0.9966683 , 0.99698824, 0.9998342 ], dtype=float32)}
max_iter
¶
Caution
Do not set this unless you know what you are doing.
Sets the maximum number of iterations performed by the iterative solver.
quasis = mit.apply_correction(raw_counts, range(6), method='iterative', max_iter=10)
tol
¶
Caution
Do not set this unless you know what you are doing.
Sets the tolerance of the iterative solver. Might need adjustments to max_iter
if value
is set too low.
quasis = mit.apply_correction(raw_counts, range(6), method='iterative', tol=1e-5)