scirs2_spatial/distance/
types.rs

1//! Auto-generated module
2//!
3//! šŸ¤– Generated with [SplitRS](https://github.com/cool-japan/splitrs)
4
5use scirs2_core::ndarray::{Array2, ArrayView1};
6use scirs2_core::numeric::Float;
7use scirs2_core::simd_ops::SimdUnifiedOps;
8use std::marker::PhantomData;
9
10#[repr(align(64))]
11#[repr(C)]
12#[derive(Debug, Clone)]
13pub struct CacheAlignedBuffer<T> {
14    data: Vec<T>,
15}
16impl<T> CacheAlignedBuffer<T> {
17    #[inline(always)]
18    #[must_use]
19    pub fn new_with_capacity(capacity: usize) -> Self {
20        Self {
21            data: Vec::with_capacity(capacity),
22        }
23    }
24    #[inline(always)]
25    #[must_use]
26    pub fn as_slice(&self) -> &[T] {
27        &self.data
28    }
29    #[inline(always)]
30    #[must_use]
31    pub fn as_mut_slice(&mut self) -> &mut [T] {
32        &mut self.data
33    }
34    #[inline(always)]
35    pub fn push(&mut self, value: T) {
36        self.data.push(value);
37    }
38    #[inline(always)]
39    #[must_use]
40    pub fn len(&self) -> usize {
41        self.data.len()
42    }
43    #[inline(always)]
44    pub fn resize(&mut self, new_len: usize, value: T)
45    where
46        T: Clone,
47    {
48        self.data.resize(new_len, value);
49    }
50}
51/// Manhattan distance metric (L1 norm)
52#[derive(Clone, Debug)]
53pub struct ManhattanDistance<T: Float>(PhantomData<T>);
54impl<T: Float> ManhattanDistance<T> {
55    /// Create a new Manhattan distance metric
56    pub fn new() -> Self {
57        ManhattanDistance(PhantomData)
58    }
59    /// Try SIMD path for f64 arrays
60    #[inline]
61    pub(super) fn try_simd_f64(a: &[T], b: &[T]) -> Option<T> {
62        if std::mem::size_of::<T>() != std::mem::size_of::<f64>() {
63            return None;
64        }
65        unsafe {
66            let a_ptr = a.as_ptr() as *const f64;
67            let b_ptr = b.as_ptr() as *const f64;
68            let len = a.len();
69            let a_slice = std::slice::from_raw_parts(a_ptr, len);
70            let b_slice = std::slice::from_raw_parts(b_ptr, len);
71            let a_view = ArrayView1::from(a_slice);
72            let b_view = ArrayView1::from(b_slice);
73            let result = f64::simd_distance_manhattan(&a_view, &b_view);
74            let result_ptr = &result as *const f64 as *const T;
75            Some(*result_ptr)
76        }
77    }
78    /// Try SIMD path for f32 arrays
79    #[inline]
80    pub(super) fn try_simd_f32(a: &[T], b: &[T]) -> Option<T> {
81        if std::mem::size_of::<T>() != std::mem::size_of::<f32>() {
82            return None;
83        }
84        unsafe {
85            let a_ptr = a.as_ptr() as *const f32;
86            let b_ptr = b.as_ptr() as *const f32;
87            let len = a.len();
88            let a_slice = std::slice::from_raw_parts(a_ptr, len);
89            let b_slice = std::slice::from_raw_parts(b_ptr, len);
90            let a_view = ArrayView1::from(a_slice);
91            let b_view = ArrayView1::from(b_slice);
92            let result = f32::simd_distance_manhattan(&a_view, &b_view);
93            let result_ptr = &result as *const f32 as *const T;
94            Some(*result_ptr)
95        }
96    }
97}
98/// Minkowski distance metric (Lp norm)
99#[derive(Clone, Debug)]
100pub struct MinkowskiDistance<T: Float> {
101    pub(super) p: T,
102    phantom: PhantomData<T>,
103}
104impl<T: Float> MinkowskiDistance<T> {
105    /// Create a new Minkowski distance metric with a given p value
106    ///
107    /// # Arguments
108    ///
109    /// * `p` - The p-value for the Minkowski distance
110    ///
111    /// # Returns
112    ///
113    /// * A new MinkowskiDistance instance
114    pub fn new(p: T) -> Self {
115        MinkowskiDistance {
116            p,
117            phantom: PhantomData,
118        }
119    }
120}
121/// Euclidean distance metric (L2 norm)
122#[derive(Clone, Debug)]
123pub struct EuclideanDistance<T: Float>(PhantomData<T>);
124impl<T: Float> EuclideanDistance<T> {
125    /// Create a new Euclidean distance metric
126    pub fn new() -> Self {
127        EuclideanDistance(PhantomData)
128    }
129    /// Try SIMD path for f64 arrays
130    #[inline]
131    pub(super) fn try_simd_f64(a: &[T], b: &[T]) -> Option<T> {
132        if std::mem::size_of::<T>() != std::mem::size_of::<f64>() {
133            return None;
134        }
135        unsafe {
136            let a_ptr = a.as_ptr() as *const f64;
137            let b_ptr = b.as_ptr() as *const f64;
138            let len = a.len();
139            let a_slice = std::slice::from_raw_parts(a_ptr, len);
140            let b_slice = std::slice::from_raw_parts(b_ptr, len);
141            let a_view = ArrayView1::from(a_slice);
142            let b_view = ArrayView1::from(b_slice);
143            let result = f64::simd_distance_euclidean(&a_view, &b_view);
144            let result_ptr = &result as *const f64 as *const T;
145            Some(*result_ptr)
146        }
147    }
148    /// Try SIMD path for f32 arrays
149    #[inline]
150    pub(super) fn try_simd_f32(a: &[T], b: &[T]) -> Option<T> {
151        if std::mem::size_of::<T>() != std::mem::size_of::<f32>() {
152            return None;
153        }
154        unsafe {
155            let a_ptr = a.as_ptr() as *const f32;
156            let b_ptr = b.as_ptr() as *const f32;
157            let len = a.len();
158            let a_slice = std::slice::from_raw_parts(a_ptr, len);
159            let b_slice = std::slice::from_raw_parts(b_ptr, len);
160            let a_view = ArrayView1::from(a_slice);
161            let b_view = ArrayView1::from(b_slice);
162            let result = f32::simd_distance_euclidean(&a_view, &b_view);
163            let result_ptr = &result as *const f32 as *const T;
164            Some(*result_ptr)
165        }
166    }
167}
168/// Chebyshev distance metric (Lāˆž norm)
169#[derive(Clone, Debug)]
170pub struct ChebyshevDistance<T: Float>(PhantomData<T>);
171impl<T: Float> ChebyshevDistance<T> {
172    /// Create a new Chebyshev distance metric
173    pub fn new() -> Self {
174        ChebyshevDistance(PhantomData)
175    }
176    /// Try SIMD path for f64 arrays
177    #[inline]
178    pub(super) fn try_simd_f64(a: &[T], b: &[T]) -> Option<T> {
179        if std::mem::size_of::<T>() != std::mem::size_of::<f64>() {
180            return None;
181        }
182        unsafe {
183            let a_ptr = a.as_ptr() as *const f64;
184            let b_ptr = b.as_ptr() as *const f64;
185            let len = a.len();
186            let a_slice = std::slice::from_raw_parts(a_ptr, len);
187            let b_slice = std::slice::from_raw_parts(b_ptr, len);
188            let a_view = ArrayView1::from(a_slice);
189            let b_view = ArrayView1::from(b_slice);
190            let result = f64::simd_distance_chebyshev(&a_view, &b_view);
191            let result_ptr = &result as *const f64 as *const T;
192            Some(*result_ptr)
193        }
194    }
195    /// Try SIMD path for f32 arrays
196    #[inline]
197    pub(super) fn try_simd_f32(a: &[T], b: &[T]) -> Option<T> {
198        if std::mem::size_of::<T>() != std::mem::size_of::<f32>() {
199            return None;
200        }
201        unsafe {
202            let a_ptr = a.as_ptr() as *const f32;
203            let b_ptr = b.as_ptr() as *const f32;
204            let len = a.len();
205            let a_slice = std::slice::from_raw_parts(a_ptr, len);
206            let b_slice = std::slice::from_raw_parts(b_ptr, len);
207            let a_view = ArrayView1::from(a_slice);
208            let b_view = ArrayView1::from(b_slice);
209            let result = f32::simd_distance_chebyshev(&a_view, &b_view);
210            let result_ptr = &result as *const f32 as *const T;
211            Some(*result_ptr)
212        }
213    }
214}