use super::*;
use crate::primitives::Matrix;
use crate::traits::UnsupervisedEstimator;
#[test]
fn falsify_hc_001_labels_length() {
let data = Matrix::from_vec(
6,
2,
vec![
0.0, 0.0, 0.1, 0.1, 0.2, 0.0, 10.0, 10.0, 10.1, 10.1, 10.0, 10.2,
],
)
.expect("valid matrix");
let mut hc = AgglomerativeClustering::new(2, Linkage::Average);
hc.fit(&data).expect("fit succeeds");
let labels = hc.labels();
assert_eq!(
labels.len(),
6,
"FALSIFIED HC-001: labels len={}, expected 6",
labels.len()
);
}
#[test]
fn falsify_hc_002_n_clusters_correct() {
let data = Matrix::from_vec(
6,
2,
vec![
0.0, 0.0, 0.1, 0.1, 0.2, 0.0, 10.0, 10.0, 10.1, 10.1, 10.0, 10.2,
],
)
.expect("valid matrix");
let mut hc = AgglomerativeClustering::new(2, Linkage::Ward);
hc.fit(&data).expect("fit succeeds");
let labels = hc.labels();
let mut unique: Vec<usize> = labels.clone();
unique.sort_unstable();
unique.dedup();
assert_eq!(
unique.len(),
2,
"FALSIFIED HC-002: unique labels={}, expected 2",
unique.len()
);
}
#[test]
fn falsify_hc_003_distinct_clusters() {
let data = Matrix::from_vec(
6,
2,
vec![
0.0, 0.0, 0.1, 0.0, 0.0, 0.1, 100.0, 100.0, 100.1, 100.0, 100.0, 100.1,
],
)
.expect("valid matrix");
let mut hc = AgglomerativeClustering::new(2, Linkage::Single);
hc.fit(&data).expect("fit succeeds");
let labels = hc.labels();
assert_eq!(
labels[0], labels[1],
"FALSIFIED HC-003: cluster A inconsistent"
);
assert_eq!(
labels[1], labels[2],
"FALSIFIED HC-003: cluster A inconsistent"
);
assert_ne!(
labels[0], labels[3],
"FALSIFIED HC-003: clusters have same label={}",
labels[0]
);
}
mod hc_proptest_falsify {
use super::*;
use proptest::prelude::*;
proptest! {
#![proptest_config(ProptestConfig::with_cases(15))]
#[test]
fn falsify_hc_001_prop_labels_length(
n in 4..=15usize,
seed in 0..500u32,
) {
let data: Vec<f32> = (0..n * 2)
.map(|i| ((i as f32 + seed as f32) * 0.37).sin() * 10.0)
.collect();
let matrix = Matrix::from_vec(n, 2, data).expect("valid");
let mut hc = AgglomerativeClustering::new(2, Linkage::Average);
hc.fit(&matrix).expect("fit");
prop_assert_eq!(
hc.labels().len(),
n,
"FALSIFIED HC-001-prop: labels len {} != {}",
hc.labels().len(), n
);
}
}
proptest! {
#![proptest_config(ProptestConfig::with_cases(15))]
#[test]
fn falsify_hc_002_prop_n_clusters(
n in 6..=15usize,
seed in 0..500u32,
) {
let data: Vec<f32> = (0..n * 2)
.map(|i| ((i as f32 + seed as f32) * 0.37).sin() * 10.0)
.collect();
let matrix = Matrix::from_vec(n, 2, data).expect("valid");
let mut hc = AgglomerativeClustering::new(2, Linkage::Ward);
hc.fit(&matrix).expect("fit");
let labels = hc.labels();
let mut unique: Vec<usize> = labels.clone();
unique.sort_unstable();
unique.dedup();
prop_assert_eq!(
unique.len(),
2,
"FALSIFIED HC-002-prop: unique labels {} != 2",
unique.len()
);
}
}
}