Error Mitigation
Divi provides built-in error mitigation to improve results from noisy quantum hardware. The main technique is Zero Noise Extrapolation (ZNE), which runs circuits at different noise levels and extrapolates to the zero-noise limit using mitiq.zne.inference.RichardsonFactory and mitiq.zne.scaling.fold_gates_at_random.
Basic Usage
Simple ZNE Setup:
from functools import partial
from mitiq.zne.inference import RichardsonFactory
from mitiq.zne.scaling import fold_gates_at_random
from divi.circuits.qem import ZNE
from divi.qprog import VQE, HartreeFockAnsatz
from divi.backends import ParallelSimulator
import pennylane as qml
import numpy as np
# Create ZNE protocol
scale_factors = [1.0, 1.5, 2.0]
zne_protocol = ZNE(
scale_factors=scale_factors,
folding_fn=partial(fold_gates_at_random),
extrapolation_factory=RichardsonFactory(scale_factors=scale_factors),
)
# Apply to VQE
h2_molecule = qml.qchem.Molecule(
symbols=["H", "H"],
coordinates=np.array([[0.0, 0.0, -0.6614], [0.0, 0.0, 0.6614]])
)
vqe = VQE(
molecule=h2_molecule,
qem_protocol=zne_protocol,
backend=ParallelSimulator(qiskit_backend="auto") # Use noisy simulator
)
vqe.run()
print(f"Mitigated energy: {vqe.best_loss:.6f}")
Configuration Options
Light Mitigation (Faster):
light_zne = ZNE(
scale_factors=[1.0, 1.5],
folding_fn=partial(fold_gates_at_random),
extrapolation_factory=RichardsonFactory(scale_factors=[1.0, 1.5]),
)
Heavy Mitigation (More Accurate):
heavy_zne = ZNE(
scale_factors=[1.0, 1.5, 2.0, 2.5, 3.0],
folding_fn=partial(fold_gates_at_random),
extrapolation_factory=RichardsonFactory(
scale_factors=[1.0, 1.5, 2.0, 2.5, 3.0]
),
)
Performance Considerations
Overhead: ZNE typically requires 2-5x more circuit evaluations
Memory: Stores results from multiple noise levels
Time: Longer execution due to additional circuits
Tip: Use fewer shots (500-1000) with mitigation since results are averaged across noise levels.
Custom Error Mitigation Protocols
You can implement custom error mitigation strategies by inheriting from QEMProtocol:
from divi.circuits.qem import QEMProtocol
import numpy as np
class ReadoutErrorMitigation(QEMProtocol):
"""Simple readout error mitigation protocol"""
def __init__(self, calibration_matrix=None):
self.calibration_matrix = calibration_matrix
self.name = "Readout Error Mitigation"
def modify_circuit(self, circuit):
"""No circuit modification needed for readout mitigation"""
return [circuit]
def postprocess_results(self, results):
"""Apply readout error correction to measurement results"""
if self.calibration_matrix is None:
return results[0] # No correction if no calibration
# Apply matrix correction to measurement probabilities
corrected_probs = np.dot(results[0], self.calibration_matrix)
return corrected_probs
# Usage example
calibration_matrix = np.array([[0.9, 0.1], [0.1, 0.9]])
readout_mitigation = ReadoutErrorMitigation(calibration_matrix=calibration_matrix)
vqe = VQE(
molecule=h2_molecule,
qem_protocol=readout_mitigation,
backend=ParallelSimulator()
)
Key Methods to Implement:
modify_circuit(circuit)- Modify circuits before execution (return list of circuits)postprocess_results(results)- Process results after executionname- Protocol name for identification
Next Steps
🛠️ API Reference: Learn about custom protocols in Circuits
📊 Program Batches: Apply mitigation to large computations in Program Batches and Workflows
📈 Advanced Usage: Explore
mitiqdocumentation for more sophisticated techniques