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