use wai_quantum::quantum_frame::Basis;
use wai_quantum::quantum_ldpc::{memory_experiment, BbCode, BpOsdConfig};
fn main() {
let a: Vec<String> = std::env::args().collect();
let code = match a[1].as_str() {
"72" => BbCode::bb72(),
"90" => BbCode::bb90(),
"108" => BbCode::bb108(),
"144" => BbCode::bb144(),
"288" => BbCode::bb288(),
other => panic!("unknown code {other}"),
};
let p: f64 = a[2].parse().unwrap();
let cycles: u32 = a[3].parse().unwrap();
let shots: usize = a[4].parse().unwrap();
let threads: usize = a.get(5).map_or(8, |x| x.parse().unwrap());
let max_iter: u32 = a.get(6).map_or(10_000, |x| x.parse().unwrap());
let cfg = BpOsdConfig { max_iter, ..BpOsdConfig::default() };
let mut both_ok = 1.0;
for (name, basis, seed) in [("Z", Basis::Z, 1u64 << 32), ("X", Basis::X, 2u64 << 32)] {
let t0 = std::time::Instant::now();
let r = memory_experiment(&code, cycles, p, basis, shots, seed, cfg, threads).unwrap();
let dt = t0.elapsed().as_secs_f64();
both_ok *= 1.0 - r.per_shot();
println!(
"{name}-basis shots {} failures {} per shot {:.5} per cycle {:.3e} bp-converged {:.3} {:.1} ms/shot",
r.shots,
r.failures,
r.per_shot(),
r.per_cycle(),
r.converged as f64 / r.shots as f64,
1e3 * dt * threads as f64 / shots as f64
);
}
let p_shot = 1.0 - both_ok;
println!("either per shot {:.5} per cycle {:.3e}", p_shot, 1.0 - (1.0 - p_shot).powf(1.0 / f64::from(cycles)));
}