use ndarray::{Array1, Array2};
fn lcg_uniform(s: &mut u64) -> f64 {
*s = s
.wrapping_mul(6364136223846793005)
.wrapping_add(1442695040888963407);
((*s >> 11) as f64) / ((1u64 << 53) as f64)
}
fn lcg_normal(s: &mut u64) -> f64 {
let u1 = lcg_uniform(s).max(1e-12);
let u2 = lcg_uniform(s);
(-2.0 * u1.ln()).sqrt() * (std::f64::consts::TAU * u2).cos()
}
fn solve_dense(a: &Array2<f64>, b: &Array1<f64>) -> Array1<f64> {
let n = a.nrows();
let mut m = a.clone();
let mut x = b.clone();
for col in 0..n {
let mut piv = col;
let mut best = m[[col, col]].abs();
for r in (col + 1)..n {
let v = m[[r, col]].abs();
if v > best {
best = v;
piv = r;
}
}
if piv != col {
for c in 0..n {
m.swap([col, c], [piv, c]);
}
x.swap(col, piv);
}
let d = m[[col, col]];
for r in (col + 1)..n {
let f = m[[r, col]] / d;
if f != 0.0 {
for c in col..n {
m[[r, c]] -= f * m[[col, c]];
}
x[r] -= f * x[col];
}
}
}
let mut y = Array1::<f64>::zeros(n);
for row in (0..n).rev() {
let mut acc = x[row];
for c in (row + 1)..n {
acc -= m[[row, c]] * y[c];
}
y[row] = acc / m[[row, row]];
}
y
}
fn coatom_precision_apply(c: &Array2<f64>, lambda: f64, v: &Array1<f64>) -> Array1<f64> {
let p = c.nrows();
let d = c.ncols();
let mut w = Array1::<f64>::zeros(d);
for k in 0..d {
let mut acc = 0.0;
for i in 0..p {
acc += c[[i, k]] * v[i];
}
w[k] = acc;
}
let mut cap = Array2::<f64>::zeros((d, d));
for a in 0..d {
for b in 0..d {
let mut acc = 0.0;
for i in 0..p {
acc += c[[i, a]] * c[[i, b]];
}
cap[[a, b]] = acc;
}
cap[[a, a]] += lambda;
}
let y = solve_dense(&cap, &w);
let mut out = Array1::<f64>::zeros(p);
for i in 0..p {
let mut cy = 0.0;
for k in 0..d {
cy += c[[i, k]] * y[k];
}
out[i] = (v[i] - cy) / lambda;
}
out
}
fn one_shot_angle<F: Fn(&Array1<f64>) -> Array1<f64>>(
frame: &Array2<f64>,
x: &Array1<f64>,
apply: &F,
) -> f64 {
let p = frame.nrows();
let col0: Array1<f64> = frame.column(0).to_owned();
let col1: Array1<f64> = frame.column(1).to_owned();
let mb0 = apply(&col0);
let mb1 = apply(&col1);
let mx = apply(x);
let dot =
|u: &Array1<f64>, w: &Array1<f64>| -> f64 { (0..p).map(|i| u[i] * w[i]).sum::<f64>() };
let mut g = Array2::<f64>::zeros((2, 2));
g[[0, 0]] = dot(&col0, &mb0);
g[[0, 1]] = dot(&col0, &mb1);
g[[1, 0]] = dot(&col1, &mb0);
g[[1, 1]] = dot(&col1, &mb1);
let h = Array1::from_vec(vec![dot(&col0, &mx), dot(&col1, &mx)]);
let z = solve_dense(&g, &h);
z[1].atan2(z[0])
}
fn wrap_pi(a: f64) -> f64 {
let two_pi = std::f64::consts::TAU;
let mut x = a.rem_euclid(two_pi);
if x > std::f64::consts::PI {
x -= two_pi;
}
x
}
fn gauge_aligned_circular_rmse(est: &[f64], truth: &[f64]) -> f64 {
let mut best = f64::INFINITY;
for &sign in &[1.0_f64, -1.0] {
let (mut cs, mut sn) = (0.0, 0.0);
for i in 0..est.len() {
let r = est[i] - sign * truth[i];
cs += r.cos();
sn += r.sin();
}
let phase = sn.atan2(cs);
let mut sse = 0.0;
for i in 0..est.len() {
let e = wrap_pi(est[i] - sign * truth[i] - phase);
sse += e * e;
}
let rmse = (sse / est.len() as f64).sqrt();
if rmse < best {
best = rmse;
}
}
best
}
#[test]
fn coatom_precision_read_is_coherence_independent_2021() {
let p = 48usize;
let n = 320usize;
let sigma2 = 1.0_f64; let lambda = 0.03_f64 * 0.03; let noise = 0.03_f64;
let unit = |dirs: &[(usize, f64)]| -> Array1<f64> {
let mut v = Array1::<f64>::zeros(p);
for &(i, w) in dirs {
v[i] = w;
}
v
};
let a0 = unit(&[(0, 1.0)]);
let a1 = unit(&[(1, 1.0)]);
let mut b_a = Array2::<f64>::zeros((p, 2));
b_a.column_mut(0).assign(&a0);
b_a.column_mut(1).assign(&a1);
let mus = [0.0_f64, 0.5, 0.8, 0.95];
let mut whitened_err = Vec::new();
let mut naive_err = Vec::new();
for &mu in &mus {
let b0 = unit(&[(0, mu), (2, (1.0 - mu * mu).sqrt())]);
let b1 = unit(&[(3, 1.0)]);
let mut b_b = Array2::<f64>::zeros((p, 2));
b_b.column_mut(0).assign(&b0);
b_b.column_mut(1).assign(&b1);
let c = b_a.mapv(|v| v * (sigma2 * 1.0).sqrt());
let whitened_apply = |v: &Array1<f64>| coatom_precision_apply(&c, lambda, v);
let naive_apply = |v: &Array1<f64>| v.clone();
let mut seed = 0x2021_C0A7_5164_0000u64 ^ ((mu * 1e6) as u64);
let (mut est_w, mut est_n, mut truth) = (Vec::new(), Vec::new(), Vec::new());
for _ in 0..n {
let th_a = std::f64::consts::TAU * lcg_uniform(&mut seed);
let th_b = std::f64::consts::TAU * lcg_uniform(&mut seed);
let mut x = Array1::<f64>::zeros(p);
for i in 0..p {
x[i] = th_a.cos() * a0[i]
+ th_a.sin() * a1[i]
+ th_b.cos() * b0[i]
+ th_b.sin() * b1[i]
+ noise * lcg_normal(&mut seed);
}
est_w.push(one_shot_angle(&b_b, &x, &whitened_apply));
est_n.push(one_shot_angle(&b_b, &x, &naive_apply));
truth.push(th_b);
}
whitened_err.push(gauge_aligned_circular_rmse(&est_w, &truth));
naive_err.push(gauge_aligned_circular_rmse(&est_n, &truth));
}
let report = format!(
"μ={:?}\n whitened circ-rmse = {:?}\n naive circ-rmse = {:?}",
mus, whitened_err, naive_err
);
eprintln!("COATOM_REPORT\n{report}");
let w_hi = *whitened_err.last().unwrap();
let w_lo = whitened_err[0];
assert!(
w_hi < 0.15,
"KILL SIGNAL: co-atom Σ⁻¹ read is NOT coherence-independent at μ=0.95 \
(circ-rmse {w_hi:.3} rad ≥ 0.15) — the co-atom-Σ form fails to de-tangle.\n{report}"
);
assert!(
(w_hi - w_lo).abs() < 0.12,
"KILL SIGNAL: whitened error is not FLAT across coherence \
(Δ={:.3} from μ=0 to μ=0.95) — de-tangling is coherence-dependent.\n{report}",
(w_hi - w_lo).abs()
);
let n_hi = *naive_err.last().unwrap();
assert!(
n_hi > 0.3,
"fixture sanity: the NAIVE read must degrade under overlap (μ=0.95 \
circ-rmse {n_hi:.3} rad ≤ 0.3), else the test cannot demonstrate de-tangling.\n{report}"
);
assert!(
w_hi < n_hi * 0.5,
"at μ=0.95 the whitened read ({w_hi:.3}) must be far better than naive \
({n_hi:.3}) — the (BᵀΣ⁻¹B)⁻¹ normalization un-clips the attenuated direction.\n{report}"
);
}