1pub const CAL_FRAC: u32 = 20;
24pub const CAL_ONE: i64 = 1 << CAL_FRAC;
26const PI_FX: i64 = 3_294_199; #[inline]
30fn fmul(a: i64, b: i64) -> i64 {
31 ((a as i128 * b as i128) >> CAL_FRAC) as i64
32}
33
34pub fn sin2_fx(theta: i64) -> i64 {
39 let pi = PI_FX as i128;
40 let t = (theta as i128).rem_euclid(pi); let p = t * (pi - t); let num = 16 * p;
43 let den = 5 * pi * pi - 4 * p;
44 let s = ((num << CAL_FRAC) / den) as i64; fmul(s, s) }
47
48fn splitmix64(state: &mut u64) -> u64 {
53 *state = state.wrapping_add(0x9E37_79B9_7F4A_7C15);
54 let mut z = *state;
55 z = (z ^ (z >> 30)).wrapping_mul(0xBF58_476D_1CE4_E5B9);
56 z = (z ^ (z >> 27)).wrapping_mul(0x94D0_49BB_1331_11EB);
57 z ^ (z >> 31)
58}
59
60#[derive(Clone, Copy, Debug)]
63pub struct Device {
64 pub a_pi_fx: i64,
66 pub seed: u64,
69}
70
71impl Device {
72 pub fn excited_prob(&self, a_fx: i64) -> i64 {
75 let theta = ((PI_FX as i128 * a_fx as i128) / (2 * self.a_pi_fx as i128)) as i64;
77 sin2_fx(theta)
78 }
79
80 pub fn measure(&self, a_fx: i64, shots: u32) -> i64 {
84 let p = self.excited_prob(a_fx);
85 let mut st = self
86 .seed
87 .wrapping_mul(0x1000_0001)
88 .wrapping_add(a_fx as u64);
89 let mut hits: u64 = 0;
90 for _ in 0..shots {
91 let r = (splitmix64(&mut st) >> (64 - CAL_FRAC)) as i64; if r < p {
93 hits += 1;
94 }
95 }
96 ((hits as i128 * CAL_ONE as i128) / shots.max(1) as i128) as i64
97 }
98}
99
100#[derive(Clone, Copy, Debug)]
106pub struct TuneConfig {
107 pub a_max_fx: i64,
110 pub n_coarse: u32,
112 pub n_fine: u32,
114 pub shots: u32,
116}
117
118impl Default for TuneConfig {
119 fn default() -> Self {
120 TuneConfig { a_max_fx: 2 * CAL_ONE, n_coarse: 41, n_fine: 41, shots: 2000 }
121 }
122}
123
124#[derive(Clone, Debug, PartialEq, Eq)]
126pub struct TuneResult {
127 pub a_pi_est_fx: i64,
129 pub peak_prob_fx: i64,
132 pub n_measurements: u32,
134 pub sweep: Vec<(i64, i64)>,
136}
137
138impl TuneResult {
139 pub fn hash(&self) -> [u8; 32] {
142 let mut h = blake3::Hasher::new();
143 h.update(b"wai:quantum-cal-rabi\x01");
144 h.update(&self.a_pi_est_fx.to_le_bytes());
145 h.update(&self.peak_prob_fx.to_le_bytes());
146 h.update(&(self.n_measurements as u64).to_le_bytes());
147 for (a, p) in &self.sweep {
148 h.update(&a.to_le_bytes());
149 h.update(&p.to_le_bytes());
150 }
151 *h.finalize().as_bytes()
152 }
153
154 pub fn artifacts(&self) -> CalArtifacts {
157 let mut ev = Vec::with_capacity(self.sweep.len() * 16 + 16);
158 ev.extend_from_slice(&self.a_pi_est_fx.to_le_bytes());
159 ev.extend_from_slice(&self.peak_prob_fx.to_le_bytes());
160 for (a, p) in &self.sweep {
161 ev.extend_from_slice(&a.to_le_bytes());
162 ev.extend_from_slice(&p.to_le_bytes());
163 }
164 CalArtifacts {
165 target: "1q_gate_amplitude".into(),
166 config_bytes: self.a_pi_est_fx.to_le_bytes().to_vec(),
167 evidence_kind: "rabi_amplitude_sweep".into(),
168 evidence_bytes: ev,
169 summary: format!("pi_amp={} peak_prob={} (2^{CAL_FRAC})", self.a_pi_est_fx, self.peak_prob_fx),
170 }
171 }
172}
173
174pub fn calibrate_rabi(device: &Device, cfg: &TuneConfig) -> TuneResult {
181 let n = cfg.n_coarse.max(4);
182 let mut sweep = Vec::with_capacity(n as usize);
183 for i in 0..n {
184 let a = ((cfg.a_max_fx as i128 * i as i128) / (n - 1) as i128) as i64;
185 sweep.push((a, device.measure(a, cfg.shots)));
186 }
187
188 let fit = |lo: i64, hi: i64, steps: u32| -> i64 {
190 let steps = steps.max(2);
191 let mut best = lo.max(1);
192 let mut best_err = i128::MAX;
193 for g in 1..=steps {
194 let a_pi = lo + ((hi - lo) as i128 * g as i128 / steps as i128) as i64;
195 if a_pi <= 0 {
196 continue;
197 }
198 let mut err = 0i128;
199 for &(a, p) in &sweep {
200 let theta = ((PI_FX as i128 * a as i128) / (2 * a_pi as i128)) as i64;
201 err += (p - sin2_fx(theta)).unsigned_abs() as i128;
202 }
203 if err < best_err {
204 best_err = err;
205 best = a_pi;
206 }
207 }
208 best
209 };
210 let coarse_step = cfg.a_max_fx / (n as i64 - 1);
211 let a_coarse = fit(coarse_step, cfg.a_max_fx, cfg.n_coarse.max(24));
212 let a_pi = fit((a_coarse - coarse_step).max(1), a_coarse + coarse_step, cfg.n_fine.max(24));
213
214 let peak = device.measure(a_pi, cfg.shots);
216 TuneResult { a_pi_est_fx: a_pi, peak_prob_fx: peak, n_measurements: n + 1, sweep }
217}
218
219#[cfg(feature = "quantum_ops")]
224mod sealed {
225 use super::*;
226 use crate::quantum_ops::{content_hash, CalibrationReceipt, Evidence, GrantRef};
227 use ed25519_dalek::SigningKey;
228
229 pub fn sweep_bytes(r: &TuneResult) -> Vec<u8> {
232 let mut o = Vec::with_capacity(r.sweep.len() * 16 + 16);
233 o.extend_from_slice(&r.a_pi_est_fx.to_le_bytes());
234 o.extend_from_slice(&r.peak_prob_fx.to_le_bytes());
235 for (a, p) in &r.sweep {
236 o.extend_from_slice(&a.to_le_bytes());
237 o.extend_from_slice(&p.to_le_bytes());
238 }
239 o
240 }
241
242 #[allow(clippy::too_many_arguments)]
248 pub fn calibrate_and_seal(
249 signer: &SigningKey,
250 signer_id: impl Into<String>,
251 device_id: impl Into<String>,
252 target: impl Into<String>,
253 device: &Device,
254 cfg: &TuneConfig,
255 joules_micro: u64,
256 grant: GrantRef,
257 parent: Option<[u8; 32]>,
258 ) -> (TuneResult, CalibrationReceipt) {
259 let r = calibrate_rabi(device, cfg);
260 let config_hash = content_hash(&r.a_pi_est_fx.to_le_bytes());
262 let ev = vec![Evidence {
264 kind: "rabi_amplitude_sweep".into(),
265 blob_hash: content_hash(&sweep_bytes(&r)),
266 summary: format!(
267 "pi_amp={} peak_prob={} (fixed-point 2^{})",
268 r.a_pi_est_fx, r.peak_prob_fx, CAL_FRAC
269 ),
270 }];
271 let receipt = CalibrationReceipt::seal(
272 signer, signer_id, device_id, target, config_hash, ev, joules_micro, grant,
273 parent,
274 );
275 (r, receipt)
276 }
277}
278
279#[cfg(feature = "quantum_ops")]
280pub use sealed::{calibrate_and_seal, sweep_bytes};
281
282const TWO_PI_FX: i64 = 6_588_397; const HALF_PI_FX: i64 = 1_647_099; const LN2_FX: i64 = 726_817; pub fn sin_fx(theta: i64) -> i64 {
292 let two_pi = TWO_PI_FX as i128;
293 let mut t = (theta as i128).rem_euclid(two_pi); let pi = PI_FX as i128;
295 let sign = if t >= pi {
296 t -= pi;
297 -1i64
298 } else {
299 1
300 };
301 let p = t * (pi - t);
302 let num = 16 * p;
303 let den = 5 * pi * pi - 4 * p;
304 let s = ((num << CAL_FRAC) / den) as i64;
305 sign * s
306}
307
308pub fn cos_fx(theta: i64) -> i64 {
310 sin_fx(theta + HALF_PI_FX)
311}
312
313pub fn exp_neg_fx(x_fx: i64) -> i64 {
316 if x_fx <= 0 {
317 return CAL_ONE;
318 }
319 let k = x_fx / LN2_FX;
320 let r = x_fx - k * LN2_FX; let r2 = fmul(r, r);
322 let r3 = fmul(r2, r);
323 let er = CAL_ONE - r + r2 / 2 - r3 / 6; if k >= 62 {
325 return 0;
326 }
327 (er >> k).max(0)
328}
329
330fn ratio_fx(a: i64, b: i64) -> i64 {
331 if b == 0 {
332 return 0;
333 }
334 (((a as i128) << CAL_FRAC) / b as i128) as i64
335}
336
337#[derive(Clone, Debug, PartialEq, Eq)]
340pub struct CalArtifacts {
341 pub target: String,
342 pub config_bytes: Vec<u8>,
343 pub evidence_kind: String,
344 pub evidence_bytes: Vec<u8>,
345 pub summary: String,
346}
347
348#[derive(Clone, Copy, Debug)]
355pub struct RamseyDevice {
356 pub omega_fx: i64,
358 pub t2_fx: i64,
360 pub seed: u64,
361}
362
363impl RamseyDevice {
364 pub fn prob(&self, tau_fx: i64) -> i64 {
366 let c = cos_fx(fmul(self.omega_fx, tau_fx));
367 let env = exp_neg_fx(ratio_fx(tau_fx, self.t2_fx));
368 (CAL_ONE + fmul(c, env)) / 2
369 }
370 pub fn measure(&self, tau_fx: i64, shots: u32) -> i64 {
371 let p = self.prob(tau_fx);
372 let mut st = self.seed.wrapping_mul(0x2545_F491).wrapping_add(tau_fx as u64);
373 let mut hits = 0u64;
374 for _ in 0..shots {
375 let r = (splitmix64(&mut st) >> (64 - CAL_FRAC)) as i64;
376 if r < p {
377 hits += 1;
378 }
379 }
380 ((hits as i128 * CAL_ONE as i128) / shots.max(1) as i128) as i64
381 }
382}
383
384#[derive(Clone, Debug, PartialEq, Eq)]
387pub struct RamseyResult {
388 pub omega_est_fx: i64,
389 pub t2_est_fx: i64,
390 pub sweep: Vec<(i64, i64)>,
391 pub n_measurements: u32,
392}
393
394impl RamseyResult {
395 pub fn hash(&self) -> [u8; 32] {
396 let mut h = blake3::Hasher::new();
397 h.update(b"wai:quantum-cal-ramsey\x01");
398 h.update(&self.omega_est_fx.to_le_bytes());
399 h.update(&self.t2_est_fx.to_le_bytes());
400 for (a, b) in &self.sweep {
401 h.update(&a.to_le_bytes());
402 h.update(&b.to_le_bytes());
403 }
404 *h.finalize().as_bytes()
405 }
406 pub fn artifacts(&self) -> CalArtifacts {
407 let mut cfg = Vec::new();
408 cfg.extend_from_slice(&self.omega_est_fx.to_le_bytes());
409 cfg.extend_from_slice(&self.t2_est_fx.to_le_bytes());
410 let mut ev = Vec::new();
411 for (a, b) in &self.sweep {
412 ev.extend_from_slice(&a.to_le_bytes());
413 ev.extend_from_slice(&b.to_le_bytes());
414 }
415 CalArtifacts {
416 target: "dephasing".into(),
417 config_bytes: cfg,
418 evidence_kind: "ramsey_fringe".into(),
419 evidence_bytes: ev,
420 summary: format!("omega={} t2={} (2^{CAL_FRAC})", self.omega_est_fx, self.t2_est_fx),
421 }
422 }
423}
424
425#[derive(Clone, Copy, Debug)]
427pub struct RamseyConfig {
428 pub tau_max_fx: i64,
429 pub n_points: u32,
430 pub shots: u32,
431 pub omega_max_fx: i64,
432 pub t2_max_fx: i64,
433 pub n_grid: u32,
434}
435
436pub fn calibrate_ramsey(dev: &RamseyDevice, cfg: &RamseyConfig) -> RamseyResult {
437 let n = cfg.n_points.max(4);
438 let mut sweep = Vec::with_capacity(n as usize);
439 for i in 0..n {
440 let tau = ((cfg.tau_max_fx as i128 * i as i128) / (n - 1) as i128) as i64;
441 sweep.push((tau, dev.measure(tau, cfg.shots)));
442 }
443 let ng = cfg.n_grid.max(4);
445 let mut best_omega = 0i64;
446 let mut best_score = -1i128;
447 for g in 1..ng {
448 let omega = ((cfg.omega_max_fx as i128 * g as i128) / ng as i128) as i64;
449 let mut acc = 0i128;
450 for &(tau, p) in &sweep {
451 acc += ((p - CAL_ONE / 2) as i128 * cos_fx(fmul(omega, tau)) as i128) >> CAL_FRAC;
452 }
453 let s = acc.abs();
454 if s > best_score {
455 best_score = s;
456 best_omega = omega;
457 }
458 }
459 let mut best_t2 = cfg.t2_max_fx;
461 let mut best_err = i128::MAX;
462 for g in 1..=ng {
463 let t2 = ((cfg.t2_max_fx as i128 * g as i128) / ng as i128) as i64;
464 let probe = RamseyDevice { omega_fx: best_omega, t2_fx: t2, seed: 0 };
465 let mut err = 0i128;
466 for &(tau, p) in &sweep {
467 err += (p - probe.prob(tau)).unsigned_abs() as i128;
468 }
469 if err < best_err {
470 best_err = err;
471 best_t2 = t2;
472 }
473 }
474 RamseyResult { omega_est_fx: best_omega, t2_est_fx: best_t2, sweep, n_measurements: n }
475}
476
477#[derive(Clone, Copy, Debug)]
483pub struct RbDevice {
484 pub epsilon_fx: i64,
485 pub seed: u64,
486}
487
488impl RbDevice {
489 pub fn survival(&self, m: u32) -> i64 {
492 let p = CAL_ONE - 2 * self.epsilon_fx;
493 let mut pm = CAL_ONE;
494 for _ in 0..m {
495 pm = fmul(pm, p);
496 }
497 CAL_ONE / 2 + fmul(CAL_ONE / 2, pm)
498 }
499 pub fn measure(&self, m: u32, k: u32, shots: u32) -> i64 {
501 let s = self.survival(m);
502 let mut st = self.seed.wrapping_mul(0x27D4_EB2F).wrapping_add(m as u64);
503 let mut hits = 0u64;
504 let total = (k.max(1) as u64) * shots.max(1) as u64;
505 for _ in 0..total {
506 let r = (splitmix64(&mut st) >> (64 - CAL_FRAC)) as i64;
507 if r < s {
508 hits += 1;
509 }
510 }
511 ((hits as i128 * CAL_ONE as i128) / total as i128) as i64
512 }
513}
514
515#[derive(Clone, Debug, PartialEq, Eq)]
516pub struct RbResult {
517 pub p_est_fx: i64,
519 pub fidelity_fx: i64,
521 pub curve: Vec<(u32, i64)>,
522}
523
524impl RbResult {
525 pub fn hash(&self) -> [u8; 32] {
526 let mut h = blake3::Hasher::new();
527 h.update(b"wai:quantum-cal-rb\x01");
528 h.update(&self.p_est_fx.to_le_bytes());
529 h.update(&self.fidelity_fx.to_le_bytes());
530 for (m, s) in &self.curve {
531 h.update(&m.to_le_bytes());
532 h.update(&s.to_le_bytes());
533 }
534 *h.finalize().as_bytes()
535 }
536 pub fn artifacts(&self) -> CalArtifacts {
537 let mut ev = Vec::new();
538 for (m, s) in &self.curve {
539 ev.extend_from_slice(&m.to_le_bytes());
540 ev.extend_from_slice(&s.to_le_bytes());
541 }
542 CalArtifacts {
543 target: "1q_gate".into(),
544 config_bytes: self.p_est_fx.to_le_bytes().to_vec(),
545 evidence_kind: "randomized_benchmarking".into(),
546 evidence_bytes: ev,
547 summary: format!("p={} fidelity={} (2^{CAL_FRAC})", self.p_est_fx, self.fidelity_fx),
548 }
549 }
550}
551
552#[derive(Clone, Copy, Debug)]
553pub struct RbConfig {
554 pub lengths: [u32; 8],
556 pub k_sequences: u32,
557 pub shots: u32,
558 pub n_grid: u32,
559}
560
561pub fn calibrate_rb(dev: &RbDevice, cfg: &RbConfig) -> RbResult {
562 let curve: Vec<(u32, i64)> =
563 cfg.lengths.iter().map(|&m| (m, dev.measure(m, cfg.k_sequences, cfg.shots))).collect();
564 let ng = cfg.n_grid.max(8);
566 let mut best_p = CAL_ONE;
567 let mut best_err = i128::MAX;
568 for g in 1..ng {
569 let p = ((CAL_ONE as i128 * g as i128) / ng as i128) as i64;
570 let mut err = 0i128;
571 for &(m, s) in &curve {
572 let mut pm = CAL_ONE;
573 for _ in 0..m {
574 pm = fmul(pm, p);
575 }
576 let pred = CAL_ONE / 2 + fmul(CAL_ONE / 2, pm);
577 err += (s - pred).unsigned_abs() as i128;
578 }
579 if err < best_err {
580 best_err = err;
581 best_p = p;
582 }
583 }
584 let fidelity = CAL_ONE - (CAL_ONE - best_p) / 2;
585 RbResult { p_est_fx: best_p, fidelity_fx: fidelity, curve }
586}
587
588#[derive(Clone, Copy, Debug)]
595pub struct ReadoutDevice {
596 pub s0_fx: i64,
597 pub s1_fx: i64,
598 pub sigma_fx: i64,
599 pub seed: u64,
600}
601
602impl ReadoutDevice {
603 fn gaussian(mean: i64, sigma: i64, st: &mut u64) -> i64 {
604 let mut acc = 0i64;
606 for _ in 0..12 {
607 acc += (splitmix64(st) >> (64 - CAL_FRAC)) as i64;
608 }
609 let z = acc - 6 * CAL_ONE;
610 mean + fmul(z, sigma)
611 }
612 pub fn dataset(&self, n: u32) -> (Vec<i64>, Vec<i64>) {
614 let mut st0 = self.seed ^ 0xA5A5;
615 let mut st1 = self.seed ^ 0x5A5A;
616 let zeros = (0..n).map(|_| Self::gaussian(self.s0_fx, self.sigma_fx, &mut st0)).collect();
617 let ones = (0..n).map(|_| Self::gaussian(self.s1_fx, self.sigma_fx, &mut st1)).collect();
618 (zeros, ones)
619 }
620}
621
622#[derive(Clone, Debug, PartialEq, Eq)]
623pub struct ReadoutResult {
624 pub threshold_fx: i64,
625 pub mean0_fx: i64,
626 pub mean1_fx: i64,
627 pub fidelity_fx: i64,
629 pub n_shots: u32,
630}
631
632impl ReadoutResult {
633 pub fn hash(&self) -> [u8; 32] {
634 let mut h = blake3::Hasher::new();
635 h.update(b"wai:quantum-cal-readout\x01");
636 for v in [self.threshold_fx, self.mean0_fx, self.mean1_fx, self.fidelity_fx] {
637 h.update(&v.to_le_bytes());
638 }
639 h.update(&self.n_shots.to_le_bytes());
640 *h.finalize().as_bytes()
641 }
642 pub fn artifacts(&self) -> CalArtifacts {
643 let mut cfg = Vec::new();
644 cfg.extend_from_slice(&self.threshold_fx.to_le_bytes());
645 CalArtifacts {
646 target: "readout".into(),
647 config_bytes: cfg,
648 evidence_kind: "readout_gmm".into(),
649 evidence_bytes: {
650 let mut e = Vec::new();
651 for v in [self.mean0_fx, self.mean1_fx, self.fidelity_fx] {
652 e.extend_from_slice(&v.to_le_bytes());
653 }
654 e.extend_from_slice(&self.n_shots.to_le_bytes());
655 e
656 },
657 summary: format!("threshold={} fidelity={} (2^{CAL_FRAC})", self.threshold_fx, self.fidelity_fx),
658 }
659 }
660}
661
662pub fn calibrate_readout(dev: &ReadoutDevice, n_per_class: u32) -> ReadoutResult {
663 let (zeros, ones) = dev.dataset(n_per_class);
664 let mean = |v: &[i64]| (v.iter().map(|&x| x as i128).sum::<i128>() / v.len().max(1) as i128) as i64;
665 let m0 = mean(&zeros);
666 let m1 = mean(&ones);
667 let threshold = (m0 + m1) / 2;
668 let high1 = m1 >= m0;
670 let mis0 = zeros.iter().filter(|&&x| (x >= threshold) == high1).count();
671 let mis1 = ones.iter().filter(|&&x| (x >= threshold) != high1).count();
672 let n = n_per_class.max(1) as i128;
673 let err = ((mis0 as i128 * CAL_ONE as i128 / n) + (mis1 as i128 * CAL_ONE as i128 / n)) / 2;
674 ReadoutResult {
675 threshold_fx: threshold,
676 mean0_fx: m0,
677 mean1_fx: m1,
678 fidelity_fx: CAL_ONE - err as i64,
679 n_shots: n_per_class,
680 }
681}
682
683#[derive(Clone, Copy, Debug)]
697pub struct ChargeDevice {
698 pub alpha_l_fx: i64,
699 pub alpha_r_fx: i64,
700 pub beta_lr_fx: i64,
701 pub beta_rl_fx: i64,
702 pub off_l_fx: i64,
703 pub off_r_fx: i64,
704}
705
706impl ChargeDevice {
707 pub fn charge_state(&self, v_l: i64, v_r: i64) -> (i32, i32) {
711 let e_l = fmul(self.alpha_l_fx, v_l) + fmul(self.beta_lr_fx, v_r) + self.off_l_fx;
712 let e_r = fmul(self.alpha_r_fx, v_r) + fmul(self.beta_rl_fx, v_l) + self.off_r_fx;
713 ((e_l >> CAL_FRAC).max(0) as i32, (e_r >> CAL_FRAC).max(0) as i32)
714 }
715}
716
717#[derive(Clone, Copy, Debug)]
719pub struct ChargeScanConfig {
720 pub v_max_fx: i64,
721 pub n_grid: u32,
722}
723impl Default for ChargeScanConfig {
724 fn default() -> Self {
725 ChargeScanConfig { v_max_fx: 8 * CAL_ONE, n_grid: 96 }
726 }
727}
728
729#[derive(Clone, Debug, PartialEq, Eq)]
732pub struct ChargeResult {
733 pub v_l_op_fx: i64,
735 pub v_r_op_fx: i64,
736 pub target: (i32, i32),
737 pub found: bool,
738 pub n_grid: u32,
739 pub v_max_fx: i64,
740 pub signal: Vec<i32>,
742}
743
744impl ChargeResult {
745 pub fn hash(&self) -> [u8; 32] {
746 let mut h = blake3::Hasher::new();
747 h.update(b"wai:quantum-cal-chargestab\x01");
748 h.update(&self.v_l_op_fx.to_le_bytes());
749 h.update(&self.v_r_op_fx.to_le_bytes());
750 h.update(&[self.target.0 as u8, self.target.1 as u8, self.found as u8]);
751 for s in &self.signal {
752 h.update(&s.to_le_bytes());
753 }
754 *h.finalize().as_bytes()
755 }
756 pub fn artifacts(&self) -> CalArtifacts {
757 let mut cfg = Vec::new();
758 cfg.extend_from_slice(&self.v_l_op_fx.to_le_bytes());
759 cfg.extend_from_slice(&self.v_r_op_fx.to_le_bytes());
760 let mut ev = Vec::with_capacity(self.signal.len() * 4);
761 for s in &self.signal {
762 ev.extend_from_slice(&s.to_le_bytes());
763 }
764 CalArtifacts {
765 target: format!("charge_state({},{})", self.target.0, self.target.1),
766 config_bytes: cfg,
767 evidence_kind: "charge_stability_scan".into(),
768 evidence_bytes: ev,
769 summary: format!(
770 "op=({},{}) target=({},{}) found={} (2^{CAL_FRAC})",
771 self.v_l_op_fx, self.v_r_op_fx, self.target.0, self.target.1, self.found
772 ),
773 }
774 }
775}
776
777pub fn tune_charge_state(
783 dev: &ChargeDevice,
784 target: (i32, i32),
785 cfg: &ChargeScanConfig,
786) -> ChargeResult {
787 let n = cfg.n_grid.max(2);
788 let mut signal = Vec::with_capacity((n * n) as usize);
789 let (mut sum_l, mut sum_r, mut count) = (0i128, 0i128, 0i128);
790 for iy in 0..n {
791 let v_r = ((cfg.v_max_fx as i128 * iy as i128) / (n - 1) as i128) as i64;
792 for ix in 0..n {
793 let v_l = ((cfg.v_max_fx as i128 * ix as i128) / (n - 1) as i128) as i64;
794 let (nl, nr) = dev.charge_state(v_l, v_r);
795 signal.push(nl + nr);
796 if (nl, nr) == target {
797 sum_l += v_l as i128;
798 sum_r += v_r as i128;
799 count += 1;
800 }
801 }
802 }
803 let found = count > 0;
804 let (v_l_op_fx, v_r_op_fx) =
805 if found { ((sum_l / count) as i64, (sum_r / count) as i64) } else { (0, 0) };
806 ChargeResult { v_l_op_fx, v_r_op_fx, target, found, n_grid: n, v_max_fx: cfg.v_max_fx, signal }
807}
808
809#[derive(Clone, Copy, Debug)]
819pub struct CrDevice {
820 pub a_pi0_fx: i64,
821 pub a_pi1_fx: i64,
822 pub seed: u64,
823}
824
825impl CrDevice {
826 pub fn measure(&self, a_fx: i64, control: bool, shots: u32) -> i64 {
829 let a_pi = if control { self.a_pi1_fx } else { self.a_pi0_fx };
830 Device { a_pi_fx: a_pi.max(1), seed: self.seed ^ (control as u64) }.measure(a_fx, shots)
831 }
832}
833
834#[derive(Clone, Copy, Debug)]
835pub struct CrConfig {
836 pub a_max_fx: i64,
837 pub n_points: u32,
838 pub shots: u32,
839 pub n_fit: u32,
840}
841impl Default for CrConfig {
842 fn default() -> Self {
843 CrConfig { a_max_fx: 2 * CAL_ONE, n_points: 41, shots: 2000, n_fit: 41 }
844 }
845}
846
847#[derive(Clone, Debug, PartialEq, Eq)]
848pub struct CrResult {
849 pub a_pi0_est_fx: i64,
850 pub a_pi1_est_fx: i64,
851 pub zx_shift_fx: i64,
853 pub sweep0: Vec<(i64, i64)>,
854 pub sweep1: Vec<(i64, i64)>,
855}
856
857impl CrResult {
858 pub fn hash(&self) -> [u8; 32] {
859 let mut h = blake3::Hasher::new();
860 h.update(b"wai:quantum-cal-cr\x01");
861 for v in [self.a_pi0_est_fx, self.a_pi1_est_fx, self.zx_shift_fx] {
862 h.update(&v.to_le_bytes());
863 }
864 for (a, p) in self.sweep0.iter().chain(self.sweep1.iter()) {
865 h.update(&a.to_le_bytes());
866 h.update(&p.to_le_bytes());
867 }
868 *h.finalize().as_bytes()
869 }
870 pub fn artifacts(&self) -> CalArtifacts {
871 let mut cfg = Vec::new();
872 cfg.extend_from_slice(&self.a_pi0_est_fx.to_le_bytes());
873 cfg.extend_from_slice(&self.a_pi1_est_fx.to_le_bytes());
874 let mut ev = Vec::new();
875 for (a, p) in self.sweep0.iter().chain(self.sweep1.iter()) {
876 ev.extend_from_slice(&a.to_le_bytes());
877 ev.extend_from_slice(&p.to_le_bytes());
878 }
879 CalArtifacts {
880 target: "cz(control,target)".into(),
881 config_bytes: cfg,
882 evidence_kind: "cross_resonance_sweep".into(),
883 evidence_bytes: ev,
884 summary: format!(
885 "a_pi0={} a_pi1={} zx_shift={} (2^{CAL_FRAC})",
886 self.a_pi0_est_fx, self.a_pi1_est_fx, self.zx_shift_fx
887 ),
888 }
889 }
890}
891
892fn fit_pi_amplitude(sweep: &[(i64, i64)], a_max: i64, coarse: u32, fine: u32) -> i64 {
895 let fit = |lo: i64, hi: i64, steps: u32| -> i64 {
896 let steps = steps.max(2);
897 let mut best = lo.max(1);
898 let mut best_err = i128::MAX;
899 for g in 1..=steps {
900 let a_pi = lo + ((hi - lo) as i128 * g as i128 / steps as i128) as i64;
901 if a_pi <= 0 {
902 continue;
903 }
904 let mut err = 0i128;
905 for &(a, p) in sweep {
906 let theta = ((PI_FX as i128 * a as i128) / (2 * a_pi as i128)) as i64;
907 err += (p - sin2_fx(theta)).unsigned_abs() as i128;
908 }
909 if err < best_err {
910 best_err = err;
911 best = a_pi;
912 }
913 }
914 best
915 };
916 let a_coarse = fit(a_max / coarse.max(2) as i64, a_max, coarse.max(24));
917 let step = a_max / coarse.max(2) as i64;
918 fit((a_coarse - step).max(1), a_coarse + step, fine.max(24))
919}
920
921pub fn calibrate_cr(dev: &CrDevice, cfg: &CrConfig) -> CrResult {
925 let n = cfg.n_points.max(4);
926 let (mut sweep0, mut sweep1) = (Vec::with_capacity(n as usize), Vec::with_capacity(n as usize));
927 for i in 0..n {
928 let a = ((cfg.a_max_fx as i128 * i as i128) / (n - 1) as i128) as i64;
929 sweep0.push((a, dev.measure(a, false, cfg.shots)));
930 sweep1.push((a, dev.measure(a, true, cfg.shots)));
931 }
932 let a0 = fit_pi_amplitude(&sweep0, cfg.a_max_fx, cfg.n_points, cfg.n_fit);
933 let a1 = fit_pi_amplitude(&sweep1, cfg.a_max_fx, cfg.n_points, cfg.n_fit);
934 CrResult { a_pi0_est_fx: a0, a_pi1_est_fx: a1, zx_shift_fx: (a1 - a0).abs(), sweep0, sweep1 }
935}
936
937#[derive(Clone, Debug)]
946pub struct CrosstalkDevice {
947 pub n: usize,
948 pub matrix_fx: Vec<i64>,
949 pub seed: u64,
950}
951
952impl CrosstalkDevice {
953 pub fn measure(&self, i: usize, j: usize, a_fx: i64, shots: u32) -> i64 {
956 let theta = fmul(self.matrix_fx[i * self.n + j], a_fx);
957 let p = sin2_fx(theta / 2);
958 let mut st = self.seed.wrapping_mul(0x1000_0001).wrapping_add((i * 97 + j) as u64);
959 let mut hits = 0u64;
960 for _ in 0..shots {
961 if ((splitmix64(&mut st) >> (64 - CAL_FRAC)) as i64) < p {
962 hits += 1;
963 }
964 }
965 ((hits as i128 * CAL_ONE as i128) / shots.max(1) as i128) as i64
966 }
967}
968
969#[derive(Clone, Debug, PartialEq, Eq)]
970pub struct CrosstalkResult {
971 pub n: usize,
972 pub matrix_fx: Vec<i64>,
974 pub worst_offdiag_fx: i64,
976}
977
978impl CrosstalkResult {
979 pub fn hash(&self) -> [u8; 32] {
980 let mut h = blake3::Hasher::new();
981 h.update(b"wai:quantum-cal-crosstalk\x01");
982 h.update(&(self.n as u64).to_le_bytes());
983 for v in &self.matrix_fx {
984 h.update(&v.to_le_bytes());
985 }
986 *h.finalize().as_bytes()
987 }
988 pub fn artifacts(&self) -> CalArtifacts {
989 let mut ev = Vec::new();
990 for v in &self.matrix_fx {
991 ev.extend_from_slice(&v.to_le_bytes());
992 }
993 CalArtifacts {
994 target: format!("crosstalk_{}x{}", self.n, self.n),
995 config_bytes: self.worst_offdiag_fx.to_le_bytes().to_vec(),
996 evidence_kind: "crosstalk_matrix".into(),
997 evidence_bytes: ev,
998 summary: format!("n={} worst_offdiag={} (2^{CAL_FRAC})", self.n, self.worst_offdiag_fx),
999 }
1000 }
1001}
1002
1003pub fn characterize_crosstalk(dev: &CrosstalkDevice, probe_a_fx: i64, shots: u32) -> CrosstalkResult {
1007 let n = dev.n;
1008 let mut matrix = vec![0i64; n * n];
1009 let sweeps = 12u32;
1011 for i in 0..n {
1012 for j in 0..n {
1013 let mut sweep = Vec::with_capacity(sweeps as usize);
1014 for s in 1..=sweeps {
1015 let a = (probe_a_fx as i128 * s as i128 / sweeps as i128) as i64;
1016 sweep.push((a, dev.measure(i, j, a, shots)));
1017 }
1018 let mut best = 0i64;
1020 let mut best_err = i128::MAX;
1021 let c_max = 2 * CAL_ONE;
1022 for g in 0..=200 {
1023 let c = (c_max as i128 * g as i128 / 200) as i64;
1024 let mut err = 0i128;
1025 for &(a, p) in &sweep {
1026 err += (p - sin2_fx(fmul(c, a) / 2)).unsigned_abs() as i128;
1027 }
1028 if err < best_err {
1029 best_err = err;
1030 best = c;
1031 }
1032 }
1033 matrix[i * n + j] = best;
1034 }
1035 }
1036 let worst = (0..n)
1037 .flat_map(|i| (0..n).filter(move |&j| i != j).map(move |j| (i, j)))
1038 .map(|(i, j)| matrix[i * n + j].abs())
1039 .max()
1040 .unwrap_or(0);
1041 CrosstalkResult { n, matrix_fx: matrix, worst_offdiag_fx: worst }
1042}
1043
1044#[derive(Clone, Copy, Debug)]
1054pub struct DragDevice {
1055 pub beta_opt_fx: i64,
1056 pub curvature_fx: i64,
1057 pub seed: u64,
1058}
1059
1060impl DragDevice {
1061 pub fn measure_leakage(&self, beta_fx: i64, shots: u32) -> i64 {
1064 let d = beta_fx - self.beta_opt_fx;
1065 let l = fmul(self.curvature_fx, fmul(d, d)).clamp(0, CAL_ONE);
1066 let mut st = self.seed.wrapping_mul(0x9E37).wrapping_add(beta_fx as u64);
1067 let mut hits = 0u64;
1068 for _ in 0..shots {
1069 if ((splitmix64(&mut st) >> (64 - CAL_FRAC)) as i64) < l {
1070 hits += 1;
1071 }
1072 }
1073 ((hits as i128 * CAL_ONE as i128) / shots.max(1) as i128) as i64
1074 }
1075}
1076
1077#[derive(Clone, Debug, PartialEq, Eq)]
1078pub struct DragResult {
1079 pub beta_opt_est_fx: i64,
1080 pub residual_leakage_fx: i64,
1082 pub sweep: Vec<(i64, i64)>,
1083}
1084
1085impl DragResult {
1086 pub fn hash(&self) -> [u8; 32] {
1087 let mut h = blake3::Hasher::new();
1088 h.update(b"wai:quantum-cal-drag\x01");
1089 h.update(&self.beta_opt_est_fx.to_le_bytes());
1090 h.update(&self.residual_leakage_fx.to_le_bytes());
1091 for (b, l) in &self.sweep {
1092 h.update(&b.to_le_bytes());
1093 h.update(&l.to_le_bytes());
1094 }
1095 *h.finalize().as_bytes()
1096 }
1097 pub fn artifacts(&self) -> CalArtifacts {
1098 let mut ev = Vec::new();
1099 for (b, l) in &self.sweep {
1100 ev.extend_from_slice(&b.to_le_bytes());
1101 ev.extend_from_slice(&l.to_le_bytes());
1102 }
1103 CalArtifacts {
1104 target: "drag_beta".into(),
1105 config_bytes: self.beta_opt_est_fx.to_le_bytes().to_vec(),
1106 evidence_kind: "drag_leakage_sweep".into(),
1107 evidence_bytes: ev,
1108 summary: format!(
1109 "beta_opt={} residual_leakage={} (2^{CAL_FRAC})",
1110 self.beta_opt_est_fx, self.residual_leakage_fx
1111 ),
1112 }
1113 }
1114}
1115
1116pub fn calibrate_drag(dev: &DragDevice, beta_min_fx: i64, beta_max_fx: i64, n: u32, shots: u32) -> DragResult {
1120 let n = n.max(4);
1121 let mut sweep = Vec::with_capacity(n as usize);
1122 let (mut best_b, mut best_l) = (beta_min_fx, i64::MAX);
1123 for i in 0..n {
1124 let b = beta_min_fx + ((beta_max_fx - beta_min_fx) as i128 * i as i128 / (n - 1) as i128) as i64;
1125 let l = dev.measure_leakage(b, shots);
1126 sweep.push((b, l));
1127 if l < best_l {
1128 best_l = l;
1129 best_b = b;
1130 }
1131 }
1132 let step = (beta_max_fx - beta_min_fx) / (n as i64 - 1);
1134 let refine = |lo: i64, hi: i64| -> (i64, i64) {
1135 let (mut bb, mut bl) = (lo, i64::MAX);
1136 for g in 0..=60 {
1137 let b = lo + ((hi - lo) as i128 * g as i128 / 60) as i64;
1138 let l = dev.measure_leakage(b, shots);
1139 if l < bl {
1140 bl = l;
1141 bb = b;
1142 }
1143 }
1144 (bb, bl)
1145 };
1146 let (beta, res) = refine((best_b - step).max(beta_min_fx), (best_b + step).min(beta_max_fx));
1147 DragResult { beta_opt_est_fx: beta, residual_leakage_fx: res, sweep }
1148}
1149
1150fn bloch_rotate(v: [i64; 3], phi: i64, alpha: i64) -> [i64; 3] {
1162 let (n0, n1) = (cos_fx(phi), sin_fx(phi));
1163 let (c, s) = (cos_fx(alpha), sin_fx(alpha));
1164 let ndotv = fmul(n0, v[0]) + fmul(n1, v[1]); let cross = [fmul(n1, v[2]), -fmul(n0, v[2]), fmul(n0, v[1]) - fmul(n1, v[0])];
1166 let n = [n0, n1, 0];
1167 let omc = CAL_ONE - c;
1168 let mut out = [0i64; 3];
1169 for k in 0..3 {
1170 out[k] = fmul(v[k], c) + fmul(cross[k], s) + fmul(n[k], fmul(ndotv, omc));
1171 }
1172 out
1173}
1174
1175pub fn apply_composite(segments: &[(i64, i64)], eps_fx: i64) -> i64 {
1180 let mut v = [0i64, 0, CAL_ONE];
1181 for &(phi, alpha) in segments {
1182 let a = alpha + fmul(alpha, eps_fx);
1183 v = bloch_rotate(v, phi, a);
1184 }
1185 ((CAL_ONE - v[2]) / 2).clamp(0, CAL_ONE)
1186}
1187
1188#[derive(Clone, Debug, PartialEq, Eq)]
1189pub struct RobustResult {
1190 pub a1_fx: i64,
1192 pub a2_fx: i64,
1193 pub phi_fx: i64,
1194 pub eps_axis_fx: Vec<i64>,
1195 pub naive_infid_fx: Vec<i64>,
1197 pub robust_infid_fx: Vec<i64>,
1199 pub worst_naive_fx: i64,
1200 pub worst_robust_fx: i64,
1201}
1202
1203impl RobustResult {
1204 pub fn hash(&self) -> [u8; 32] {
1205 let mut h = blake3::Hasher::new();
1206 h.update(b"wai:quantum-cal-robust\x01");
1207 for v in [self.a1_fx, self.a2_fx, self.phi_fx, self.worst_naive_fx, self.worst_robust_fx] {
1208 h.update(&v.to_le_bytes());
1209 }
1210 for v in self.naive_infid_fx.iter().chain(self.robust_infid_fx.iter()) {
1211 h.update(&v.to_le_bytes());
1212 }
1213 *h.finalize().as_bytes()
1214 }
1215 pub fn artifacts(&self) -> CalArtifacts {
1216 let mut cfg = Vec::new();
1217 for v in [self.a1_fx, self.a2_fx, self.phi_fx] {
1218 cfg.extend_from_slice(&v.to_le_bytes());
1219 }
1220 let mut ev = Vec::new();
1221 for v in self.naive_infid_fx.iter().chain(self.robust_infid_fx.iter()) {
1222 ev.extend_from_slice(&v.to_le_bytes());
1223 }
1224 CalArtifacts {
1225 target: "x_pi_robust".into(),
1226 config_bytes: cfg,
1227 evidence_kind: "robust_pulse_infidelity".into(),
1228 evidence_bytes: ev,
1229 summary: format!(
1230 "worst_naive={} worst_robust={} (2^{CAL_FRAC})",
1231 self.worst_naive_fx, self.worst_robust_fx
1232 ),
1233 }
1234 }
1235}
1236
1237pub fn optimize_robust_pulse(err_max_fx: i64, n_eps: u32) -> RobustResult {
1242 let n_eps = n_eps.max(3);
1243 let eps_axis: Vec<i64> = (0..n_eps)
1244 .map(|i| -err_max_fx + (2 * err_max_fx as i128 * i as i128 / (n_eps - 1) as i128) as i64)
1245 .collect();
1246 let worst = |segs: &[(i64, i64)]| -> (Vec<i64>, i64) {
1247 let mut curve = Vec::with_capacity(eps_axis.len());
1248 let mut w = 0i64;
1249 for &e in &eps_axis {
1250 let inf = CAL_ONE - apply_composite(segs, e);
1251 w = w.max(inf);
1252 curve.push(inf);
1253 }
1254 (curve, w)
1255 };
1256
1257 let (naive_curve, worst_naive) = worst(&[(0, PI_FX)]);
1258
1259 let (mut best, mut best_w) = ((PI_FX / 2, PI_FX, 0i64), i64::MAX);
1260 let a1_lo = PI_FX / 4;
1261 let quarter = PI_FX / 2;
1262 for i in 0..=20 {
1263 let a1 = a1_lo + ((PI_FX - a1_lo) as i128 * i as i128 / 20) as i64;
1264 for j in 0..=20 {
1265 let a2 = quarter + ((3 * PI_FX / 2 - quarter) as i128 * j as i128 / 20) as i64;
1266 for k in 0..=24 {
1267 let phi = (TWO_PI_FX as i128 * k as i128 / 24) as i64;
1268 let segs = [(0, a1), (phi, a2), (0, a1)];
1269 if (CAL_ONE - apply_composite(&segs, 0)).abs() > CAL_ONE / 100 {
1270 continue; }
1272 let (_, w) = worst(&segs);
1273 if w < best_w {
1274 best_w = w;
1275 best = (a1, a2, phi);
1276 }
1277 }
1278 }
1279 }
1280 let best_segs = [(0, best.0), (best.2, best.1), (0, best.0)];
1281 let (robust_curve, worst_robust) = worst(&best_segs);
1282 RobustResult {
1283 a1_fx: best.0,
1284 a2_fx: best.1,
1285 phi_fx: best.2,
1286 eps_axis_fx: eps_axis,
1287 naive_infid_fx: naive_curve,
1288 robust_infid_fx: robust_curve,
1289 worst_naive_fx: worst_naive,
1290 worst_robust_fx: worst_robust,
1291 }
1292}
1293
1294#[cfg(feature = "quantum_ops")]
1299mod seal_any {
1300 use super::CalArtifacts;
1301 use crate::quantum_ops::{content_hash, CalibrationReceipt, Evidence, GrantRef};
1302 use ed25519_dalek::SigningKey;
1303
1304 #[allow(clippy::too_many_arguments)]
1308 pub fn seal_artifacts(
1309 signer: &SigningKey,
1310 signer_id: impl Into<String>,
1311 device_id: impl Into<String>,
1312 art: &CalArtifacts,
1313 joules_micro: u64,
1314 grant: GrantRef,
1315 parent: Option<[u8; 32]>,
1316 ) -> CalibrationReceipt {
1317 let ev = vec![Evidence {
1318 kind: art.evidence_kind.clone(),
1319 blob_hash: content_hash(&art.evidence_bytes),
1320 summary: art.summary.clone(),
1321 }];
1322 CalibrationReceipt::seal(
1323 signer, signer_id, device_id, art.target.clone(),
1324 content_hash(&art.config_bytes), ev, joules_micro, grant, parent,
1325 )
1326 }
1327}
1328
1329#[cfg(feature = "quantum_ops")]
1330pub use seal_any::seal_artifacts;
1331
1332#[cfg(feature = "quantum_ops")]
1339mod campaign {
1340 use super::*;
1341 use crate::quantum_ops::{CalibrationReceipt, GrantRef};
1342 use ed25519_dalek::SigningKey;
1343
1344 #[allow(clippy::large_enum_variant)]
1347 #[derive(Clone, Debug)]
1348 pub enum CalStep {
1349 Rabi(Device, TuneConfig),
1350 Ramsey(RamseyDevice, RamseyConfig),
1351 Rb(RbDevice, RbConfig),
1352 Readout(ReadoutDevice, u32),
1353 Charge(ChargeDevice, (i32, i32), ChargeScanConfig),
1354 }
1355
1356 impl CalStep {
1357 fn run(&self) -> (CalArtifacts, &'static str) {
1358 match self {
1359 CalStep::Rabi(d, c) => (calibrate_rabi(d, c).artifacts(), "rabi"),
1360 CalStep::Ramsey(d, c) => (calibrate_ramsey(d, c).artifacts(), "ramsey"),
1361 CalStep::Rb(d, c) => (calibrate_rb(d, c).artifacts(), "rb"),
1362 CalStep::Readout(d, n) => (calibrate_readout(d, *n).artifacts(), "readout"),
1363 CalStep::Charge(d, t, c) => (tune_charge_state(d, *t, c).artifacts(), "charge"),
1364 }
1365 }
1366 }
1367
1368 #[derive(Clone, Debug)]
1371 pub struct Campaign {
1372 pub receipts: Vec<CalibrationReceipt>,
1373 pub kinds: Vec<String>,
1374 }
1375
1376 impl Campaign {
1377 pub fn campaign_hash(&self) -> [u8; 32] {
1380 let mut h = blake3::Hasher::new();
1381 h.update(b"wai:quantum-cal-campaign\x01");
1382 for r in &self.receipts {
1383 h.update(&r.receipt_hash());
1384 }
1385 *h.finalize().as_bytes()
1386 }
1387
1388 pub fn verify_chain(&self) -> bool {
1393 let mut prev: Option<[u8; 32]> = None;
1394 for r in &self.receipts {
1395 if !r.verify() || r.parent_receipt_hash != prev {
1396 return false;
1397 }
1398 prev = Some(r.receipt_hash());
1399 }
1400 true
1401 }
1402 }
1403
1404 pub fn run_campaign(
1409 signer: &SigningKey,
1410 signer_id: &str,
1411 device_id: &str,
1412 joules_each: u64,
1413 grant: &GrantRef,
1414 steps: &[CalStep],
1415 ) -> Campaign {
1416 let mut receipts = Vec::with_capacity(steps.len());
1417 let mut kinds = Vec::with_capacity(steps.len());
1418 let mut parent: Option<[u8; 32]> = None;
1419 for step in steps {
1420 let (art, kind) = step.run();
1421 let r = seal_artifacts(signer, signer_id, device_id, &art, joules_each, grant.clone(), parent);
1422 parent = Some(r.receipt_hash());
1423 kinds.push(kind.to_string());
1424 receipts.push(r);
1425 }
1426 Campaign { receipts, kinds }
1427 }
1428}
1429
1430#[cfg(feature = "quantum_ops")]
1431pub use campaign::{run_campaign, CalStep, Campaign};
1432
1433#[cfg(test)]
1434mod tests {
1435 use super::*;
1436
1437 #[test]
1438 fn sine_is_accurate_enough() {
1439 assert_eq!(sin2_fx(0), 0);
1441 let at_half_pi = sin2_fx(PI_FX / 2);
1442 assert!((at_half_pi - CAL_ONE).abs() < CAL_ONE / 200, "sin²(π/2)≈1, got {at_half_pi}");
1443 let at_quarter = sin2_fx(PI_FX / 4);
1444 assert!((at_quarter - CAL_ONE / 2).abs() < CAL_ONE / 100, "sin²(π/4)≈0.5, got {at_quarter}");
1445 }
1446
1447 #[test]
1448 fn tune_up_finds_the_true_pi_amplitude() {
1449 let a_pi_true = (0.80 * CAL_ONE as f64) as i64;
1451 let device = Device { a_pi_fx: a_pi_true, seed: 0xCAFE };
1452 let cfg = TuneConfig { a_max_fx: (1.6 * CAL_ONE as f64) as i64, ..Default::default() };
1453 let r = calibrate_rabi(&device, &cfg);
1454 let tol = cfg.a_max_fx / (cfg.n_coarse as i64 - 1) / (cfg.n_fine as i64 - 1) + CAL_ONE / 50;
1456 assert!(
1457 (r.a_pi_est_fx - a_pi_true).abs() <= tol,
1458 "estimate {} vs true {} (tol {tol})",
1459 r.a_pi_est_fx, a_pi_true
1460 );
1461 assert!(r.peak_prob_fx > CAL_ONE - CAL_ONE / 20, "peak prob {} not ~1", r.peak_prob_fx);
1463 }
1464
1465 #[test]
1466 fn calibration_is_byte_exact_deterministic() {
1467 let device = Device { a_pi_fx: (0.73 * CAL_ONE as f64) as i64, seed: 7 };
1468 let cfg = TuneConfig::default();
1469 let a = calibrate_rabi(&device, &cfg);
1470 let b = calibrate_rabi(&device, &cfg);
1471 assert_eq!(a, b);
1472 assert_eq!(a.hash(), b.hash(), "same (device,cfg) must give the same tune-up hash");
1473 }
1474
1475 #[test]
1476 fn different_devices_tune_differently() {
1477 let d1 = Device { a_pi_fx: (0.5 * CAL_ONE as f64) as i64, seed: 1 };
1478 let d2 = Device { a_pi_fx: (1.1 * CAL_ONE as f64) as i64, seed: 1 };
1479 let cfg = TuneConfig { a_max_fx: 2 * CAL_ONE, ..Default::default() };
1480 let r1 = calibrate_rabi(&d1, &cfg);
1481 let r2 = calibrate_rabi(&d2, &cfg);
1482 assert!(r1.a_pi_est_fx < r2.a_pi_est_fx);
1483 }
1484
1485 #[cfg(feature = "quantum_ops")]
1486 #[test]
1487 fn calibrate_and_seal_produces_a_verifying_receipt() {
1488 use crate::quantum_ops::GrantRef;
1489 use ed25519_dalek::SigningKey;
1490 let device = Device { a_pi_fx: (0.9 * CAL_ONE as f64) as i64, seed: 0xABCD };
1491 let cfg = TuneConfig::default();
1492 let grant = GrantRef {
1493 grant_hash: [0u8; 32],
1494 capability: "quantum.calibrate".into(),
1495 joule_ceiling_micro: 10_000_000,
1496 funds_ceiling: None,
1497 };
1498 let (r, receipt) = calibrate_and_seal(
1499 &SigningKey::from_bytes(&[9u8; 32]), "did:key:lab", "sim:transmon:q0", "q0",
1500 &device, &cfg, 3_500_000, grant, None,
1501 );
1502 assert!(receipt.verify());
1503 assert!(receipt.evidence_matches(0, &sweep_bytes(&r)));
1505 let r2 = calibrate_rabi(&device, &cfg);
1507 assert!(receipt.evidence_matches(0, &sweep_bytes(&r2)));
1508 }
1509
1510 fn fx(x: f64) -> i64 {
1511 (x * CAL_ONE as f64) as i64
1512 }
1513
1514 #[test]
1515 fn ramsey_recovers_detuning_and_t2_deterministically() {
1516 let dev = RamseyDevice { omega_fx: fx(3.0), t2_fx: fx(3.0), seed: 0x1234 };
1517 let cfg = RamseyConfig {
1518 tau_max_fx: fx(6.0), n_points: 80, shots: 4000,
1519 omega_max_fx: fx(6.0), t2_max_fx: fx(6.0), n_grid: 60,
1520 };
1521 let r = calibrate_ramsey(&dev, &cfg);
1522 assert!((r.omega_est_fx - fx(3.0)).abs() < fx(0.4), "omega {} vs 3.0", r.omega_est_fx);
1523 assert!((r.t2_est_fx - fx(3.0)).abs() < fx(0.8), "t2 {} vs 3.0", r.t2_est_fx);
1524 assert_eq!(r, calibrate_ramsey(&dev, &cfg));
1526 assert_eq!(r.hash(), calibrate_ramsey(&dev, &cfg).hash());
1527 }
1528
1529 #[test]
1530 fn rb_recovers_gate_fidelity_deterministically() {
1531 let dev = RbDevice { epsilon_fx: fx(0.01), seed: 0xBEEF };
1533 let cfg = RbConfig {
1534 lengths: [1, 2, 4, 8, 16, 32, 64, 128], k_sequences: 20, shots: 100, n_grid: 300,
1535 };
1536 let r = calibrate_rb(&dev, &cfg);
1537 assert!((r.p_est_fx - fx(0.98)).abs() < fx(0.02), "p {} vs 0.98", r.p_est_fx);
1538 assert!((r.fidelity_fx - fx(0.99)).abs() < fx(0.01), "F {} vs 0.99", r.fidelity_fx);
1539 assert_eq!(r, calibrate_rb(&dev, &cfg));
1540 }
1541
1542 #[test]
1543 fn readout_discriminates_well_separated_blobs_deterministically() {
1544 let dev = ReadoutDevice { s0_fx: fx(-2.0), s1_fx: fx(2.0), sigma_fx: fx(1.0), seed: 42 };
1546 let r = calibrate_readout(&dev, 500);
1547 assert!(r.fidelity_fx > fx(0.9), "readout fidelity {} not > 0.9", r.fidelity_fx);
1548 assert!(r.mean0_fx < r.threshold_fx && r.threshold_fx < r.mean1_fx);
1549 assert_eq!(r, calibrate_readout(&dev, 500));
1550 assert_eq!(r.hash(), calibrate_readout(&dev, 500).hash());
1551 }
1552
1553 #[cfg(feature = "quantum_ops")]
1554 #[test]
1555 fn every_routine_seals_a_verifying_receipt() {
1556 use crate::quantum_ops::GrantRef;
1557 use ed25519_dalek::SigningKey;
1558 let signer = SigningKey::from_bytes(&[5u8; 32]);
1559 let grant = GrantRef::unbounded("quantum.calibrate");
1560
1561 let ram = calibrate_ramsey(
1562 &RamseyDevice { omega_fx: fx(2.0), t2_fx: fx(4.0), seed: 1 },
1563 &RamseyConfig { tau_max_fx: fx(8.0), n_points: 60, shots: 3000, omega_max_fx: fx(6.0), t2_max_fx: fx(8.0), n_grid: 50 },
1564 );
1565 let rb = calibrate_rb(
1566 &RbDevice { epsilon_fx: fx(0.005), seed: 2 },
1567 &RbConfig { lengths: [1, 2, 4, 8, 16, 32, 64, 128], k_sequences: 10, shots: 100, n_grid: 200 },
1568 );
1569 let ro = calibrate_readout(&ReadoutDevice { s0_fx: fx(-1.5), s1_fx: fx(1.5), sigma_fx: fx(1.0), seed: 3 }, 400);
1570
1571 for art in [ram.artifacts(), rb.artifacts(), ro.artifacts()] {
1572 let r = seal_artifacts(&signer, "did:key:lab", "sim:transmon:q0", &art, 1_000_000, grant.clone(), None);
1573 assert!(r.verify(), "receipt for {} must verify", art.evidence_kind);
1574 assert!(r.evidence_matches(0, &art.evidence_bytes));
1575 }
1576 }
1577
1578 fn dot() -> ChargeDevice {
1579 ChargeDevice {
1580 alpha_l_fx: fx(0.4), alpha_r_fx: fx(0.4),
1581 beta_lr_fx: fx(0.1), beta_rl_fx: fx(0.1),
1582 off_l_fx: 0, off_r_fx: 0,
1583 }
1584 }
1585
1586 #[test]
1587 fn charge_tune_is_byte_exact_deterministic() {
1588 let (d, cfg) = (dot(), ChargeScanConfig::default());
1589 let a = tune_charge_state(&d, (1, 1), &cfg);
1590 let b = tune_charge_state(&d, (1, 1), &cfg);
1591 assert_eq!(a, b);
1592 assert_eq!(a.hash(), b.hash());
1593 }
1594
1595 #[test]
1596 fn charge_tune_operating_point_reads_the_target() {
1597 let (d, cfg) = (dot(), ChargeScanConfig::default());
1598 for target in [(1, 1), (2, 1), (1, 2), (2, 2)] {
1599 let r = tune_charge_state(&d, target, &cfg);
1600 assert!(r.found, "target {target:?} not in the scan window");
1601 assert_eq!(
1603 d.charge_state(r.v_l_op_fx, r.v_r_op_fx),
1604 target,
1605 "operating point for {target:?} reads the wrong charge state"
1606 );
1607 }
1608 }
1609
1610 #[test]
1611 fn charge_tune_higher_target_needs_higher_voltage() {
1612 let (d, cfg) = (dot(), ChargeScanConfig::default());
1613 let r1 = tune_charge_state(&d, (1, 1), &cfg);
1614 let r2 = tune_charge_state(&d, (2, 2), &cfg);
1615 assert!(r2.v_l_op_fx > r1.v_l_op_fx && r2.v_r_op_fx > r1.v_r_op_fx);
1616 }
1617
1618 #[cfg(feature = "quantum_ops")]
1619 #[test]
1620 fn charge_tune_seals_a_verifying_receipt() {
1621 use crate::quantum_ops::GrantRef;
1622 use ed25519_dalek::SigningKey;
1623 let r = tune_charge_state(&dot(), (1, 1), &ChargeScanConfig::default());
1624 let art = r.artifacts();
1625 let rec = seal_artifacts(
1626 &SigningKey::from_bytes(&[6u8; 32]), "did:key:lab", "sim:double-dot:d0",
1627 &art, 2_000_000, GrantRef::unbounded("quantum.calibrate"), None,
1628 );
1629 assert!(rec.verify());
1630 assert!(rec.evidence_matches(0, &art.evidence_bytes));
1631 }
1632
1633 #[cfg(feature = "quantum_ops")]
1634 #[test]
1635 fn campaign_chains_receipts_into_a_signed_lineage() {
1636 use crate::quantum_ops::GrantRef;
1637 use ed25519_dalek::SigningKey;
1638 let signer = SigningKey::from_bytes(&[7u8; 32]);
1639 let grant = GrantRef::unbounded("quantum.calibrate");
1640 let steps = vec![
1641 CalStep::Readout(
1642 ReadoutDevice { s0_fx: fx(-1.5), s1_fx: fx(1.5), sigma_fx: fx(1.0), seed: 1 },
1643 400,
1644 ),
1645 CalStep::Rabi(Device { a_pi_fx: fx(0.8), seed: 2 }, TuneConfig::default()),
1646 CalStep::Charge(dot(), (1, 1), ChargeScanConfig::default()),
1647 ];
1648 let camp = run_campaign(&signer, "did:key:lab", "sim:q0", 1_000_000, &grant, &steps);
1649 assert_eq!(camp.receipts.len(), 3);
1650 assert_eq!(camp.kinds, ["readout", "rabi", "charge"]);
1651 assert!(camp.verify_chain(), "the campaign lineage must verify");
1652 let camp2 = run_campaign(&signer, "did:key:lab", "sim:q0", 1_000_000, &grant, &steps);
1654 assert_eq!(camp.campaign_hash(), camp2.campaign_hash());
1655 }
1656
1657 #[cfg(feature = "quantum_ops")]
1658 #[test]
1659 fn campaign_tamper_breaks_the_chain() {
1660 use crate::quantum_ops::GrantRef;
1661 use ed25519_dalek::SigningKey;
1662 let steps = vec![
1663 CalStep::Rabi(Device { a_pi_fx: fx(0.8), seed: 2 }, TuneConfig::default()),
1664 CalStep::Rb(
1665 RbDevice { epsilon_fx: fx(0.005), seed: 3 },
1666 RbConfig { lengths: [1, 2, 4, 8, 16, 32, 64, 128], k_sequences: 8, shots: 80, n_grid: 150 },
1667 ),
1668 ];
1669 let mut camp = run_campaign(
1670 &SigningKey::from_bytes(&[8u8; 32]), "m", "d", 10,
1671 &GrantRef::unbounded("quantum.calibrate"), &steps,
1672 );
1673 camp.receipts[1].parent_receipt_hash = Some([0u8; 32]);
1675 assert!(!camp.verify_chain());
1676 }
1677
1678 #[test]
1679 fn cr_recovers_both_conditional_amplitudes() {
1680 let dev = CrDevice { a_pi0_fx: fx(0.70), a_pi1_fx: fx(0.95), seed: 11 };
1681 let cfg = CrConfig { a_max_fx: fx(1.8), ..Default::default() };
1682 let r = calibrate_cr(&dev, &cfg);
1683 assert!((r.a_pi0_est_fx - fx(0.70)).abs() < CAL_ONE / 20, "a0 {}", r.a_pi0_est_fx);
1684 assert!((r.a_pi1_est_fx - fx(0.95)).abs() < CAL_ONE / 20, "a1 {}", r.a_pi1_est_fx);
1685 assert!(r.zx_shift_fx > 0);
1686 assert_eq!(r, calibrate_cr(&dev, &cfg));
1687 }
1688
1689 #[test]
1690 fn crosstalk_recovers_the_matrix() {
1691 let dev = CrosstalkDevice {
1692 n: 2,
1693 matrix_fx: vec![fx(1.0), fx(0.12), fx(0.15), fx(1.0)],
1694 seed: 5,
1695 };
1696 let r = characterize_crosstalk(&dev, fx(3.0), 4000);
1697 for k in 0..4 {
1698 assert!(
1699 (r.matrix_fx[k] - dev.matrix_fx[k]).abs() < CAL_ONE / 10,
1700 "coeff {k}: got {} want {}",
1701 r.matrix_fx[k], dev.matrix_fx[k]
1702 );
1703 }
1704 assert!(r.worst_offdiag_fx > 0);
1705 assert_eq!(r, characterize_crosstalk(&dev, fx(3.0), 4000));
1706 }
1707
1708 #[test]
1709 fn drag_finds_the_leakage_minimum() {
1710 let dev = DragDevice { beta_opt_fx: fx(0.5), curvature_fx: fx(2.0), seed: 9 };
1711 let r = calibrate_drag(&dev, fx(-1.0), fx(2.0), 41, 3000);
1712 assert!((r.beta_opt_est_fx - fx(0.5)).abs() < CAL_ONE / 12, "beta {}", r.beta_opt_est_fx);
1713 assert!(r.residual_leakage_fx < CAL_ONE / 20, "residual {}", r.residual_leakage_fx);
1714 assert_eq!(r, calibrate_drag(&dev, fx(-1.0), fx(2.0), 41, 3000));
1715 }
1716
1717 #[cfg(feature = "quantum_ops")]
1718 #[test]
1719 fn new_routines_seal_verifying_receipts() {
1720 use crate::quantum_ops::GrantRef;
1721 use ed25519_dalek::SigningKey;
1722 let signer = SigningKey::from_bytes(&[4u8; 32]);
1723 let grant = GrantRef::unbounded("quantum.calibrate");
1724 let cr = calibrate_cr(&CrDevice { a_pi0_fx: fx(0.7), a_pi1_fx: fx(0.95), seed: 1 }, &CrConfig::default());
1725 let xt = characterize_crosstalk(&CrosstalkDevice { n: 2, matrix_fx: vec![fx(1.0), fx(0.12), fx(0.15), fx(1.0)], seed: 2 }, fx(3.0), 2000);
1726 let dg = calibrate_drag(&DragDevice { beta_opt_fx: fx(0.5), curvature_fx: fx(2.0), seed: 3 }, fx(-1.0), fx(2.0), 31, 2000);
1727 for art in [cr.artifacts(), xt.artifacts(), dg.artifacts()] {
1728 let r = seal_artifacts(&signer, "did:key:lab", "sim:q0", &art, 1_000_000, grant.clone(), None);
1729 assert!(r.verify(), "receipt for {} must verify", art.evidence_kind);
1730 assert!(r.evidence_matches(0, &art.evidence_bytes));
1731 }
1732 }
1733
1734 #[test]
1735 fn sin_cos_are_accurate() {
1736 assert!(sin_fx(0).abs() < CAL_ONE / 400);
1737 assert!((sin_fx(PI_FX / 2) - CAL_ONE).abs() < CAL_ONE / 200);
1738 assert!(sin_fx(PI_FX).abs() < CAL_ONE / 200);
1739 assert!((cos_fx(0) - CAL_ONE).abs() < CAL_ONE / 200);
1740 assert!((sin_fx(PI_FX + PI_FX / 2) + CAL_ONE).abs() < CAL_ONE / 200); }
1742
1743 #[test]
1744 fn naive_pi_pulse_transfers_at_nominal() {
1745 let p = apply_composite(&[(0, PI_FX)], 0);
1746 assert!((p - CAL_ONE).abs() < CAL_ONE / 50, "naive P(0) = {p}");
1747 }
1748
1749 #[test]
1750 fn robust_pulse_beats_naive() {
1751 let r = optimize_robust_pulse(fx(0.3), 13);
1752 assert!(r.worst_naive_fx > CAL_ONE / 12, "naive worst {} too low", r.worst_naive_fx);
1754 assert!(
1756 r.worst_robust_fx * 2 < r.worst_naive_fx,
1757 "robust {} not better than naive {}",
1758 r.worst_robust_fx, r.worst_naive_fx
1759 );
1760 assert_eq!(r, optimize_robust_pulse(fx(0.3), 13)); }
1762
1763 #[cfg(feature = "quantum_ops")]
1764 #[test]
1765 fn robust_pulse_seals_a_receipt() {
1766 use crate::quantum_ops::GrantRef;
1767 use ed25519_dalek::SigningKey;
1768 let r = optimize_robust_pulse(fx(0.3), 13);
1769 let art = r.artifacts();
1770 let rec = seal_artifacts(
1771 &SigningKey::from_bytes(&[3u8; 32]), "did:key:lab", "sim:q0", &art,
1772 5_000_000, GrantRef::unbounded("quantum.calibrate"), None,
1773 );
1774 assert!(rec.verify());
1775 assert!(rec.evidence_matches(0, &art.evidence_bytes));
1776 }
1777}