1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
//! Distance/ similarity functions. use crate::data::Numeric; use ndarray::prelude::*; use num::Float; use rayon::prelude::*; /// L2 norm of a single vector. /// /// # Examples /// /// ``` /// use lsh_rs::dist::l2_norm; /// let a = vec![1., -1.]; /// let norm_a = l2_norm(&a); /// /// // norm between two vectors /// let b = vec![0.2, 1.2]; /// let c: Vec<_> = a.iter().zip(b).map(|(ai, bi)| ai - bi).collect(); /// let norm_ab = l2_norm(&c); /// ``` pub fn l2_norm<N: Numeric + Float>(x: &[N]) -> N { let x = aview1(x); x.dot(&x).sqrt() } /// Dot product between two vectors. /// /// # Panics /// /// Panics if `a.len() != b.len()`. /// /// # Examples /// /// ``` /// use lsh_rs::dist::inner_prod; /// let a = vec![1., -1.]; /// let b = vec![0.2, 1.2]; /// let prod = inner_prod(&a, &b); /// ``` pub fn inner_prod<N: Numeric + Float>(a: &[N], b: &[N]) -> N { aview1(a).dot(&aview1(b)) } /// Cosine similarity between two vectors. /// /// # Panics /// /// Panics if `a.len() != b.len()`. /// /// # Examples /// /// ``` /// use lsh_rs::dist::cosine_sim; /// let a = vec![1., -1.]; /// let b = vec![0.2, 1.2]; /// let sim = cosine_sim(&a, &b); /// ``` pub fn cosine_sim<N: Numeric + Float>(a: &[N], b: &[N]) -> N { inner_prod(a, b) / (l2_norm(a) * l2_norm(b)) }