kd_tree/
lib.rs

1//! k-dimensional tree.
2//!
3//! # Usage
4//! ```
5//! // construct kd-tree
6//! let kdtree = kd_tree::KdTree::build_by_ordered_float(vec![
7//!     [1.0, 2.0, 3.0],
8//!     [3.0, 1.0, 2.0],
9//!     [2.0, 3.0, 1.0],
10//! ]);
11//!
12//! // search the nearest neighbor
13//! let found = kdtree.nearest(&[3.1, 0.9, 2.1]).unwrap();
14//! assert_eq!(found.item, &[3.0, 1.0, 2.0]);
15//!
16//! // search k-nearest neighbors
17//! let found = kdtree.nearests(&[1.5, 2.5, 1.8], 2);
18//! assert_eq!(found[0].item, &[2.0, 3.0, 1.0]);
19//! assert_eq!(found[1].item, &[1.0, 2.0, 3.0]);
20//!
21//! // search points within a sphere
22//! let found = kdtree.within_radius(&[2.0, 1.5, 2.5], 1.5);
23//! assert_eq!(found.len(), 2);
24//! assert!(found.iter().any(|&&p| p == [1.0, 2.0, 3.0]));
25//! assert!(found.iter().any(|&&p| p == [3.0, 1.0, 2.0]));
26//! ```
27mod nalgebra;
28mod nearest;
29mod nearests;
30mod sort;
31mod tests;
32mod within;
33use nearest::*;
34use nearests::*;
35use sort::*;
36use std::cmp::Ordering;
37use std::marker::PhantomData;
38use typenum::Unsigned;
39use within::*;
40
41/// A trait to represent k-dimensional point.
42///
43/// # Example
44/// ```
45/// struct MyItem {
46///     point: [f64; 3],
47///     id: usize,
48/// }
49/// impl kd_tree::KdPoint for MyItem {
50///     type Scalar = f64;
51///     type Dim = typenum::U3;
52///     fn at(&self, k: usize) -> f64 { self.point[k] }
53/// }
54/// let kdtree: kd_tree::KdTree<MyItem> = kd_tree::KdTree::build_by_ordered_float(vec![
55///     MyItem { point: [1.0, 2.0, 3.0], id: 111 },
56///     MyItem { point: [3.0, 1.0, 2.0], id: 222 },
57///     MyItem { point: [2.0, 3.0, 1.0], id: 333 },
58/// ]);
59/// assert_eq!(kdtree.nearest(&[3.1, 0.1, 2.2]).unwrap().item.id, 222);
60/// ```
61pub trait KdPoint {
62    type Scalar: num_traits::NumAssign + Copy + PartialOrd;
63    type Dim: Unsigned;
64    fn dim() -> usize {
65        <Self::Dim as Unsigned>::to_usize()
66    }
67    fn at(&self, i: usize) -> Self::Scalar;
68}
69
70#[derive(Debug, Clone, Copy, PartialEq, Eq)]
71pub struct ItemAndDistance<'a, T, Scalar> {
72    pub item: &'a T,
73    pub squared_distance: Scalar,
74}
75
76/// A slice of kd-tree.
77/// This type implements [`std::ops::Deref`] to `[T]`.
78/// This is an unsized type, meaning that it must always be used as a reference.
79/// For an owned version of this type, see [`KdTree`].
80#[derive(Debug, PartialEq, Eq)]
81pub struct KdSliceN<T, N: Unsigned>(PhantomData<N>, [T]);
82pub type KdSlice<T> = KdSliceN<T, <T as KdPoint>::Dim>;
83impl<T, N: Unsigned> std::ops::Deref for KdSliceN<T, N> {
84    type Target = [T];
85    fn deref(&self) -> &[T] {
86        &self.1
87    }
88}
89impl<T: Clone, N: Unsigned> std::borrow::ToOwned for KdSliceN<T, N> {
90    type Owned = KdTreeN<T, N>;
91    fn to_owned(&self) -> Self::Owned {
92        KdTreeN(PhantomData, self.1.to_vec())
93    }
94}
95impl<T, N: Unsigned> KdSliceN<T, N> {
96    pub fn items(&self) -> &[T] {
97        &self.1
98    }
99
100    unsafe fn new_unchecked(items: &[T]) -> &Self {
101        &*(items as *const _ as *const Self)
102    }
103
104    /// # Example
105    /// ```
106    /// struct Item {
107    ///     point: [i32; 3],
108    ///     id: usize,
109    /// }
110    /// let mut items: Vec<Item> = vec![
111    ///     Item { point: [1, 2, 3], id: 111 },
112    ///     Item { point: [3, 1, 2], id: 222 },
113    ///     Item { point: [2, 3, 1], id: 333 },
114    /// ];
115    /// let kdtree = kd_tree::KdSlice3::sort_by(&mut items, |item1, item2, k| item1.point[k].cmp(&item2.point[k]));
116    /// assert_eq!(kdtree.nearest_by(&[3, 1, 2], |item, k| item.point[k]).unwrap().item.id, 222);
117    /// ```
118    pub fn sort_by<F>(items: &mut [T], compare: F) -> &Self
119    where
120        F: Fn(&T, &T, usize) -> Ordering + Copy,
121    {
122        kd_sort_by(items, N::to_usize(), compare);
123        unsafe { Self::new_unchecked(items) }
124    }
125
126    /// # Example
127    /// ```
128    /// struct Item {
129    ///     point: [f64; 3],
130    ///     id: usize,
131    /// }
132    /// let mut items: Vec<Item> = vec![
133    ///     Item { point: [1.0, 2.0, 3.0], id: 111 },
134    ///     Item { point: [3.0, 1.0, 2.0], id: 222 },
135    ///     Item { point: [2.0, 3.0, 1.0], id: 333 },
136    /// ];
137    /// use ordered_float::OrderedFloat;
138    /// let kdtree = kd_tree::KdSlice3::sort_by_key(&mut items, |item, k| OrderedFloat(item.point[k]));
139    /// assert_eq!(kdtree.nearest_by(&[3.1, 0.9, 2.1], |item, k| item.point[k]).unwrap().item.id, 222);
140    /// ```
141    pub fn sort_by_key<Key: Ord, F>(items: &mut [T], kd_key: F) -> &Self
142    where
143        F: Fn(&T, usize) -> Key + Copy,
144    {
145        Self::sort_by(items, |item1, item2, k| {
146            kd_key(item1, k).cmp(&kd_key(item2, k))
147        })
148    }
149
150    /// # Example
151    /// ```
152    /// use kd_tree::KdSlice;
153    /// let mut items: Vec<[f64; 3]> = vec![[1.0, 2.0, 3.0], [3.0, 1.0, 2.0], [2.0, 3.0, 1.0]];
154    /// let kdtree: &KdSlice<[f64; 3]> = KdSlice::sort_by_ordered_float(&mut items);
155    /// assert_eq!(kdtree.nearest(&[3.1, 0.9, 2.1]).unwrap().item, &[3.0, 1.0, 2.0]);
156    /// ```
157    pub fn sort_by_ordered_float(points: &mut [T]) -> &Self
158    where
159        T: KdPoint<Dim = N>,
160        T::Scalar: ordered_float::FloatCore,
161    {
162        Self::sort_by_key(points, |item, k| ordered_float::OrderedFloat(item.at(k)))
163    }
164
165    /// # Example
166    /// ```
167    /// use kd_tree::KdSlice;
168    /// let mut items: Vec<[i32; 3]> = vec![[1, 2, 3], [3, 1, 2], [2, 3, 1]];
169    /// let kdtree: &KdSlice<[i32; 3]> = KdSlice::sort(&mut items);
170    /// assert_eq!(kdtree.nearest(&[3, 1, 2]).unwrap().item, &[3, 1, 2]);
171    /// ```
172    pub fn sort(points: &mut [T]) -> &Self
173    where
174        T: KdPoint<Dim = N>,
175        T::Scalar: Ord,
176    {
177        Self::sort_by_key(points, |item, k| item.at(k))
178    }
179
180    /// Returns the nearest item from the input point. Returns `None` if `self.is_empty()`.
181    /// # Example
182    /// ```
183    /// struct Item {
184    ///     point: [f64; 3],
185    ///     id: usize,
186    /// }
187    /// let mut items: Vec<Item> = vec![
188    ///     Item { point: [1.0, 2.0, 3.0], id: 111 },
189    ///     Item { point: [3.0, 1.0, 2.0], id: 222 },
190    ///     Item { point: [2.0, 3.0, 1.0], id: 333 },
191    /// ];
192    /// use ordered_float::OrderedFloat;
193    /// let kdtree = kd_tree::KdSlice3::sort_by_key(&mut items, |item, k| OrderedFloat(item.point[k]));
194    /// assert_eq!(kdtree.nearest_by(&[3.1, 0.9, 2.1], |item, k| item.point[k]).unwrap().item.id, 222);
195    /// ```
196    pub fn nearest_by<Q: KdPoint<Dim = N>>(
197        &self,
198        query: &Q,
199        coord: impl Fn(&T, usize) -> Q::Scalar + Copy,
200    ) -> Option<ItemAndDistance<T, Q::Scalar>> {
201        if self.is_empty() {
202            None
203        } else {
204            Some(kd_nearest_by(self.items(), query, coord))
205        }
206    }
207
208    /// Returns the nearest item from the input point. Returns `None` if `self.is_empty()`.
209    /// # Example
210    /// ```
211    /// let mut items: Vec<[i32; 3]> = vec![[1, 2, 3], [3, 1, 2], [2, 3, 1]];
212    /// let kdtree = kd_tree::KdSlice::sort(&mut items);
213    /// assert_eq!(kdtree.nearest(&[3, 1, 2]).unwrap().item, &[3, 1, 2]);
214    /// ```
215    pub fn nearest(
216        &self,
217        query: &impl KdPoint<Scalar = T::Scalar, Dim = N>,
218    ) -> Option<ItemAndDistance<T, T::Scalar>>
219    where
220        T: KdPoint<Dim = N>,
221    {
222        if self.is_empty() {
223            None
224        } else {
225            Some(kd_nearest(self.items(), query))
226        }
227    }
228
229    /*
230    /// # Example
231    /// ```
232    /// let kdtree = kd_tree::KdTree3::build(vec![[1, 2, 3], [3, 1, 2], [2, 3, 1]]);
233    /// let key = [3, 1, 2];
234    /// assert_eq!(kdtree.nearest_with(|p, k| key[k] - p[k]).item, &[3, 1, 2]);
235    /// ```
236    pub fn nearest_with<Scalar>(
237        &self,
238        kd_difference: impl Fn(&T, usize) -> Scalar + Copy,
239    ) -> ItemAndDistance<T, Scalar>
240    where
241        Scalar: num_traits::NumAssign + Copy + PartialOrd,
242    {
243        kd_nearest_with(self.items(), N::to_usize(), kd_difference)
244    }
245    */
246
247    /// Returns the nearest item from the input point. Returns `None` if `self.is_empty()`.
248    /// # Example
249    /// ```
250    /// struct Item {
251    ///     point: [f64; 3],
252    ///     id: usize,
253    /// }
254    /// let mut items: Vec<Item> = vec![
255    ///     Item { point: [1.0, 2.0, 3.0], id: 111 },
256    ///     Item { point: [3.0, 1.0, 2.0], id: 222 },
257    ///     Item { point: [2.0, 3.0, 1.0], id: 333 },
258    /// ];
259    /// use ordered_float::OrderedFloat;
260    /// let kdtree = kd_tree::KdSlice3::sort_by_key(&mut items, |item, k| OrderedFloat(item.point[k]));
261    /// let nearests = kdtree.nearests_by(&[2.5, 2.0, 1.4], 2, |item, k| item.point[k]);
262    /// assert_eq!(nearests.len(), 2);
263    /// assert_eq!(nearests[0].item.id, 333);
264    /// assert_eq!(nearests[1].item.id, 222);
265    /// ```
266    pub fn nearests_by<Q: KdPoint<Dim = N>>(
267        &self,
268        query: &Q,
269        num: usize,
270        coord: impl Fn(&T, usize) -> Q::Scalar + Copy,
271    ) -> Vec<ItemAndDistance<T, Q::Scalar>> {
272        kd_nearests_by(self.items(), query, num, coord)
273    }
274
275    /// Returns kNN(k nearest neighbors) from the input point.
276    /// # Example
277    /// ```
278    /// let mut items: Vec<[i32; 3]> = vec![[1, 2, 3], [3, 1, 2], [2, 3, 1], [3, 2, 2]];
279    /// let kdtree = kd_tree::KdSlice::sort(&mut items);
280    /// let nearests = kdtree.nearests(&[3, 1, 2], 2);
281    /// assert_eq!(nearests.len(), 2);
282    /// assert_eq!(nearests[0].item, &[3, 1, 2]);
283    /// assert_eq!(nearests[1].item, &[3, 2, 2]);
284    /// ```
285    pub fn nearests(
286        &self,
287        query: &impl KdPoint<Scalar = T::Scalar, Dim = N>,
288        num: usize,
289    ) -> Vec<ItemAndDistance<T, T::Scalar>>
290    where
291        T: KdPoint<Dim = N>,
292    {
293        kd_nearests(self.items(), query, num)
294    }
295
296    pub fn within_by_cmp(&self, compare: impl Fn(&T, usize) -> Ordering + Copy) -> Vec<&T> {
297        kd_within_by_cmp(self, N::to_usize(), compare)
298    }
299
300    pub fn within_by<Q: KdPoint<Dim = N>>(
301        &self,
302        query: &[Q; 2],
303        coord: impl Fn(&T, usize) -> Q::Scalar + Copy,
304    ) -> Vec<&T> {
305        assert!((0..Q::dim()).all(|k| query[0].at(k) <= query[1].at(k)));
306        self.within_by_cmp(|item, k| {
307            let a = coord(item, k);
308            if a < query[0].at(k) {
309                Ordering::Less
310            } else if a > query[1].at(k) {
311                Ordering::Greater
312            } else {
313                Ordering::Equal
314            }
315        })
316    }
317
318    /// search points within a rectangular region
319    /// # Example
320    /// ```
321    /// let mut items: Vec<[i32; 2]> = vec![[0, 0], [1, 0], [0, 1], [1, 1]];
322    /// let kdtree = kd_tree::KdSlice::sort(&mut items);
323    /// let within = kdtree.within(&[[1, 0], [2, 1]]);
324    /// assert_eq!(within.len(), 2);
325    /// assert!(within.contains(&&[1, 0]));
326    /// assert!(within.contains(&&[1, 1]));
327    /// ```
328    pub fn within(&self, query: &[impl KdPoint<Scalar = T::Scalar, Dim = N>; 2]) -> Vec<&T>
329    where
330        T: KdPoint<Dim = N>,
331    {
332        self.within_by(query, |item, k| item.at(k))
333    }
334
335    pub fn within_radius_by<Q: KdPoint<Dim = N>>(
336        &self,
337        query: &Q,
338        radius: Q::Scalar,
339        coord: impl Fn(&T, usize) -> Q::Scalar + Copy,
340    ) -> Vec<&T> {
341        let mut results = self.within_by_cmp(|item, k| {
342            let coord = coord(item, k);
343            if coord < query.at(k) - radius {
344                Ordering::Less
345            } else if coord > query.at(k) + radius {
346                Ordering::Greater
347            } else {
348                Ordering::Equal
349            }
350        });
351        results.retain(|item| {
352            let mut distance = <Q::Scalar as num_traits::Zero>::zero();
353            for k in 0..N::to_usize() {
354                let diff = coord(item, k) - query.at(k);
355                distance += diff * diff;
356            }
357            distance < radius * radius
358        });
359        results
360    }
361
362    /// search points within k-dimensional sphere
363    pub fn within_radius(
364        &self,
365        query: &impl KdPoint<Scalar = T::Scalar, Dim = N>,
366        radius: T::Scalar,
367    ) -> Vec<&T>
368    where
369        T: KdPoint<Dim = N>,
370    {
371        self.within_radius_by(query, radius, |item, k| item.at(k))
372    }
373}
374#[cfg(feature = "rayon")]
375impl<T: Send, N: Unsigned> KdSliceN<T, N> {
376    /// Same as [`Self::sort_by`], but using multiple threads.
377    pub fn par_sort_by<F>(items: &mut [T], compare: F) -> &Self
378    where
379        F: Fn(&T, &T, usize) -> Ordering + Copy + Send,
380    {
381        kd_par_sort_by(items, N::to_usize(), compare);
382        unsafe { Self::new_unchecked(items) }
383    }
384
385    /// Same as [`Self::sort_by_key`], but using multiple threads.
386    pub fn par_sort_by_key<Key: Ord, F>(items: &mut [T], kd_key: F) -> &Self
387    where
388        F: Fn(&T, usize) -> Key + Copy + Send,
389    {
390        Self::par_sort_by(items, move |item1, item2, k| {
391            kd_key(item1, k).cmp(&kd_key(item2, k))
392        })
393    }
394
395    /// Same as [`Self::sort_by_ordered_float`], but using multiple threads.
396    pub fn par_sort_by_ordered_float(points: &mut [T]) -> &Self
397    where
398        T: KdPoint<Dim = N>,
399        T::Scalar: ordered_float::FloatCore,
400    {
401        Self::par_sort_by_key(points, |item, k| ordered_float::OrderedFloat(item.at(k)))
402    }
403
404    /// Same as [`Self::sort`], but using multiple threads.
405    pub fn par_sort(points: &mut [T]) -> &Self
406    where
407        T: KdPoint<Dim = N>,
408        T::Scalar: Ord,
409    {
410        Self::par_sort_by_key(points, |item, k| item.at(k))
411    }
412}
413
414/// An owned kd-tree.
415/// This type implements [`std::ops::Deref`] to [`KdSlice`].
416#[derive(Debug, Clone, PartialEq, Eq, Default)]
417pub struct KdTreeN<T, N: Unsigned>(PhantomData<N>, Vec<T>);
418pub type KdTree<T> = KdTreeN<T, <T as KdPoint>::Dim>;
419impl<T, N: Unsigned> std::ops::Deref for KdTreeN<T, N> {
420    type Target = KdSliceN<T, N>;
421    fn deref(&self) -> &Self::Target {
422        unsafe { KdSliceN::new_unchecked(&self.1) }
423    }
424}
425impl<T, N: Unsigned> AsRef<KdSliceN<T, N>> for KdTreeN<T, N> {
426    fn as_ref(&self) -> &KdSliceN<T, N> {
427        self
428    }
429}
430impl<T, N: Unsigned> std::borrow::Borrow<KdSliceN<T, N>> for KdTreeN<T, N> {
431    fn borrow(&self) -> &KdSliceN<T, N> {
432        self
433    }
434}
435impl<T, N: Unsigned> From<KdTreeN<T, N>> for Vec<T> {
436    fn from(src: KdTreeN<T, N>) -> Self {
437        src.1
438    }
439}
440impl<T, N: Unsigned> KdTreeN<T, N> {
441    pub fn into_vec(self) -> Vec<T> {
442        self.1
443    }
444
445    /// # Example
446    /// ```
447    /// struct Item {
448    ///     point: [i32; 3],
449    ///     id: usize,
450    /// }
451    /// let kdtree = kd_tree::KdTree3::build_by(
452    ///     vec![
453    ///         Item { point: [1, 2, 3], id: 111 },
454    ///         Item { point: [3, 1, 2], id: 222 },
455    ///         Item { point: [2, 3, 1], id: 333 },
456    ///     ],
457    ///     |item1, item2, k| item1.point[k].cmp(&item2.point[k])
458    /// );
459    /// assert_eq!(kdtree.nearest_by(&[3, 1, 2], |item, k| item.point[k]).unwrap().item.id, 222);
460    /// ```
461    pub fn build_by<F>(mut items: Vec<T>, compare: F) -> Self
462    where
463        F: Fn(&T, &T, usize) -> Ordering + Copy,
464    {
465        kd_sort_by(&mut items, N::to_usize(), compare);
466        Self(PhantomData, items)
467    }
468
469    /// # Example
470    /// ```
471    /// struct Item {
472    ///     point: [f64; 3],
473    ///     id: usize,
474    /// }
475    /// let kdtree = kd_tree::KdTree3::build_by_key(
476    ///     vec![
477    ///         Item { point: [1.0, 2.0, 3.0], id: 111 },
478    ///         Item { point: [3.0, 1.0, 2.0], id: 222 },
479    ///         Item { point: [2.0, 3.0, 1.0], id: 333 },
480    ///     ],
481    ///     |item, k| ordered_float::OrderedFloat(item.point[k])
482    /// );
483    /// assert_eq!(kdtree.nearest_by(&[3.1, 0.9, 2.1], |item, k| item.point[k]).unwrap().item.id, 222);
484    /// ```
485    pub fn build_by_key<Key, F>(items: Vec<T>, kd_key: F) -> Self
486    where
487        Key: Ord,
488        F: Fn(&T, usize) -> Key + Copy,
489    {
490        Self::build_by(items, |item1, item2, k| {
491            kd_key(item1, k).cmp(&kd_key(item2, k))
492        })
493    }
494
495    /// # Example
496    /// ```
497    /// use kd_tree::KdTree;
498    /// let kdtree: KdTree<[f64; 3]> = KdTree::build_by_ordered_float(vec![
499    ///     [1.0, 2.0, 3.0], [3.0, 1.0, 2.0], [2.0, 3.0, 1.0]
500    /// ]);
501    /// assert_eq!(kdtree.nearest(&[3.1, 0.9, 2.1]).unwrap().item, &[3.0, 1.0, 2.0]);
502    /// ```
503    pub fn build_by_ordered_float(points: Vec<T>) -> Self
504    where
505        T: KdPoint<Dim = N>,
506        T::Scalar: ordered_float::FloatCore,
507    {
508        Self::build_by_key(points, |item, k| ordered_float::OrderedFloat(item.at(k)))
509    }
510
511    /// # Example
512    /// ```
513    /// use kd_tree::KdTree;
514    /// let kdtree: KdTree<[i32; 3]> = KdTree::build(vec![[1, 2, 3], [3, 1, 2], [2, 3, 1]]);
515    /// assert_eq!(kdtree.nearest(&[3, 1, 2]).unwrap().item, &[3, 1, 2]);
516    /// ```
517    pub fn build(points: Vec<T>) -> Self
518    where
519        T: KdPoint<Dim = N>,
520        T::Scalar: Ord,
521    {
522        Self::build_by_key(points, |item, k| item.at(k))
523    }
524}
525#[cfg(feature = "serde")]
526mod impl_serde {
527    use super::{KdTreeN, PhantomData, Unsigned};
528    impl<T: serde::Serialize, N: Unsigned> serde::Serialize for KdTreeN<T, N> {
529        fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
530            self.1.serialize(serializer)
531        }
532    }
533    impl<'de, T: serde::Deserialize<'de>, N: Unsigned> serde::Deserialize<'de> for KdTreeN<T, N> {
534        fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
535            Vec::<T>::deserialize(deserializer).map(|items| Self(PhantomData, items))
536        }
537    }
538}
539#[cfg(feature = "rayon")]
540impl<T: Send, N: Unsigned> KdTreeN<T, N> {
541    /// Same as [`Self::build_by`], but using multiple threads.
542    pub fn par_build_by<F>(mut items: Vec<T>, compare: F) -> Self
543    where
544        F: Fn(&T, &T, usize) -> Ordering + Copy + Send,
545    {
546        kd_par_sort_by(&mut items, N::to_usize(), compare);
547        Self(PhantomData, items)
548    }
549
550    /// Same as [`Self::build_by_key`], but using multiple threads.
551    pub fn par_build_by_key<Key, F>(items: Vec<T>, kd_key: F) -> Self
552    where
553        Key: Ord,
554        F: Fn(&T, usize) -> Key + Copy + Send,
555    {
556        Self::par_build_by(items, move |item1, item2, k| {
557            kd_key(item1, k).cmp(&kd_key(item2, k))
558        })
559    }
560
561    /// Same as [`Self::build_by_ordered_float`], but using multiple threads.
562    pub fn par_build_by_ordered_float(points: Vec<T>) -> Self
563    where
564        T: KdPoint<Dim = N>,
565        T::Scalar: ordered_float::FloatCore,
566    {
567        Self::par_build_by_key(points, |item, k| ordered_float::OrderedFloat(item.at(k)))
568    }
569
570    /// Same as [`Self::build`], but using multiple threads.
571    pub fn par_build(points: Vec<T>) -> Self
572    where
573        T: KdPoint<Dim = N>,
574        T::Scalar: Ord,
575    {
576        Self::par_build_by_key(points, |item, k| item.at(k))
577    }
578}
579
580/// This type refers a slice of items, `[T]`, and contains kd-tree of indices to the items, `KdTree<usize, N>`.
581/// Unlike [`KdSliceN::sort`], [`KdIndexTreeN::build`] doesn't sort input items.
582/// ```
583/// let items = vec![[1, 2, 3], [3, 1, 2], [2, 3, 1]];
584/// let kdtree = kd_tree::KdIndexTree::build(&items);
585/// assert_eq!(kdtree.nearest(&[3, 1, 2]).unwrap().item, &1); // nearest() returns an index of items.
586/// ```
587#[derive(Debug, Clone, PartialEq, Eq)]
588pub struct KdIndexTreeN<'a, T, N: Unsigned> {
589    source: &'a [T],
590    kdtree: KdTreeN<usize, N>,
591}
592pub type KdIndexTree<'a, T> = KdIndexTreeN<'a, T, <T as KdPoint>::Dim>;
593impl<'a, T, N: Unsigned> KdIndexTreeN<'a, T, N> {
594    pub fn source(&self) -> &'a [T] {
595        self.source
596    }
597
598    pub fn indices(&self) -> &KdSliceN<usize, N> {
599        &self.kdtree
600    }
601
602    pub fn item(&self, i: usize) -> &'a T {
603        &self.source[i]
604    }
605
606    pub fn build_by<F>(source: &'a [T], compare: F) -> Self
607    where
608        F: Fn(&T, &T, usize) -> Ordering + Copy,
609    {
610        Self {
611            source,
612            kdtree: KdTreeN::build_by((0..source.len()).collect(), |i1, i2, k| {
613                compare(&source[*i1], &source[*i2], k)
614            }),
615        }
616    }
617
618    pub fn build_by_key<Key, F>(source: &'a [T], kd_key: F) -> Self
619    where
620        Key: Ord,
621        F: Fn(&T, usize) -> Key + Copy,
622    {
623        Self::build_by(source, |item1, item2, k| {
624            kd_key(item1, k).cmp(&kd_key(item2, k))
625        })
626    }
627
628    pub fn build_by_ordered_float(points: &'a [T]) -> Self
629    where
630        T: KdPoint<Dim = N>,
631        T::Scalar: ordered_float::FloatCore,
632    {
633        Self::build_by_key(points, |item, k| ordered_float::OrderedFloat(item.at(k)))
634    }
635
636    pub fn build(points: &'a [T]) -> Self
637    where
638        T: KdPoint<Dim = N>,
639        T::Scalar: Ord,
640    {
641        Self::build_by_key(points, |item, k| item.at(k))
642    }
643
644    pub fn nearest_by<Q: KdPoint<Dim = N>>(
645        &self,
646        query: &Q,
647        coord: impl Fn(&T, usize) -> Q::Scalar + Copy,
648    ) -> Option<ItemAndDistance<usize, Q::Scalar>> {
649        self.kdtree
650            .nearest_by(query, |&index, k| coord(&self.source[index], k))
651    }
652
653    /// # Example
654    /// ```
655    /// let mut items: Vec<[i32; 3]> = vec![[1, 2, 3], [3, 1, 2], [2, 3, 1]];
656    /// let kdtree = kd_tree::KdIndexTree3::build(&items);
657    /// assert_eq!(kdtree.nearest(&[3, 1, 2]).unwrap().item, &1);
658    /// ```
659    pub fn nearest(
660        &self,
661        query: &impl KdPoint<Scalar = T::Scalar, Dim = N>,
662    ) -> Option<ItemAndDistance<usize, T::Scalar>>
663    where
664        T: KdPoint<Dim = N>,
665    {
666        self.nearest_by(query, |item, k| item.at(k))
667    }
668
669    pub fn nearests_by<Q: KdPoint<Dim = N>>(
670        &self,
671        query: &Q,
672        num: usize,
673        coord: impl Fn(&T, usize) -> Q::Scalar + Copy,
674    ) -> Vec<ItemAndDistance<usize, Q::Scalar>> {
675        self.kdtree
676            .nearests_by(query, num, |&index, k| coord(&self.source[index], k))
677    }
678
679    /// Returns kNN(k nearest neighbors) from the input point.
680    /// # Example
681    /// ```
682    /// let mut items: Vec<[i32; 3]> = vec![[1, 2, 3], [3, 1, 2], [2, 3, 1], [3, 2, 2]];
683    /// let kdtree = kd_tree::KdIndexTree::build(&mut items);
684    /// let nearests = kdtree.nearests(&[3, 1, 2], 2);
685    /// assert_eq!(nearests.len(), 2);
686    /// assert_eq!(nearests[0].item, &1);
687    /// assert_eq!(nearests[1].item, &3);
688    /// ```
689    pub fn nearests(
690        &self,
691        query: &impl KdPoint<Scalar = T::Scalar, Dim = N>,
692        num: usize,
693    ) -> Vec<ItemAndDistance<usize, T::Scalar>>
694    where
695        T: KdPoint<Dim = N>,
696    {
697        self.nearests_by(query, num, |item, k| item.at(k))
698    }
699
700    pub fn within_by_cmp(&self, compare: impl Fn(&T, usize) -> Ordering + Copy) -> Vec<&usize> {
701        self.kdtree
702            .within_by_cmp(|&index, k| compare(&self.source[index], k))
703    }
704
705    pub fn within_by<Q: KdPoint<Dim = N>>(
706        &self,
707        query: &[Q; 2],
708        coord: impl Fn(&T, usize) -> Q::Scalar + Copy,
709    ) -> Vec<&usize> {
710        self.kdtree
711            .within_by(query, |&index, k| coord(&self.source[index], k))
712    }
713
714    pub fn within(&self, query: &[impl KdPoint<Scalar = T::Scalar, Dim = N>; 2]) -> Vec<&usize>
715    where
716        T: KdPoint<Dim = N>,
717    {
718        self.within_by(query, |item, k| item.at(k))
719    }
720
721    pub fn within_radius_by<Q: KdPoint<Dim = N>>(
722        &self,
723        query: &Q,
724        radius: Q::Scalar,
725        coord: impl Fn(&T, usize) -> Q::Scalar + Copy,
726    ) -> Vec<&usize> {
727        self.kdtree
728            .within_radius_by(query, radius, |&index, k| coord(&self.source[index], k))
729    }
730
731    pub fn within_radius(
732        &self,
733        query: &impl KdPoint<Scalar = T::Scalar, Dim = N>,
734        radius: T::Scalar,
735    ) -> Vec<&usize>
736    where
737        T: KdPoint<Dim = N>,
738    {
739        self.within_radius_by(query, radius, |item, k| item.at(k))
740    }
741}
742#[cfg(feature = "rayon")]
743impl<'a, T: Sync, N: Unsigned> KdIndexTreeN<'a, T, N> {
744    pub fn par_build_by<F>(source: &'a [T], compare: F) -> Self
745    where
746        F: Fn(&T, &T, usize) -> Ordering + Copy + Send,
747    {
748        Self {
749            source,
750            kdtree: KdTreeN::par_build_by((0..source.len()).collect(), move |i1, i2, k| {
751                compare(&source[*i1], &source[*i2], k)
752            }),
753        }
754    }
755
756    pub fn par_build_by_key<Key, F>(source: &'a [T], kd_key: F) -> Self
757    where
758        Key: Ord,
759        F: Fn(&T, usize) -> Key + Copy + Send,
760    {
761        Self::par_build_by(source, move |item1, item2, k| {
762            kd_key(item1, k).cmp(&kd_key(item2, k))
763        })
764    }
765
766    pub fn par_build_by_ordered_float(points: &'a [T]) -> Self
767    where
768        T: KdPoint<Dim = N>,
769        T::Scalar: ordered_float::FloatCore,
770    {
771        Self::par_build_by_key(points, |item, k| ordered_float::OrderedFloat(item.at(k)))
772    }
773
774    pub fn par_build(points: &'a [T]) -> Self
775    where
776        T: KdPoint<Dim = N>,
777        T::Scalar: Ord,
778    {
779        Self::par_build_by_key(points, |item, k| item.at(k))
780    }
781}
782
783macro_rules! define_kdtree_aliases {
784    ($($dim:literal),*) => {
785        $(
786            paste::paste! {
787                pub type [<KdSlice $dim>]<T> = KdSliceN<T, typenum::[<U $dim>]>;
788                pub type [<KdTree $dim>]<T> = KdTreeN<T, typenum::[<U $dim>]>;
789                pub type [<KdIndexTree $dim>]<'a, T> = KdIndexTreeN<'a, T, typenum::[<U $dim>]>;
790            }
791        )*
792    };
793}
794define_kdtree_aliases!(1, 2, 3, 4, 5, 6, 7, 8);
795
796macro_rules! impl_kd_points {
797    ($($len:literal),*) => {
798        $(
799            paste::paste!{
800                impl<T: num_traits::NumAssign + Copy + PartialOrd> KdPoint for [T; $len] {
801                    type Scalar = T;
802                    type Dim = typenum::[<U $len>];
803                    fn at(&self, i: usize) -> T { self[i] }
804                }
805            }
806        )*
807    };
808}
809impl_kd_points!(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
810
811impl<P: KdPoint, T> KdPoint for (P, T) {
812    type Scalar = P::Scalar;
813    type Dim = P::Dim;
814    fn at(&self, k: usize) -> Self::Scalar {
815        self.0.at(k)
816    }
817}
818
819/// kd-tree of key-value pairs.
820/// ```
821/// let kdmap: kd_tree::KdMap<[isize; 3], &'static str> = kd_tree::KdMap::build(vec![
822///     ([1, 2, 3], "foo"),
823///     ([2, 3, 1], "bar"),
824///     ([3, 1, 2], "buzz"),
825/// ]);
826/// assert_eq!(kdmap.nearest(&[3, 1, 2]).unwrap().item.1, "buzz");
827/// ```
828pub type KdMap<P, T> = KdTree<(P, T)>;
829
830/// kd-tree slice of key-value pairs.
831/// ```
832/// let mut items: Vec<([isize; 3], &'static str)> = vec![
833///     ([1, 2, 3], "foo"),
834///     ([2, 3, 1], "bar"),
835///     ([3, 1, 2], "buzz"),
836/// ];
837/// let kdmap = kd_tree::KdMapSlice::sort(&mut items);
838/// assert_eq!(kdmap.nearest(&[3, 1, 2]).unwrap().item.1, "buzz");
839/// ```
840pub type KdMapSlice<P, T> = KdSlice<(P, T)>;