Semi-ready implementation of Simple KNN

This commit is contained in:
Volodymyr Orlov
2019-09-16 08:52:12 -07:00
parent 9c5f6eb307
commit 3efd078034
6 changed files with 125 additions and 99 deletions
+24 -12
View File
@@ -1,39 +1,51 @@
use super::Distance;
use crate::math::distance::Distance;
use ndarray::{ArrayBase, Data, Dimension};
use crate::common::AnyNumber;
pub struct EuclidianDistance{}
impl<A, S, D> Distance<ArrayBase<S, D>> for EuclidianDistance
impl<A, S1, S2, D> Distance<ArrayBase<S2, D>> for ArrayBase<S1, D>
where
A: AnyNumber,
S: Data<Elem = A>,
D: Dimension
A: AnyNumber,
S1: Data<Elem = A>,
S2: Data<Elem = A>,
D: Dimension
{
fn distance_to(&self, other: &Self) -> f64
{
Self::distance(self, other)
}
fn distance(a: &ArrayBase<S, D>, b: &ArrayBase<S, D>) -> f64 {
fn distance(a: &Self, b: &ArrayBase<S2, D>) -> f64
{
if a.len() != b.len() {
panic!("vectors a and b have different length");
} else {
((a - b)*(a - b)).sum().to_f64().unwrap().sqrt()
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use ndarray::arr1;
use ndarray::{Array1, ArrayView1, arr1};
#[test]
fn measure_simple_euclidian_distance() {
let a = arr1(&[1, 2, 3]);
let b = arr1(&[4, 5, 6]);
let d_arr = EuclidianDistance::distance(&a, &b);
let d_view = EuclidianDistance::distance(&a.view(), &b.view());
// let r1 = a.distance_to(&b);
// let r2 = a.view().distance_to(&b.view());
let d_arr = Array1::distance(&a, &b);
let d_view = ArrayView1::distance(&a.view(), &b.view());
// assert!((r1 - 5.19615242).abs() < 1e-8);
// assert!((r2 - 5.19615242).abs() < 1e-8);
assert!((d_arr - 5.19615242).abs() < 1e-8);
assert!((d_view - 5.19615242).abs() < 1e-8);
}
@@ -43,7 +55,7 @@ mod tests {
let a = arr1(&[-2.1968219, -0.9559913, -0.0431738, 1.0567679, 0.3853515]);
let b = arr1(&[-1.7781325, -0.6659839, 0.9526148, -0.9460919, -0.3925300]);
let d = EuclidianDistance::distance(&a, &b);
let d = Array1::distance(&a, &b);
assert!((d - 2.422302).abs() < 1e-6);
}
+5 -4
View File
@@ -1,8 +1,9 @@
pub mod euclidian;
use num_traits::Float;
pub trait Distance<T> {
fn distance_to(&self, other: &Self) -> f64;
fn distance(a: &Self, b: &T) -> f64;
pub trait Distance<T>
{
fn distance(a: &T, b: &T) -> f64;
}