Converting to probabilites¶

M3 natively works with quasi-probability distributions; distributions that contain negative values but nonetheless sum to one. This is useful for mitigating expectation values, but there could be situations where a true probability distribution is useful / needed. To this end, it is possible to find the closest probability distribution to a quasi-probability distribution in terms of \(L2\)-norm using: mthree.classes.QuasiDistribution.nearest_probability_distribution(). This conversion is done in linear time.

from qiskit import *
from qiskit_ibm_runtime.fake_provider import FakeCasablancaV2
import mthree

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()

backend = FakeCasablancaV2()
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()

quasis = mit.apply_correction(raw_counts, range(6))

# Here is where the conversion happens
quasis.nearest_probability_distribution()
{'100100': np.float32(1.2372489e-05),
 '000011': np.float32(1.8537092e-05),
 '010010': np.float32(2.5061807e-05),
 '011001': np.float32(5.2582476e-05),
 '011010': np.float32(6.233902e-05),
 '001011': np.float32(6.4512365e-05),
 '110101': np.float32(6.54489e-05),
 '100101': np.float32(7.242779e-05),
 '100011': np.float32(7.6106066e-05),
 '001101': np.float32(7.812127e-05),
 '101001': np.float32(8.1627266e-05),
 '001110': np.float32(8.477365e-05),
 '001000': np.float32(0.000106018604),
 '001001': np.float32(0.00013935733),
 '110100': np.float32(0.0001743302),
 '101011': np.float32(0.0001873179),
 '001010': np.float32(0.00025005074),
 '101101': np.float32(0.00026449992),
 '011011': np.float32(0.00033367818),
 '100000': np.float32(0.00036363336),
 '010000': np.float32(0.0011727436),
 '000001': np.float32(0.0014612271),
 '000100': np.float32(0.0019161778),
 '110000': np.float32(0.002174427),
 '000010': np.float32(0.002248123),
 '110111': np.float32(0.002422524),
 '101111': np.float32(0.0034184202),
 '000110': np.float32(0.0035131983),
 '111101': np.float32(0.0037060152),
 '011111': np.float32(0.004674465),
 '111110': np.float32(0.0050088116),
 '111001': np.float32(0.005207894),
 '001111': np.float32(0.0057791495),
 '111000': np.float32(0.0059057614),
 '000111': np.float32(0.006720885),
 '111011': np.float32(0.00717622),
 '111111': np.float32(0.45109168),
 '000000': np.float32(0.48388952)}