1use crate::config::DistanceMetric;
4use crate::error::KnnError;
5
6#[derive(Debug, Clone)]
8pub struct NeighborList {
9 pub indices: Vec<u32>,
11 pub distances: Vec<f32>,
13}
14
15#[derive(Debug, Clone)]
17pub struct KnnGraph {
18 pub neighbors: Vec<NeighborList>,
19 pub n: usize,
20 pub k: usize,
21 pub metric: DistanceMetric,
22 pub provenance: Option<String>,
23}
24
25impl KnnGraph {
26 pub fn required_k_for_pacmap(n: usize, n_neighbors: usize) -> usize {
28 let n_nb = n_neighbors.min(n.saturating_sub(1));
29 (n_nb + 50).min(n.saturating_sub(1))
30 }
31
32 pub fn validate(
34 &self,
35 data_n: usize,
36 required_k: usize,
37 metric: DistanceMetric,
38 ) -> Result<(), KnnError> {
39 if self.n != data_n || self.neighbors.len() != data_n {
40 return Err(KnnError::GraphSizeMismatch {
41 graph_n: self.n,
42 neighbors_len: self.neighbors.len(),
43 data_n,
44 });
45 }
46 if self.k < required_k {
47 return Err(KnnError::GraphInsufficientK {
48 graph_k: self.k,
49 required_k,
50 });
51 }
52 if self.metric != metric {
53 return Err(KnnError::GraphMetricMismatch {
54 graph: self.metric,
55 requested: metric,
56 });
57 }
58 Ok(())
59 }
60
61 pub fn validate_for_pacmap(
63 &self,
64 data_n: usize,
65 n_neighbors: usize,
66 config_metric: DistanceMetric,
67 ) -> Result<(), KnnError> {
68 self.validate(
69 data_n,
70 Self::required_k_for_pacmap(data_n, n_neighbors),
71 config_metric,
72 )
73 }
74}