scirs2_spatial/distance/
minkowskidistance_traits.rs1use 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}