use super::*;
#[test]
fn fit_recovers_known_statistics() {
let latent = seq(3, 2, vec![0.0, 1.0, 2.0, 1.0, 4.0, 1.0]);
let norm = LatentNorm::fit([&latent], LatentNorm::DEFAULT_EPS).unwrap();
assert_eq!(norm.dim(), 2);
assert!((norm.mean()[0] - 2.0).abs() < 1e-6);
assert!((norm.mean()[1] - 1.0).abs() < 1e-6);
assert!((norm.std()[0] as f64 - (8.0f64 / 3.0).sqrt()).abs() < 1e-5);
assert_eq!(norm.std()[1], LatentNorm::DEFAULT_EPS);
}
#[test]
fn fit_pools_across_latents() {
let a = seq(2, 1, vec![0.0, 2.0]);
let b = seq(2, 1, vec![4.0, 6.0]);
let norm = LatentNorm::fit([&a, &b], LatentNorm::DEFAULT_EPS).unwrap();
assert_eq!(norm.dim(), 1);
assert!((norm.mean()[0] - 3.0).abs() < 1e-6);
}
#[test]
fn standardize_centers_and_scales_the_fit_data() {
let latent = seq(3, 2, vec![0.0, 10.0, 2.0, 20.0, 4.0, 30.0]);
let norm = LatentNorm::fit([&latent], LatentNorm::DEFAULT_EPS).unwrap();
let std = norm.standardize(&latent).unwrap();
for d in 0..2 {
let col: Vec<f64> = (0..3).map(|f| std.values()[f * 2 + d] as f64).collect();
let mean = col.iter().sum::<f64>() / 3.0;
let var = col.iter().map(|x| (x - mean).powi(2)).sum::<f64>() / 3.0;
assert!(mean.abs() < 1e-5, "dim {d} mean {mean}");
assert!(
(var.sqrt() - 1.0).abs() < 1e-4,
"dim {d} std {}",
var.sqrt()
);
}
}