Skip to main content

scirs2_spatial/distance/
minkowskidistance_traits.rs

1//! # MinkowskiDistance - Trait Implementations
2//!
3//! This module contains trait implementations for `MinkowskiDistance`.
4//!
5//! ## Implemented Traits
6//!
7//! - `Distance`
8//!
9//! 🤖 Generated with [SplitRS](https://github.com/cool-japan/splitrs)
10
11use scirs2_core::numeric::Float;
12
13use super::functions::prefetch_read;
14use super::functions::Distance;
15use super::types::MinkowskiDistance;
16
17impl<T: Float + Send + Sync> Distance<T> for MinkowskiDistance<T> {
18    fn distance(&self, a: &[T], b: &[T]) -> T {
19        if a.len() != b.len() {
20            return T::nan();
21        }
22        if self.p == T::one() {
23            let mut sum = T::zero();
24            for i in 0..a.len() {
25                sum = sum + (a[i] - b[i]).abs();
26            }
27            sum
28        } else if self.p == T::from(2.0).expect("Operation failed") {
29            let mut sum = T::zero();
30            for i in 0..a.len() {
31                let diff = a[i] - b[i];
32                sum = sum + diff * diff;
33            }
34            sum.sqrt()
35        } else if self.p == T::infinity() {
36            let mut max_diff = T::zero();
37            for i in 0..a.len() {
38                let diff = (a[i] - b[i]).abs();
39                if diff > max_diff {
40                    max_diff = diff;
41                }
42            }
43            max_diff
44        } else {
45            let mut sum = T::zero();
46            for i in 0..a.len() {
47                sum = sum + (a[i] - b[i]).abs().powf(self.p);
48            }
49            sum.powf(T::one() / self.p)
50        }
51    }
52    fn min_distance_point_rectangle(&self, point: &[T], mins: &[T], maxes: &[T]) -> T {
53        if self.p == T::one() {
54            let mut sum = T::zero();
55            for i in 0..point.len() {
56                if point[i] < mins[i] {
57                    sum = sum + (mins[i] - point[i]);
58                } else if point[i] > maxes[i] {
59                    sum = sum + (point[i] - maxes[i]);
60                }
61            }
62            sum
63        } else if self.p == T::from(2.0).expect("Operation failed") {
64            let mut sum = T::zero();
65            for i in 0..point.len() {
66                if point[i] < mins[i] {
67                    let diff = mins[i] - point[i];
68                    sum = sum + diff * diff;
69                } else if point[i] > maxes[i] {
70                    let diff = point[i] - maxes[i];
71                    sum = sum + diff * diff;
72                }
73            }
74            sum.sqrt()
75        } else if self.p == T::infinity() {
76            let mut max_diff = T::zero();
77            for i in 0..point.len() {
78                let diff = if point[i] < mins[i] {
79                    mins[i] - point[i]
80                } else if point[i] > maxes[i] {
81                    point[i] - maxes[i]
82                } else {
83                    T::zero()
84                };
85                if diff > max_diff {
86                    max_diff = diff;
87                }
88            }
89            max_diff
90        } else {
91            let mut sum = T::zero();
92            for i in 0..point.len() {
93                let diff = if point[i] < mins[i] {
94                    mins[i] - point[i]
95                } else if point[i] > maxes[i] {
96                    point[i] - maxes[i]
97                } else {
98                    T::zero()
99                };
100                sum = sum + diff.powf(self.p);
101            }
102            sum.powf(T::one() / self.p)
103        }
104    }
105}