use super::tests::{gamma_fd_tiny_fixture, small_two_atom_periodic_term};
use super::tests_logdet_adjoint_780::deflation_blind_cache;
use super::tests_recovery_split_780::{
FdAnchorRegime, certified_fd_anchor, rho_ladder_family, sparse_lift_ladder,
};
use super::*;
const DEFLATING_SPARSE_LIFTS: [f64; 10] = [2.4, 1.8, 1.3, 0.9, 0.5, 0.2, 0.0, -0.3, -0.6, -1.0];
fn obb_deflated_anchor(label: &str) -> (SaeManifoldTerm, SaeManifoldRho, Array2<f64>, ArrowFactorCache)
{
let (mut term, target, rho) = gamma_fd_tiny_fixture();
term.assignment.mode = AssignmentMode::ordered_beta_bernoulli(0.7, 0.9, true);
let anchor = certified_fd_anchor(
label,
&target,
FdAnchorRegime::deflated(),
rho_ladder_family(&term, sparse_lift_ladder(&rho, &DEFLATING_SPARSE_LIFTS), 5),
);
(anchor.term, anchor.rho, target, anchor.cache)
}
pub(crate) fn residual_excited_deflated_anchor(
label: &str,
) -> (SaeManifoldTerm, SaeManifoldRho, Array2<f64>, ArrowFactorCache) {
let (mut term, mut target, mut rho) = gamma_fd_tiny_fixture();
let (n, p) = (target.nrows(), target.ncols());
for row in 0..n {
for col in 0..p {
let phase = (row as f64 + 0.35) / n as f64;
let theta = std::f64::consts::TAU * phase;
target[[row, col]] += 0.6 * (3.0 * theta + 0.5 * col as f64).sin();
}
}
rho.log_lambda_sparse = -0.5;
for value in rho.log_lambda_smooth.iter_mut() {
*value = -1.0;
}
for axis in rho.log_ard.iter_mut() {
for value in axis.iter_mut() {
*value = -0.5;
}
}
term.penalized_quasi_laplace_criterion_with_cache(
target.view(),
&rho,
None,
40,
0.4,
1.0e-6,
1.0e-6,
)
.expect("off-manifold fixture converges with both atoms alive");
let eval_rho_ladder: Vec<(String, SaeManifoldRho)> = [
(0.5_f64, -2.0_f64, -1.2_f64, -1.0_f64),
(0.5, -1.5, -1.2, -1.0),
(0.2, -2.0, -1.2, -1.0),
(0.2, -1.5, -1.0, -0.8),
(0.0, -1.5, -1.0, -0.8),
(-0.2, -1.2, -0.8, -0.6),
(-0.5, -1.0, -0.5, -0.5),
]
.iter()
.map(|&(sparse, smooth, ard0, ard1)| {
let mut candidate = rho.clone();
candidate.log_lambda_sparse = sparse;
for value in candidate.log_lambda_smooth.iter_mut() {
*value = smooth;
}
candidate.log_ard = vec![ndarray::array![ard0], ndarray::array![ard1]];
(
format!("eval rho (sparse={sparse:.1}, smooth={smooth:.1}, ard=[{ard0:.1}, {ard1:.1}])"),
candidate,
)
})
.collect();
let anchor = certified_fd_anchor(
label,
&target,
FdAnchorRegime::deflated(),
rho_ladder_family(&term, eval_rho_ladder, 0),
);
(anchor.term, anchor.rho, target, anchor.cache)
}
fn spectrally_deflated_cold_state() -> (SaeManifoldTerm, SaeManifoldRho, ArrowFactorCache) {
let (mut term, target, rho) = small_two_atom_periodic_term();
let options = ArrowSolveOptions::direct().with_positive_definite_evidence();
let system = term
.assemble_arrow_schur(target.view(), &rho, None)
.expect("cold arrow assembly");
let (_delta_t, _delta_beta, cache) =
solve_arrow_newton_step_with_options(&system, 0.0, 0.0, &options)
.expect("the cold undamped factor is spectrally conditioned (#1117), not refused");
let spectral_rows = cache
.deflation_row_spectra
.iter()
.filter(|spectrum| spectrum.is_some())
.count();
assert!(
spectral_rows > 0,
"#2712 premise: this gate needs a row whose deflation carries a RECORDED \
SPECTRUM (the Daleckii–Krein branch that reads the off-diagonal block). \
Got {spectral_rows} spectral row(s) and {} gauge direction(s).",
cache.gauge_deflated_directions
);
assert!(
cache.k > 0,
"#2712 premise: the fixture must carry a border, or `S⁻¹` is not in play at all"
);
(term, rho, cache)
}
fn full_basis_bundle(cache: &ArrowFactorCache) -> (Vec<Array1<f64>>, Vec<Array1<f64>>) {
let k = cache.k;
let sqrt_k = (k as f64).sqrt();
let probes: Vec<Array1<f64>> = (0..k)
.map(|j| {
let mut v = Array1::<f64>::zeros(k);
v[j] = sqrt_k;
v
})
.collect();
let sinv: Vec<Array1<f64>> = probes
.iter()
.map(|v| {
cache
.schur_inverse_apply(v.view())
.expect("schur_inverse_apply")
})
.collect();
(probes, sinv)
}
fn sup_difference(a: &SaeArrowVector, b: &SaeArrowVector) -> f64 {
a.t.iter()
.zip(b.t.iter())
.chain(a.beta.iter().zip(b.beta.iter()))
.map(|(x, y)| (x - y).abs())
.fold(0.0_f64, f64::max)
}
fn sup_norm(a: &SaeArrowVector) -> f64 {
a.t.iter()
.chain(a.beta.iter())
.map(|x| x.abs())
.fold(0.0_f64, f64::max)
}
fn assert_deflation_resolved(what: &str, parity: f64, separation: f64) {
assert!(
separation.is_finite() && separation > 0.0,
"{what}: the deflation-aware and deflation-blind operators do not separate at \
all on this fixture (separation {separation:.6e}), so agreement between the \
dense and from-probes routes says nothing about the Daleckii–Krein \
correction."
);
let margin = separation / parity.max(f64::MIN_POSITIVE);
assert!(
parity * 1.0e3 <= separation,
"{what}: from-probes parity error {parity:.6e} is not small enough against the \
{separation:.6e} distance to the deflation-blind operator. The gate can only \
claim the correction is reconstructed if a port that dropped it would be \
caught by a wide margin; the measured margin is {margin:.3e}x."
);
eprintln!(
"#2712 {what}: parity {parity:.6e}, deflation-blind separation \
{separation:.6e} — a port that dropped the correction would be caught by \
{margin:.3e}x"
);
}
fn deflation_redirected_to_slot(cache: &ArrowFactorCache, slot: usize) -> ArrowFactorCache {
let mut redirected = cache.clone();
let rows = cache.deflation_row_spectra.len();
let mut dirs: Vec<Vec<Array1<f64>>> = vec![Vec::new(); rows];
let mut spectra: Vec<Option<RowDeflationSpectrum>> = vec![None; rows];
for row in 0..rows {
let Some(spectrum) = cache.deflation_row_spectra[row].as_ref() else {
continue;
};
let q = spectrum.evecs.nrows();
if slot >= q {
continue;
}
let mut best = 0usize;
let mut best_weight = -1.0_f64;
for column in 0..spectrum.evecs.ncols() {
let weight = spectrum.evecs[[slot, column]].abs();
if weight > best_weight {
best_weight = weight;
best = column;
}
}
let mut conditioning: Vec<RowSpectralConditioning> =
spectrum.conditioning.iter().copied().collect();
let mut cond_evals = spectrum.cond_evals.clone();
for (index, decision) in conditioning.iter_mut().enumerate() {
if index == best {
*decision = RowSpectralConditioning::UnitDeflated;
cond_evals[index] = 1.0;
} else {
*decision = RowSpectralConditioning::Raw;
cond_evals[index] = spectrum.raw_evals[index];
}
}
dirs[row] = vec![spectrum.evecs.column(best).to_owned()];
spectra[row] = Some(RowDeflationSpectrum {
evecs: spectrum.evecs.clone(),
raw_evals: spectrum.raw_evals.clone(),
cond_evals,
conditioning: conditioning.into(),
});
}
redirected.deflated_row_directions = std::sync::Arc::from(dirs);
redirected.deflation_row_spectra = std::sync::Arc::from(spectra);
redirected
}
#[test]
fn zz_measure_deflation_correction_size_2712() {
fn report(
label: &str,
term: &SaeManifoldTerm,
rho: &SaeManifoldRho,
cache: &ArrowFactorCache,
) {
let mut unit_deflated = 0usize;
let mut floor_clamped = 0usize;
let mut raw_kept = 0usize;
let mut rows_with_dirs = 0usize;
let mut rows_with_spectrum = 0usize;
for row in 0..cache.row_dims.len() {
if cache
.deflated_row_directions
.get(row)
.is_some_and(|d| !d.is_empty())
{
rows_with_dirs += 1;
}
if let Some(spectrum) = cache.deflation_row_spectra.get(row).and_then(Option::as_ref) {
rows_with_spectrum += 1;
for decision in spectrum.conditioning.iter() {
match decision {
RowSpectralConditioning::UnitDeflated => unit_deflated += 1,
RowSpectralConditioning::FloorClamped => floor_clamped += 1,
RowSpectralConditioning::Raw => raw_kept += 1,
}
}
}
}
let solver = DeflatedArrowSolver::plain(cache);
let dense = term.logdet_theta_adjoint(rho, cache, &solver);
let blind_cache = deflation_blind_cache(cache);
let blind_solver = DeflatedArrowSolver::plain(&blind_cache);
let blind = term.logdet_theta_adjoint(rho, &blind_cache, &blind_solver);
let (scale, separation) = match (&dense, &blind) {
(Ok(d), Ok(b)) => (sup_norm(d), sup_difference(d, b)),
_ => (f64::NAN, f64::NAN),
};
eprintln!(
"[#2712 correction size] {label}: rows(dirs)={rows_with_dirs} \
rows(spectrum)={rows_with_spectrum} conditioning(unit={unit_deflated}, \
floor={floor_clamped}, raw={raw_kept}) ‖Γ‖∞={scale:.6e} \
‖Γ_dense − Γ_deflation-blind‖∞={separation:.6e} relative={:.6e}",
separation / (1.0 + scale)
);
}
let (term, rho, _target, cache) =
obb_deflated_anchor("#2712 correction size: ordered Beta--Bernoulli");
report(
"ordered Beta--Bernoulli tiny (certified deflated anchor)",
&term,
&rho,
&cache,
);
let (term, rho, cache) = spectrally_deflated_cold_state();
report("two-atom softmax cold seed (spectral)", &term, &rho, &cache);
let (term, rho, _target, cache) =
residual_excited_deflated_anchor("#2712 correction size: residual-excited softmax");
report(
"residual-excited two-atom softmax (certified deflated anchor)",
&term,
&rho,
&cache,
);
}
#[test]
fn row_selected_inverse_from_probes_matches_dense_on_spectrally_deflated_rows_2712() {
let (_term, _rho, cache) = spectrally_deflated_cold_state();
let (probes, sinv) = full_basis_bundle(&cache);
let solver = DeflatedArrowSolver::plain(&cache);
let beta_inv = solver.beta_inv().expect("beta_inv");
let mut rows = 0usize;
let mut worst_diagonal = 0.0_f64;
let mut worst_off_diagonal = 0.0_f64;
let mut worst_border = 0.0_f64;
let mut off_diagonal_mass = 0.0_f64;
let mut block_scale = 0.0_f64;
for row in 0..cache.row_dims.len() {
if cache
.deflation_row_spectra
.get(row)
.and_then(Option::as_ref)
.is_none()
{
continue;
}
rows += 1;
let q = cache.row_dims[row];
let (dense_vv, dense_vbeta) = solver
.selected_inverse_row_blocks(row, &beta_inv)
.expect("dense selected inverse row blocks");
let (probe_vv, probe_vbeta) = row_selected_inverse_from_probes(
&cache,
row,
&probes,
&sinv,
true,
"#2712 spectral reconstruction gate",
)
.expect("from-probes selected inverse row blocks");
for a in 0..q {
for b in 0..q {
let err = (dense_vv[[a, b]] - probe_vv[[a, b]]).abs();
if a == b {
worst_diagonal = worst_diagonal.max(err);
} else {
worst_off_diagonal = worst_off_diagonal.max(err);
off_diagonal_mass = off_diagonal_mass.max(dense_vv[[a, b]].abs());
}
block_scale = block_scale.max(dense_vv[[a, b]].abs());
}
}
for (d, p) in dense_vbeta.iter().zip(probe_vbeta.iter()) {
worst_border = worst_border.max((d - p).abs());
block_scale = block_scale.max(d.abs());
}
}
eprintln!(
"#2712 spectral reconstruction: {rows} spectrally deflated row(s); \
worst diagonal error {worst_diagonal:.3e}, worst off-diagonal error \
{worst_off_diagonal:.3e} (off-diagonal magnitude {off_diagonal_mass:.3e}), \
worst t–β error {worst_border:.3e}, block magnitude {block_scale:.3e}"
);
assert!(
rows > 0,
"the premise promised a spectrally deflated row and the loop found none"
);
assert!(
off_diagonal_mass > 1.0e-6 * (1.0 + block_scale),
"the deflated selected-inverse block must carry real off-diagonal mass for \
the Daleckii–Krein rotation term to be under test; got \
{off_diagonal_mass:.3e} against block magnitude {block_scale:.3e}"
);
let tol = 1.0e-11 * (1.0 + block_scale);
assert!(
worst_diagonal <= tol && worst_off_diagonal <= tol && worst_border <= tol,
"from-probes reconstruction must equal the dense selected inverse on a \
spectrally deflated row: diag {worst_diagonal:.3e}, off-diag \
{worst_off_diagonal:.3e}, t–β {worst_border:.3e} against tolerance {tol:.3e}"
);
}
#[test]
fn ard_log_precision_hessian_trace_from_probes_matches_dense_on_deflated_rows_2712() {
let (term, rho, _target, cache) =
residual_excited_deflated_anchor("#2712 deflated ARD trace parity");
let (probes, sinv) = full_basis_bundle(&cache);
let compare = |label: &str, cache: &ArrowFactorCache| -> (f64, f64, f64, usize) {
let solver = DeflatedArrowSolver::plain(cache);
let dense = term
.ard_log_precision_hessian_trace(&rho, cache, &solver, EvidenceOperator::Majorizer)
.expect("dense ARD trace");
let blind_cache = deflation_blind_cache(cache);
let blind_solver = DeflatedArrowSolver::plain(&blind_cache);
let blind = term
.ard_log_precision_hessian_trace(
&rho,
&blind_cache,
&blind_solver,
EvidenceOperator::Majorizer,
)
.expect("deflation-blind dense ARD trace");
let from_probes = term
.ard_log_precision_hessian_trace_from_probes(
&rho,
cache,
&probes,
&sinv,
EvidenceOperator::Majorizer,
)
.expect("the from-probes ARD trace must PRICE a deflated cache, not refuse it");
let mut separation = 0.0_f64;
let mut parity = 0.0_f64;
let mut scale = 0.0_f64;
let mut entries = 0usize;
for ((d, b), m) in dense.iter().zip(blind.iter()).zip(from_probes.iter()) {
assert_eq!(d.len(), m.len());
assert_eq!(d.len(), b.len());
for ((dv, bv), mv) in d.iter().zip(b.iter()).zip(m.iter()) {
separation = separation.max((dv - bv).abs());
parity = parity.max((dv - mv).abs());
scale = scale.max(dv.abs());
entries += 1;
}
}
eprintln!(
"#2712 ARD trace [{label}] over {entries} (atom, axis) entries: magnitude \
{scale:.6e}, parity {parity:.6e}, deflation-blind separation {separation:.6e}"
);
(parity, separation, scale, entries)
};
let (parity, _separation, scale, entries) = compare("fixture deflation", &cache);
assert!(
entries > 0,
"the fixture must carry at least one live ARD axis for this gate to mean anything"
);
assert!(
parity <= 1.0e-11 * (1.0 + scale),
"from-probes ARD trace must equal the dense trace on a deflated cache: \
{parity:.6e} against trace magnitude {scale:.6e}"
);
let q_max = cache.row_dims.iter().copied().max().unwrap_or(0);
assert!(q_max > 0, "the fixture must have a non-empty row block");
let mut best_separation = 0.0_f64;
let mut best_parity = 0.0_f64;
for slot in 0..q_max {
let redirected = deflation_redirected_to_slot(&cache, slot);
let (parity, separation, scale, _entries) =
compare(&format!("deflation redirected to slot {slot}"), &redirected);
assert!(
parity <= 1.0e-11 * (1.0 + scale),
"from-probes ARD trace must equal the dense trace on the record redirected \
to slot {slot}: {parity:.6e} against trace magnitude {scale:.6e}"
);
if separation > best_separation {
best_separation = separation;
best_parity = parity;
}
}
assert_deflation_resolved("ARD log-precision trace", best_parity, best_separation);
}
#[test]
fn assignment_log_strength_hessian_trace_from_probes_matches_dense_on_deflated_rows_2712() {
let (term, rho, _target, cache) =
obb_deflated_anchor("#2712 deflated assignment-strength trace parity");
let (probes, sinv) = full_basis_bundle(&cache);
let solver = DeflatedArrowSolver::plain(&cache);
let dense = term
.assignment_log_strength_hessian_trace(&rho, &cache, &solver)
.expect("dense assignment-strength trace");
let blind_cache = deflation_blind_cache(&cache);
let blind_solver = DeflatedArrowSolver::plain(&blind_cache);
let blind = term
.assignment_log_strength_hessian_trace(&rho, &blind_cache, &blind_solver)
.expect("deflation-blind dense assignment-strength trace");
let from_probes = term
.assignment_log_strength_hessian_trace_from_probes(
&rho,
&cache,
&probes,
&sinv,
EvidenceOperator::Majorizer,
)
.expect("the from-probes assignment trace must PRICE a deflated cache, not refuse it");
let separation = (dense - blind).abs();
let parity = (dense - from_probes).abs();
eprintln!(
"#2712 assignment trace: dense {dense:.10e}, deflation-blind {blind:.10e}, \
from-probes {from_probes:.10e}"
);
assert!(
parity <= 1.0e-11 * (1.0 + dense.abs()),
"from-probes assignment trace must equal the dense trace on a deflated \
cache: {parity:.6e}"
);
assert_deflation_resolved("assignment-strength trace", parity, separation);
}
#[test]
fn complete_outer_gradient_deflation_contribution_is_route_independent_2712() {
let (term, rho, target, cache) =
residual_excited_deflated_anchor("#2712 complete-gradient deflated attribution");
let deflated_rows = cache
.deflated_row_directions
.iter()
.filter(|d| !d.is_empty())
.count();
assert!(deflated_rows > 0, "the certified anchor promised deflation");
let loss = term
.loss(target.view(), &rho)
.expect("loss at the frozen anchor");
let (probes, sinv) = full_basis_bundle(&cache);
let blind_cache = deflation_blind_cache(&cache);
let gradients = |cache: &ArrowFactorCache| -> (Array1<f64>, Array1<f64>) {
let solver = DeflatedArrowSolver::plain(cache);
let dense = term
.analytic_outer_rho_gradient_components(target.view(), &rho, &loss, cache, &solver)
.expect("dense complete outer gradient")
.gradient();
let bundled = term
.analytic_outer_rho_gradient_components_with_bundle(
target.view(),
&rho,
&loss,
cache,
&solver,
Some(BundleEvidenceGeometry {
operator: EvidenceOperator::Majorizer,
cache,
probes: &probes,
sinv: &sinv,
}),
None,
)
.expect(
"the from-probes cluster must PRICE a deflated fit; before #2712 every \
channel in it refused here",
)
.gradient();
(dense, bundled)
};
let (dense, bundled) = gradients(&cache);
let (dense_blind, bundled_blind) = gradients(&blind_cache);
let mut scale = 0.0_f64;
let mut deflation_contribution_gap = 0.0_f64;
let mut dense_deflation = 0.0_f64;
let mut route_gap = 0.0_f64;
let mut route_gap_blind = 0.0_f64;
let mut route_gap_is_deflation_dependent = 0.0_f64;
for i in 0..dense.len() {
for value in [dense[i], bundled[i], dense_blind[i], bundled_blind[i]] {
assert!(value.is_finite(), "gradient coordinate {i} must be finite");
}
scale = scale.max(dense[i].abs());
let dense_delta = dense[i] - dense_blind[i];
let bundled_delta = bundled[i] - bundled_blind[i];
dense_deflation = dense_deflation.max(dense_delta.abs());
deflation_contribution_gap =
deflation_contribution_gap.max((dense_delta - bundled_delta).abs());
let gap = dense[i] - bundled[i];
let gap_blind = dense_blind[i] - bundled_blind[i];
route_gap = route_gap.max(gap.abs());
route_gap_blind = route_gap_blind.max(gap_blind.abs());
route_gap_is_deflation_dependent =
route_gap_is_deflation_dependent.max((gap - gap_blind).abs());
eprintln!(
" coord {i}: dense={:+.8e} bundle={:+.8e} | deflation Δ dense={:+.3e} \
bundle={:+.3e} | route gap={:+.3e} (blind {:+.3e})",
dense[i], bundled[i], dense_delta, bundled_delta, gap, gap_blind
);
}
eprintln!(
"#2712 complete outer gradient, {} coordinate(s), {deflated_rows} deflated row(s): \
‖g‖∞={scale:.6e} ‖deflation contribution‖∞={dense_deflation:.6e} \
‖deflation contribution, dense − bundle‖∞={deflation_contribution_gap:.6e} \
route gap={route_gap:.6e} (deflation-blind {route_gap_blind:.6e}, \
difference {route_gap_is_deflation_dependent:.6e})",
dense.len()
);
assert!(
scale > 1.0e-10 && scale.is_finite(),
"a zero gradient would make this decomposition vacuous; ‖g‖∞ = {scale:.6e}"
);
assert!(
deflation_contribution_gap <= 1.0e-9 * (1.0 + scale),
"the two routes must price the DEFLATION CONTRIBUTION identically: dense \
prices {dense_deflation:.6e}, and the routes differ on it by \
{deflation_contribution_gap:.6e}"
);
assert!(
route_gap_is_deflation_dependent <= 1.0e-9 * (1.0 + route_gap),
"the dense↔bundle route gap must be the SAME with and without deflation for \
it to be attributable to the #2499/#2515 β-Schur smoothness channel; \
measured {route_gap:.6e} against {route_gap_blind:.6e} (difference \
{route_gap_is_deflation_dependent:.6e})"
);
}