#[derive(Debug, Clone, Copy, PartialEq)]
pub struct LshStats {
pub num_bands: usize,
pub rows_per_band: usize,
pub threshold: f64,
pub doc_count: usize,
pub total_buckets: usize,
pub total_entries: usize,
pub avg_bucket_size: f64,
pub cluster_count: usize,
pub duplicate_count: usize,
}
impl LshStats {
#[must_use]
pub fn estimated_false_positive_rate(&self) -> f64 {
if self.total_buckets == 0 {
return 0.0;
}
let avg_docs_per_bucket = self.avg_bucket_size;
let prob_collision = avg_docs_per_bucket / self.doc_count.max(1) as f64;
1.0 - (1.0 - prob_collision).powf(self.num_bands as f64)
}
#[must_use]
pub fn estimated_recall(&self) -> f64 {
let s = self.threshold;
let band_match_prob = s.powf(self.rows_per_band as f64);
1.0 - (1.0 - band_match_prob).powf(self.num_bands as f64)
}
}