use super::*;
use crate::primitives::Matrix;
#[test]
fn falsify_ica_001_output_shape() {
let x = Matrix::from_vec(
10,
3,
vec![
1.0, 0.0, 0.5, 0.0, 1.0, 0.5, 1.0, 1.0, 1.0, -1.0, 0.0, -0.5, 0.0, -1.0, -0.5, -1.0,
-1.0, -1.0, 0.5, -0.5, 0.0, -0.5, 0.5, 0.0, 0.5, 0.5, 0.5, 0.3, 0.7, 0.5,
],
)
.expect("valid");
let mut ica = ICA::new(2);
ica.fit(&x).expect("fit");
let transformed = ica.transform(&x).expect("transform");
let (rows, cols) = transformed.shape();
assert_eq!(
rows, 10,
"FALSIFIED ICA-001: output rows={rows}, expected 10"
);
assert_eq!(cols, 2, "FALSIFIED ICA-001: output cols={cols}, expected 2");
}
#[test]
fn falsify_ica_002_finite_output() {
let x = Matrix::from_vec(
8,
2,
vec![
1.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0, -1.0, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5,
],
)
.expect("valid");
let mut ica = ICA::new(2);
ica.fit(&x).expect("fit");
let transformed = ica.transform(&x).expect("transform");
let (rows, cols) = transformed.shape();
for i in 0..rows {
for j in 0..cols {
let v = transformed.get(i, j);
assert!(
v.is_finite(),
"FALSIFIED ICA-002: output[{i},{j}] = {v} is not finite"
);
}
}
}
#[test]
fn falsify_ica_003_deterministic() {
let x = Matrix::from_vec(
6,
2,
vec![
1.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0, -1.0, 0.5, 0.5, -0.5, -0.5,
],
)
.expect("valid");
let mut ica1 = ICA::new(2);
ica1.fit(&x).expect("fit 1");
let t1 = ica1.transform(&x).expect("transform 1");
let mut ica2 = ICA::new(2);
ica2.fit(&x).expect("fit 2");
let t2 = ica2.transform(&x).expect("transform 2");
let (rows, cols) = t1.shape();
for i in 0..rows {
for j in 0..cols {
assert!(
(t1.get(i, j) - t2.get(i, j)).abs() < 1e-4,
"FALSIFIED ICA-003: output differs at [{i},{j}]"
);
}
}
}
mod ica_proptest_falsify {
use super::*;
use proptest::prelude::*;
proptest! {
#![proptest_config(ProptestConfig::with_cases(10))]
#[test]
fn falsify_ica_001_prop_output_shape(
n_comp in 1..=2usize,
seed in 0..200u32,
) {
let n_samples = 10;
let n_features = 3;
let data: Vec<f32> = (0..n_samples * n_features)
.map(|i| {
let t = i as f32 + seed as f32;
(t * 0.37).sin() * 3.0 + (t * 1.7).cos() * 2.0
})
.collect();
let x = Matrix::from_vec(n_samples, n_features, data).expect("valid");
let mut ica = ICA::new(n_comp);
prop_assume!(ica.fit(&x).is_ok());
let transformed = ica.transform(&x).expect("transform");
let (rows, cols) = transformed.shape();
prop_assert_eq!(rows, n_samples, "FALSIFIED ICA-001-prop: rows {} != {}", rows, n_samples);
prop_assert_eq!(cols, n_comp, "FALSIFIED ICA-001-prop: cols {} != {}", cols, n_comp);
}
}
proptest! {
#![proptest_config(ProptestConfig::with_cases(10))]
#[test]
fn falsify_ica_002_prop_finite_output(
seed in 0..200u32,
) {
let n_samples = 8;
let data: Vec<f32> = (0..n_samples * 2)
.map(|i| {
let t = i as f32 + seed as f32;
(t * 0.37).sin() * 5.0 + (t * 1.7).cos() * 3.0
})
.collect();
let x = Matrix::from_vec(n_samples, 2, data).expect("valid");
let mut ica = ICA::new(2);
prop_assume!(ica.fit(&x).is_ok());
let transformed = ica.transform(&x).expect("transform");
let (rows, cols) = transformed.shape();
for i in 0..rows {
for j in 0..cols {
let v = transformed.get(i, j);
prop_assert!(
v.is_finite(),
"FALSIFIED ICA-002-prop: output[{},{}]={} not finite",
i, j, v
);
}
}
}
}
}