open-standards/wai/wai-quantum/examples/gbs_check.rs
Transaction Science 6ab907e107
Some checks failed
standards workspaces build + test / jouleclaw-rs (pull_request) Successful in 4m54s
no-vanity-metrics / Scan committed Markdown for vanity metrics (pull_request) Successful in 3s
no-vanity-metrics / WAI public text names no comparison (pull_request) Successful in 3s
no-vanity-metrics / WAI public text names no company or product (pull_request) Successful in 3s
standards workspaces build + test / aac-rs (pull_request) Successful in 2m19s
standards workspaces build + test / eoc-rs (pull_request) Successful in 1m54s
standards workspaces build + test / joule-code-rs (pull_request) Successful in 1m51s
standards workspaces build + test / jcp-rs (pull_request) Successful in 1m25s
standards workspaces build + test / joulecontract-rs (pull_request) Successful in 1m3s
standards workspaces build + test / proof-rs (pull_request) Successful in 1m12s
standards workspaces build + test / map-rs (pull_request) Successful in 1m1s
standards workspaces build + test / mesh-rs (pull_request) Successful in 52s
standards workspaces build + test / sandbox-rs (pull_request) Successful in 2m11s
standards workspaces build + test / openpay (pull_request) Successful in 4m8s
standards workspaces build + test / smart-byte-rs (pull_request) Successful in 3m42s
WAI conformance / cargo-class corpora · linux (pull_request) Successful in 3m57s
WAI conformance / v2 vocabulary · manifests validate as stated (pull_request) Successful in 14s
WAI conformance / cargo-class corpora · linux-arm64 (pull_request) Successful in 5m15s
WAI conformance / cross-arch byte-equality · linux-arm64 (pull_request) Successful in 42s
WAI conformance / independent verifiers · claims, JWP, key discovery and integer payloads (Python) (pull_request) Successful in 2m12s
WAI conformance / cross-arch byte-equality · linux (pull_request) Successful in 24s
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Successful in 1m45s
WAI conformance / C2PA manifest emission · signed, read back, validated (pull_request) Successful in 46s
WAI energy receipts / energy receipts · linux (pull_request) Successful in 1m11s
WAI JPEG-AI whole decode (pinned inputs, required) / fetch pinned JPEG-AI inputs → whole decode + pixel hash, required (pull_request) Successful in 1m0s
WAI neural sink gates / model-free refusals of the neural sink (pull_request) Successful in 1m1s
WAI mbt2018_mean integer decode (regenerated vectors) / regenerate mbt2018_mean integer vectors → Rust decode, required (pull_request) Successful in 4m1s
wai-web wasm32 / wai-web wasm32 build · corpus, menu and writers (pull_request) Successful in 1m46s
standards workspaces build + test / arl-rs (pull_request) Successful in 5m0s
standards workspaces build + test / joule-ui-rs (pull_request) Successful in 7m4s
standards workspaces build + test / jouledesk-rs (pull_request) Successful in 5m28s
standards workspaces build + test / joulehook-rs (pull_request) Successful in 4m36s
standards workspaces build + test / sense-rs (pull_request) Successful in 6m2s
standards workspaces build + test / macOS energy backends (pull_request) Failing after 7m31s
WAI conformance / cargo-class corpora · macos (pull_request) Successful in 7m16s
WAI conformance / cross-arch byte-equality · macos (pull_request) Successful in 36s
WAI energy receipts / energy receipts · macos (pull_request) Successful in 2m39s
wai-quantum 0.3.27: Gaussian boson sampling, exactly
A photonic sampler's outcome probabilities are hafnians (photon-number
detection) or torontonians (threshold detection) of its Gaussian state.
quantum_gbs computes both exactly and reproducibly.

- hafnian: power traces, a sum over 2^{n/2} pair subsets, each the
  lambda^{n/2} coefficient of exp(sum tr(B^k) lambda^k / 2k). The traces come
  from a Householder Hessenberg reduction, La Budde's characteristic
  polynomial and Newton's identities: O(n^3 2^{n/2}).
- torontonian: inclusion-exclusion over the 2^m clicked-mode subsets.
- Both sums run in 64 fixed chunks, threaded natively and sequential on WASI,
  added in chunk order, so the bits do not depend on threading.
- GaussianState: squeezed vacua through an interferometer with uniform loss,
  as the complex covariance in the (a, a-dagger) basis.
