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()
{'000100': np.float32(6.473434e-05),
 '001110': np.float32(9.600079e-05),
 '100111': np.float32(0.0001649973),
 '110101': np.float32(0.00018833106),
 '101011': np.float32(0.00027177174),
 '000110': np.float32(0.0008907791),
 '000001': np.float32(0.0009815614),
 '001000': np.float32(0.0013853181),
 '100000': np.float32(0.0015513115),
 '110111': np.float32(0.002598933),
 '110000': np.float32(0.0031237034),
 '101111': np.float32(0.0032482478),
 '111001': np.float32(0.003527014),
 '111101': np.float32(0.0039979788),
 '001111': np.float32(0.0041356916),
 '111000': np.float32(0.004668914),
 '010000': np.float32(0.005247114),
 '000111': np.float32(0.006918437),
 '111011': np.float32(0.01640486),
 '111111': np.float32(0.45435613),
 '000000': np.float32(0.4861782)}