1use crate::quantum_cal::{cos_fx, exp_neg_fx, seal_artifacts, sin_fx, CalArtifacts, CAL_FRAC, CAL_ONE};
35use crate::quantum_ops::{content_hash, CalibrationReceipt, GrantRef};
36use ed25519_dalek::SigningKey;
37
38const ONE: i64 = CAL_ONE;
39const FRAC: u32 = CAL_FRAC;
40const PI_FX: i64 = 3_294_199; const INV_PI_FX: i64 = 333_772; #[inline]
44fn fmul(a: i64, b: i64) -> i64 {
45 ((a as i128 * b as i128) >> FRAC) as i64
46}
47#[inline]
48fn fdiv(a: i64, b: i64) -> i64 {
49 if b == 0 {
50 return 0;
51 }
52 (((a as i128) << FRAC) / b as i128) as i64
53}
54
55fn ln_fx(x: i64) -> i64 {
58 if x <= 0 {
59 return -20 * ONE; }
61 let z = fdiv(x - ONE, x + ONE); let z2 = fmul(z, z);
63 let mut term = z;
64 let mut acc = 0i64;
65 let mut k = 1i64;
66 for _ in 0..12 {
67 acc += term / k;
68 term = fmul(term, z2);
69 k += 2;
70 }
71 2 * acc
72}
73
74fn splitmix64(state: &mut u64) -> u64 {
75 *state = state.wrapping_add(0x9E37_79B9_7F4A_7C15);
76 let mut z = *state;
77 z = (z ^ (z >> 30)).wrapping_mul(0xBF58_476D_1CE4_E5B9);
78 z = (z ^ (z >> 27)).wrapping_mul(0x94D0_49BB_1331_11EB);
79 z ^ (z >> 31)
80}
81
82#[derive(Clone, Debug)]
89pub struct NoiseGrid {
90 pub omega: Vec<i64>,
91 pub dw: i64,
92}
93
94impl NoiseGrid {
95 pub fn linear(w_min: f64, w_max: f64, n: usize) -> NoiseGrid {
98 let wmin = (w_min * ONE as f64) as i64;
99 let wmax = (w_max * ONE as f64) as i64;
100 let dw = (wmax - wmin) / (n as i64 - 1).max(1);
101 let omega = (0..n).map(|i| wmin + i as i64 * dw).collect();
102 NoiseGrid { omega, dw }
103 }
104}
105
106pub fn psd_model(g: &NoiseGrid, a_over_f: f64, bump: f64, w0: f64, gamma: f64) -> Vec<i64> {
110 let a = (a_over_f * ONE as f64) as i64;
111 let h = (bump * ONE as f64) as i64;
112 let w0f = (w0 * ONE as f64) as i64;
113 let gf = (gamma * ONE as f64) as i64;
114 let g2 = fmul(gf, gf);
115 g.omega
116 .iter()
117 .map(|&w| {
118 let one_over_f = fdiv(a, w); let dwn = w - w0f;
120 let lor = fmul(h, fdiv(g2, fmul(dwn, dwn) + g2)); one_over_f + lor
122 })
123 .collect()
124}
125
126fn hash_psd(psd: &[i64]) -> [u8; 32] {
127 let mut b = Vec::with_capacity(psd.len() * 8 + 8);
128 b.extend_from_slice(b"wai:qc-psd\x01");
129 for &v in psd {
130 b.extend_from_slice(&v.to_le_bytes());
131 }
132 content_hash(&b)
133}
134
135pub fn dd_free() -> Vec<i64> {
141 Vec::new()
142}
143pub fn dd_hahn() -> Vec<i64> {
145 vec![ONE / 2]
146}
147pub fn dd_cpmg(n: usize) -> Vec<i64> {
149 (1..=n)
150 .map(|k| ((2 * k as i64 - 1) * ONE) / (2 * n as i64))
151 .collect()
152}
153pub fn dd_udd(n: usize) -> Vec<i64> {
156 (1..=n)
157 .map(|k| {
158 let theta = (PI_FX * k as i64) / (2 * n as i64 + 2);
159 let s = sin_fx(theta);
160 fmul(s, s)
161 })
162 .collect()
163}
164
165pub fn filter_kernel(pulses: &[i64], g: &NoiseGrid) -> Vec<i64> {
171 let mut t = Vec::with_capacity(pulses.len() + 2);
173 t.push(0i64);
174 t.extend_from_slice(pulses);
175 t.push(ONE);
176 g.omega
177 .iter()
178 .map(|&w| {
179 let (mut re, mut im) = (0i64, 0i64);
180 for k in 0..t.len() - 1 {
182 let sign = if k % 2 == 0 { 1i64 } else { -1 };
183 let p1 = fmul(w, t[k + 1]);
184 let p0 = fmul(w, t[k]);
185 re += sign * (cos_fx(p1) - cos_fx(p0));
186 im += sign * (sin_fx(p1) - sin_fx(p0));
187 }
188 let mag2 = re as i128 * re as i128 + im as i128 * im as i128;
190 let w2 = w as i128 * w as i128;
191 let yy = if w2 == 0 { 0 } else { ((mag2 * ONE as i128) / w2) as i64 };
192 fmul(fmul(yy, g.dw), INV_PI_FX)
193 })
194 .collect()
195}
196
197pub fn overlap(psd: &[i64], kern: &[i64]) -> i64 {
199 psd.iter().zip(kern).map(|(&s, &k)| fmul(s, k)).sum()
200}
201
202pub fn coherence(chi: i64) -> i64 {
204 exp_neg_fx(chi)
205}
206
207#[derive(Clone, Debug, PartialEq, Eq)]
213pub struct SpectroResult {
214 pub omega: Vec<i64>,
215 pub psd_true: Vec<i64>,
216 pub psd_est: Vec<i64>,
217 pub n_sequences: usize,
219 pub error_fx: i64,
221}
222
223pub fn reconstruct_psd(
229 g: &NoiseGrid,
230 psd_true: &[i64],
231 n_max: usize,
232 shots: u32,
233 iters: u32,
234 seed: u64,
235) -> SpectroResult {
236 let kernels: Vec<Vec<i64>> = (1..=n_max).map(|n| filter_kernel(&dd_cpmg(n), g)).collect();
238 let mut chi_meas = Vec::with_capacity(n_max);
239 for (idx, kern) in kernels.iter().enumerate() {
240 let chi_true = overlap(psd_true, kern);
241 let c_true = coherence(chi_true);
242 let mut st = seed.wrapping_mul(0x100_0001).wrapping_add(idx as u64 + 1);
244 let p_plus = (ONE + c_true) / 2;
245 let mut hits = 0u64;
246 for _ in 0..shots {
247 let r = (splitmix64(&mut st) >> (64 - FRAC)) as i64;
248 if r < p_plus {
249 hits += 1;
250 }
251 }
252 let c_hat = (2 * (hits as i128 * ONE as i128) / shots.max(1) as i128 - ONE as i128) as i64;
253 let c_hat = c_hat.clamp(ONE / 100, ONE);
254 chi_meas.push(-ln_fx(c_hat));
255 }
256
257 let ng = g.omega.len();
259 let denom: Vec<i64> = (0..ng).map(|i| kernels.iter().map(|k| k[i]).sum()).collect();
260 let mut est = vec![ONE / 10; ng]; for _ in 0..iters {
262 let pred: Vec<i64> = kernels.iter().map(|k| overlap(&est, k)).collect();
264 let ratio: Vec<i64> = pred
265 .iter()
266 .zip(&chi_meas)
267 .map(|(&p, &m)| if p <= 0 { ONE } else { fdiv(m, p) })
268 .collect();
269 for i in 0..ng {
270 if denom[i] <= 0 {
271 continue;
272 }
273 let num: i64 = kernels.iter().zip(&ratio).map(|(k, &r)| fmul(k[i], r)).sum();
274 let corr = fdiv(num, denom[i]);
275 est[i] = fmul(est[i], corr).max(0);
276 }
277 }
278
279 let error_fx = {
280 let s: i64 = psd_true
281 .iter()
282 .zip(&est)
283 .map(|(&a, &b)| (a - b).abs())
284 .sum();
285 s / ng.max(1) as i64
286 };
287
288 SpectroResult {
289 omega: g.omega.clone(),
290 psd_true: psd_true.to_vec(),
291 psd_est: est,
292 n_sequences: n_max,
293 error_fx,
294 }
295}
296
297impl SpectroResult {
298 pub fn hash(&self) -> [u8; 32] {
299 let mut h = blake3::Hasher::new();
300 h.update(b"wai:qc-spectro\x01");
301 for &v in &self.psd_est {
302 h.update(&v.to_le_bytes());
303 }
304 *h.finalize().as_bytes()
305 }
306 pub fn artifacts(&self) -> CalArtifacts {
307 let mut cfg = Vec::new();
308 for &v in &self.psd_est {
309 cfg.extend_from_slice(&v.to_le_bytes());
310 }
311 let mut ev = Vec::new();
312 for &v in &self.psd_true {
313 ev.extend_from_slice(&v.to_le_bytes());
314 }
315 CalArtifacts {
316 target: "noise-psd:q0".into(),
317 config_bytes: cfg,
318 evidence_kind: "dd_noise_spectroscopy".into(),
319 evidence_bytes: ev,
320 summary: format!("PSD reconstructed from {} CPMG filters", self.n_sequences),
321 }
322 }
323 pub fn seal(&self, signer: &SigningKey, signer_id: &str, joules_micro: u64, grant: GrantRef) -> CalibrationReceipt {
324 seal_artifacts(signer, signer_id, "sim:transmon:q0", &self.artifacts(), joules_micro, grant, None)
325 }
326}
327
328#[derive(Clone, Debug, PartialEq, Eq)]
334pub struct RobustResult {
335 pub pulses: Vec<i64>,
337 pub chi_opt: i64,
339 pub chi_cpmg: i64,
341 pub coh_opt: i64,
343 pub coh_cpmg: i64,
344 pub psd_hash: [u8; 32],
346 pub kern_opt: Vec<i64>,
348 pub kern_cpmg: Vec<i64>,
349}
350
351pub fn optimize_dd(g: &NoiseGrid, psd: &[i64], n: usize, rounds: u32) -> RobustResult {
355 let cpmg = dd_cpmg(n);
356 let kern_cpmg = filter_kernel(&cpmg, g);
357 let chi_cpmg = overlap(psd, &kern_cpmg);
358
359 let mut pos = cpmg.clone();
360 let chi_of = |p: &[i64]| overlap(psd, &filter_kernel(p, g));
361 let mut best = chi_of(&pos);
362 let mut step = ONE / 8;
363 for _ in 0..rounds {
364 for i in 0..n {
365 let lo = if i == 0 { ONE / 200 } else { pos[i - 1] + ONE / 200 };
366 let hi = if i == n - 1 { ONE - ONE / 200 } else { pos[i + 1] - ONE / 200 };
367 for &dir in &[-1i64, 1] {
368 let cand = (pos[i] + dir * step).clamp(lo, hi);
369 if cand == pos[i] {
370 continue;
371 }
372 let save = pos[i];
373 pos[i] = cand;
374 let c = chi_of(&pos);
375 if c < best {
376 best = c;
377 } else {
378 pos[i] = save;
379 }
380 }
381 }
382 step = (step * 3) / 5; if step < ONE / 2000 {
384 break;
385 }
386 }
387
388 let kern_opt = filter_kernel(&pos, g);
389 let chi_opt = overlap(psd, &kern_opt);
390 RobustResult {
391 pulses: pos,
392 chi_opt,
393 chi_cpmg,
394 coh_opt: coherence(chi_opt),
395 coh_cpmg: coherence(chi_cpmg),
396 psd_hash: hash_psd(psd),
397 kern_opt,
398 kern_cpmg,
399 }
400}
401
402impl RobustResult {
403 pub fn improvement_fx(&self) -> i64 {
405 fdiv(self.chi_cpmg, self.chi_opt.max(1))
406 }
407 pub fn hash(&self) -> [u8; 32] {
408 let mut h = blake3::Hasher::new();
409 h.update(b"wai:qc-robust-ff\x01");
410 for &p in &self.pulses {
411 h.update(&p.to_le_bytes());
412 }
413 h.update(&self.chi_opt.to_le_bytes());
414 *h.finalize().as_bytes()
415 }
416 pub fn artifacts(&self) -> CalArtifacts {
417 let mut cfg = Vec::new();
418 for &p in &self.pulses {
419 cfg.extend_from_slice(&p.to_le_bytes());
420 }
421 let mut ev = Vec::new();
423 ev.extend_from_slice(&self.psd_hash);
424 ev.extend_from_slice(&self.chi_opt.to_le_bytes());
425 CalArtifacts {
426 target: "robust-dd:q0".into(),
427 config_bytes: cfg,
428 evidence_kind: "filter_function_robust_control".into(),
429 evidence_bytes: ev,
430 summary: format!(
431 "{}-pulse DD, χ {}→{} vs CPMG (filter dodges the pinned PSD)",
432 self.pulses.len(),
433 self.chi_cpmg,
434 self.chi_opt
435 ),
436 }
437 }
438 pub fn seal(&self, signer: &SigningKey, signer_id: &str, joules_micro: u64, grant: GrantRef) -> CalibrationReceipt {
439 seal_artifacts(signer, signer_id, "sim:transmon:q0", &self.artifacts(), joules_micro, grant, None)
440 }
441}
442
443#[cfg(test)]
444mod tests {
445 use super::*;
446
447 fn key(s: u8) -> SigningKey {
448 SigningKey::from_bytes(&[s; 32])
449 }
450 fn grid() -> NoiseGrid {
451 NoiseGrid::linear(0.5, 90.0, 180)
452 }
453 fn f(v: i64) -> f64 {
454 v as f64 / ONE as f64
455 }
456
457 #[test]
458 fn ln_and_coherence_roundtrip() {
459 for &chi in &[ONE / 10, ONE / 2, ONE, 2 * ONE] {
461 let c = coherence(chi);
462 let back = -ln_fx(c);
463 assert!((back - chi).abs() < ONE / 20, "χ {} → C {} → {}", f(chi), f(c), f(back));
464 }
465 }
466
467 #[test]
468 fn more_pulses_suppress_low_freq_noise() {
469 let g = grid();
472 let psd = psd_model(&g, 0.02, 0.0, 0.0, 1.0);
473 let chi_free = overlap(&psd, &filter_kernel(&dd_free(), &g));
474 let chi_hahn = overlap(&psd, &filter_kernel(&dd_hahn(), &g));
475 let chi_cpmg8 = overlap(&psd, &filter_kernel(&dd_cpmg(8), &g));
476 assert!(chi_hahn < chi_free, "echo beats free: {} vs {}", chi_hahn, chi_free);
477 assert!(chi_cpmg8 < chi_hahn, "CPMG-8 beats echo: {} vs {}", chi_cpmg8, chi_hahn);
478 }
479
480 #[test]
481 fn spectroscopy_recovers_hidden_bump() {
482 let g = grid();
485 let psd = psd_model(&g, 0.015, 0.5, 40.0, 6.0);
486 let r = reconstruct_psd(&g, &psd, 20, 40_000, 40, 0xC0FFEE);
487 let mean_psd: i64 = psd.iter().sum::<i64>() / psd.len() as i64;
489 assert!(
490 r.error_fx < mean_psd,
491 "reconstruction error {} should be below mean PSD {}",
492 r.error_fx, mean_psd
493 );
494 assert!(r.psd_est.iter().all(|&v| v >= 0));
496 }
497
498 #[test]
499 fn spectroscopy_is_deterministic() {
500 let g = grid();
501 let psd = psd_model(&g, 0.02, 0.3, 30.0, 5.0);
502 let a = reconstruct_psd(&g, &psd, 16, 20_000, 30, 7);
503 let b = reconstruct_psd(&g, &psd, 16, 20_000, 30, 7);
504 assert_eq!(a, b);
505 }
506
507 #[test]
508 fn robust_control_beats_cpmg() {
509 let g = grid();
512 let psd = psd_model(&g, 0.04, 0.0, 0.0, 1.0);
513 let r = optimize_dd(&g, &psd, 6, 30);
514 assert!(r.chi_opt <= r.chi_cpmg, "optimised {} must not exceed CPMG {}", r.chi_opt, r.chi_cpmg);
515 assert!(r.coh_opt >= r.coh_cpmg);
516 }
517
518 #[test]
519 fn results_seal_and_verify() {
520 let g = grid();
521 let psd = psd_model(&g, 0.02, 0.4, 35.0, 5.0);
522 let spec = reconstruct_psd(&g, &psd, 16, 20_000, 30, 1);
523 let sr = spec.seal(&key(1), "did:key:lab", 1_000_000, GrantRef::unbounded("quantum.calibrate"));
524 assert!(sr.verify());
525
526 let rob = optimize_dd(&g, &psd, 6, 25);
527 let rr = rob.seal(&key(2), "did:key:lab", 1_000_000, GrantRef::unbounded("quantum.calibrate"));
528 assert!(rr.verify());
529 assert!(rob.artifacts().evidence_bytes.starts_with(&hash_psd(&psd)));
531 }
532}
533