#[derive(Debug, Clone)]
pub enum Init {
Pca,
Random(Option<u64>),
}
#[derive(Debug, Clone)]
pub enum KnnMethod {
#[cfg(feature = "hnsw")]
Hnsw(HnswParams),
Exact,
#[cfg(feature = "kdtree")]
KdTree,
Annoy,
}
impl Default for KnnMethod {
fn default() -> Self {
#[cfg(feature = "hnsw")]
return Self::Hnsw(HnswParams::default());
#[cfg(not(feature = "hnsw"))]
return Self::Exact;
}
}
#[derive(Debug, Clone)]
pub struct HnswParams {
pub m: usize,
pub ef_construction: usize,
pub ef_search: usize,
pub quantization: Quantization,
}
impl Default for HnswParams {
fn default() -> Self {
Self {
m: 16,
ef_construction: 200,
ef_search: 50,
quantization: Quantization::F32,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum Quantization {
#[default]
F32,
F16,
I8,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum DistanceMetric {
#[default]
Euclidean,
EuclideanSq,
Cosine,
Manhattan,
}
#[derive(Debug, Clone)]
pub struct PaCMAPConfig {
pub n_neighbors: usize,
pub mn_ratio: f32,
pub fp_ratio: f32,
pub phase_iters: [usize; 3],
pub learning_rate: f32,
pub init: Init,
pub seed: Option<u64>,
pub knn_method: KnnMethod,
pub distance_metric: DistanceMetric,
}
impl Default for PaCMAPConfig {
fn default() -> Self {
Self {
n_neighbors: 10,
mn_ratio: 0.5,
fp_ratio: 2.0,
phase_iters: [100, 100, 250],
learning_rate: 1.0,
init: Init::Pca,
seed: None,
knn_method: KnnMethod::default(),
distance_metric: DistanceMetric::default(),
}
}
}
impl PaCMAPConfig {
pub fn n_mn(&self) -> usize {
(self.n_neighbors as f32 * self.mn_ratio).floor() as usize
}
pub fn n_fp(&self) -> usize {
(self.n_neighbors as f32 * self.fp_ratio).floor() as usize
}
pub fn total_iters(&self) -> usize {
self.phase_iters.iter().sum()
}
}