vectors/dense/stack/
distance.rs

1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at http://mozilla.org/MPL/2.0/.
4
5use num_traits::Signed;
6
7use arrayvec::Array;
8
9use Distance;
10use super::DenseVector;
11
12impl<T, A> Distance for DenseVector<A>
13where
14    T: Copy + Signed,
15    A: Array<Item = T>,
16{
17    type Scalar = T;
18
19    fn squared_distance(&self, rhs: &Self) -> Self::Scalar {
20        let lhs_iter = self.iter();
21        let rhs_iter = rhs.iter();
22        debug_assert_eq!(lhs_iter.len(), rhs_iter.len());
23        lhs_iter.zip(rhs_iter).fold(T::zero(), |sum, ((_, lhs), (_, rhs))| {
24            let delta = lhs - rhs;
25            sum + (delta * delta)
26        })
27    }
28}
29
30#[cfg(test)]
31mod test {
32    use super::*;
33
34    use expectest::prelude::*;
35
36    #[test]
37    fn squared_distance() {
38        let subject = DenseVector::from([0.0, 0.5, 1.0, 2.0, 4.0]);
39        let other = DenseVector::from([0.1, 0.2, 0.3, 0.4, 0.0]);
40        let squared_distance = subject.squared_distance(&other);
41        expect!(squared_distance).to(be_close_to(19.15));
42    }
43
44    #[test]
45    fn distance() {
46        let subject = DenseVector::from([0.0, 0.5, 1.0, 2.0, 4.0]);
47        let other = DenseVector::from([0.1, 0.2, 0.3, 0.4, 0.0]);
48        let distance = subject.distance(&other);
49        expect!(distance).to(be_close_to(4.376));
50    }
51}