dense-Evolution / experiments /matrix_healing_zne.py
Tatopenn's picture
Sync v8.1.37: density-matrix ZNE healing
ae40686 verified
Raw
History Blame Contribute Delete
3.08 kB
"""
Density-matrix ZNE healing experiment.
Builds a noiseless circuit's ideal density matrix, a Monte-Carlo-ensemble
noisy density matrix at 3 depolarizing-noise scales, then compares raw
(base-scale) fidelity against corrected (Richardson-extrapolated +
Smolin-Gambetta-Smith-projected, via `dense_evolution.mitigation.
zne_density_matrix`) fidelity -- both against the true ideal state, used
ONLY here for grading, never as input to the noise ensemble, the
extrapolation, or the physical-projection step (that would be oracle
access, not error mitigation).
This is the exact experiment `zne_density_matrix`'s docstring reports the
measured finding from -- run it yourself to reproduce (or change SEEDS to
check other random draws):
python experiments/matrix_healing_zne.py
"""
import os
import sys
import numpy as np
import jax.numpy as jnp
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import dense_evolution as de
from dense_evolution.registry import NoiseModel
from dense_evolution.mitigation import uhlmann_fidelity, zne_density_matrix
N_QUBITS = 2
BASE_P = 0.05
SCALES = (1.0, 2.0, 3.0)
K_TRAJECTORIES = 200
SEEDS = (0, 1, 2, 3)
def bell_state_sv():
sim = de.DenseSVSimulator(N_QUBITS)
sim.run_circuit([("h", 0), ("cx", 0, 1)])
return np.asarray(sim.get_statevector())
def noisy_density_matrix(ideal_sv, p, k, rng):
dim = len(ideal_sv)
rho = np.zeros((dim, dim), dtype=np.complex128)
for _ in range(k):
sv_noisy = NoiseModel.apply_to_sv(ideal_sv.copy(), N_QUBITS, 'depolarizing', p, rng=rng)
rho += np.outer(sv_noisy, sv_noisy.conj())
rho /= k
return jnp.asarray(rho, dtype=jnp.complex128)
def run_one_seed(ideal_sv, rho_ideal, seed):
rng = np.random.default_rng(seed)
rho_at_scales = jnp.stack([
noisy_density_matrix(ideal_sv, BASE_P * scale, K_TRAJECTORIES, rng)
for scale in SCALES
])
raw_fidelity = uhlmann_fidelity(rho_at_scales[0], rho_ideal)
corrected = zne_density_matrix(rho_at_scales, SCALES)
corrected_fidelity = uhlmann_fidelity(corrected, rho_ideal)
return raw_fidelity, corrected_fidelity
def main():
ideal_sv = bell_state_sv()
rho_ideal = jnp.asarray(np.outer(ideal_sv, ideal_sv.conj()), dtype=jnp.complex128)
raw_vals, corrected_vals = [], []
for seed in SEEDS:
raw, corrected = run_one_seed(ideal_sv, rho_ideal, seed)
delta = corrected - raw
print(f"seed={seed}: raw={raw:.6f} corrected={corrected:.6f} delta={delta:+.6f}")
raw_vals.append(raw)
corrected_vals.append(corrected)
raw_vals, corrected_vals = np.array(raw_vals), np.array(corrected_vals)
print()
print(f"avg raw fidelity: {raw_vals.mean():.6f}")
print(f"avg corrected fidelity: {corrected_vals.mean():.6f}")
print(f"avg delta: {(corrected_vals - raw_vals).mean():+.6f}")
print(f"delta range: [{(corrected_vals - raw_vals).min():+.6f}, "
f"{(corrected_vals - raw_vals).max():+.6f}]")
if __name__ == "__main__":
main()