use proptest::prelude::*;
use super::*;
proptest! {
#[test]
fn round_trip_identity_prop(
means in prop::collection::vec(-100.0f32..100.0, 1..6),
scales in prop::collection::vec(0.01f32..100.0, 1..6),
rows in 0usize..8,
) {
let dim = means.len().min(scales.len());
let norm = LatentNorm::new(
means[..dim].to_vec(),
scales[..dim].to_vec(),
LatentNorm::DEFAULT_EPS,
).unwrap();
let data: Vec<f32> = (0..rows * dim).map(|i| (i as f32 % 7.0) - 3.0).collect();
let latent = seq(rows, dim, data);
let standardized = norm.standardize(&latent).unwrap();
let back = norm.unstandardize(&standardized).unwrap();
for (x, y) in latent.values().iter().zip(back.values()) {
let tol = 1e-3 * (1.0 + x.abs());
prop_assert!((x - y).abs() <= tol, "{x} vs {y}");
}
}
#[test]
fn fit_yields_valid_invariants(
values in prop::collection::vec(-1.0e3f32..1.0e3, 2..32),
) {
let rows = values.len() / 2;
let data = values[..rows * 2].to_vec();
let latent = seq(rows, 2, data);
let norm = LatentNorm::fit([&latent], LatentNorm::DEFAULT_EPS).unwrap();
prop_assert_eq!(norm.mean().len(), norm.std().len());
prop_assert!(norm.mean().iter().all(|m| m.is_finite()));
prop_assert!(norm.std().iter().all(|s| s.is_finite() && *s > 0.0));
}
}