use nalgebra::{DMatrix, DVector};
const D: usize = 256;
const V: usize = 64;
const SEEDS: u64 = 5;
const RHO: f64 = 0.3;
fn mix(x: u64, k: u64) -> u64 {
let mut h = x.wrapping_mul(0x9E37_79B9_7F4A_7C15) ^ k.wrapping_mul(0xC2B2_AE3D_27D4_EB4F);
h ^= h >> 29;
h = h.wrapping_mul(0xBF58_476D_1CE4_E5B9);
h ^= h >> 32;
h
}
fn g(seed: u64, a: u64) -> f64 {
let u1 = (mix(a, seed) % 1_000_000 + 1) as f64 / 1_000_001.0;
let u2 = (mix(a, seed ^ 0x5A) % 1_000_000) as f64 / 1_000_000.0;
(-2.0 * u1.ln()).sqrt() * (std::f64::consts::TAU * u2).cos()
}
#[allow(clippy::needless_range_loop)]
fn recall(m: usize, d_res: usize, d_base: usize) -> (f64, f64) {
let (mut ex, mut cue, mut tot) = (0i64, 0i64, 0i64);
for seed in 0..SEEDS {
let keys: Vec<Vec<f64>> = (0..m)
.map(|i| {
(0..D)
.map(|d| g(seed, (i as u64) << 20 | d as u64))
.collect()
})
.collect();
let truth: Vec<usize> = (0..m)
.map(|i| (mix(i as u64, seed ^ 0xC0) % V as u64) as usize)
.collect();
let obj: Vec<Vec<f64>> = (0..V)
.map(|o| {
(0..d_base)
.map(|d| g(seed ^ 0xB0, (o as u64) << 12 | d as u64))
.collect()
})
.collect();
let (mut x, mut s, mut c) = (DVector::<f64>::zeros(d_res.max(1)), 0.0, 0.0);
if d_res > 0 {
let mut a = DMatrix::<f64>::zeros(m, d_res);
for i in 0..m {
for d in 0..d_res {
a[(i, d)] = keys[i][d_base + d];
}
}
let v = DVector::from_iterator(m, truth.iter().map(|&t| t as f64));
let at = a.transpose();
let mut reg = &at * &a;
let md = reg.diagonal().mean();
for d in 0..d_res {
reg[(d, d)] += 1e-6 * md;
}
if let Some(sol) = reg.lu().solve(&(&at * &v)) {
x = sol;
let raw: Vec<f64> = (0..m).map(|i| a.row(i).dot(&x.transpose())).collect();
let mp = raw.iter().sum::<f64>() / m as f64;
let mt = v.mean();
let cov: f64 = raw
.iter()
.zip(&truth)
.map(|(&p, &t)| (p - mp) * (t as f64 - mt))
.sum();
let var: f64 = raw
.iter()
.map(|&p| (p - mp).powi(2))
.sum::<f64>()
.max(1e-12);
s = cov / var;
c = mt - s * mp;
}
}
let mut w = vec![vec![0.0f64; d_base]; d_base];
if d_base > 0 {
for i in 0..m {
for r in 0..d_base {
let orv = obj[truth[i]][r];
for cc in 0..d_base {
w[r][cc] += orv * keys[i][cc];
}
}
}
}
let read_coded = |kq: &[f64]| -> usize {
let dot: f64 = (0..d_res).map(|d| kq[d_base + d] * x[d]).sum();
(s * dot + c).round().clamp(0.0, (V - 1) as f64) as usize
};
let read_base = |kq: &[f64]| -> usize {
let y: Vec<f64> = (0..d_base)
.map(|r| (0..d_base).map(|cc| w[r][cc] * kq[cc]).sum())
.collect();
(0..V)
.max_by(|&a, &b| {
let sa: f64 = (0..d_base).map(|d| y[d] * obj[a][d]).sum();
let sb: f64 = (0..d_base).map(|d| y[d] * obj[b][d]).sum();
sa.partial_cmp(&sb).unwrap()
})
.unwrap()
};
for i in 0..m {
let ve = if d_res > 0 {
read_coded(&keys[i])
} else {
read_base(&keys[i])
};
ex += (ve == truth[i]) as i64;
let mut kq = keys[i].clone();
for d in 0..D {
if (mix(d as u64, seed ^ (i as u64) ^ 0xD0) as f64 / u64::MAX as f64) < RHO {
kq[d] = g(seed ^ 0x77, (i as u64) << 20 | d as u64);
}
}
let vc = if d_base > 0 {
read_base(&kq)
} else {
read_coded(&kq)
};
cue += (vc == truth[i]) as i64;
tot += 1;
}
}
(
100.0 * ex as f64 / tot as f64,
100.0 * cue as f64 / tot as f64,
)
}
fn main() {
let loads = [0.1f64, 0.3, 0.5, 0.75, 1.0];
println!(
"base-residual | D={D} V={V} seeds={SEEDS} rho={RHO} | recall %, chance={:.1}%",
100.0 / V as f64
);
println!("EXACT-key recall / partial-CUE recall for 3 matched-D stores.\n");
let stores: [(&str, usize, usize); 3] = [
("pure-coded", D, 0),
("pure-holographic", 0, D),
("fused(128+128)", 128, 128),
];
for &(name, dr, db) in &stores {
println!("== {name} (coded={dr} dims, base={db} dims) ==");
print!("{:>8}", "M/D");
for l in loads {
print!(" {:>9}", format!("{l:.2}"));
}
println!();
print!("{:>8}", "exact");
for &l in &loads {
print!(
" {:>8.0}%",
recall(((l * D as f64) as usize).max(1), dr, db).0
);
}
println!();
print!("{:>8}", "cue");
for &l in &loads {
print!(
" {:>8.0}%",
recall(((l * D as f64) as usize).max(1), dr, db).1
);
}
println!("\n");
}
println!("Fusion: pure-coded = exact✓ cue✗; pure-holo = exact-limited cue✓;");
println!("fused = exact✓ (to ~0.5·D via coded) AND cue✓ (via base) — both, at a split budget.");
}