Dashboard Core — Mitigation (Composer's ZNE panel)¶
Real Zero-Noise Extrapolation (ZNE) error mitigation, wired to the same
engine and real noise channels (dense_evolution.registry.NoiseModel)
the rest of Composer uses — a thin dashboard-facing layer over
dense_evolution.mitigation, not a separate
reimplementation.
mitigation ¶
Real Zero-Noise Extrapolation (ZNE) error mitigation, wired to the same engine and real noise channels (dense_evolution.NoiseModel) the rest of the Composer uses. Noise is scaled by running the real channel at noise_p, 2noise_p, 3noise_p and Richardson-extrapolating the measured Pauli expectation back to zero noise via dense_evolution's own zero_noise_extrapolation -- not a fabricated mitigated curve.
run_zne_mitigation ¶
run_zne_mitigation(
qasm_text: str,
pauli_string: str,
noise_model: str,
noise_p: float,
seed: Optional[int] = None,
noise_factors=None,
n_trials: int = 200,
extrapolation_method: str = "richardson",
) -> MitigationResult
Real ZNE:
is measured at the real ideal state and at the real channel applied at noise_p * each factor, then extrapolated to zero noise -- either Richardson (dense_evolution.zero_noise_extrapolation, the exact interpolating polynomial through 3 points, the default) or a degree-2 least-squares polynomial fit through 5 points (dense_evolution.polynomial_extrapolate) -- caller's choice, not silently picked: noise_factors defaults to the 3- or 5-point set that matches whichever method was requested, unless the caller overrides it explicitly.
NoiseModel.apply_to_sv is a stochastic single-shot Kraus draw (one random outcome per call, not the channel's averaged/ensemble behavior) -- feeding a single draw straight into ZNE gives a discontinuous, meaningless curve (verified: bitflip/depolarizing jumped 1.0 -> 0.0 -> 0.0 across noise scales instead of decaying smoothly).
under a Kraus channel is Tr(rho P) = mean over the channel's trajectories, so each scale here averages n_trials independent stochastic draws -- the actual expectation value ZNE is defined against, not one random sample of it.
pauli_string uses dense_evolution's own qubit-0-is-position-0 convention (same as pauli_expectation), independent of Qiskit's little-endian display convention used elsewhere on this page -- this function never touches a Qiskit-ordered array.
Source code in tools/dashboard_core/mitigation.py
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 | |
run_density_matrix_zne ¶
run_density_matrix_zne(
qasm_text: str,
noise_model: str,
noise_p: float,
seed: Optional[int] = None,
noise_factors=_DEFAULT_NOISE_FACTORS,
n_trials: int = 200,
) -> DensityMatrixZNEResult
Density-matrix ZNE (dense_evolution.zne_density_matrix): builds a real Monte-Carlo density-matrix estimate at each noise scale (the mean of n_trials |psi_k><psi_k| projectors from independent NoiseModel draws -- a real ensemble reconstruction, not a single trajectory), extrapolates to zero noise, and projects onto the nearest physical (PSD, trace-1) density matrix internally.
Graded (never fed back into the extrapolation) against the true ideal density matrix via dense_evolution.uhlmann_fidelity, so the reported improvement is an honest measurement of whether the correction actually helped -- matches the pattern in zne_density_matrix's own docstring (experiments/matrix_healing_zne.py: raw ~0.865, corrected ~0.947 on a 2-qubit Bell state).
Source code in tools/dashboard_core/mitigation.py
Not to be confused with dense_evolution.mitigation
(same name, different module) — that one is the actual ZNE
implementation (richardson_extrapolate, zne_density_matrix,
jsd_predictive_zne_density_matrix, ...); this one is the dashboard's
request/response wrapper around it.