| Crates.io | ruvector-hyperbolic-hnsw |
| lib.rs | ruvector-hyperbolic-hnsw |
| version | 0.1.0 |
| created_at | 2026-01-23 02:19:38.8515+00 |
| updated_at | 2026-01-23 02:19:38.8515+00 |
| description | Hyperbolic (Poincare ball) embeddings with HNSW integration for hierarchy-aware vector search, enabling efficient similarity search in non-Euclidean spaces for taxonomies, ontologies, and hierarchical data |
| homepage | https://ruv.io/ruvector |
| repository | https://github.com/ruvnet/ruvector |
| max_upload_size | |
| id | 2063181 |
| size | 134,818 |
Hyperbolic (Poincaré ball) embeddings with HNSW integration for hierarchy-aware vector search.
Hierarchies compress naturally in hyperbolic space. Taxonomies, catalogs, ICD trees, product facets, org charts, and long-tail tags all fit better than in Euclidean space, which means higher recall on deep leaves without blowing up memory or latency.
r < 1 − eps[dependencies]
ruvector-hyperbolic-hnsw = "0.1.0"
cd crates/ruvector-hyperbolic-hnsw-wasm
wasm-pack build --target web --release
import init, {
HyperbolicIndex,
poincareDistance,
mobiusAdd,
expMap,
logMap
} from 'ruvector-hyperbolic-hnsw-wasm';
await init();
const index = new HyperbolicIndex(16, 1.0);
index.insert(new Float32Array([0.1, 0.2, 0.3]));
const results = index.search(new Float32Array([0.15, 0.1, 0.2]), 5);
use ruvector_hyperbolic_hnsw::{HyperbolicHnsw, HyperbolicHnswConfig};
// Create index with default settings
let mut index = HyperbolicHnsw::default_config();
// Insert vectors (automatically projected to Poincaré ball)
index.insert(vec![0.1, 0.2, 0.3]).unwrap();
index.insert(vec![-0.1, 0.15, 0.25]).unwrap();
index.insert(vec![0.2, -0.1, 0.1]).unwrap();
// Search for nearest neighbors
let results = index.search(&[0.15, 0.1, 0.2], 2).unwrap();
for r in results {
println!("ID: {}, Distance: {:.4}", r.id, r.distance);
}
The core optimization:
u = log_c(x) at a shard centroid c||u_q - u_p|| to pruneuse ruvector_hyperbolic_hnsw::{HyperbolicHnsw, HyperbolicHnswConfig};
let mut config = HyperbolicHnswConfig::default();
config.use_tangent_pruning = true;
config.prune_factor = 10; // Consider 10x candidates in tangent space
let mut index = HyperbolicHnsw::new(config);
// ... insert vectors ...
// Build tangent cache for pruning optimization
index.build_tangent_cache().unwrap();
// Search with pruning (faster!)
let results = index.search_with_pruning(&[0.1, 0.15], 5).unwrap();
use ruvector_hyperbolic_hnsw::poincare::{
mobius_add, exp_map, log_map, poincare_distance, project_to_ball
};
let x = vec![0.3, 0.2];
let y = vec![-0.1, 0.4];
let c = 1.0; // Curvature
// Möbius addition (hyperbolic vector addition)
let z = mobius_add(&x, &y, c);
// Geodesic distance in hyperbolic space
let d = poincare_distance(&x, &y, c);
// Map to tangent space at x
let v = log_map(&y, &x, c);
// Map back to manifold
let y_recovered = exp_map(&v, &x, c);
use ruvector_hyperbolic_hnsw::{ShardedHyperbolicHnsw, ShardStrategy};
let mut manager = ShardedHyperbolicHnsw::new(1.0);
// Insert with hierarchy depth information
manager.insert(vec![0.1, 0.2], Some(0)).unwrap(); // Root level
manager.insert(vec![0.3, 0.1], Some(3)).unwrap(); // Deeper level
// Update curvature for specific shard
manager.update_curvature("radius_1", 0.5).unwrap();
// Canary testing for new curvature
manager.registry.set_canary("radius_1", 0.3, 10); // 10% traffic
// Search across all shards
let results = manager.search(&[0.2, 0.15], 5).unwrap();
All operations include numerical safeguards:
eps = 1e-5log1p expansions for safetyarctanh and atanh arguments bounded away from ±1Small Möbius deltas and tangent-space micro updates that never push points outside the ball.
use ruvector_hyperbolic_hnsw::tangent_micro_update;
let updated = tangent_micro_update(
&point,
&delta,
¢roid,
curvature,
0.1 // max step size
);
Riemannian SGD passes to clean neighborhoods and optionally relearn per-shard curvature. Run canary first.
Rebuild of HNSW with true hyperbolic metric, curvature retune, and shard reshuffle if hierarchy preservation drops below SLO.
nalgebra = "0.34.1"
ndarray = "0.17.1"
wasm-bindgen = "0.2.106"
cd crates/ruvector-hyperbolic-hnsw
cargo bench
Benchmark suite includes:
MIT