use crate::metric::Metric;
use crate::metric::MetricType;
use ndarray::Array1;
use ndarray::ArrayView1;
#[derive(Debug, Clone, Copy)]
pub struct EuclideanMetric;
impl Metric for EuclideanMetric {
fn metric_type(&self) -> MetricType {
MetricType::Euclidean
}
fn distance(&self, x: ArrayView1<f32>, y: ArrayView1<f32>) -> (f32, Array1<f32>) {
let mut sum_sq = 0.0;
for i in 0..x.len() {
let diff = x[i] - y[i];
sum_sq += diff * diff;
}
let dist = sum_sq.sqrt();
let mut grad = Array1::zeros(x.len());
let denom = dist + 1e-6;
for i in 0..x.len() {
grad[i] = (x[i] - y[i]) / denom;
}
(dist, grad)
}
fn disconnection_threshold(&self) -> f32 {
f32::INFINITY
}
fn squared_distance(&self, x: ArrayView1<f32>, y: ArrayView1<f32>) -> Option<f32> {
Some(rdist(&x, &y))
}
}
#[inline]
pub fn rdist(x: &ArrayView1<f32>, y: &ArrayView1<f32>) -> f32 {
let mut sum_sq = 0.0;
for i in 0..x.len() {
let diff = x[i] - y[i];
sum_sq += diff * diff;
}
sum_sq
}