use vicinity::hnsw::HNSWIndex;
fn main() -> vicinity::Result<()> {
let dim = 32;
let n = 200;
let k = 5;
let ef = 50;
let vectors: Vec<Vec<f32>> = (0..n)
.map(|i| normalize(&pseudo_random_vec(dim, i)))
.collect();
let mut index = HNSWIndex::new(dim, 16, 32)?;
for (id, vec) in vectors.iter().enumerate() {
index.add(id as u32, vec.clone())?;
}
index.build()?;
let query = &vectors[0];
let results = index.search(query, k, ef)?;
println!("HNSW search (n={n}, dim={dim}, k={k}, ef={ef})");
println!("query: vector 0");
println!();
for (id, distance) in &results {
println!(" id={id:3} distance={distance:.6}");
}
assert_eq!(
results[0].0, 0,
"expected vector 0 as its own nearest neighbor"
);
println!("\npassed: vector 0 is its own nearest neighbor");
Ok(())
}
fn pseudo_random_vec(dim: usize, seed: usize) -> Vec<f32> {
(0..dim)
.map(|i| ((seed * 31 + i * 17) as f32 * 0.001).sin())
.collect()
}
fn normalize(v: &[f32]) -> Vec<f32> {
let norm: f32 = v.iter().map(|x| x * x).sum::<f32>().sqrt();
if norm == 0.0 {
return v.to_vec();
}
v.iter().map(|x| x / norm).collect()
}