Example: Advanced Readout Mitigation#
For background on readout errors and the M3 method, see the Readout Error Mitigation guide.
Setup Backend#
from iqm.qiskit_iqm import IQMProvider
from fiqci.ems import FiQCIBackend
from qiskit import QuantumCircuit, transpile
url = None
quantum_computer = None
# Connect to an IQM quantum computer using the provider
if url is not None and quantum_computer is not None:
provider = IQMProvider(url=url, quantum_computer=quantum_computer)
backend = provider.get_backend()
else:
# Or using a noisy simulator
from iqm.qiskit_iqm import IQMFakeAphrodite
backend = IQMFakeAphrodite()
# Wrap backend with mitigation level 1 (readout error mitigation)
mitigated_backend = FiQCIBackend(backend, mitigation_level=1, calibration_shots=2048, calibration_file="cals.json")
print(f"Backend: {backend.name}")
print(f"Mitigation level: {mitigated_backend.mitigation_level}")
Backend: IQMFakeAphroditeBackend
Mitigation level: 1
Bell State Preparation with mitigation#
# Create a Bell state circuit
qc = QuantumCircuit(2)
qc.h(0)
qc.cx(0, 1)
qc.measure_all()
# Transpile for specific qubits
qubits = ["QB9", "QB17"]
qubit_indices = [backend.qubit_name_to_index(q) for q in qubits]
qc_transpiled = transpile(qc, backend=backend, initial_layout=qubit_indices)
display(qc_transpiled.draw(output="mpl"))
# Run with automatic mitigation!
shots = 2048
job = mitigated_backend.run(qc_transpiled, shots=shots)
mitigated_counts = job.result().get_counts()
print("Mitigated counts:", mitigated_counts)
Mitigated counts: {'01': 4, '10': 23, '11': 987, '00': 1033}
Get Metadata#
Metadata is added to the Qiskit Result object including the original raw counts
print(job.result().results[0].header)
raw_counts = job.result().results[0].header["fiqci_ems"]["raw_counts"]
print(raw_counts)
{'creg_sizes': [['meas', 2]], 'global_phase': 0.0, 'memory_slots': 2, 'n_qubits': 54, 'name': 'circuit-19877', 'qreg_sizes': [['q', 2], ['ancilla', 52]], 'metadata': {}, 'fiqci_ems': {'mitigation_level': 1, 'mitigation_method': 'M3', 'calibration_shots': 2048, 'raw_counts': {'01': 116, '10': 105, '00': 928, '11': 899}}}
{'01': 116, '10': 105, '00': 928, '11': 899}
mitigated_counts
Visualize raw vs mitigated results#
from qiskit.visualization import plot_histogram
# Compare raw vs mitigated results
plot_histogram(
[raw_counts, mitigated_counts],
legend=["Raw", "Mitigated (M3)"],
title="Raw vs Mitigated Counts",
bar_labels=True,
figsize=(10, 5),
)
Advanced Usage: Direct M3IQM Control#
from fiqci.ems.mitigators.rem import M3IQM
from fiqci.ems.utils import probabilities_to_counts
# Initialize M3 mitigator
m3_mitigator = M3IQM(backend)
# Calibrate for specific qubits
m3_mitigator.cals_from_system(qubits=qubit_indices, shots=2048, method="balanced")
# Inspect calibration matrices
print("QB26 (index", qubit_indices[0], ") calibration matrix:")
print(m3_mitigator.cals_to_matrices()[qubit_indices[0]])
print("\nQB27 (index", qubit_indices[1], ") calibration matrix:")
print(m3_mitigator.cals_to_matrices()[qubit_indices[1]])
QB26 (index 8 ) calibration matrix:
[[0.94091797 0.05566406]
[0.05908203 0.94433594]]
QB27 (index 16 ) calibration matrix:
[[0.95947266 0.04736328]
[0.04052734 0.9526367 ]]
# Run circuit and get raw counts
raw_counts_manual = backend.run(qc_transpiled, shots=shots).result().get_counts()
# Apply M3 correction manually
quasi_dist = m3_mitigator.apply_correction(raw_counts_manual, qubits=qubit_indices, return_mitigation_overhead=True)
# Get expectation value and standard deviation
expval, stddev = quasi_dist.expval_and_stddev()
print(f"Expectation value: {expval:.4f} ± {stddev:.4f}")
# Convert to nearest probability distribution
mitigated_probs = quasi_dist.nearest_probability_distribution()
mitigated_counts_manual = probabilities_to_counts(mitigated_probs, shots)
print("\nRaw counts:", raw_counts_manual)
print("Mitigated counts:", mitigated_counts_manual[0])
Expectation value: 0.9966 ± 0.0276
Raw counts: {'01': 105, '10': 95, '00': 929, '11': 919}
Mitigated counts: {'01': 1, '10': 2, '11': 1018, '00': 1025}
from qiskit.visualization import plot_histogram
# Compare raw vs mitigated results
plot_histogram(
[raw_counts_manual, mitigated_counts_manual[0]],
legend=["Raw", "Mitigated (M3)"],
title="Raw vs Mitigated Counts",
bar_labels=True,
figsize=(10, 5),
)