use faer::Side;
use gam_linalg::faer_ndarray::FaerEigh;
use ndarray::{Array1, Array2, ArrayView2};
const ISA_SUBSAMPLE_FLOOR: usize = 500;
const ISA_ANGLE_SAMPLES: usize = 64;
const ISA_SWEEP_RTOL: f64 = 1.0e-12;
#[derive(Clone, Copy, Debug)]
pub struct IsaSeedConfig {
pub n_inits: usize,
pub max_sweeps: usize,
}
impl Default for IsaSeedConfig {
fn default() -> Self {
Self {
n_inits: 6,
max_sweeps: 64,
}
}
}
pub struct IsaEigenParts {
pub mean: Array1<f64>,
pub evals: Array1<f64>,
pub evecs: Array2<f64>,
pub above: Vec<usize>,
pub mp_edge: f64,
pub sigma2_cert: f64,
}
pub fn isa_eigen_parts(residual: ArrayView2<'_, f64>) -> Result<Option<IsaEigenParts>, String> {
let (n, p) = residual.dim();
if n < 2 || p == 0 {
return Ok(None);
}
let mut mean = Array1::<f64>::zeros(p);
for row in 0..n {
for j in 0..p {
mean[j] += residual[[row, j]];
}
}
mean.mapv_inplace(|v| v / n as f64);
let mut s = Array2::<f64>::zeros((p, p));
for row in 0..n {
for a in 0..p {
let ra = residual[[row, a]] - mean[a];
for b in a..p {
s[[a, b]] += ra * (residual[[row, b]] - mean[b]);
}
}
}
for a in 0..p {
for b in a..p {
let v = s[[a, b]] / n as f64;
s[[a, b]] = v;
s[[b, a]] = v;
}
}
let (evals, evecs) = s
.eigh(Side::Lower)
.map_err(|err| format!("isa_eigen_parts: residual eigensolve failed: {err:?}"))?;
if evals.is_empty() {
return Ok(None);
}
let mut ascending: Vec<f64> = evals.iter().copied().collect();
ascending.sort_by(|a, b| a.total_cmp(b));
let mid = ascending.len() / 2;
let sigma2 = if ascending.len() % 2 == 1 {
ascending[mid]
} else {
0.5 * (ascending[mid - 1] + ascending[mid])
}
.max(f64::MIN_POSITIVE);
let gamma = p as f64 / n as f64;
let mp_edge = sigma2 * (1.0 + gamma.sqrt()).powi(2);
let mut above: Vec<usize> = (0..evals.len()).filter(|&k| evals[k] > mp_edge).collect();
above.sort_by(|&a, &b| evals[b].total_cmp(&evals[a]));
if above.is_empty() {
return Ok(None);
}
let q = (evals.len() / 4).max(1);
let sigma2_cert = evals[(q - 1) / 2].max(0.0);
Ok(Some(IsaEigenParts {
mean,
evals,
evecs,
above,
mp_edge,
sigma2_cert,
}))
}
pub struct IsaPlaneCandidate {
pub basis: Array2<f64>,
pub amplitudes: [f64; 2],
pub phases_turns: Array2<f64>,
pub gate_logits: Vec<f64>,
pub kappa: f64,
pub q_hat: f64,
}
fn lcg_normal(state: &mut u64) -> f64 {
let mut u = [0.0_f64; 2];
for slot in u.iter_mut() {
*state = state
.wrapping_mul(6364136223846793005)
.wrapping_add(1442695040888963407);
*slot = ((*state >> 11) as f64) / ((1u64 << 53) as f64);
}
let u1 = u[0].max(f64::MIN_POSITIVE);
(-2.0 * u1.ln()).sqrt() * (std::f64::consts::TAU * u[1]).cos()
}
pub(crate) fn orthonormalize2(w: &mut Array2<f64>) -> bool {
let d = w.nrows();
let n0: f64 = (0..d).map(|i| w[[i, 0]] * w[[i, 0]]).sum::<f64>().sqrt();
if !(n0 > 1e-12) {
return false;
}
for i in 0..d {
w[[i, 0]] /= n0;
}
let dot: f64 = (0..d).map(|i| w[[i, 0]] * w[[i, 1]]).sum();
for i in 0..d {
w[[i, 1]] -= dot * w[[i, 0]];
}
let n1: f64 = (0..d).map(|i| w[[i, 1]] * w[[i, 1]]).sum::<f64>().sqrt();
if !(n1 > 1e-12) {
return false;
}
for i in 0..d {
w[[i, 1]] /= n1;
}
true
}
#[derive(Clone, Copy)]
struct PlanePolys {
d: [f64; 3],
n: [f64; 5],
}
impl PlanePolys {
fn kappa(&self, c2: f64, s2: f64, c4: f64, s4: f64) -> f64 {
let den = self.d[0] + self.d[1] * c2 + self.d[2] * s2;
if !(den > 0.0) {
return f64::INFINITY;
}
let num =
self.n[0] + self.n[1] * c2 + self.n[2] * s2 + self.n[3] * c4 + self.n[4] * s4;
num / (den * den)
}
fn dkappa(&self, c2: f64, s2: f64, c4: f64, s4: f64) -> f64 {
let den = self.d[0] + self.d[1] * c2 + self.d[2] * s2;
if !(den > 0.0) {
return 0.0;
}
let num =
self.n[0] + self.n[1] * c2 + self.n[2] * s2 + self.n[3] * c4 + self.n[4] * s4;
let dden = -2.0 * self.d[1] * s2 + 2.0 * self.d[2] * c2;
let dnum = -2.0 * self.n[1] * s2 + 2.0 * self.n[2] * c2 - 4.0 * self.n[3] * s4
+ 4.0 * self.n[4] * c4;
(dnum * den - 2.0 * num * dden) / (den * den * den)
}
}
fn pair_polys(
y: &Array2<f64>,
i: usize,
j: usize,
partner_i: Option<usize>,
partner_j: Option<usize>,
) -> (Option<PlanePolys>, Option<PlanePolys>) {
let n = y.ncols();
let inv_n = 1.0 / n as f64;
let (mut m20, mut m11, mut m02) = (0.0_f64, 0.0_f64, 0.0_f64);
let (mut m40, mut m31, mut m22, mut m13, mut m04) = (0.0_f64, 0.0, 0.0, 0.0, 0.0);
let (mut a2, mut a4, mut awi, mut awx, mut awj) = (0.0_f64, 0.0, 0.0, 0.0, 0.0);
let (mut b2, mut b4, mut bwi, mut bwx, mut bwj) = (0.0_f64, 0.0, 0.0, 0.0, 0.0);
for col in 0..n {
let yi = y[[i, col]];
let yj = y[[j, col]];
let (yi2, yj2, yij) = (yi * yi, yj * yj, yi * yj);
m20 += yi2;
m11 += yij;
m02 += yj2;
m40 += yi2 * yi2;
m31 += yi2 * yij;
m22 += yi2 * yj2;
m13 += yij * yj2;
m04 += yj2 * yj2;
if let Some(pi) = partner_i {
let w2 = y[[pi, col]] * y[[pi, col]];
a2 += w2;
a4 += w2 * w2;
awi += w2 * yi2;
awx += w2 * yij;
awj += w2 * yj2;
}
if let Some(pj) = partner_j {
let w2 = y[[pj, col]] * y[[pj, col]];
b2 += w2;
b4 += w2 * w2;
bwi += w2 * yi2;
bwx += w2 * yij;
bwj += w2 * yj2;
}
}
for v in [
&mut m20, &mut m11, &mut m02, &mut m40, &mut m31, &mut m22, &mut m13, &mut m04, &mut a2,
&mut a4, &mut awi, &mut awx, &mut awj, &mut b2, &mut b4, &mut bwi, &mut bwx, &mut bwj,
] {
*v *= inv_n;
}
let euu = (m40 + 2.0 * m22 + m04) / 4.0;
let evv = (m40 - 2.0 * m22 + m04) / 4.0;
let eww = m22;
let euv = (m40 - m04) / 4.0;
let euw = (m31 + m13) / 2.0;
let evw = (m31 - m13) / 2.0;
let h0 = (m20 + m02) / 2.0;
let h1 = (m20 - m02) / 2.0;
let h2 = m11;
let quart_dc = euu + (evv + eww) / 2.0;
let quart_c4 = (evv - eww) / 2.0;
let plane_a = partner_i.map(|_| {
let g0 = (awi + awj) / 2.0;
let g1 = (awi - awj) / 2.0;
PlanePolys {
d: [a2 + h0, h1, -h2],
n: [
a4 + 2.0 * g0 + quart_dc,
2.0 * g1 + 2.0 * euv,
-2.0 * awx - 2.0 * euw,
quart_c4,
-evw,
],
}
});
let plane_b = partner_j.map(|_| {
let g0 = (bwi + bwj) / 2.0;
let g1 = (bwi - bwj) / 2.0;
PlanePolys {
d: [b2 + h0, -h1, h2],
n: [
b4 + 2.0 * g0 + quart_dc,
-2.0 * g1 - 2.0 * euv,
2.0 * bwx + 2.0 * euw,
quart_c4,
-evw,
],
}
});
(plane_a, plane_b)
}
fn pair_objective(a: &Option<PlanePolys>, b: &Option<PlanePolys>, theta: f64) -> f64 {
let (c2, s2) = ((2.0 * theta).cos(), (2.0 * theta).sin());
let (c4, s4) = ((4.0 * theta).cos(), (4.0 * theta).sin());
let mut j = 0.0;
for side in [a, b].into_iter().flatten() {
let k = side.kappa(c2, s2, c4, s4);
if k.is_finite() {
j += (k - 2.0) * (k - 2.0);
}
}
j
}
fn pair_objective_deriv(a: &Option<PlanePolys>, b: &Option<PlanePolys>, theta: f64) -> f64 {
let (c2, s2) = ((2.0 * theta).cos(), (2.0 * theta).sin());
let (c4, s4) = ((4.0 * theta).cos(), (4.0 * theta).sin());
let mut dj = 0.0;
for side in [a, b].into_iter().flatten() {
let k = side.kappa(c2, s2, c4, s4);
if k.is_finite() {
dj += 2.0 * (k - 2.0) * side.dkappa(c2, s2, c4, s4);
}
}
dj
}
fn best_pair_rotation(a: &Option<PlanePolys>, b: &Option<PlanePolys>) -> (f64, f64) {
let step = std::f64::consts::PI / ISA_ANGLE_SAMPLES as f64;
let mut samples: Vec<(f64, f64, f64)> = Vec::with_capacity(ISA_ANGLE_SAMPLES + 1);
for k in 0..=ISA_ANGLE_SAMPLES {
let theta = -std::f64::consts::FRAC_PI_2 + step * k as f64;
samples.push((
theta,
pair_objective(a, b, theta),
pair_objective_deriv(a, b, theta),
));
}
let mut best_theta = 0.0_f64;
let mut best_j = pair_objective(a, b, 0.0);
for &(theta, jv, _) in &samples {
if jv > best_j {
best_j = jv;
best_theta = theta;
}
}
for k in 0..ISA_ANGLE_SAMPLES {
let (mut lo, _, dlo) = samples[k];
let (mut hi, _, dhi) = samples[k + 1];
if !(dlo.is_finite() && dhi.is_finite()) {
continue;
}
if dlo == 0.0 {
let jv = pair_objective(a, b, lo);
if jv > best_j {
best_j = jv;
best_theta = lo;
}
continue;
}
if dhi == 0.0 {
let jv = pair_objective(a, b, hi);
if jv > best_j {
best_j = jv;
best_theta = hi;
}
continue;
}
if dlo.signum() == dhi.signum() {
continue;
}
let mut dlo_cur = dlo;
for _ in 0..60 {
let mid = 0.5 * (lo + hi);
let dmid = pair_objective_deriv(a, b, mid);
if dmid == 0.0 {
lo = mid;
hi = mid;
break;
}
if dmid.signum() == dlo_cur.signum() {
lo = mid;
dlo_cur = dmid;
} else {
hi = mid;
}
}
let theta = 0.5 * (lo + hi);
let jv = pair_objective(a, b, theta);
if jv > best_j {
best_j = jv;
best_theta = theta;
}
}
(best_theta, best_j)
}
fn plane_rows_kappa(y: &Array2<f64>, m: usize) -> f64 {
let n = y.ncols();
let (mut s2, mut s4) = (0.0_f64, 0.0_f64);
for col in 0..n {
let y0 = y[[2 * m, col]];
let y1 = y[[2 * m + 1, col]];
let r2 = y0 * y0 + y1 * y1;
s2 += r2;
s4 += r2 * r2;
}
let m2 = s2 / n as f64;
if !(m2 > 0.0) {
return f64::INFINITY;
}
(s4 / n as f64) / (m2 * m2)
}
fn total_contrast(y: &Array2<f64>, n_planes: usize) -> f64 {
(0..n_planes)
.map(|m| {
let k = plane_rows_kappa(y, m);
if k.is_finite() { (k - 2.0) * (k - 2.0) } else { 0.0 }
})
.sum()
}
fn jacobi_optimize(y: &mut Array2<f64>, q: &mut Array2<f64>, n_planes: usize, max_sweeps: usize) {
let r = y.nrows();
let partner = |c: usize| -> Option<usize> {
if c < 2 * n_planes {
Some(c ^ 1)
} else {
None
}
};
let mut total = total_contrast(y, n_planes);
for _ in 0..max_sweeps {
let mut improved = false;
for i in 0..r {
for j in (i + 1)..r {
if partner(i) == Some(j) {
continue;
}
let (pa, pb) = pair_polys(y, i, j, partner(i), partner(j));
if pa.is_none() && pb.is_none() {
continue;
}
let j0 = pair_objective(&pa, &pb, 0.0);
let (best_theta, best_j) = best_pair_rotation(&pa, &pb);
if best_j > j0 * (1.0 + ISA_SWEEP_RTOL) + f64::MIN_POSITIVE {
let (c, s) = (best_theta.cos(), best_theta.sin());
for col in 0..y.ncols() {
let yi = y[[i, col]];
let yj = y[[j, col]];
y[[i, col]] = c * yi - s * yj;
y[[j, col]] = s * yi + c * yj;
}
for row in 0..q.nrows() {
let qi = q[[row, i]];
let qj = q[[row, j]];
q[[row, i]] = c * qi - s * qj;
q[[row, j]] = s * qi + c * qj;
}
improved = true;
}
}
}
let new_total = total_contrast(y, n_planes);
if !improved || new_total - total <= ISA_SWEEP_RTOL * (1.0 + total.abs()) {
break;
}
total = new_total;
}
}
fn subsample_columns(n: usize) -> Vec<usize> {
if n <= ISA_SUBSAMPLE_FLOOR {
return (0..n).collect();
}
(0..ISA_SUBSAMPLE_FLOOR)
.map(|i| i * n / ISA_SUBSAMPLE_FLOOR)
.collect()
}
fn whitened_subsample(
residual: ArrayView2<'_, f64>,
parts: &IsaEigenParts,
) -> Option<Array2<f64>> {
let n = residual.nrows();
let r = parts.above.len();
if r < 2 || n < 2 {
return None;
}
let cols = subsample_columns(n);
let mut z = Array2::<f64>::zeros((r, cols.len()));
for (a, &k) in parts.above.iter().enumerate() {
let inv = 1.0 / parts.evals[k].max(f64::MIN_POSITIVE).sqrt();
for (cc, &row) in cols.iter().enumerate() {
let mut proj = 0.0_f64;
for j in 0..residual.ncols() {
proj += (residual[[row, j]] - parts.mean[j]) * parts.evecs[[j, k]];
}
z[[a, cc]] = proj * inv;
}
}
Some(z)
}
fn joint_jacobi_basis(
residual: ArrayView2<'_, f64>,
parts: &IsaEigenParts,
config: &IsaSeedConfig,
) -> Option<(Array2<f64>, Array2<f64>)> {
let z = whitened_subsample(residual, parts)?;
let r = z.nrows();
let n_planes = r / 2;
let mut best: Option<(f64, Array2<f64>, Array2<f64>)> = None;
let n_inits = if n_planes == 1 {
1
} else {
config.n_inits.max(1)
};
for init in 0..n_inits {
let mut q = Array2::<f64>::eye(r);
if init > 0 {
let mut state = 0x2111_15A0_u64 ^ ((init as u64) << 32) ^ residual.nrows() as u64;
let mut g = Array2::<f64>::from_shape_fn((r, r), |_| lcg_normal(&mut state));
for c in 0..r {
for prev in 0..c {
let mut dot = 0.0;
for row in 0..r {
dot += g[[row, c]] * g[[row, prev]];
}
for row in 0..r {
let sub = dot * g[[row, prev]];
g[[row, c]] -= sub;
}
}
let mut nrm = 0.0;
for row in 0..r {
nrm += g[[row, c]] * g[[row, c]];
}
let nrm = nrm.sqrt();
if nrm > 1e-12 {
for row in 0..r {
g[[row, c]] /= nrm;
}
} else {
for row in 0..r {
g[[row, c]] = if row == c { 1.0 } else { 0.0 };
}
}
}
q = g;
}
let mut y = q.t().dot(&z);
jacobi_optimize(&mut y, &mut q, n_planes, config.max_sweeps);
let contrast = total_contrast(&y, n_planes);
if best.as_ref().is_none_or(|(bc, _, _)| contrast > *bc) {
best = Some((contrast, q, y));
}
}
best.map(|(_, q, y)| (q, y))
}
pub(crate) fn capture_signal_span(
residual: ArrayView2<'_, f64>,
max_planes: usize,
) -> Result<Option<IsaEigenParts>, String> {
if max_planes == 0 {
return Ok(None);
}
let max_dims = 2 * max_planes;
let Some(mut parts) = isa_eigen_parts(residual)? else {
return Ok(None);
};
let mut keep = parts.above.len().min(max_dims);
if keep % 2 == 1 {
keep -= 1;
}
if keep < 2 {
return Ok(None);
}
parts.above.truncate(keep);
Ok(Some(parts))
}
fn certify_plane(
residual: ArrayView2<'_, f64>,
parts: &IsaEigenParts,
w: &Array2<f64>,
) -> Option<IsaPlaneCandidate> {
let (n, p) = residual.dim();
let r = parts.above.len();
let mut amb = Array2::<f64>::zeros((p, 2));
for (a, &k) in parts.above.iter().enumerate().take(r) {
let scale = parts.evals[k].max(f64::MIN_POSITIVE).sqrt();
for j in 0..p {
amb[[j, 0]] += parts.evecs[[j, k]] * scale * w[[a, 0]];
amb[[j, 1]] += parts.evecs[[j, k]] * scale * w[[a, 1]];
}
}
if !orthonormalize2(&mut amb) {
return None;
}
let noise_2plane = 2.0 * parts.sigma2_cert.max(f64::MIN_POSITIVE) * (n as f64).ln();
let mut phases = Array2::<f64>::zeros((n, 1));
let mut gate = vec![f64::NEG_INFINITY; n];
let (mut r2_sum, mut r4_sum) = (0.0_f64, 0.0_f64);
let (mut c_num, mut c_den, mut s_num, mut s_den) = (0.0_f64, 0.0, 0.0, 0.0);
let mut n_active = 0usize;
for i in 0..n {
let (mut p1, mut p2) = (0.0_f64, 0.0_f64);
for j in 0..p {
let ri = residual[[i, j]] - parts.mean[j];
p1 += ri * amb[[j, 0]];
p2 += ri * amb[[j, 1]];
}
let theta = p2.atan2(p1);
phases[[i, 0]] = theta.rem_euclid(std::f64::consts::TAU) / std::f64::consts::TAU;
let r2 = p1 * p1 + p2 * p2;
r2_sum += r2;
r4_sum += r2 * r2;
if r2 > noise_2plane {
gate[i] = (r2 / noise_2plane).ln();
n_active += 1;
let (ct, st) = (theta.cos(), theta.sin());
c_num += p1 * ct;
c_den += ct * ct;
s_num += p2 * st;
s_den += st * st;
}
}
if n_active == 0 {
return None;
}
let active_floor = ((n as f64).ln().powi(2).ceil() as usize).max(4);
if n_active < active_floor {
return None;
}
let q_hat = n_active as f64 / n as f64;
let m2 = (r2_sum / n as f64).max(f64::MIN_POSITIVE);
let kappa_obs = (r4_sum / n as f64) / (m2 * m2);
let sig2 = parts.sigma2_cert;
let a2t = ((m2 - 2.0 * sig2) / q_hat).max(0.0);
let common = 8.0 * q_hat * a2t * sig2 + 8.0 * sig2 * sig2;
let kappa_model = (q_hat * a2t * a2t + common) / (m2 * m2);
let kappa_blend = (1.25 * q_hat * a2t * a2t + common) / (m2 * m2);
if !(kappa_model < kappa_blend) {
return None; }
let gate_mid = 0.5 * (kappa_model + kappa_blend);
if !(kappa_obs < gate_mid) {
return None; }
let a1 = if c_den > 0.0 { c_num / c_den } else { 0.0 };
let a2 = if s_den > 0.0 { s_num / s_den } else { 0.0 };
if !(a1.is_finite() && a2.is_finite()) {
return None;
}
Some(IsaPlaneCandidate {
basis: amb,
amplitudes: [a1, a2],
phases_turns: phases,
gate_logits: gate,
kappa: kappa_obs,
q_hat,
})
}
pub fn isa_extract_certified_planes(
residual: ArrayView2<'_, f64>,
parts: &IsaEigenParts,
max_planes: usize,
config: &IsaSeedConfig,
) -> Vec<IsaPlaneCandidate> {
let r = parts.above.len();
if r < 2 || max_planes == 0 {
return Vec::new();
}
let n_planes = r / 2;
let Some((q, y)) = joint_jacobi_basis(residual, parts, config) else {
return Vec::new();
};
let mut order: Vec<(f64, usize)> = (0..n_planes)
.map(|m| {
let k = plane_rows_kappa(&y, m);
let c = if k.is_finite() { (k - 2.0) * (k - 2.0) } else { 0.0 };
(c, m)
})
.collect();
order.sort_by(|a, b| b.0.total_cmp(&a.0));
let mut out = Vec::new();
for (contrast, m) in order {
if !(contrast > 0.0) {
continue;
}
let mut w = Array2::<f64>::zeros((r, 2));
for row in 0..r {
w[[row, 0]] = q[[row, 2 * m]];
w[[row, 1]] = q[[row, 2 * m + 1]];
}
if let Some(cand) = certify_plane(residual, parts, &w) {
out.push(cand);
if out.len() >= max_planes {
break;
}
}
}
out
}
pub fn isa_extract_certified_plane(
residual: ArrayView2<'_, f64>,
parts: &IsaEigenParts,
config: &IsaSeedConfig,
) -> Option<IsaPlaneCandidate> {
isa_extract_certified_planes(residual, parts, 1, config)
.into_iter()
.next()
}
pub fn isa_deflate_fitted_curve(residual: &mut Array2<f64>, cand: &IsaPlaneCandidate) {
let (n, p) = residual.dim();
let mut mean = Array1::<f64>::zeros(p);
for i in 0..n {
for j in 0..p {
mean[j] += residual[[i, j]];
}
}
mean.mapv_inplace(|v| v / n as f64);
for i in 0..n {
if !cand.gate_logits[i].is_finite() {
continue;
}
let (mut p1, mut p2) = (0.0_f64, 0.0_f64);
for j in 0..p {
let ri = residual[[i, j]] - mean[j];
p1 += ri * cand.basis[[j, 0]];
p2 += ri * cand.basis[[j, 1]];
}
for j in 0..p {
residual[[i, j]] -= p1 * cand.basis[[j, 0]] + p2 * cand.basis[[j, 1]];
}
}
if cand.gate_logits.iter().all(|g| g.is_finite()) {
mean.fill(0.0);
for i in 0..n {
for j in 0..p {
mean[j] += residual[[i, j]];
}
}
mean.mapv_inplace(|v| v / n as f64);
for i in 0..n {
let (mut p1, mut p2) = (0.0_f64, 0.0_f64);
for j in 0..p {
let ri = residual[[i, j]] - mean[j];
p1 += ri * cand.basis[[j, 0]];
p2 += ri * cand.basis[[j, 1]];
}
for j in 0..p {
residual[[i, j]] -= p1 * cand.basis[[j, 0]] + p2 * cand.basis[[j, 1]];
}
}
}
}
pub struct IsaHarvest {
pub planes: Vec<IsaPlaneCandidate>,
pub natural_exit: bool,
}
pub fn isa_deflationary_producer(
residual: ArrayView2<'_, f64>,
max_planes: usize,
config: &IsaSeedConfig,
) -> Result<IsaHarvest, String> {
let Some(parts) = capture_signal_span(residual, max_planes)? else {
return Ok(IsaHarvest {
planes: Vec::new(),
natural_exit: true,
});
};
let planes = isa_extract_certified_planes(residual, &parts, max_planes, config);
let natural_exit = planes.len() < max_planes;
Ok(IsaHarvest {
planes,
natural_exit,
})
}
#[cfg(test)]
mod tests {
use super::*;
fn lcg_uniform(state: &mut u64) -> f64 {
*state = state
.wrapping_mul(6364136223846793005)
.wrapping_add(1442695040888963407);
((*state >> 11) as f64) / ((1u64 << 53) as f64)
}
fn planted_circles(
n: usize,
p: usize,
k: usize,
q: f64,
amps: &[f64],
sigma: f64,
seed: u64,
) -> (Array2<f64>, Vec<Array2<f64>>) {
assert!(p >= 2 * k && amps.len() == k);
let mut state = seed;
let mut frame = Array2::<f64>::from_shape_fn((p, 2 * k), |_| lcg_normal(&mut state));
for c in 0..2 * k {
for prev in 0..c {
let mut dot = 0.0;
for row in 0..p {
dot += frame[[row, c]] * frame[[row, prev]];
}
for row in 0..p {
let sub = dot * frame[[row, prev]];
frame[[row, c]] -= sub;
}
}
let mut nrm = 0.0;
for row in 0..p {
nrm += frame[[row, c]] * frame[[row, c]];
}
let nrm = nrm.sqrt();
for row in 0..p {
frame[[row, c]] /= nrm;
}
}
let mut data = Array2::<f64>::zeros((n, p));
for i in 0..n {
for c in 0..k {
if lcg_uniform(&mut state) >= q {
continue;
}
let th = std::f64::consts::TAU * lcg_uniform(&mut state);
for j in 0..p {
data[[i, j]] +=
amps[c] * (th.cos() * frame[[j, 2 * c]] + th.sin() * frame[[j, 2 * c + 1]]);
}
}
for j in 0..p {
data[[i, j]] += sigma * lcg_normal(&mut state);
}
}
let true_planes: Vec<Array2<f64>> = (0..k)
.map(|c| {
Array2::from_shape_fn((p, 2), |(row, col)| frame[[row, 2 * c + col]])
})
.collect();
(data, true_planes)
}
fn plane_overlap(u: &Array2<f64>, v: &Array2<f64>) -> f64 {
let m = u.t().dot(v);
m.iter().map(|x| x * x).sum::<f64>() / 2.0
}
fn producer_gate(
data: &Array2<f64>,
true_planes: &[Array2<f64>],
max_planes: usize,
) -> (usize, usize, usize, usize, bool) {
let harvest = isa_deflationary_producer(data.view(), max_planes, &IsaSeedConfig::default())
.expect("producer must run");
let mut claimed = std::collections::HashSet::new();
let (mut n_real, mut n_clean) = (0usize, 0usize);
for cand in &harvest.planes {
let mut overlaps: Vec<(f64, usize)> = true_planes
.iter()
.enumerate()
.map(|(idx, tp)| (plane_overlap(&cand.basis, tp), idx))
.collect();
overlaps.sort_by(|a, b| b.0.total_cmp(&a.0));
claimed.insert(overlaps[0].1);
if overlaps[0].0 >= 0.9 {
n_real += 1;
if overlaps.len() < 2 || overlaps[1].0 <= 0.2 {
n_clean += 1;
}
}
}
(
claimed.len(),
n_real,
n_clean,
harvest.planes.len(),
harvest.natural_exit,
)
}
#[test]
fn isa_producer_gate_dense_torus_equal_amplitude() {
let k = 6usize;
let amps = vec![1.0_f64; k];
let (data, truth) = planted_circles(2000, 32, k, 1.0, &s, 0.05, 0x2111_D07A_u64);
let (n_distinct, n_real, n_clean, n_planes, natural_exit) =
producer_gate(&data, &truth, 2 * k);
assert!(
n_distinct == k && n_real == k && n_clean == k && n_planes == k && natural_exit,
"dense equal-amplitude torus gate: n_distinct={n_distinct} n_real={n_real} \
n_clean={n_clean} planes={n_planes} natural_exit={natural_exit} (want 6/6/6, \
6 planes, natural exit)"
);
}
#[test]
fn isa_producer_gate_sparse_gated() {
let k = 6usize;
let amps: Vec<f64> = (0..k).map(|c| 1.0 + 0.1 * c as f64).collect();
let (data, truth) = planted_circles(2000, 32, k, 0.25, &s, 0.05, 0x2111_6A7E_u64);
let (n_distinct, n_real, n_clean, n_planes, natural_exit) =
producer_gate(&data, &truth, 2 * k);
assert!(
n_distinct == k && n_real == k && n_clean == k && n_planes == k && natural_exit,
"sparse gated gate: n_distinct={n_distinct} n_real={n_real} n_clean={n_clean} \
planes={n_planes} natural_exit={natural_exit} (want 6/6/6, 6 planes, natural exit)"
);
}
fn best_truth_overlaps(planes: &[Array2<f64>], truth: &[Array2<f64>]) -> Vec<f64> {
let mut per_truth = vec![0.0_f64; truth.len()];
for plane in planes {
for (idx, tp) in truth.iter().enumerate() {
per_truth[idx] = per_truth[idx].max(plane_overlap(plane, tp));
}
}
per_truth
}
fn candidate_overlaps(
planes: &[IsaPlaneCandidate],
truth: &[Array2<f64>],
) -> Vec<f64> {
let bases: Vec<Array2<f64>> = planes.iter().map(|cand| cand.basis.clone()).collect();
best_truth_overlaps(&bases, truth)
}
fn ambient_plane_from_captured_parts(parts: &IsaEigenParts, q: &Array2<f64>, m: usize) -> Array2<f64> {
let p = parts.evecs.nrows();
let r = parts.above.len();
let mut amb = Array2::<f64>::zeros((p, 2));
for (a, &k) in parts.above.iter().enumerate().take(r) {
let scale = parts.evals[k].max(f64::MIN_POSITIVE).sqrt();
for j in 0..p {
amb[[j, 0]] += parts.evecs[[j, k]] * scale * q[[a, 2 * m]];
amb[[j, 1]] += parts.evecs[[j, k]] * scale * q[[a, 2 * m + 1]];
}
}
assert!(orthonormalize2(&mut amb), "captured joint plane must have rank 2");
amb
}
fn greedy_deflation_probe(
data: &Array2<f64>,
max_planes: usize,
config: &IsaSeedConfig,
) -> Vec<IsaPlaneCandidate> {
let mut work = data.clone();
let mut planes = Vec::new();
while planes.len() < max_planes {
let Some(parts) = isa_eigen_parts(work.view()).expect("greedy probe eigensolve") else {
break;
};
let Some(cand) = isa_extract_certified_plane(work.view(), &parts, config) else {
break;
};
isa_deflate_fitted_curve(&mut work, &cand);
planes.push(cand);
}
planes
}
#[test]
fn isa_joint_rotation_recovers_unequal_gated_circles_where_greedy_collapses() {
let k = 6usize;
let amps = vec![1.00, 0.86, 0.73, 0.61, 0.50, 0.41];
let qs = vec![0.90, 0.65, 0.42, 0.25, 0.14, 0.08];
let (data, truth) = planted_circles_unequal_gates(
12_000,
32,
&qs,
&s,
0.03,
0x2111_15A_u64,
);
let config = IsaSeedConfig {
n_inits: 10,
max_sweeps: 80,
};
let greedy = greedy_deflation_probe(&data, k, &config);
let greedy_overlaps = candidate_overlaps(&greedy, &truth);
let captured = capture_signal_span(data.view(), k)
.expect("capture must run")
.expect("capture must find signal span");
let (q, _y) = joint_jacobi_basis(data.view(), &captured, &config)
.expect("joint basis must optimize captured span");
let joint_planes: Vec<Array2<f64>> = (0..k)
.map(|m| ambient_plane_from_captured_parts(&captured, &q, m))
.collect();
let joint_overlaps = best_truth_overlaps(&joint_planes, &truth);
eprintln!(
"[#2111 unequal gated] greedy overlaps = {:?}; joint overlaps = {:?}",
greedy_overlaps, joint_overlaps
);
assert!(
joint_overlaps.iter().all(|&ov| ov > 0.35),
"joint ISA must recover every unequal gated plane above the weak-source floor; \
overlaps={joint_overlaps:?}"
);
}
fn planted_circles_unequal_gates(
n: usize,
p: usize,
qs: &[f64],
amps: &[f64],
sigma: f64,
seed: u64,
) -> (Array2<f64>, Vec<Array2<f64>>) {
assert!(qs.len() == amps.len() && p >= 2 * qs.len());
let k = qs.len();
let mut state = seed;
let mut frame = Array2::<f64>::from_shape_fn((p, 2 * k), |_| lcg_normal(&mut state));
for c in 0..2 * k {
for prev in 0..c {
let mut dot = 0.0;
for row in 0..p {
dot += frame[[row, c]] * frame[[row, prev]];
}
for row in 0..p {
let sub = dot * frame[[row, prev]];
frame[[row, c]] -= sub;
}
}
let mut nrm = 0.0;
for row in 0..p {
nrm += frame[[row, c]] * frame[[row, c]];
}
let nrm = nrm.sqrt();
for row in 0..p {
frame[[row, c]] /= nrm;
}
}
let mut data = Array2::<f64>::zeros((n, p));
for i in 0..n {
for c in 0..k {
if lcg_uniform(&mut state) >= qs[c] {
continue;
}
let th = std::f64::consts::TAU * lcg_uniform(&mut state);
for j in 0..p {
data[[i, j]] += amps[c]
* (th.cos() * frame[[j, 2 * c]] + th.sin() * frame[[j, 2 * c + 1]]);
}
}
for j in 0..p {
data[[i, j]] += sigma * lcg_normal(&mut state);
}
}
let true_planes: Vec<Array2<f64>> = (0..k)
.map(|c| {
Array2::from_shape_fn((p, 2), |(row, col)| frame[[row, 2 * c + col]])
})
.collect();
(data, true_planes)
}
#[test]
fn isa_producer_rejects_planted_gaussian_blend() {
let n = 2000usize;
let p = 32usize;
let rank = 6usize;
let mut state = 0x2111_B1E4_D00D_u64;
let mut frame = Array2::<f64>::from_shape_fn((p, rank), |_| lcg_normal(&mut state));
for c in 0..rank {
for prev in 0..c {
let mut dot = 0.0;
for row in 0..p {
dot += frame[[row, c]] * frame[[row, prev]];
}
for row in 0..p {
let sub = dot * frame[[row, prev]];
frame[[row, c]] -= sub;
}
}
let mut nrm = 0.0;
for row in 0..p {
nrm += frame[[row, c]] * frame[[row, c]];
}
let nrm = nrm.sqrt();
for row in 0..p {
frame[[row, c]] /= nrm;
}
}
let mut data = Array2::<f64>::zeros((n, p));
for i in 0..n {
for c in 0..rank {
let g = lcg_normal(&mut state);
for j in 0..p {
data[[i, j]] += g * frame[[j, c]];
}
}
for j in 0..p {
data[[i, j]] += 0.05 * lcg_normal(&mut state);
}
}
let harvest =
isa_deflationary_producer(data.view(), 12, &IsaSeedConfig::default()).expect("run");
assert!(
harvest.planes.is_empty() && harvest.natural_exit,
"Gaussian factor blend must certify NO circle plane (got {} planes, \
natural_exit={})",
harvest.planes.len(),
harvest.natural_exit
);
}
#[test]
fn pair_polys_match_brute_force_rotation() {
let r = 5usize;
let n = 400usize;
let mut state = 0xC0DE_2111_u64;
let y = Array2::<f64>::from_shape_fn((r, n), |_| lcg_normal(&mut state));
let (i, j) = (0usize, 2usize); let (pa, pb) = pair_polys(&y, i, j, Some(1), Some(3));
for &theta in &[0.0, 0.3, -0.7, 1.1, std::f64::consts::FRAC_PI_3] {
let (c, s) = (theta.cos(), theta.sin());
let mut yr = y.clone();
for col in 0..n {
let yi = y[[i, col]];
let yj = y[[j, col]];
yr[[i, col]] = c * yi - s * yj;
yr[[j, col]] = s * yi + c * yj;
}
let brute = {
let ka = plane_rows_kappa(&yr, 0);
let kb = plane_rows_kappa(&yr, 1);
(ka - 2.0) * (ka - 2.0) + (kb - 2.0) * (kb - 2.0)
};
let poly = pair_objective(&pa, &pb, theta);
assert!(
(brute - poly).abs() < 1e-10 * (1.0 + brute.abs()),
"pair polynomial mismatch at θ={theta}: brute={brute:.12} poly={poly:.12}"
);
let h = 1e-6;
let secant =
(pair_objective(&pa, &pb, theta + h) - pair_objective(&pa, &pb, theta - h))
/ (2.0 * h);
let deriv = pair_objective_deriv(&pa, &pb, theta);
assert!(
(secant - deriv).abs() < 1e-5 * (1.0 + secant.abs()),
"dJ/dθ mismatch at θ={theta}: secant={secant:.9} analytic={deriv:.9}"
);
}
}
}