- click_probability, photon_probability: exact pattern probabilities.
- sample_clicks: exact samples, drawn mode by mode from marginal
  torontonians.
- click_marginals, check_samples: the one- and two-mode click statistics
  every sampler of the state must reproduce, polynomial in the modes, and a
  z-score check of observed patterns against them.

Against an independent implementation:
- click probabilities of three lossy states, every pattern: 1.1e-10;
- photon probabilities up to four photons: 2.3e-13;
- hafnians: 1.5e-12 up to 20x20 and 4.5e-8 at 36x36, where the alternating
  sum loses precision on either side. A 36x36 hafnian takes under 2 s.

Tests:
- hafnians match exhaustion over matchings, and (2k-1)!!;
- squeezed vacuum reproduces its textbook click and photon statistics;
- click probabilities sum to one with loss;
- exact samples reproduce marginals and full-pattern frequencies, and pass
  the check, while a different interferometer fails it.
Mutating the hafnian sign, La Budde's recurrence, Newton's identities, the
torontonian sign or the loss channel fails a named test. bit_identity pins a
24x24 hafnian and a 14-click torontonian (threaded natively, sequential under
WASI), probabilities, samples and marginals, on both targets.

CLI: wai-quantum gbs --squeezing ... [--eta --seed | --unitary] [--sample K |
--check FILE] [--json], byte-identical natively and under wasm32-wasip2.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-04 16:19:25 -04:00

67 lines
2.9 KiB
Rust

//! Gaussian boson sampling numbers, as JSON, for checking against any other
//! implementation.
//!
//! ```text
//! cargo run --release --example gbs_check --features quantum_gbs -- state MODES SEED ETA R1,R2,…
//! cargo run --release --example gbs_check --features quantum_gbs -- hafnian N SEED
//! ```
use wai_quantum::quantum_gbs::{hafnian, random_unitary, GaussianState, Mat, C};
fn c(z: C) -> String {
format!("[{:e},{:e}]", z.re, z.im)
}
fn main() {
let a: Vec<String> = std::env::args().collect();
match a.get(1).map(String::as_str) {
Some("state") => {
let n: usize = a[2].parse().unwrap();
let seed: u64 = a[3].parse().unwrap();
let eta: f64 = a[4].parse().unwrap();
let r: Vec<f64> = a[5].split(',').map(|x| x.parse().unwrap()).collect();
let u = random_unitary(n, seed);
let st = GaussianState::squeezed(&r, &u, eta).unwrap();
let cov: Vec<String> = st.cov.a.iter().map(|z| c(*z)).collect();
let clicks: Vec<String> = (0..1u32 << n)
.map(|m| {
let p: Vec<bool> = (0..n).map(|i| m >> i & 1 == 1).collect();
format!("{:e}", st.click_probability(&p).unwrap())
})
.collect();
// Photon patterns with up to 4 photons in total.
let mut photons = Vec::new();
let mut counts = vec![0usize; n];
fn rec(i: usize, left: usize, counts: &mut Vec<usize>, st: &GaussianState, out: &mut Vec<String>) {
if i == counts.len() {
out.push(format!("[{:?},{:e}]", counts, st.photon_probability(counts).unwrap()));
return;
}
for k in 0..=left {
counts[i] = k;
rec(i + 1, left - k, counts, st, out);
}
counts[i] = 0;
}
rec(0, 4, &mut counts, &st, &mut photons);
println!("{{\"n\":{n},\"cov\":[{}],\"clicks\":[{}],\"photons\":[{}]}}", cov.join(","), clicks.join(","), photons.join(","));
}
Some("hafnian") => {
let n: usize = a[2].parse().unwrap();
let seed: u64 = a[3].parse().unwrap();
let u = random_unitary(n, seed);
let mut m = Mat::zeros(n);
for i in 0..n {
for j in 0..n {
let (x, y) = (u.at(i, j), u.at(j, i));
m.a[i * n + j] = C { re: x.re + y.re, im: x.im + y.im };
}
}
let t0 = std::time::Instant::now();
let h = hafnian(&m);
let dt = t0.elapsed().as_secs_f64();
let entries: Vec<String> = m.a.iter().map(|z| c(*z)).collect();
println!("{{\"n\":{n},\"m\":[{}],\"haf\":{},\"seconds\":{dt}}}", entries.join(","), c(h));
}
_ => eprintln!("usage: gbs_check state MODES SEED ETA R1,R2,… | hafnian N SEED"),
}
}