#![cfg(test)]
use super::*;
use crate::manifold::construction::ThetaAdjointDhChannel;
use ndarray::{Array1, Array2, s};
pub(crate) fn threshold_gate_tiny_fixture(
straddle: bool,
) -> (SaeManifoldTerm, Array2<f64>, SaeManifoldRho) {
let n = 10usize;
let p = 3usize;
let k_atoms = 2usize;
let m = 3usize;
let tau = 1.0_f64;
let threshold = 0.0_f64;
let evaluator = Arc::new(
PeriodicHarmonicEvaluator::new(m)
.expect("m=3 is odd and positive, the basis width this evaluator requires"),
);
let mut logits = Array2::<f64>::zeros((n, k_atoms));
let mut coords = vec![Array2::<f64>::zeros((n, 1)), Array2::<f64>::zeros((n, 1))];
let weights = [
[
[0.10, -0.05, 0.03],
[0.35, -0.20, 0.12],
[-0.16, 0.18, 0.08],
],
[
[-0.08, 0.04, 0.06],
[0.22, 0.10, -0.18],
[0.11, -0.24, 0.15],
],
];
let mut target = Array2::<f64>::zeros((n, p));
for row in 0..n {
let phase = (row as f64 + 0.35) / n as f64;
coords[0][[row, 0]] = phase;
coords[1][[row, 0]] = (phase + 0.21).fract();
if straddle {
logits[[row, 0]] = if row % 2 == 0 { -0.8 } else { 0.9 };
logits[[row, 1]] = if row % 2 == 0 { 0.7 } else { -0.5 };
} else {
logits[[row, 0]] = -0.8;
logits[[row, 1]] = -0.5;
}
for atom in 0..k_atoms {
let gate = 1.0 / (1.0 + (-(logits[[row, atom]] - threshold) / tau).exp());
let theta = std::f64::consts::TAU * coords[atom][[row, 0]];
let basis = [1.0, theta.sin(), theta.cos()];
for out_col in 0..p {
for basis_col in 0..m {
target[[row, out_col]] +=
gate * basis[basis_col] * weights[atom][basis_col][out_col];
}
}
}
}
let mut atoms = Vec::with_capacity(k_atoms);
for atom in 0..k_atoms {
let (phi, jet) = evaluator
.evaluate(coords[atom].view())
.expect("fixture coords are finite and inside the unit-period circle chart");
let decoder = Array2::from_shape_fn((m, p), |(basis_col, out_col)| {
weights[atom][basis_col][out_col]
});
atoms.push(
SaeManifoldAtom::new_with_provided_function_gram(
format!("tgate_{atom}"),
SaeAtomBasisKind::Periodic,
1,
phi,
jet,
decoder,
Array2::<f64>::eye(m),
)
.expect("decoder is (m, p) and phi/jet come from the same evaluator")
.with_basis_second_jet(evaluator.clone()),
);
}
let mode = AssignmentMode::threshold_gate(tau, threshold);
let assignment = SaeAssignment::from_blocks_with_mode_and_manifolds(
logits,
coords,
vec![LatentManifold::Circle { period: 1.0 }; k_atoms],
mode,
)
.expect("k_atoms coord blocks and k_atoms manifolds match the logits' k_atoms columns");
let term = SaeManifoldTerm::new(atoms, assignment)
.expect("the assignment was built with exactly one block per atom");
let rho = SaeManifoldRho::new(
-1.0,
-1.0,
vec![Array1::from_vec(vec![-1.0]), Array1::from_vec(vec![-1.0])],
)
.for_assignment(mode);
(term, target, rho)
}
fn frozen_cache(
term: &SaeManifoldTerm,
target: &Array2<f64>,
rho: &SaeManifoldRho,
) -> (SaeManifoldLoss, ArrowFactorCache) {
let (_anchor, loss, cache) = anchored_frozen_cache(term, target, rho);
(loss, cache)
}
fn anchored_frozen_cache(
term: &SaeManifoldTerm,
target: &Array2<f64>,
rho: &SaeManifoldRho,
) -> (SaeManifoldTerm, SaeManifoldLoss, ArrowFactorCache) {
let mut anchor = term.clone();
let (_value, loss, cache) = anchor
.penalized_quasi_laplace_criterion_with_cache(
target.view(),
rho,
None,
0,
0.4,
1.0e-6,
1.0e-6,
)
.expect("threshold-gate fixed-theta cache");
anchor.streaming_gates_frozen = true;
(anchor, loss, cache)
}
fn frozen_gate_endpoint(anchor: &SaeManifoldTerm) -> SaeManifoldTerm {
let mut endpoint = anchor.clone();
endpoint.decoder_repulsion_gate = anchor.decoder_repulsion_gate.clone();
endpoint.barrier_coactivation_gate = anchor.barrier_coactivation_gate.clone();
endpoint.amplitude_barrier_gate = anchor.amplitude_barrier_gate;
endpoint.streaming_gates_frozen = true;
endpoint
}
fn deflated_direction_count(term: &SaeManifoldTerm, cache: &ArrowFactorCache) -> usize {
(0..term.n_obs())
.map(|row| cache.deflated_row_directions[row].len())
.sum()
}
fn logit_slots(term: &SaeManifoldTerm, cache: &ArrowFactorCache) -> Vec<(usize, usize, usize)> {
let mut out = Vec::new();
let dim = term.assignment.assignment_coord_dim();
for row in 0..term.n_obs() {
let base = cache.row_offsets[row];
for atom in 0..dim.min(cache.row_dims[row]) {
out.push((row, atom, base + atom));
}
}
out
}
#[test]
fn exact_hessian_probe_assembly_equals_the_column_loop_2267() {
for straddle in [false, true] {
let (term, target, rho) = threshold_gate_tiny_fixture(straddle);
let (_loss, cache) = frozen_cache(&term, &target, &rho);
assert!(
cache.n_rows() > 1,
"the fixture must carry more than one row, or cross-row coupling is untested"
);
let by_columns = term
.materialize_exact_hessian_dense_by_columns(&rho, target.view(), &cache)
.expect("column-loop exact A");
let by_probes = term
.materialize_exact_hessian_dense(&rho, target.view(), &cache)
.expect("probe-assembled exact A");
assert_eq!(by_columns.dim(), by_probes.dim());
let scale = by_columns
.iter()
.fold(0.0_f64, |acc, v| acc.max(v.abs()))
.max(1.0);
let max_diff = by_columns
.iter()
.zip(by_probes.iter())
.fold(0.0_f64, |acc, (x, y)| acc.max((x - y).abs()));
assert!(
max_diff <= 1.0e-12 * scale,
"straddle={straddle}: the probe assembly differs from the column loop by \
{max_diff:.3e} against a scale of {scale:.3e}"
);
}
}
#[test]
fn threshold_gate_sparse_operator_is_the_installed_exact_a_derivative_2500() {
for straddle in [false, true] {
let (term, target, rho) = threshold_gate_tiny_fixture(straddle);
let (_loss, cache) = frozen_cache(&term, &target, &rho);
let sparse = rho
.sparse_flat_index()
.expect("a ThresholdGate rho must carry a sparse log-strength coordinate");
let operators = term
.penalty_curvature_operators_by_flat(&rho, &cache)
.expect("#2500: the ThresholdGate sparse curvature operator must be modelled");
let block = operators
.get(&sparse)
.expect("#2500: the sparse coordinate must own a curvature operator");
let deflated = deflated_direction_count(&term, &cache);
let deltas = term
.exact_stationarity_penalty_derivative_delta_by_flat(&rho, &cache)
.expect("exact-minus-majorizer delta map");
let raw_derivatives = term
.exact_stationarity_penalty_derivatives_by_flat(&rho, &cache)
.expect("#2500: the raw exact-A derivative map");
let delta = deltas.get(&sparse);
if straddle {
let mass = delta
.expect(
"#2500: above the threshold `B` installs a hard zero, so the WHOLE of \
dA/drho_sparse on those logits lives in the dC delta; its \
absence is the sign error this gate was blind to",
)
.iter()
.fold(0.0_f64, |acc, v| acc.max(v.abs()));
assert!(
mass > 1.0e-3,
"#2500: the straddling arm must carry a MATERIAL clamped remainder, else it \
is a duplicate of the below-threshold arm; max|delta| = {mass:.3e}"
);
} else {
assert!(
delta.is_none(),
"#2500: below the threshold the clamp is inactive, so `B` IS `A` on the \
logit slots and the delta map must carry no sparse entry -- that \
is what isolates this arm from the clamped one"
);
}
let expected = raw_derivatives
.get(&sparse)
.expect("#2500: the sparse coordinate must own a raw curvature derivative");
let conditioned_pair = match delta {
Some(d) => block + d,
None => block.clone(),
};
let conditioning_gap = expected
.iter()
.zip(conditioned_pair.iter())
.fold(0.0_f64, |acc, (x, y)| acc.max((x - y).abs()));
assert!(
deflated == 0 && conditioning_gap == 0.0,
"#2500 (straddle={straddle}): this arm is stated on the deflation-free \
stratum, where the raw and conditioned tangents are bit-identical; got \
{deflated} deflated direction(s) and a conditioning gap of \
{conditioning_gap:.3e}"
);
let dense_a = |r: &SaeManifoldRho| -> (Array2<f64>, usize) {
let (_l, c) = frozen_cache(&term, &target, r);
let a = term
.materialize_exact_hessian_dense(r, target.view(), &c)
.expect("dense exact A");
let count = deflated_direction_count(&term, &c);
(a, count)
};
let base = rho.to_flat();
let h = 1.0e-5;
let mut plus_flat = base.clone();
plus_flat[sparse] += h;
let mut minus_flat = base.clone();
minus_flat[sparse] -= h;
let (a_plus, deflated_plus) = dense_a(&rho.from_flat(plus_flat.view()).unwrap());
let (a_minus, deflated_minus) = dense_a(&rho.from_flat(minus_flat.view()).unwrap());
assert!(
deflated_plus == deflated && deflated_minus == deflated,
"#2500: the ±h endpoints must sit on the SAME discrete deflation stratum \
(base={deflated}, +h={deflated_plus}, -h={deflated_minus})"
);
let dim = a_plus.nrows();
let mut worst = 0.0_f64;
let mut worst_label = String::new();
for i in 0..dim {
for j in 0..dim {
let fd = (a_plus[[i, j]] - a_minus[[i, j]]) / (2.0 * h);
let analytic = expected[[i, j]];
let err = (fd - analytic).abs();
let tol = 1.0e-7 + 1.0e-5 * analytic.abs();
if err / tol > worst {
worst = err / tol;
worst_label =
format!("[{i},{j}] analytic={analytic:.12e} fd={fd:.12e} tol={tol:.3e}");
}
}
}
assert!(
worst <= 1.0,
"#2500 (straddle={straddle}, {deflated} deflated directions): the sparse \
curvature operator must equal dA/drho_sparse of the INSTALLED exact Hessian; \
worst normalized error {worst:.3} at {worst_label}"
);
}
}
#[test]
fn threshold_gate_dense_exact_a_sparse_logdet_trace_matches_finite_difference_2500() {
for straddle in [false, true] {
let (term, target, rho) = threshold_gate_tiny_fixture(straddle);
let (loss, cache) = frozen_cache(&term, &target, &rho);
let sparse = rho.sparse_flat_index().expect("sparse coordinate");
let trace = term
.dense_exact_a_logdet_channels(target.view(), &rho, &loss, &cache)
.expect("#2500: the dense exact-A logdet channels must assemble")
.logdet_trace;
assert!(
trace[sparse].abs() > 1.0e-3,
"#2500: the sparse logdet trace must be materially live on this fixture, else \
the FD comparison is a zero-vs-zero gate: {}",
trace[sparse]
);
let log_dets = |r: &SaeManifoldRho| -> (f64, f64) {
let (_l, c) = frozen_cache(&term, &target, r);
term.exact_observed_information_log_dets(r, target.view(), &c)
.expect("production exact-A log dets")
};
let base = rho.to_flat();
let h = 1.0e-5;
let mut plus_flat = base.clone();
plus_flat[sparse] += h;
let mut minus_flat = base.clone();
minus_flat[sparse] -= h;
let (joint_plus, tt_plus) = log_dets(&rho.from_flat(plus_flat.view()).unwrap());
let (joint_minus, tt_minus) = log_dets(&rho.from_flat(minus_flat.view()).unwrap());
let fd = 0.5 * ((joint_plus - joint_minus) - (tt_plus - tt_minus)) / (2.0 * h);
let err = (trace[sparse] - fd).abs();
let tol = 1.0e-6 + 1.0e-5 * fd.abs();
assert!(
err <= tol,
"#2500 (straddle={straddle}): the sparse logdet trace must differentiate the \
ranked value; analytic={:.9e} fd={fd:.9e} err={err:.3e} tol={tol:.3e}",
trace[sparse]
);
}
}
fn deflating_ard_fixture() -> (SaeManifoldTerm, Array2<f64>, SaeManifoldRho) {
use gam_linalg::utils::{SMOOTH_PSD_CLAMP_TEMPERATURE, SPECTRAL_DEFLATION_REL_FLOOR};
let (mut term, target, rho) = crate::manifold::tests::small_two_atom_periodic_term();
let cosine = SMOOTH_PSD_CLAMP_TEMPERATURE * SPECTRAL_DEFLATION_REL_FLOOR.sqrt().ln();
let weak_phase = cosine.acos() / std::f64::consts::TAU;
let n = term.n_obs();
for atom in &mut term.atoms {
atom.decoder_coefficients_mut().fill(0.0);
}
for (atom, coords) in term.assignment.coords.iter_mut().enumerate() {
let phase = if atom == 0 { weak_phase } else { 0.05 };
coords.set_flat(Array1::from_elem(n, phase).view());
}
term.refresh_basis_from_current_coords()
.expect("the declared weak phase is inside the periodic chart");
(term, target, rho)
}
fn deflating_ard_cache(
term: &SaeManifoldTerm,
target: &Array2<f64>,
rho: &SaeManifoldRho,
) -> ArrowFactorCache {
let mut assembler = term.clone();
let mut system = assembler
.assemble_arrow_schur(target.view(), rho, None)
.expect("cold arrow assembly at the deflating anchor");
SaeManifoldTerm::ensure_row_gauge_deflation_for_quasi_laplace(&mut system);
let options = ArrowSolveOptions::direct().with_positive_definite_evidence();
let (_delta_t, _delta_beta, cache) =
solve_arrow_newton_step_with_options(&system, 0.0, 0.0, &options)
.expect("the production spectral-discovery evidence factor");
cache
}
#[test]
fn deflation_map_applies_to_every_row_local_curvature_coordinate_2500() {
let (term, target, rho) = deflating_ard_fixture();
let cache = deflating_ard_cache(&term, &target, &rho);
let spectral_rows = (0..cache.n_rows())
.filter(|&row| cache.deflation_row_spectra[row].is_some())
.count();
assert!(
spectral_rows > 0 && deflated_direction_count(&term, &cache) > 0,
"#2500: this gate needs the deflating stratum, with a RECORDED spectrum \
(the Daleckii–Krein branch); got {spectral_rows} spectral row(s) and {} \
deflated direction(s)",
deflated_direction_count(&term, &cache)
);
let coord = rho.ard_flat_index(0, 0);
let raw = term
.exact_stationarity_penalty_derivatives_by_flat(&rho, &cache)
.expect("#2500: the raw exact-A derivative map");
let conditioned = term
.penalty_curvature_operators_by_flat(&rho, &cache)
.expect("#2500: the conditioned operator map");
let deltas = term
.exact_stationarity_penalty_derivative_delta_by_flat(&rho, &cache)
.expect("delta map");
let expected = raw
.get(&coord)
.expect("#2500: the ARD coordinate must own a curvature operator");
let conditioned_b = conditioned
.get(&coord)
.expect("#2500: the ARD coordinate must own a conditioned curvature operator");
let total_t = cache.delta_t_len();
let base = rho.to_flat();
let h = 1.0e-5;
let base_deflated = deflated_direction_count(&term, &cache);
let dense_a = |flat: &Array1<f64>| -> (Array2<f64>, usize) {
let r = rho.from_flat(flat.view()).unwrap();
let c = deflating_ard_cache(&term, &target, &r);
let a = term
.materialize_exact_hessian_dense(&r, target.view(), &c)
.expect("dense exact A");
let count = deflated_direction_count(&term, &c);
(a, count)
};
let mut plus_flat = base.clone();
plus_flat[coord] += h;
let mut minus_flat = base.clone();
minus_flat[coord] -= h;
let (a_plus, deflated_plus) = dense_a(&plus_flat);
let (a_minus, deflated_minus) = dense_a(&minus_flat);
assert!(
deflated_plus == base_deflated && deflated_minus == base_deflated,
"#2500: the ±h endpoints must sit on the SAME discrete deflation stratum \
(base={base_deflated}, +h={deflated_plus}, -h={deflated_minus})"
);
let mut worst = 0.0_f64;
let mut label = String::new();
for i in 0..total_t {
for j in 0..total_t {
let fd = (a_plus[[i, j]] - a_minus[[i, j]]) / (2.0 * h);
let analytic = expected[[i, j]];
let tol = 1.0e-6 + 1.0e-4 * analytic.abs();
let ratio = (fd - analytic).abs() / tol;
if ratio > worst {
worst = ratio;
label = format!("[{i},{j}] analytic={analytic:.9e} fd={fd:.9e}");
}
}
}
assert!(
worst <= 1.0,
"#2500: the ARD curvature operator must equal dA/drho on the t-block of a \
deflating fixture; worst normalized error {worst:.3} at {label}"
);
let raw_b = match deltas.get(&coord) {
Some(delta) => expected - delta,
None => expected.clone(),
};
let scale = raw_b.iter().fold(0.0_f64, |acc, v| acc.max(v.abs()));
let resolution = f64::EPSILON.sqrt() * scale;
let mut removed_rows = 0usize;
for row in 0..cache.n_rows() {
let width = cache.row_dims[row];
let base_index = cache.row_offsets[row];
let raw_block = raw_b.slice(s![
base_index..base_index + width,
base_index..base_index + width
]);
let cond_block = conditioned_b.slice(s![
base_index..base_index + width,
base_index..base_index + width
]);
for direction in cache.deflated_row_directions[row].iter() {
let raw_response = direction.dot(&raw_block.dot(direction));
let conditioned_response = direction.dot(&cond_block.dot(direction));
assert!(
raw_response > resolution,
"#2500 row {row}: the deflated direction's RAW ρ_ard response \
{raw_response:.6e} is not resolved against the operator scale \
{scale:.6e} (floor {resolution:.6e}), so annihilating it is not a \
measurement — this arm would pass on a deflation-blind map"
);
assert!(
conditioned_response.abs() <= 1.0e-6 * raw_response,
"#2500 row {row}: the conditioned ARD operator must carry NO \
ρ-response along a unit-stiffness deflated direction; raw \
{raw_response:.6e}, conditioned {conditioned_response:.6e}"
);
removed_rows += 1;
}
}
assert!(
removed_rows >= cache.n_rows(),
"#2500: every row of this anchor deflates exactly one direction, so the \
map must have been exercised on all {} of them; reached {removed_rows}",
cache.n_rows()
);
}
#[test]
fn threshold_gate_outer_solve_is_not_aborted_by_an_unmodelled_sparse_operator_2500() {
use gam_solve::rho_optimizer::OuterProblem;
use gam_solve::seeding::SeedConfig;
let (term, target, rho) = threshold_gate_tiny_fixture(true);
let init_flat = rho.to_flat();
let n_params = init_flat.len();
let mut objective =
SaeManifoldOuterObjective::new(term, target, None, rho, 8, 0.04, 1.0e-6, 1.0e-6);
let result = OuterProblem::new(n_params)
.with_initial_rho(init_flat)
.with_seed_config(SeedConfig {
max_seeds: 1,
seed_budget: 1,
..Default::default()
})
.run(&mut objective, "SAE manifold");
if let Err(err) = &result {
let msg = err.to_string();
for marker in [
"operator this map does not model",
"majorizer operator this channel does not yet model",
"explicit second derivative this channel does not yet model",
] {
assert!(
!msg.contains(marker),
"#2500: a ThresholdGate outer solve must not abort on an unmodelled sparse \
log-strength operator ({marker}); got: {msg}"
);
}
}
}
#[test]
fn dense_theta_adjoint_is_not_interchangeable_for_a_threshold_gate_2500() {
for straddle in [false, true] {
let (term, target, rho) = threshold_gate_tiny_fixture(straddle);
let (_loss, cache) = frozen_cache(&term, &target, &rho);
let solver = crate::manifold::arrow_solver::DeflatedArrowSolver::plain(&cache);
let production = term
.logdet_theta_adjoint(&rho, &cache, &solver)
.expect("production theta adjoint");
let g = term
.materialize_joint_inverse(&cache, &solver)
.expect("joint inverse");
let dense = term
.logdet_theta_adjoint_dense(
&rho,
&cache,
&g,
ThetaAdjointDhChannel::All,
false,
false,
None,
)
.expect("dense theta adjoint");
let worst = production
.t
.iter()
.zip(dense.t.iter())
.filter(|(p, _)| p.abs() > 1.0e-3)
.map(|(p, d)| (p - d).abs() / p.abs())
.fold(0.0_f64, f64::max);
assert!(
worst > 1.0,
"#2500 (straddle={straddle}): refusing the exact-A override for this family is \
only justified if the two θ-adjoints genuinely disagree; worst per-entry \
relative gap = {worst:.3}"
);
}
}
#[test]
fn threshold_gate_coordinate_block_theta_adjoint_matches_finite_difference_2500() {
for straddle in [false, true] {
let (term, target, rho) = threshold_gate_tiny_fixture(straddle);
let (_loss, cache) = frozen_cache(&term, &target, &rho);
let coord = term
.coordinate_block_logdet_theta_adjoint(
&rho,
&cache,
crate::manifold::EvidenceOperator::Majorizer,
None,
)
.expect("coordinate-block theta adjoint");
let base_deflated = deflated_direction_count(&term, &cache);
let block_logdet = |t: &SaeManifoldTerm| -> (f64, usize) {
let (_l, c) = frozen_cache(t, &target, &rho);
let mut acc = 0.0_f64;
for row in 0..t.n_obs() {
let factor = c.undamped_factor(row);
for d in 0..c.row_dims[row] {
acc += 2.0 * factor[[d, d]].ln();
}
}
(acc, deflated_direction_count(t, &c))
};
let h = 1.0e-6;
let mut worst = 0.0_f64;
let mut label = String::new();
let mut checked = 0usize;
for (row, atom, slot) in logit_slots(&term, &cache) {
let mut plus = term.clone();
plus.assignment.logits[[row, atom]] += h;
let mut minus = term.clone();
minus.assignment.logits[[row, atom]] -= h;
let (lp, dp) = block_logdet(&plus);
let (lm, dm) = block_logdet(&minus);
if dp != base_deflated || dm != base_deflated {
continue;
}
let fd = (lp - lm) / (2.0 * h);
let analytic = coord.t[slot];
let tol = 1.0e-6 + 1.0e-4 * analytic.abs().max(fd.abs());
let ratio = (analytic - fd).abs() / tol;
if ratio > worst {
worst = ratio;
label = format!(
"row {row} atom {atom}: analytic={analytic:.9e} fd={fd:.9e} tol={tol:.3e}"
);
}
checked += 1;
}
assert!(
checked >= 4,
"#2500 (straddle={straddle}): the FD gate must reach at least four logits on a \
fixed deflation stratum; checked={checked}"
);
assert!(
worst <= 1.0,
"#2500 (straddle={straddle}): the coordinate-block theta-adjoint must \
differentiate the per-row log|H_tt| it is defined as; worst normalized error \
{worst:.3} at {label}"
);
}
}
#[test]
fn dense_exact_a_matches_finite_difference_of_the_kkt_gradient_2330() {
let (term, target, rho) = threshold_gate_tiny_fixture(false);
let (anchor, _loss, cache) = anchored_frozen_cache(&term, &target, &rho);
assert_eq!(
deflated_direction_count(&anchor, &cache),
0,
"#2330 FD gate: the below-threshold arm must be deflation-free, or the +/-h \
endpoints can straddle a discrete deflation change and the central \
difference stops being a difference of one smooth branch"
);
let a = anchor
.materialize_exact_hessian_dense(&rho, target.view(), &cache)
.expect("dense exact A at the frozen fixture mode");
let total_t = cache.delta_t_len();
let k = cache.k;
let dim = total_t + k;
assert_eq!(
a.nrows(),
dim,
"#2330 FD gate: dense A must be (total_t + k) square before it can be compared \
against the (gt, gb) gradient layout"
);
let gradient = |t: &mut SaeManifoldTerm| -> Array1<f64> {
let sys = t
.assemble_arrow_schur(target.view(), &rho, None)
.expect("arrow-Schur assembly at the finite-difference endpoint");
let mut g = Array1::<f64>::zeros(dim);
let mut offset = 0usize;
for row in &sys.rows {
for (axis, &value) in row.gt.iter().enumerate() {
g[offset + axis] = value;
}
offset += row.gt.len();
}
assert_eq!(
offset, total_t,
"#2330 FD gate: concatenated per-row gt width must equal cache.delta_t_len(), \
or the gradient and A are not in the same coordinates"
);
assert_eq!(
sys.gb.len(),
k,
"#2330 FD gate: border gradient width must equal cache.k"
);
for (axis, &value) in sys.gb.iter().enumerate() {
g[total_t + axis] = value;
}
g
};
let h = 1.0e-5_f64;
{
let mut base = frozen_gate_endpoint(&anchor);
let g0 = gradient(&mut base);
let mut worst = 0.0_f64;
let mut worst_idx = 0usize;
for idx in 0..dim {
let mut e = Array1::<f64>::zeros(dim);
e[idx] = 1.0;
let e_t = e.slice(s![0..total_t]).to_owned();
let e_beta = e.slice(s![total_t..dim]).to_owned();
let mut plus = frozen_gate_endpoint(&anchor);
plus.apply_newton_step(e_t.view(), e_beta.view(), h)
.expect("positive objective endpoint");
let mut minus = frozen_gate_endpoint(&anchor);
minus
.apply_newton_step(
e_t.mapv(|value| -value).view(),
e_beta.mapv(|value| -value).view(),
h,
)
.expect("negative objective endpoint");
let fd = (plus
.penalized_objective_total(target.view(), &rho, None, 1.0)
.expect("positive penalized objective")
- minus
.penalized_objective_total(target.view(), &rho, None, 1.0)
.expect("negative penalized objective"))
/ (2.0 * h);
let error = (g0[idx] - fd).abs();
if error > worst {
worst = error;
worst_idx = idx;
}
}
assert!(
worst <= 1.0e-6,
"#2330 FD gate premise: the assembled (gt, gb) is NOT the gradient of \
`penalized_objective_total`; worst coordinate error {worst:.6e} at index \
{worst_idx} (of {total_t} coordinate + {k} border). A central difference of \
a non-gradient is not a Hessian, so nothing below this line would mean \
anything."
);
}
for (label, weight_t, weight_beta) in [
("coordinate-weighted", 1.0_f64, 0.25_f64),
("border-weighted", 0.25_f64, 1.0_f64),
] {
let mut v_t = Array1::<f64>::zeros(total_t);
let mut v_beta = Array1::<f64>::zeros(k);
let mut v = Array1::<f64>::zeros(dim);
for idx in 0..dim {
let phase = 0.7 + 0.31 * (idx as f64);
let raw = phase.sin() + 0.5 * (2.0 * phase).cos();
let value = raw * if idx < total_t { weight_t } else { weight_beta };
v[idx] = value;
}
let norm = v.dot(&v).sqrt();
assert!(
norm.is_finite() && norm > 0.0,
"#2330 FD gate ({label}): probe direction must be finite and nonzero"
);
v.mapv_inplace(|value| value / norm);
for idx in 0..total_t {
v_t[idx] = v[idx];
}
for idx in 0..k {
v_beta[idx] = v[total_t + idx];
}
let analytic = a.dot(&v);
let endpoint = |sign: f64| -> Array1<f64> {
let mut moved = frozen_gate_endpoint(&anchor);
let signed_t = v_t.mapv(|value| sign * value);
let signed_beta = v_beta.mapv(|value| sign * value);
moved
.apply_newton_step(signed_t.view(), signed_beta.view(), h)
.expect("finite-difference endpoint step");
gradient(&mut moved)
};
let g_plus = endpoint(1.0);
let g_minus = endpoint(-1.0);
let fd = (&g_plus - &g_minus).mapv(|delta| delta / (2.0 * h));
let analytic_norm = analytic.dot(&analytic).sqrt();
let fd_norm = fd.dot(&fd).sqrt();
assert!(
analytic_norm > 1.0e-6,
"#2330 FD gate ({label}): |A.v|={analytic_norm:.6e} is too small for this \
comparison to be a gate rather than a zero-vs-zero tautology"
);
let mut worst = 0.0_f64;
let mut worst_idx = 0usize;
for idx in 0..dim {
let scale = analytic[idx].abs().max(fd[idx].abs()).max(1.0e-8);
let relative = (analytic[idx] - fd[idx]).abs() / scale;
if relative > worst {
worst = relative;
worst_idx = idx;
}
}
let directional = analytic.dot(&v);
let directional_fd = fd.dot(&v);
let block_residual = |lo: usize, hi: usize| -> f64 {
(lo..hi).fold(0.0_f64, |acc, idx| acc.max((analytic[idx] - fd[idx]).abs()))
};
let block_of = |idx: usize| if idx < total_t { "t" } else { "beta" };
assert!(
worst <= 1.0e-4,
"#2330: the dense exact A is NOT the second derivative of the penalized \
objective whose gradient the inner solve drives to zero. Worst component \
relative error {worst:.6e} at index {worst_idx} (block {}, A.v={:.9e}, \
FD={:.9e}); |A.v|={analytic_norm:.6e} |FD|={fd_norm:.6e}; \
max|A.v-FD| over the t block = {:.6e}, over the beta block = {:.6e}; \
v'Av={directional:.9e} vs v'(dg/dtheta)v={directional_fd:.9e} (ratio \
{:.6e}). If this fires, the IndefiniteObservedInformation refusal is \
measuring the wrong operator, the converged-but-indefinite verdict is an \
artefact of the refusal site rather than a saddle upstream, and the \
negative-curvature escape is the WRONG fix. Probe: {label}, h={h:.3e}",
block_of(worst_idx),
analytic[worst_idx],
fd[worst_idx],
block_residual(0, total_t),
block_residual(total_t, dim),
directional_fd / directional,
);
}
}
#[test]
fn threshold_gate_priced_clamp_theta_diagonal_matches_finite_difference_2820() {
let (term, target, rho) = threshold_gate_tiny_fixture(true);
let (_, cache) = frozen_cache(&term, &target, &rho);
let derivative = term
.ard_concave_clamp_dt_diagonal(&rho, &cache)
.expect("priced-clamp theta derivative");
let h = 1.0e-5;
let mut live = 0;
for (row, atom, slot) in logit_slots(&term, &cache) {
let mut plus = term.clone();
let mut minus = term.clone();
plus.assignment.logits[[row, atom]] += h;
minus.assignment.logits[[row, atom]] -= h;
let ep = plus
.materialize_ard_concave_clamp_diagonal(&rho, &cache)
.expect("positive endpoint remainder");
let em = minus
.materialize_ard_concave_clamp_diagonal(&rho, &cache)
.expect("negative endpoint remainder");
for index in 0..derivative.len() {
let fd = (ep[index] - em[index]) / (2.0 * h);
let expected = if index == slot { derivative[slot] } else { 0.0 };
assert!(
(fd - expected).abs() <= 1.0e-9 + 1.0e-7 * expected.abs(),
"row={row} atom={atom} output={index}: analytic={expected:e}, fd={fd:e}"
);
}
live += usize::from(derivative[slot].abs() > 1.0e-3);
}
assert!(live >= term.n_obs(), "the concave logit channel must be live");
let mut fixed = term.clone();
fixed.assignment.ungated[0] = true;
let fixed_derivative = fixed
.ard_concave_clamp_dt_diagonal(&rho, &cache)
.expect("fixed-logit clamp derivative");
for (_, atom, slot) in logit_slots(&fixed, &cache) {
assert_eq!(fixed_derivative[slot], if atom == 0 { 0.0 } else { derivative[slot] });
}
}