Skip to content

Commit b0335ef

Browse files
committed
test(pillar): wire Pillar 12 drift-check against splat3d::Spd3::from_scale_quat
Cross-validation test that runs both the pillar's independently-derived covariance_from_scale_quat() AND the production Spd3::from_scale_quat() on the same SplitMix64-seeded 256 (scale, quat) pairs, then asserts upper-triangle agreement to within 1e-5 per lane. This is the missing wire from #188's "Pillars 12-14 implemented": the pillar files reference their production targets in docstrings but do not cross-check against them. The PR description explicitly noted this gap ("Production code paths in splat3d, dn_tree, ogit_bridge are not coupled to pillars in this PR. The pillars re-derive their math independently, by design — drift between substrate and pillar is the failure mode pillars exist to catch.") The cross-check below preserves that design — it adds NO coupling in src/ — but it gates CI on production and pillar agreeing, so drift WILL fail the build instead of silently passing both kernels. For the other two implemented pillars in #188: - Pillar 13 needs `pub(crate) fn bundle_into` to be re-exported on `dn_tree` so a sibling cross-check can compare to production (currently private). - Pillar 14 needs a separable closure/ancestor accessor on `OntologySchema` (currently the closure is implicit in the heel→hip→leaf family-bitmap construction with no public point-pair `is_ancestor(t, u) -> bool` to validate against). Both gaps require small production-side surface changes, which is a better fit for the session that owns the pillar branch; this commit wires only the gap that needed zero production change.
1 parent e30e15d commit b0335ef

1 file changed

Lines changed: 52 additions & 0 deletions

File tree

src/hpc/pillar/splat_invariants.rs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,4 +437,56 @@ mod tests {
437437
assert!((r1.psd_rate - r2.psd_rate).abs() < 1e-12);
438438
assert!((r1.lognorm_concentration - r2.lognorm_concentration).abs() < 1e-12);
439439
}
440+
441+
/// Drift-detection: the pillar's `covariance_from_scale_quat`
442+
/// independently re-derives `Σ = R(q) · diag(s²) · R(q)ᵀ`. The
443+
/// production code path at `crate::hpc::splat3d::spd3::Spd3::from_scale_quat`
444+
/// is the substrate the pillar is *defending*. This test runs both
445+
/// on the same SplitMix64-seeded sample of 256 `(scale, quat)` pairs
446+
/// and asserts agreement to within `1e-5` per upper-triangle entry.
447+
///
448+
/// Any divergence ≥ ε indicates one of two failure modes:
449+
/// (a) production drifted from the canonical quaternion-rotation
450+
/// formula (the pillar definition wins by design — fix the
451+
/// production code), or
452+
/// (b) the pillar itself drifted (audit `covariance_from_scale_quat`
453+
/// against Kerbl 2023 Eq. 3 before changing).
454+
///
455+
/// This is the *coupling* the per-pillar docstring promises:
456+
/// production and pillar share no code, but they share a CI gate
457+
/// that compares them point-for-point.
458+
#[test]
459+
fn pillar_12_matches_production_spd3_from_scale_quat() {
460+
use crate::hpc::splat3d::spd3::Spd3;
461+
462+
const N: u32 = 256;
463+
let mut rng = SplitMix64::new(PILLAR_12_SEED);
464+
let mut max_abs_err: f32 = 0.0;
465+
466+
for _ in 0..N {
467+
let s = [
468+
sample_scale_axis(&mut rng),
469+
sample_scale_axis(&mut rng),
470+
sample_scale_axis(&mut rng),
471+
];
472+
let q = sample_unit_quaternion(&mut rng);
473+
474+
let pillar = covariance_from_scale_quat(s, q);
475+
let prod = Spd3::from_scale_quat(s, q);
476+
let prod_ut = [prod.a11, prod.a12, prod.a13, prod.a22, prod.a23, prod.a33];
477+
478+
for (i, (&p, &pr)) in pillar.iter().zip(prod_ut.iter()).enumerate() {
479+
let err = (p - pr).abs();
480+
if err > max_abs_err {
481+
max_abs_err = err;
482+
}
483+
assert!(
484+
err < 1e-5,
485+
"Pillar/Spd3 drift at lane {i}: pillar={p:.7} prod={pr:.7} err={err:.2e} s={s:?} quat={q:?}"
486+
);
487+
}
488+
}
489+
490+
eprintln!("Pillar 12 ↔ Spd3::from_scale_quat agreement: max_abs_err={max_abs_err:.3e} over {N} pairs");
491+
}
440492
}

0 commit comments

Comments
 (0)