use sqlite_vector_rs::distance::{DistanceMetric, compute_distance};
use sqlite_vector_rs::types::VectorType;
#[test]
fn l2_identical_vectors_float4() {
let a: Vec<f32> = vec![1.0, 2.0, 3.0];
let blob_a = VectorType::Float4.slice_to_blob(&a);
let dist =
compute_distance(&blob_a, &blob_a, VectorType::Float4, DistanceMetric::L2, 3).unwrap();
assert!((dist - 0.0).abs() < 1e-6);
}
#[test]
fn l2_known_distance_float4() {
let a: Vec<f32> = vec![1.0, 0.0, 0.0];
let b: Vec<f32> = vec![0.0, 1.0, 0.0];
let blob_a = VectorType::Float4.slice_to_blob(&a);
let blob_b = VectorType::Float4.slice_to_blob(&b);
let dist =
compute_distance(&blob_a, &blob_b, VectorType::Float4, DistanceMetric::L2, 3).unwrap();
assert!((dist - 2.0).abs() < 1e-6);
}
#[test]
fn cosine_identical_float4() {
let a: Vec<f32> = vec![1.0, 2.0, 3.0];
let blob_a = VectorType::Float4.slice_to_blob(&a);
let dist = compute_distance(
&blob_a,
&blob_a,
VectorType::Float4,
DistanceMetric::Cosine,
3,
)
.unwrap();
assert!(dist.abs() < 1e-5);
}
#[test]
fn cosine_orthogonal_float4() {
let a: Vec<f32> = vec![1.0, 0.0];
let b: Vec<f32> = vec![0.0, 1.0];
let blob_a = VectorType::Float4.slice_to_blob(&a);
let blob_b = VectorType::Float4.slice_to_blob(&b);
let dist = compute_distance(
&blob_a,
&blob_b,
VectorType::Float4,
DistanceMetric::Cosine,
2,
)
.unwrap();
assert!((dist - 1.0).abs() < 1e-5);
}
#[test]
fn inner_product_known_float4() {
let a: Vec<f32> = vec![1.0, 2.0, 3.0];
let b: Vec<f32> = vec![4.0, 5.0, 6.0];
let blob_a = VectorType::Float4.slice_to_blob(&a);
let blob_b = VectorType::Float4.slice_to_blob(&b);
let dist = compute_distance(
&blob_a,
&blob_b,
VectorType::Float4,
DistanceMetric::InnerProduct,
3,
)
.unwrap();
assert!((dist - (-32.0)).abs() < 1e-6);
}
#[test]
fn parse_metric_names() {
assert_eq!(DistanceMetric::from_name("l2").unwrap(), DistanceMetric::L2);
assert_eq!(
DistanceMetric::from_name("cosine").unwrap(),
DistanceMetric::Cosine
);
assert_eq!(
DistanceMetric::from_name("ip").unwrap(),
DistanceMetric::InnerProduct
);
assert!(DistanceMetric::from_name("hamming").is_err());
}
#[test]
fn distance_dimension_mismatch() {
let a: Vec<f32> = vec![1.0, 2.0, 3.0];
let b: Vec<f32> = vec![1.0, 2.0];
let blob_a = VectorType::Float4.slice_to_blob(&a);
let blob_b = VectorType::Float4.slice_to_blob(&b);
assert!(compute_distance(&blob_a, &blob_b, VectorType::Float4, DistanceMetric::L2, 3).is_err());
}