# Redoal > Gesture indexing math library for generating stable index keys from gestures A library focused purely on gesture indexing mathematics for DHT-based path comparisons and similarity search. ## Core Capabilities 1. **Gesture Normalization** - Remove translation and scale variations 2. **Path Resampling** - Fixed number of evenly spaced points 3. **Shape Descriptors** - Hu invariant moments for shape characterization 4. **Spectral Embeddings** - Laplacian eigenvalues for gesture signature 5. **Dimensionality Reduction** - PCA for feature compression 6. **Spatial Indexing** - Morton/Z-order curve for integer keys 7. **Multiple Hashing Strategies** - Moment, spectral, hybrid, and global vector addressing 8. **Multi-Probe Hashing** - Query neighboring buckets for improved recall 9. **HNSW Index** - Approximate nearest neighbor search for fast similarity ## Usage Example ### Creating a Gesture Key for DHT ```rust use redoal::*; fn main() { // Load or create a gesture (sequence of points) let gesture = vec![ Point::new(0.0, 0.0), Point::new(1.0, 0.0), Point::new(0.5, 1.0), Point::new(0.0, 0.5), ]; // Normalize the gesture (remove translation and scale) let normalized = normalize(&gesture); // Resample to fixed number of points for consistency let resampled = resample(&normalized, 64); // Compute spectral signature let spectral = spectral_signature(&resampled, 4); // Create Morton code for DHT key let key = morton2( (spectral[0] * 1000.0) as u32, (spectral[1] * 1000.0) as u32 ); println!("Gesture key: {}", key); } ``` ### Similarity Search with HNSW ```rust use redoal::*; fn find_similar_gestures(query: &[Point], database: &[(&str, Vec)]) -> Vec<(&str, f64)> { // Normalize and resample query let query_norm = normalize(query); let query_resamp = resample(&query_norm, 64); let query_spectral = spectral_signature(&query_resamp, 4); // Compute similarity for each gesture in database let mut similarities = Vec::new(); for (name, gesture) in database { let gesture_norm = normalize(gesture); let gesture_resamp = resample(&gesture_norm, 64); let gesture_spectral = spectral_signature(&gesture_resamp, 4); // Euclidean distance between spectral signatures let distance = query_spectral.iter() .zip(gesture_spectral.iter()) .map(|(a, b)| (a - b).powi(2)) .sum::() .sqrt(); similarities.push((name, distance)); } // Sort by similarity (lower distance = more similar) similarities.sort_by(|a, b| a.1.partial_cmp(&b.1).unwrap()); similarities } ``` ### Multi-Probe Hashing for Improved Recall ```rust use redoal::*; fn multi_probe_query(points: &[Point]) { // Use moment hash for stable partitioning let moment_key = hu_moment_hash(points, 10); // Generate neighboring keys for multi-probe let neighbors = neighboring_keys(moment_key, 3); println!("Querying {} buckets", neighbors.len()); for key in neighbors { println!("Bucket: {}", key); } // Or use adaptive probing let keys = adaptive_probe( points, 10, 5, 15, HashStrategy::Hybrid, ); println!("Adaptive probe found {} keys", keys.len()); } ``` ### HNSW Index for Fast Local Search ```rust use redoal::*; fn hnsw_example() { // Create HNSW index let mut index = HnswIndex::new(HnswConfig::default()); // Add gestures to index let gesture1 = vec![ Point::new(0.0, 0.0), Point::new(1.0, 0.0), Point::new(0.5, 1.0), ]; let norm1 = normalize(&gesture1); let resamp1 = resample(&norm1, 64); let embedding1 = spectral_signature(&resamp1, 4); index.add(&embedding1, "triangle"); // Query the index let query = vec![ Point::new(0.1, 0.1), Point::new(1.1, 0.1), Point::new(0.6, 1.1), ]; let norm = normalize(&query); let resamp = resample(&norm, 64); let embedding = spectral_signature(&resamp, 4); let results = index.search(&embedding, 5); for (label, distance) in results { println!("Found {} at distance {}", label, distance); } } ``` ## Mathematical Operations | Module | Function | Purpose | |--------|----------|---------| | `point` | `Point::new(x, y)` | Create 2D points with floating-point coordinates | | `normalize` | `normalize(points)` | Center gesture at origin and scale to unit size | | `resample` | `resample(points, n)` | Resample to n evenly spaced points | | `moments` | `hu_moments(points)` | Compute Hu invariant moments (7-value shape descriptor) | | `spectral` | `spectral_signature(points, k)` | Compute k Laplacian eigenvalues | | `pca` | `pca(data, k)` | Dimensionality reduction to k principal components | | `morton` | `morton2(x, y)` | Convert 2D coordinates to 64-bit Morton code | | `hashing` | `hu_moment_hash()` | Moment-based hashing for DHT | | `hashing` | `spectral_hash()` | Spectral-based hashing | | `hashing` | `hybrid_hash()` | Combined moment+spectral hashing | | `hashing` | `vector_to_dht_key()` | Global vector addressing | | `hashing` | `neighboring_keys()` | Multi-probe hashing | | `hashing` | `adaptive_probe()` | Adaptive query planning | | `hnsw` | `HnswIndex` | Approximate nearest neighbor search | ## Hashing Strategies ### Moment Hash (Stable) - Uses Hu invariant moments - Translation and scale invariant - Good for broad gesture categories - Coarse partitioning ### Spectral Hash (Precise) - Uses Laplacian eigenvalues - More sensitive to small changes - Better for fine-grained similarity - Requires multi-probe for robustness ### Hybrid Hash (Balanced) - Combines moment and spectral features - Weighted fusion for optimal balance - Good default choice ### Global Vector Addressing - Directly maps embeddings to DHT keys - No intermediate hashing - Most precise but requires careful quantization ## Multi-Probe Hashing To handle hash instability and improve recall: ```rust // Basic multi-probe let key = hu_moment_hash(points, 10); let neighbors = neighboring_keys(key, 3); // Query 3 neighboring buckets // Adaptive probing let keys = adaptive_probe( points, 10, // quantization bits 5, // min peers 15, // max peers HashStrategy::Hybrid, // hash strategy ); ``` ## HNSW Index For fast local similarity search on peers: ```rust let mut index = HnswIndex::new(HnswConfig::default()); index.add(&embedding, "gesture_label"); let results = index.search(&query_embedding, 10); ``` ## Dependencies - `nalgebra` - Linear algebra and matrix operations - `ndarray` - Multi-dimensional array support - `itertools` - Iteration helpers - `rand` - Test data generation ## Testing Run tests with: ```bash cargo test ``` All tests pass, demonstrating correct implementation of gesture indexing mathematics and distributed search capabilities.