#![cfg(test)]
use super::{DistanceMetric, distance, normalize_in_place};
fn reference_dot(a: &[f32], b: &[f32]) -> f32 {
assert_eq!(a.len(), b.len());
let mut sum = 0.0f32;
for i in 0..a.len() {
sum += a[i] * b[i];
}
sum
}
fn reference_l2(a: &[f32], b: &[f32]) -> f32 {
assert_eq!(a.len(), b.len());
let mut sum = 0.0f32;
for i in 0..a.len() {
let d = a[i] - b[i];
sum += d * d;
}
sum.sqrt()
}
struct Lcg {
state: u64,
}
impl Lcg {
fn new(seed: u64) -> Self {
Self { state: seed }
}
fn next_f32(&mut self, mag: f32) -> f32 {
self.state = self
.state
.wrapping_mul(6_364_136_223_846_793_005)
.wrapping_add(1_442_695_040_888_963_407);
let bits = (self.state >> 33) as u32;
let normalized = (bits as f32 / u32::MAX as f32) * 2.0 - 1.0;
normalized * mag
}
fn vec(&mut self, dim: usize, mag: f32) -> Vec<f32> {
(0..dim).map(|_| self.next_f32(mag)).collect()
}
}
const TOL_ABS: f32 = 1e-5;
const TOL_REL: f32 = 1e-4;
fn close(a: f32, b: f32) -> bool {
let abs_diff = (a - b).abs();
if abs_diff <= TOL_ABS {
return true;
}
let larger = a.abs().max(b.abs());
abs_diff <= larger * TOL_REL
}
#[test]
fn dot_matches_reference_on_lcg_inputs() {
let mut rng = Lcg::new(0xdeadbeef);
for &dim in &[
1_usize, 4, 8, 15, 16, 17, 31, 32, 33, 63, 64, 65, 128, 257, 1024,
] {
for &mag in &[1e-3_f32, 1.0, 10.0, 1e3] {
let a = rng.vec(dim, mag);
let b = rng.vec(dim, mag);
let p = super::dot_product(&a, &b);
let r = reference_dot(&a, &b);
assert!(
close(p, r),
"dot mismatch at dim={dim} mag={mag}: production={p} reference={r}"
);
}
}
}
#[test]
fn l2_matches_reference_on_lcg_inputs() {
let mut rng = Lcg::new(0xc0ffee);
for &dim in &[
1_usize, 4, 8, 15, 16, 17, 31, 32, 33, 63, 64, 65, 128, 257, 1024,
] {
for &mag in &[1e-3_f32, 1.0, 10.0, 1e3] {
let a = rng.vec(dim, mag);
let b = rng.vec(dim, mag);
let p = super::l2_distance(&a, &b);
let r = reference_l2(&a, &b);
assert!(
close(p, r),
"l2 mismatch at dim={dim} mag={mag}: production={p} reference={r}"
);
}
}
}
#[test]
fn dot_identical_unit_vector_is_one() {
let mut v = vec![1.0f32, 2.0, 3.0, 4.0];
normalize_in_place(&mut v).unwrap();
let d = super::dot_product(&v, &v);
assert!(
close(d, 1.0),
"self-dot of unit vector should be 1.0, got {d}"
);
}
#[test]
fn cosine_orthogonal_distance_is_one() {
let e1 = vec![1.0f32, 0.0, 0.0];
let e2 = vec![0.0f32, 1.0, 0.0];
let d = distance(&e1, &e2, DistanceMetric::Cosine);
assert!(
close(d, 1.0),
"orthogonal cosine distance should be 1.0, got {d}"
);
}
#[test]
fn cosine_identical_distance_is_zero() {
let v = vec![0.6f32, 0.8, 0.0]; let d = distance(&v, &v, DistanceMetric::Cosine);
assert!(
close(d, 0.0),
"identical cosine distance should be 0.0, got {d}"
);
}
#[test]
fn l2_identical_distance_is_zero() {
let v = vec![1.5f32, -2.7, 3.14, 0.0];
let d = distance(&v, &v, DistanceMetric::L2);
assert!(
close(d, 0.0),
"identical L2 distance should be 0.0, got {d}"
);
}
#[test]
fn dot_product_off_boundary_remainder_runs() {
let a: Vec<f32> = (0..17).map(|i| (i as f32) * 0.1).collect();
let b: Vec<f32> = (0..17).map(|i| (16 - i) as f32 * 0.1).collect();
let p = super::dot_product(&a, &b);
let r = reference_dot(&a, &b);
assert!(
close(p, r),
"dim=17 tail mismatch: production={p} reference={r}"
);
}
#[test]
fn l2_distance_off_boundary_remainder_runs() {
let a: Vec<f32> = (0..33).map(|i| (i as f32) * 0.05).collect();
let b: Vec<f32> = (0..33).map(|i| ((33 - i) as f32) * 0.05).collect();
let p = super::l2_distance(&a, &b);
let r = reference_l2(&a, &b);
assert!(
close(p, r),
"dim=33 tail mismatch: production={p} reference={r}"
);
}
#[test]
fn dot_handles_small_magnitudes_without_underflow() {
let a = vec![1e-20_f32; 64];
let b = vec![1e-20_f32; 64];
let d = super::dot_product(&a, &b);
assert!(d.is_finite(), "small-mag dot should be finite, got {d}");
}