#![allow(clippy::ptr_arg)]
use crate::algorithm::neighbour::cover_tree::CoverTree;
use crate::algorithm::neighbour::linear_search::LinearKNNSearch;
use crate::error::Failed;
use crate::metrics::distance::Distance;
use crate::numbers::basenum::Number;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
pub(crate) mod bbd_tree;
pub mod cover_tree;
pub mod fastpair;
pub mod linear_search;
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Debug, Clone)]
pub enum KNNAlgorithmName {
LinearSearch,
CoverTree,
}
impl Default for KNNAlgorithmName {
fn default() -> Self {
KNNAlgorithmName::CoverTree
}
}
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Debug)]
pub(crate) enum KNNAlgorithm<T: Number, D: Distance<Vec<T>>> {
LinearSearch(LinearKNNSearch<Vec<T>, D>),
CoverTree(CoverTree<Vec<T>, D>),
}
impl KNNAlgorithmName {
pub(crate) fn fit<T: Number, D: Distance<Vec<T>>>(
&self,
data: Vec<Vec<T>>,
distance: D,
) -> Result<KNNAlgorithm<T, D>, Failed> {
match *self {
KNNAlgorithmName::LinearSearch => {
LinearKNNSearch::new(data, distance).map(KNNAlgorithm::LinearSearch)
}
KNNAlgorithmName::CoverTree => {
CoverTree::new(data, distance).map(KNNAlgorithm::CoverTree)
}
}
}
}
impl<T: Number, D: Distance<Vec<T>>> KNNAlgorithm<T, D> {
pub fn find(&self, from: &Vec<T>, k: usize) -> Result<Vec<(usize, f64, &Vec<T>)>, Failed> {
match *self {
KNNAlgorithm::LinearSearch(ref linear) => linear.find(from, k),
KNNAlgorithm::CoverTree(ref cover) => cover.find(from, k),
}
}
pub fn find_radius(
&self,
from: &Vec<T>,
radius: f64,
) -> Result<Vec<(usize, f64, &Vec<T>)>, Failed> {
match *self {
KNNAlgorithm::LinearSearch(ref linear) => linear.find_radius(from, radius),
KNNAlgorithm::CoverTree(ref cover) => cover.find_radius(from, radius),
}
}
}