Merge commit 'd803bfe2b1fe7f5e219e50ac20d6801a0a58ac75' as 'vendor/ruvector'

This commit is contained in:
ruv
2026-02-28 14:39:40 -05:00
7854 changed files with 3522914 additions and 0 deletions
+701
View File
@@ -0,0 +1,701 @@
//! ruQu Demo Binary - Proof Artifact
//!
//! This is the runnable demonstration of ruQu's capabilities.
//!
//! ## What it does
//!
//! 1. Generates a streaming syndrome feed
//! 2. Runs the coherence gate loop per round
//! 3. Prints live status: round, cut value, risk, region mask
//! 4. Writes metrics file: latency histogram, p50/p99/p999, false alarms
//!
//! ## Usage
//!
//! ```bash
//! # Basic run with defaults
//! cargo run --bin ruqu_demo --release
//!
//! # Custom parameters
//! cargo run --bin ruqu_demo --release -- \
//! --distance 7 \
//! --error-rate 0.01 \
//! --rounds 10000 \
//! --output metrics.json
//! ```
use std::collections::VecDeque;
use std::fs::File;
use std::io::Write;
use std::time::Instant;
use ruqu::stim::{StimSyndromeSource, SurfaceCodeConfig};
use ruqu::syndrome::DetectorBitmap;
// ============================================================================
// CONFIGURATION
// ============================================================================
#[derive(Debug, Clone)]
struct DemoConfig {
/// Code distance
code_distance: usize,
/// Physical error rate
error_rate: f64,
/// Number of rounds to run
num_rounds: usize,
/// Random seed
seed: u64,
/// Output metrics file
output_file: Option<String>,
/// Print interval (every N rounds)
print_interval: usize,
/// Gate threshold
threshold: f64,
}
impl Default for DemoConfig {
fn default() -> Self {
Self {
code_distance: 5,
error_rate: 0.01,
num_rounds: 10000,
seed: 42,
output_file: Some("ruqu_metrics.json".to_string()),
print_interval: 1000,
threshold: 5.0,
}
}
}
fn parse_args() -> DemoConfig {
let args: Vec<String> = std::env::args().collect();
let mut config = DemoConfig::default();
let mut i = 1;
while i < args.len() {
match args[i].as_str() {
"--distance" | "-d" => {
i += 1;
config.code_distance = args[i].parse().expect("Invalid distance");
}
"--error-rate" | "-e" => {
i += 1;
config.error_rate = args[i].parse().expect("Invalid error rate");
}
"--rounds" | "-r" => {
i += 1;
config.num_rounds = args[i].parse().expect("Invalid rounds");
}
"--seed" | "-s" => {
i += 1;
config.seed = args[i].parse().expect("Invalid seed");
}
"--output" | "-o" => {
i += 1;
config.output_file = Some(args[i].clone());
}
"--threshold" | "-t" => {
i += 1;
config.threshold = args[i].parse().expect("Invalid threshold");
}
"--help" | "-h" => {
print_help();
std::process::exit(0);
}
_ => {
eprintln!("Unknown argument: {}", args[i]);
std::process::exit(1);
}
}
i += 1;
}
config
}
fn print_help() {
println!(
r#"
ruQu Demo - Coherence Gate Demonstration
USAGE:
ruqu_demo [OPTIONS]
OPTIONS:
-d, --distance <N> Code distance (default: 5)
-e, --error-rate <P> Physical error rate (default: 0.01)
-r, --rounds <N> Number of rounds (default: 10000)
-s, --seed <N> Random seed (default: 42)
-o, --output <FILE> Output metrics file (default: ruqu_metrics.json)
-t, --threshold <T> Gate threshold (default: 5.0)
-h, --help Print this help message
"#
);
}
// ============================================================================
// LATENCY TRACKING
// ============================================================================
struct LatencyTracker {
latencies: Vec<u64>,
recent: VecDeque<u64>,
max_recent: usize,
}
impl LatencyTracker {
fn new(max_recent: usize) -> Self {
Self {
latencies: Vec::new(),
recent: VecDeque::with_capacity(max_recent),
max_recent,
}
}
fn record(&mut self, latency_ns: u64) {
self.latencies.push(latency_ns);
if self.recent.len() >= self.max_recent {
self.recent.pop_front();
}
self.recent.push_back(latency_ns);
}
fn percentile(&self, p: f64) -> u64 {
if self.latencies.is_empty() {
return 0;
}
let mut sorted = self.latencies.clone();
sorted.sort_unstable();
let idx = ((p / 100.0) * (sorted.len() - 1) as f64) as usize;
sorted[idx]
}
fn p50(&self) -> u64 {
self.percentile(50.0)
}
fn p99(&self) -> u64 {
self.percentile(99.0)
}
fn p999(&self) -> u64 {
self.percentile(99.9)
}
fn max(&self) -> u64 {
self.latencies.iter().copied().max().unwrap_or(0)
}
fn mean(&self) -> f64 {
if self.latencies.is_empty() {
return 0.0;
}
let sum: u64 = self.latencies.iter().sum();
sum as f64 / self.latencies.len() as f64
}
fn count(&self) -> usize {
self.latencies.len()
}
fn histogram(&self, num_buckets: usize) -> Vec<(u64, u64, usize)> {
if self.latencies.is_empty() {
return vec![];
}
let min = *self.latencies.iter().min().unwrap();
let max = self.max();
let range = max - min + 1;
let bucket_size = (range / num_buckets as u64).max(1);
let mut buckets = vec![0usize; num_buckets];
for &lat in &self.latencies {
let bucket = ((lat - min) / bucket_size).min(num_buckets as u64 - 1) as usize;
buckets[bucket] += 1;
}
buckets
.into_iter()
.enumerate()
.map(|(i, count)| {
let start = min + i as u64 * bucket_size;
let end = start + bucket_size;
(start, end, count)
})
.collect()
}
}
// ============================================================================
// SIMPLE MIN-CUT GATE
// ============================================================================
use std::collections::{HashMap, HashSet};
struct MinCutGate {
threshold: f64,
grid_size: usize,
base_weight: f64,
}
impl MinCutGate {
fn new(code_distance: usize, error_rate: f64, threshold: f64) -> Self {
Self {
threshold,
grid_size: code_distance - 1,
base_weight: (-error_rate.ln()).max(0.1),
}
}
fn process(&self, syndrome: &DetectorBitmap) -> GateResult {
let start = Instant::now();
// Compute min-cut
let fired_set: HashSet<usize> = syndrome.iter_fired().collect();
let min_cut = self.compute_min_cut(&fired_set);
// Compute risk
let risk = if min_cut < self.threshold {
1.0 - (min_cut / self.threshold)
} else {
0.0
};
// Compute region mask (simplified: which quadrants have errors)
let region_mask = self.compute_region_mask(&fired_set);
let latency_ns = start.elapsed().as_nanos() as u64;
GateResult {
min_cut,
risk,
region_mask,
decision: if min_cut >= self.threshold {
Decision::Permit
} else if min_cut >= self.threshold * 0.5 {
Decision::Defer
} else {
Decision::Deny
},
latency_ns,
fired_count: fired_set.len(),
}
}
fn compute_min_cut(&self, fired_set: &HashSet<usize>) -> f64 {
// Simple s-t min-cut using Edmonds-Karp
let mut adj: HashMap<u32, Vec<(u32, f64)>> = HashMap::new();
let fired_weight = 0.01;
// Build grid
for row in 0..self.grid_size {
for col in 0..self.grid_size {
let node = (row * self.grid_size + col) as u32;
let is_fired = fired_set.contains(&(node as usize));
if col + 1 < self.grid_size {
let right = (row * self.grid_size + col + 1) as u32;
let right_fired = fired_set.contains(&(right as usize));
let weight = if is_fired || right_fired {
fired_weight
} else {
self.base_weight
};
adj.entry(node).or_default().push((right, weight));
adj.entry(right).or_default().push((node, weight));
}
if row + 1 < self.grid_size {
let bottom = ((row + 1) * self.grid_size + col) as u32;
let bottom_fired = fired_set.contains(&(bottom as usize));
let weight = if is_fired || bottom_fired {
fired_weight
} else {
self.base_weight
};
adj.entry(node).or_default().push((bottom, weight));
adj.entry(bottom).or_default().push((node, weight));
}
}
}
let source = (self.grid_size * self.grid_size) as u32;
let sink = source + 1;
// Connect boundaries
let boundary_weight = self.base_weight * 2.0;
for row in 0..self.grid_size {
let left = (row * self.grid_size) as u32;
let right = (row * self.grid_size + self.grid_size - 1) as u32;
adj.entry(source).or_default().push((left, boundary_weight));
adj.entry(left).or_default().push((source, boundary_weight));
adj.entry(right).or_default().push((sink, boundary_weight));
adj.entry(sink).or_default().push((right, boundary_weight));
}
// Max-flow = min-cut
let mut capacity: HashMap<(u32, u32), f64> = HashMap::new();
for (&u, neighbors) in &adj {
for &(v, w) in neighbors {
*capacity.entry((u, v)).or_default() += w;
}
}
let mut max_flow = 0.0;
loop {
// BFS for augmenting path
let mut parent: HashMap<u32, u32> = HashMap::new();
let mut visited = HashSet::new();
let mut queue = std::collections::VecDeque::new();
queue.push_back(source);
visited.insert(source);
while let Some(u) = queue.pop_front() {
if u == sink {
break;
}
if let Some(neighbors) = adj.get(&u) {
for &(v, _) in neighbors {
let cap = capacity.get(&(u, v)).copied().unwrap_or(0.0);
if !visited.contains(&v) && cap > 1e-10 {
visited.insert(v);
parent.insert(v, u);
queue.push_back(v);
}
}
}
}
if !parent.contains_key(&sink) {
break;
}
// Find bottleneck
let mut path_flow = f64::INFINITY;
let mut v = sink;
while v != source {
let u = parent[&v];
path_flow = path_flow.min(capacity.get(&(u, v)).copied().unwrap_or(0.0));
v = u;
}
// Update capacities
v = sink;
while v != source {
let u = parent[&v];
*capacity.entry((u, v)).or_default() -= path_flow;
*capacity.entry((v, u)).or_default() += path_flow;
v = u;
}
max_flow += path_flow;
}
max_flow
}
fn compute_region_mask(&self, fired_set: &HashSet<usize>) -> u64 {
// Split into 4 quadrants
let half = self.grid_size / 2;
let mut mask = 0u64;
for &det in fired_set {
let row = det / self.grid_size;
let col = det % self.grid_size;
let quadrant = match (row < half, col < half) {
(true, true) => 0, // Top-left
(true, false) => 1, // Top-right
(false, true) => 2, // Bottom-left
(false, false) => 3, // Bottom-right
};
mask |= 1 << quadrant;
}
mask
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
enum Decision {
Permit,
Defer,
Deny,
}
#[derive(Debug, Clone)]
struct GateResult {
min_cut: f64,
risk: f64,
region_mask: u64,
decision: Decision,
latency_ns: u64,
fired_count: usize,
}
// ============================================================================
// METRICS OUTPUT
// ============================================================================
#[derive(Debug, serde::Serialize)]
struct DemoMetrics {
config: MetricsConfig,
summary: MetricsSummary,
latency: LatencyMetrics,
decisions: DecisionMetrics,
histogram: Vec<HistogramBucket>,
}
#[derive(Debug, serde::Serialize)]
struct MetricsConfig {
code_distance: usize,
error_rate: f64,
num_rounds: usize,
seed: u64,
threshold: f64,
}
#[derive(Debug, serde::Serialize)]
struct MetricsSummary {
total_rounds: usize,
total_time_ms: f64,
throughput_per_sec: f64,
total_fired: usize,
avg_fired_per_round: f64,
}
#[derive(Debug, serde::Serialize)]
struct LatencyMetrics {
mean_ns: f64,
p50_ns: u64,
p99_ns: u64,
p999_ns: u64,
max_ns: u64,
}
#[derive(Debug, serde::Serialize)]
struct DecisionMetrics {
permits: usize,
defers: usize,
denies: usize,
permit_rate: f64,
deny_rate: f64,
}
#[derive(Debug, serde::Serialize)]
struct HistogramBucket {
start_ns: u64,
end_ns: u64,
count: usize,
}
// ============================================================================
// MAIN
// ============================================================================
fn main() {
let config = parse_args();
println!("╔═══════════════════════════════════════════════════════════════════╗");
println!("║ ruQu Demo - Proof Artifact ║");
println!("╠═══════════════════════════════════════════════════════════════════╣");
println!(
"║ Code Distance: d={} | Error Rate: {:.4} | Rounds: {:>6}",
config.code_distance, config.error_rate, config.num_rounds
);
println!(
"║ Threshold: {:.2} | Seed: {:>10}",
config.threshold, config.seed
);
println!("╚═══════════════════════════════════════════════════════════════════╝");
println!();
// Initialize components
let surface_config =
SurfaceCodeConfig::new(config.code_distance, config.error_rate).with_seed(config.seed);
let mut syndrome_source = match StimSyndromeSource::new(surface_config) {
Ok(s) => s,
Err(e) => {
eprintln!("Failed to create syndrome source: {:?}", e);
std::process::exit(1);
}
};
let gate = MinCutGate::new(config.code_distance, config.error_rate, config.threshold);
let mut latency_tracker = LatencyTracker::new(1000);
// Counters
let mut permits = 0usize;
let mut defers = 0usize;
let mut denies = 0usize;
let mut total_fired = 0usize;
// Run demo
println!("Round │ Cut │ Risk │ Decision │ Regions │ Latency │ Fired");
println!("──────┼───────┼───────┼──────────┼─────────┼─────────┼──────");
let start_time = Instant::now();
for round in 0..config.num_rounds {
// Get syndrome
let syndrome: DetectorBitmap = match syndrome_source.sample() {
Ok(s) => s,
Err(_) => continue,
};
// Process through gate
let result = gate.process(&syndrome);
latency_tracker.record(result.latency_ns);
total_fired += result.fired_count;
// Update counters
match result.decision {
Decision::Permit => permits += 1,
Decision::Defer => defers += 1,
Decision::Deny => denies += 1,
}
// Print live status
if round % config.print_interval == 0 || result.decision == Decision::Deny {
let decision_str = match result.decision {
Decision::Permit => "\x1b[32mPERMIT\x1b[0m ",
Decision::Defer => "\x1b[33mDEFER\x1b[0m ",
Decision::Deny => "\x1b[31mDENY\x1b[0m ",
};
println!(
"{:>5}{:>5.2}{:>5.2}{}{:>07b}{:>5}ns │ {:>3}",
round,
result.min_cut,
result.risk,
decision_str,
result.region_mask,
result.latency_ns,
result.fired_count
);
}
}
let total_time = start_time.elapsed();
// Summary
println!();
println!("╔═══════════════════════════════════════════════════════════════════╗");
println!("║ RESULTS SUMMARY ║");
println!("╠═══════════════════════════════════════════════════════════════════╣");
println!(
"║ Total Time: {:>10.2} ms ║",
total_time.as_secs_f64() * 1000.0
);
println!(
"║ Throughput: {:>10.0} rounds/sec ║",
config.num_rounds as f64 / total_time.as_secs_f64()
);
println!(
"║ Avg Fired/Round: {:>10.2}",
total_fired as f64 / config.num_rounds as f64
);
println!("╠═══════════════════════════════════════════════════════════════════╣");
println!("║ Latency: ║");
println!(
"║ Mean: {:>8.0} ns ║",
latency_tracker.mean()
);
println!(
"║ P50: {:>8} ns ║",
latency_tracker.p50()
);
println!(
"║ P99: {:>8} ns ║",
latency_tracker.p99()
);
println!(
"║ P999: {:>8} ns ║",
latency_tracker.p999()
);
println!(
"║ Max: {:>8} ns ║",
latency_tracker.max()
);
println!("╠═══════════════════════════════════════════════════════════════════╣");
println!("║ Decisions: ║");
println!(
"║ Permits: {:>6} ({:>5.1}%) ║",
permits,
permits as f64 / config.num_rounds as f64 * 100.0
);
println!(
"║ Defers: {:>6} ({:>5.1}%) ║",
defers,
defers as f64 / config.num_rounds as f64 * 100.0
);
println!(
"║ Denies: {:>6} ({:>5.1}%) ║",
denies,
denies as f64 / config.num_rounds as f64 * 100.0
);
println!("╚═══════════════════════════════════════════════════════════════════╝");
// Write metrics file
if let Some(output_file) = &config.output_file {
let metrics = DemoMetrics {
config: MetricsConfig {
code_distance: config.code_distance,
error_rate: config.error_rate,
num_rounds: config.num_rounds,
seed: config.seed,
threshold: config.threshold,
},
summary: MetricsSummary {
total_rounds: config.num_rounds,
total_time_ms: total_time.as_secs_f64() * 1000.0,
throughput_per_sec: config.num_rounds as f64 / total_time.as_secs_f64(),
total_fired,
avg_fired_per_round: total_fired as f64 / config.num_rounds as f64,
},
latency: LatencyMetrics {
mean_ns: latency_tracker.mean(),
p50_ns: latency_tracker.p50(),
p99_ns: latency_tracker.p99(),
p999_ns: latency_tracker.p999(),
max_ns: latency_tracker.max(),
},
decisions: DecisionMetrics {
permits,
defers,
denies,
permit_rate: permits as f64 / config.num_rounds as f64,
deny_rate: denies as f64 / config.num_rounds as f64,
},
histogram: latency_tracker
.histogram(20)
.into_iter()
.map(|(start, end, count)| HistogramBucket {
start_ns: start,
end_ns: end,
count,
})
.collect(),
};
match File::create(output_file) {
Ok(mut file) => {
let json = serde_json::to_string_pretty(&metrics).unwrap();
file.write_all(json.as_bytes()).unwrap();
println!("\nMetrics written to: {}", output_file);
}
Err(e) => {
eprintln!("Failed to write metrics file: {}", e);
}
}
}
// Latency histogram
println!("\nLatency Histogram:");
let histogram = latency_tracker.histogram(10);
let max_count = histogram.iter().map(|(_, _, c)| *c).max().unwrap_or(1);
for (start, end, count) in histogram {
let bar_len = (count as f64 / max_count as f64 * 40.0) as usize;
let bar = "".repeat(bar_len);
println!("{:>8}-{:<8}{:<40} {:>5}", start, end, bar, count);
}
}
@@ -0,0 +1,856 @@
//! ruQu Predictive Evaluation Binary
//!
//! This binary produces formal evaluation metrics for ruQu's predictive capabilities.
//! It demonstrates that ruQu can detect logical failure risk BEFORE it manifests.
//!
//! ## Usage
//!
//! ```bash
//! cargo run --bin ruqu_predictive_eval --release -- \
//! --distance 5 \
//! --error-rate 0.001 \
//! --runs 100
//! ```
//!
//! ## Output
//!
//! Produces DARPA-style evaluation metrics including:
//! - Lead time distribution (median, p10, p90)
//! - Precision and recall
//! - False alarm rate per 100k cycles
//! - Actionability for different mitigation windows
use std::collections::{HashMap, HashSet, VecDeque};
use std::time::Instant;
use ruqu::stim::{StimSyndromeSource, SurfaceCodeConfig};
use ruqu::syndrome::DetectorBitmap;
// ============================================================================
// CONFIGURATION
// ============================================================================
#[derive(Debug, Clone)]
struct EvalConfig {
code_distance: usize,
error_rate: f64,
num_runs: usize,
cycles_per_run: usize,
seed: u64,
inject_mode: InjectMode,
}
#[derive(Debug, Clone, Copy)]
enum InjectMode {
/// Independent noise only (baseline)
Independent,
/// Correlated burst injection
CorrelatedBurst,
/// Both modes for comparison
Both,
}
impl Default for EvalConfig {
fn default() -> Self {
Self {
code_distance: 5,
error_rate: 0.001,
num_runs: 100,
cycles_per_run: 500,
seed: 42,
inject_mode: InjectMode::CorrelatedBurst,
}
}
}
fn parse_args() -> EvalConfig {
let args: Vec<String> = std::env::args().collect();
let mut config = EvalConfig::default();
let mut i = 1;
while i < args.len() {
match args[i].as_str() {
"--distance" | "-d" => {
i += 1;
config.code_distance = args[i].parse().expect("Invalid distance");
}
"--error-rate" | "-e" => {
i += 1;
config.error_rate = args[i].parse().expect("Invalid error rate");
}
"--runs" | "-r" => {
i += 1;
config.num_runs = args[i].parse().expect("Invalid runs");
}
"--cycles" | "-c" => {
i += 1;
config.cycles_per_run = args[i].parse().expect("Invalid cycles");
}
"--seed" | "-s" => {
i += 1;
config.seed = args[i].parse().expect("Invalid seed");
}
"--inject" => {
i += 1;
config.inject_mode = match args[i].as_str() {
"independent" => InjectMode::Independent,
"burst" | "correlated" | "correlated_burst" => InjectMode::CorrelatedBurst,
"both" => InjectMode::Both,
_ => panic!("Invalid inject mode: {}", args[i]),
};
}
"--help" | "-h" => {
print_help();
std::process::exit(0);
}
_ => {
eprintln!("Unknown argument: {}", args[i]);
print_help();
std::process::exit(1);
}
}
i += 1;
}
config
}
fn print_help() {
println!("ruQu Predictive Evaluation");
println!();
println!("USAGE:");
println!(" ruqu_predictive_eval [OPTIONS]");
println!();
println!("OPTIONS:");
println!(" -d, --distance <N> Code distance (default: 5)");
println!(" -e, --error-rate <F> Physical error rate (default: 0.001)");
println!(" -r, --runs <N> Number of evaluation runs (default: 100)");
println!(" -c, --cycles <N> Cycles per run (default: 500)");
println!(" -s, --seed <N> Random seed (default: 42)");
println!(" --inject <MODE> Injection mode: independent, burst, both");
println!(" -h, --help Print this help");
}
// ============================================================================
// STRUCTURAL SIGNAL WITH DYNAMICS
// ============================================================================
/// Structural signal with cut dynamics (velocity and curvature)
#[derive(Debug, Clone, Default)]
pub struct StructuralSignal {
/// Current min-cut value
pub cut: f64,
/// Rate of change (Δλ)
pub velocity: f64,
/// Acceleration of change (Δ²λ)
pub curvature: f64,
/// Baseline mean for adaptive thresholding
pub baseline_mean: f64,
/// Baseline standard deviation
pub baseline_std: f64,
}
/// Warning detector with velocity and curvature tracking
struct WarningDetector {
history: VecDeque<f64>,
velocity_history: VecDeque<f64>,
max_history: usize,
warmup_samples: usize,
baseline_mean: f64,
baseline_std: f64,
theta_sigma: f64,
theta_absolute: f64,
delta: f64,
lookback: usize,
min_event_count: usize,
}
impl WarningDetector {
fn new() -> Self {
Self {
history: VecDeque::new(),
velocity_history: VecDeque::new(),
max_history: 100,
warmup_samples: 20,
baseline_mean: 0.0,
baseline_std: 0.0,
theta_sigma: 2.5,
theta_absolute: 2.0,
delta: 1.2,
lookback: 5,
min_event_count: 5,
}
}
fn push(&mut self, cut: f64) {
// Track velocity
if let Some(&prev) = self.history.back() {
let velocity = cut - prev;
self.velocity_history.push_back(velocity);
if self.velocity_history.len() > self.max_history {
self.velocity_history.pop_front();
}
}
self.history.push_back(cut);
if self.history.len() > self.max_history {
self.history.pop_front();
}
// Update baseline during warmup
if self.history.len() <= self.warmup_samples {
let sum: f64 = self.history.iter().sum();
self.baseline_mean = sum / self.history.len() as f64;
if self.history.len() > 1 {
let variance: f64 = self
.history
.iter()
.map(|x| (x - self.baseline_mean).powi(2))
.sum::<f64>()
/ (self.history.len() - 1) as f64;
self.baseline_std = variance.sqrt();
}
}
}
fn current(&self) -> f64 {
self.history.back().copied().unwrap_or(0.0)
}
fn velocity(&self) -> f64 {
self.velocity_history.back().copied().unwrap_or(0.0)
}
fn curvature(&self) -> f64 {
if self.velocity_history.len() < 2 {
return 0.0;
}
let n = self.velocity_history.len();
self.velocity_history[n - 1] - self.velocity_history[n - 2]
}
fn signal(&self) -> StructuralSignal {
StructuralSignal {
cut: self.current(),
velocity: self.velocity(),
curvature: self.curvature(),
baseline_mean: self.baseline_mean,
baseline_std: self.baseline_std,
}
}
fn drop_from_lookback(&self) -> f64 {
if self.history.len() <= self.lookback {
return 0.0;
}
let n = self.history.len();
self.history[n - 1] - self.history[n - 1 - self.lookback]
}
fn is_warning(&self, event_count: usize) -> bool {
if self.history.len() < self.warmup_samples {
return false;
}
if self.baseline_mean == 0.0 {
return false;
}
let adaptive_threshold =
(self.baseline_mean - self.theta_sigma * self.baseline_std).max(0.5);
let below_adaptive = self.current() <= adaptive_threshold;
let below_absolute = self.current() <= self.theta_absolute;
let rapid_drop = self.drop_from_lookback() <= -self.delta;
let high_events = event_count >= self.min_event_count;
// AND mode: structural + drop + intensity
(below_adaptive || below_absolute) && rapid_drop && high_events
}
}
// ============================================================================
// QEC GRAPH CONSTRUCTION
// ============================================================================
struct STMinCutGraph {
num_nodes: u32,
edges: Vec<(u32, u32, f64)>,
source_edges: Vec<(u32, f64)>,
sink_edges: Vec<(u32, f64)>,
}
impl STMinCutGraph {
fn new(num_nodes: u32) -> Self {
Self {
num_nodes,
edges: Vec::new(),
source_edges: Vec::new(),
sink_edges: Vec::new(),
}
}
fn add_edge(&mut self, u: u32, v: u32, weight: f64) {
self.edges.push((u, v, weight));
}
fn connect_source(&mut self, node: u32, weight: f64) {
self.source_edges.push((node, weight));
}
fn connect_sink(&mut self, node: u32, weight: f64) {
self.sink_edges.push((node, weight));
}
fn compute_min_cut(&self) -> f64 {
// BFS-based approximation
let mut visited = vec![false; self.num_nodes as usize];
let mut queue = VecDeque::new();
let mut total_flow = 0.0;
// Build adjacency with capacities
let mut adj: HashMap<u32, Vec<(u32, f64)>> = HashMap::new();
for &(u, v, w) in &self.edges {
adj.entry(u).or_default().push((v, w));
adj.entry(v).or_default().push((u, w));
}
// Start from source-connected nodes
for &(node, cap) in &self.source_edges {
if !visited[node as usize] {
queue.push_back((node, cap));
visited[node as usize] = true;
}
}
// BFS to sink
let sink_set: HashSet<u32> = self.sink_edges.iter().map(|(n, _)| *n).collect();
while let Some((current, flow)) = queue.pop_front() {
if sink_set.contains(&current) {
total_flow += flow;
continue;
}
if let Some(neighbors) = adj.get(&current) {
for &(next, cap) in neighbors {
if !visited[next as usize] {
visited[next as usize] = true;
let next_flow = flow.min(cap);
queue.push_back((next, next_flow));
}
}
}
}
// Return cut value (inverse of flow for this approximation)
let source_capacity: f64 = self.source_edges.iter().map(|(_, c)| c).sum();
(source_capacity - total_flow).max(0.1)
}
}
fn build_qec_graph(
code_distance: usize,
error_rate: f64,
syndrome: &DetectorBitmap,
) -> STMinCutGraph {
let grid_size = code_distance - 1;
let num_detectors = 2 * grid_size * grid_size;
let mut graph = STMinCutGraph::new(num_detectors as u32);
let fired_set: HashSet<usize> = syndrome.iter_fired().collect();
let base_weight = (-error_rate.ln()).max(0.1);
let fired_weight = 0.01;
// Build X-stabilizer grid
for row in 0..grid_size {
for col in 0..grid_size {
let node = (row * grid_size + col) as u32;
let is_fired = fired_set.contains(&(node as usize));
if col + 1 < grid_size {
let right = (row * grid_size + col + 1) as u32;
let right_fired = fired_set.contains(&(right as usize));
let weight = if is_fired || right_fired {
fired_weight
} else {
base_weight
};
graph.add_edge(node, right, weight);
}
if row + 1 < grid_size {
let bottom = ((row + 1) * grid_size + col) as u32;
let bottom_fired = fired_set.contains(&(bottom as usize));
let weight = if is_fired || bottom_fired {
fired_weight
} else {
base_weight
};
graph.add_edge(node, bottom, weight);
}
}
}
let boundary_weight = base_weight * 2.0;
for row in 0..grid_size {
let left = (row * grid_size) as u32;
let right = (row * grid_size + grid_size - 1) as u32;
graph.connect_source(left, boundary_weight);
graph.connect_sink(right, boundary_weight);
}
graph
}
// ============================================================================
// GROUND TRUTH
// ============================================================================
fn is_logical_failure(syndrome: &DetectorBitmap, code_distance: usize) -> bool {
let grid_size = code_distance - 1;
let fired: HashSet<usize> = syndrome.iter_fired().collect();
if fired.is_empty() {
return false;
}
let left_boundary: Vec<usize> = (0..grid_size)
.map(|row| row * grid_size)
.filter(|&d| fired.contains(&d))
.collect();
if left_boundary.is_empty() {
return false;
}
let mut visited: HashSet<usize> = HashSet::new();
let mut queue: VecDeque<usize> = VecDeque::new();
for &start in &left_boundary {
queue.push_back(start);
visited.insert(start);
}
while let Some(current) = queue.pop_front() {
let row = current / grid_size;
let col = current % grid_size;
if col == grid_size - 1 {
return true;
}
let neighbors = [
if col > 0 {
Some(row * grid_size + col - 1)
} else {
None
},
if col + 1 < grid_size {
Some(row * grid_size + col + 1)
} else {
None
},
if row > 0 {
Some((row - 1) * grid_size + col)
} else {
None
},
if row + 1 < grid_size {
Some((row + 1) * grid_size + col)
} else {
None
},
];
for neighbor_opt in neighbors.iter().flatten() {
let neighbor = *neighbor_opt;
if fired.contains(&neighbor) && !visited.contains(&neighbor) {
visited.insert(neighbor);
queue.push_back(neighbor);
}
}
}
false
}
// ============================================================================
// EVALUATION RESULTS
// ============================================================================
#[derive(Default)]
struct EvalResults {
total_cycles: u64,
failures_observed: u64,
warnings_issued: u64,
true_warnings: u64,
false_warnings: u64,
lead_times: Vec<u64>,
}
impl EvalResults {
fn precision(&self) -> f64 {
if self.warnings_issued == 0 {
return 0.0;
}
self.true_warnings as f64 / self.warnings_issued as f64
}
fn recall(&self) -> f64 {
if self.failures_observed == 0 {
return 0.0;
}
self.true_warnings as f64 / self.failures_observed as f64
}
fn false_alarms_per_100k(&self) -> f64 {
if self.total_cycles == 0 {
return 0.0;
}
self.false_warnings as f64 / self.total_cycles as f64 * 100_000.0
}
fn median_lead_time(&self) -> f64 {
if self.lead_times.is_empty() {
return 0.0;
}
let mut sorted = self.lead_times.clone();
sorted.sort();
sorted[sorted.len() / 2] as f64
}
fn p10_lead_time(&self) -> f64 {
if self.lead_times.is_empty() {
return 0.0;
}
let mut sorted = self.lead_times.clone();
sorted.sort();
let idx = (sorted.len() as f64 * 0.10) as usize;
sorted[idx.min(sorted.len() - 1)] as f64
}
fn p90_lead_time(&self) -> f64 {
if self.lead_times.is_empty() {
return 0.0;
}
let mut sorted = self.lead_times.clone();
sorted.sort();
let idx = (sorted.len() as f64 * 0.90) as usize;
sorted[idx.min(sorted.len() - 1)] as f64
}
fn actionable_rate(&self, min_cycles: u64) -> f64 {
if self.lead_times.is_empty() {
return 0.0;
}
let actionable = self.lead_times.iter().filter(|&&t| t >= min_cycles).count();
actionable as f64 / self.lead_times.len() as f64
}
}
// ============================================================================
// SYNDROME GENERATOR WITH BURST INJECTION
// ============================================================================
struct SyndromeGenerator {
source: StimSyndromeSource,
burst_active: bool,
burst_remaining: usize,
burst_center: usize,
burst_radius: usize,
code_distance: usize,
}
impl SyndromeGenerator {
fn new(code_distance: usize, error_rate: f64, seed: u64) -> Self {
let config = SurfaceCodeConfig {
distance: code_distance,
error_rate,
seed: Some(seed),
rounds: 1,
rotated: false,
measure_errors: true,
};
Self {
source: StimSyndromeSource::new(config).expect("Failed to create source"),
burst_active: false,
burst_remaining: 0,
burst_center: 0,
burst_radius: 2,
code_distance,
}
}
fn inject_burst(&mut self, duration: usize, center: usize) {
self.burst_active = true;
self.burst_remaining = duration;
self.burst_center = center;
}
fn sample(&mut self) -> DetectorBitmap {
let mut syndrome = self.source.sample().unwrap_or_else(|_| {
DetectorBitmap::new(2 * (self.code_distance - 1) * (self.code_distance - 1))
});
if self.burst_active && self.burst_remaining > 0 {
let grid_size = self.code_distance - 1;
let center_row = self.burst_center / grid_size;
let center_col = self.burst_center % grid_size;
for dr in 0..=self.burst_radius {
for dc in 0..=self.burst_radius {
if dr == 0 && dc == 0 {
continue;
}
for &(sr, sc) in &[(1i32, 1i32), (1, -1), (-1, 1), (-1, -1)] {
let row = center_row as i32 + dr as i32 * sr;
let col = center_col as i32 + dc as i32 * sc;
if row >= 0 && row < grid_size as i32 && col >= 0 && col < grid_size as i32
{
let detector = (row as usize) * grid_size + (col as usize);
if detector < syndrome.detector_count() {
syndrome.set(detector, true);
}
}
}
}
}
if self.burst_center < syndrome.detector_count() {
syndrome.set(self.burst_center, true);
}
self.burst_remaining -= 1;
if self.burst_remaining == 0 {
self.burst_active = false;
}
}
syndrome
}
}
// ============================================================================
// MAIN EVALUATION
// ============================================================================
fn run_evaluation(config: &EvalConfig, with_bursts: bool) -> EvalResults {
let mut results = EvalResults::default();
let grid_size = config.code_distance - 1;
let num_detectors = 2 * grid_size * grid_size;
for run in 0..config.num_runs {
let seed = config.seed + run as u64;
let mut generator = SyndromeGenerator::new(config.code_distance, config.error_rate, seed);
let mut detector = WarningDetector::new();
let mut warning_active = false;
let mut warning_start = 0u64;
let mut cycles_since_warning = 0u64;
// Schedule burst injection at random point
let burst_cycle = if with_bursts {
(seed % (config.cycles_per_run as u64 / 2)) as usize + config.cycles_per_run / 4
} else {
usize::MAX
};
let burst_duration = 8;
let burst_center = ((seed * 7) % num_detectors as u64) as usize;
for cycle in 0..config.cycles_per_run {
// Inject burst at scheduled time
if cycle == burst_cycle && with_bursts {
generator.inject_burst(burst_duration, burst_center);
}
let syndrome = generator.sample();
let graph = build_qec_graph(config.code_distance, config.error_rate, &syndrome);
let cut = graph.compute_min_cut();
let event_count = syndrome.fired_count();
detector.push(cut);
let is_failure = is_logical_failure(&syndrome, config.code_distance);
let is_warning = detector.is_warning(event_count);
// Track warning onset
if is_warning && !warning_active {
warning_active = true;
warning_start = cycle as u64;
cycles_since_warning = 0;
results.warnings_issued += 1;
}
if warning_active {
cycles_since_warning += 1;
}
// Track failures
if is_failure {
results.failures_observed += 1;
if warning_active && cycles_since_warning > 0 {
results.true_warnings += 1;
results.lead_times.push(cycles_since_warning);
}
// Reset warning state after failure
warning_active = false;
}
// Timeout warnings without failure (false alarm)
if warning_active && cycles_since_warning > 20 {
results.false_warnings += 1;
warning_active = false;
}
results.total_cycles += 1;
}
}
results
}
fn main() {
let config = parse_args();
let start_time = Instant::now();
println!();
println!("╔═══════════════════════════════════════════════════════════════════════╗");
println!("║ ruQu PREDICTIVE EVALUATION ║");
println!("║ Formal Metrics for Early Warning ║");
println!("╚═══════════════════════════════════════════════════════════════════════╝");
println!();
println!("Configuration:");
println!(" Code Distance: d={}", config.code_distance);
println!(" Error Rate: {:.4}", config.error_rate);
println!(" Runs: {}", config.num_runs);
println!(" Cycles/Run: {}", config.cycles_per_run);
println!(" Seed: {}", config.seed);
println!(" Inject Mode: {:?}", config.inject_mode);
// Run with correlated bursts
let results = match config.inject_mode {
InjectMode::Independent => run_evaluation(&config, false),
InjectMode::CorrelatedBurst => run_evaluation(&config, true),
InjectMode::Both => {
println!();
println!("═══════════════════════════════════════════════════════════════════════");
println!(" REGIME A: Independent Noise");
println!("═══════════════════════════════════════════════════════════════════════");
let independent = run_evaluation(&config, false);
print_results(&independent);
println!();
println!("═══════════════════════════════════════════════════════════════════════");
println!(" REGIME B: Correlated Bursts");
println!("═══════════════════════════════════════════════════════════════════════");
let bursts = run_evaluation(&config, true);
print_results(&bursts);
bursts
}
};
if !matches!(config.inject_mode, InjectMode::Both) {
println!();
println!("═══════════════════════════════════════════════════════════════════════");
println!(" EVALUATION RESULTS");
println!("═══════════════════════════════════════════════════════════════════════");
print_results(&results);
}
// Actionability breakdown
println!();
println!("═══════════════════════════════════════════════════════════════════════");
println!(" ACTIONABILITY");
println!("═══════════════════════════════════════════════════════════════════════");
println!();
println!(
" Decoder switch (1 cycle): {:>5.1}%",
results.actionable_rate(1) * 100.0
);
println!(
" Extra syndrome round (2 cycles): {:>5.1}%",
results.actionable_rate(2) * 100.0
);
println!(
" Region quarantine (5 cycles): {:>5.1}%",
results.actionable_rate(5) * 100.0
);
println!(
" Full recalibration (10 cycles): {:>5.1}%",
results.actionable_rate(10) * 100.0
);
// Summary
println!();
println!("═══════════════════════════════════════════════════════════════════════");
println!(" SUMMARY");
println!("═══════════════════════════════════════════════════════════════════════");
let predictive = results.recall() >= 0.80
&& results.false_alarms_per_100k() < 50.0
&& results.median_lead_time() >= 2.0;
if predictive {
println!();
println!(" ✓ PREDICTIVE: ruQu satisfies all criteria");
println!(" - Recall >= 80%: {:.1}%", results.recall() * 100.0);
println!(
" - False alarms < 50/100k: {:.1}/100k",
results.false_alarms_per_100k()
);
println!(
" - Median lead >= 2 cycles: {:.1} cycles",
results.median_lead_time()
);
} else {
println!();
println!(" ~ PARTIAL: Some criteria not met");
println!(
" - Recall: {:.1}% (target: >=80%)",
results.recall() * 100.0
);
println!(
" - False alarms: {:.1}/100k (target: <50)",
results.false_alarms_per_100k()
);
println!(
" - Median lead: {:.1} cycles (target: >=2)",
results.median_lead_time()
);
}
let elapsed = start_time.elapsed();
println!();
println!(" Total time: {:.2}s", elapsed.as_secs_f64());
println!(
" Throughput: {:.0} cycles/sec",
results.total_cycles as f64 / elapsed.as_secs_f64()
);
println!();
}
fn print_results(results: &EvalResults) {
println!();
println!("Failures observed: {}", results.failures_observed);
println!("Warnings issued: {}", results.warnings_issued);
println!("True warnings: {}", results.true_warnings);
println!("False warnings: {}", results.false_warnings);
println!();
println!("Lead time (cycles):");
println!(" median: {:.1}", results.median_lead_time());
println!(" p10: {:.1}", results.p10_lead_time());
println!(" p90: {:.1}", results.p90_lead_time());
println!();
println!("Precision: {:.2}", results.precision());
println!("Recall: {:.2}", results.recall());
println!(
"False alarms: {:.1} / 100k cycles",
results.false_alarms_per_100k()
);
}