use abd_clam::{Cluster, Dataset, Instance, PartitionCriteria, Tree, UniBall, VecDataset};
use distances::Number;
use tempdir::TempDir;
mod utils;
#[test]
fn leaf_indices() {
let data = utils::gen_dataset_from(
vec![
vec![10.],
vec![1.],
vec![-5.],
vec![8.],
vec![3.],
vec![2.],
vec![0.5],
vec![0.],
],
utils::euclidean::<f32, f32>,
vec![true, true, false, false, true, false, true, false],
);
let criteria = PartitionCriteria::default();
let tree = Tree::<_, _, _, UniBall<_>>::new(data, Some(42)).partition(&criteria, Some(42));
let leaf_indices = tree.root().indices().collect::<Vec<_>>();
let tree_indices = (0..tree.cardinality()).collect::<Vec<_>>();
assert_eq!(leaf_indices, tree_indices);
}
#[test]
fn reordering() {
let data = utils::gen_dataset_from(
vec![
vec![10.],
vec![1.],
vec![-5.],
vec![8.],
vec![3.],
vec![2.],
vec![0.5],
vec![0.],
],
utils::euclidean::<f32, f32>,
vec![true, true, false, false, true, false, true, false],
);
let criteria = PartitionCriteria::default();
let tree = Tree::<_, _, _, UniBall<_>>::new(data, Some(42)).partition(&criteria, Some(42));
let tree_indices = (0..tree.cardinality()).collect::<Vec<_>>();
assert_eq!(tree.data().cardinality(), tree_indices.len());
assert_eq!((0..tree.cardinality()).collect::<Vec<_>>(), tree_indices);
}
#[test]
fn save_load() {
let data = utils::gen_dataset(1000, 10, 42, utils::euclidean);
let metric = data.metric();
let criteria = PartitionCriteria::default();
let raw_tree = Tree::new(data, Some(42)).partition(&criteria, Some(42));
let tree_dir = TempDir::new("tree_medium").unwrap();
raw_tree.save(tree_dir.path()).unwrap();
let rec_tree = Tree::load(tree_dir.path(), metric, false).unwrap();
assert_eq!(raw_tree.depth(), rec_tree.depth(), "Tree depths not equal.");
assert_subtree_equal(
raw_tree.root(),
raw_tree.data(),
rec_tree.root(),
rec_tree.data(),
metric,
);
}
fn assert_subtree_equal<I: Instance, U: Number, M: Instance>(
raw_cluster: &UniBall<U>,
raw_data: &VecDataset<I, U, M>,
rec_cluster: &UniBall<U>,
rec_data: &VecDataset<I, U, M>,
metric: fn(&I, &I) -> U,
) {
assert_eq!(
raw_cluster.cardinality(),
rec_cluster.cardinality(),
"Cardinalities are not equal."
);
let (raw_center, rec_center) = (&raw_data[raw_cluster.arg_center()], &rec_data[rec_cluster.arg_center()]);
let (raw_radial, rec_radial) = (&raw_data[raw_cluster.arg_radial()], &rec_data[rec_cluster.arg_radial()]);
assert_eq!(metric(raw_center, rec_center), U::zero(), "Centers are not equal.");
assert_eq!(metric(raw_radial, rec_radial), U::zero(), "Radials are not equal.");
let (raw_children, rec_children) = (&raw_cluster.children(), &rec_cluster.children());
match raw_children {
None => assert!(rec_children.is_none(), "One cluster has children, the other does not"),
Some([left_1, right_1]) => {
assert!(rec_children.is_some(), "One cluster has children, the other does not");
let [left_2, right_2] = rec_children.unwrap();
assert_subtree_equal(left_1, raw_data, left_2, rec_data, metric);
assert_subtree_equal(right_1, raw_data, right_2, rec_data, metric);
}
}
}
#[test]
fn get_cluster() {
let data = utils::gen_dataset(1000, 10, 42, utils::euclidean);
let criteria = PartitionCriteria::default();
let tree = Tree::<_, _, _, UniBall<_>>::new(data, Some(42)).partition(&criteria, Some(42));
let clusters = tree.root().subtree();
for d in 0..tree.depth() {
for &c in clusters.iter().filter(|c| c.depth() == d) {
let (offset, cardinality) = (c.offset(), c.cardinality());
let c_ = tree.get_cluster(offset, cardinality);
assert!(c_.is_some());
let c_ = c_.unwrap();
assert_eq!(c_, c);
}
}
}