Files
wifi-densepose/examples/meta-cognition-spiking-neural-network/demos/attention/hyperbolic-deep-dive.js
ruv d803bfe2b1 Squashed 'vendor/ruvector/' content from commit b64c2172
git-subtree-dir: vendor/ruvector
git-subtree-split: b64c21726f2bb37286d9ee36a7869fef60cc6900
2026-02-28 14:39:40 -05:00

507 lines
20 KiB
JavaScript
Executable File
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env node
/**
* Hyperbolic Attention & Poincaré Ball Model Exploration
*
* This demonstration explores hyperbolic geometry and why it's superior
* for representing hierarchical structures like:
* - Knowledge taxonomies
* - Organizational charts
* - Concept hierarchies
* - Skill trees
*
* Key Concepts:
* - Poincaré ball model
* - Hyperbolic space vs Euclidean space
* - Natural hierarchy representation
* - Distance preservation in hyperbolic geometry
*/
const {
HyperbolicAttention,
MultiHeadAttention,
expMap,
logMap,
mobiusAddition,
poincareDistance,
projectToPoincareBall
} = require('@ruvector/attention');
console.log('🌀 Hyperbolic Attention & Poincaré Ball Model\n');
console.log('=' .repeat(70));
// ============================================================================
// PART 1: Understanding Hyperbolic Space
// ============================================================================
function explainPoincareModel() {
console.log('\n📐 PART 1: Understanding the Poincaré Ball Model\n');
console.log('=' .repeat(70));
console.log('\n🌍 What is Hyperbolic Space?\n');
console.log('Hyperbolic space is a non-Euclidean geometry where:');
console.log(' • Space curves with negative curvature (like a saddle)');
console.log(' • Parallel lines diverge (unlike Euclidean geometry)');
console.log(' • Space grows exponentially as you move from the center');
console.log(' • Perfect for representing hierarchies naturally\n');
console.log('🔵 The Poincaré Ball Model:\n');
console.log('Represents hyperbolic space as a ball where:');
console.log(' • Center (0,0,0) = root of hierarchy');
console.log(' • Points near center = high-level concepts');
console.log(' • Points near boundary = specific/leaf concepts');
console.log(' • Distance to boundary = level in hierarchy');
console.log(' • Exponentially more space near boundary\n');
console.log('📊 Why This Matters:\n');
console.log(' Problem: In Euclidean space (normal geometry):');
console.log(' • Need exponentially more dimensions for deep trees');
console.log(' • Distance doesn\'t reflect hierarchical relationships');
console.log(' • Embedding large trees causes distortion\n');
console.log(' Solution: In Hyperbolic space:');
console.log(' • Trees embed naturally with low dimensions');
console.log(' • Distance reflects hierarchy (parent-child, siblings)');
console.log(' • No distortion even for huge trees\n');
console.log('💡 Real-World Example:\n');
console.log(' Imagine organizing "Animals":');
console.log(' Center: "Animals" (most general)');
console.log(' Mid-level: "Mammals", "Birds", "Fish"');
console.log(' Boundary: "Golden Retriever", "Sparrow", "Goldfish"\n');
console.log(' In Euclidean space: All species equidistant from center');
console.log(' In Hyperbolic space: Hierarchy preserved in distances!\n');
}
// ============================================================================
// PART 2: Visualizing Hyperbolic vs Euclidean
// ============================================================================
function visualizeSpaceComparison() {
console.log('\n' + '=' .repeat(70));
console.log('\n📊 PART 2: Hyperbolic vs Euclidean Space\n');
console.log('=' .repeat(70));
console.log('\n🔷 EUCLIDEAN SPACE (Normal geometry):\n');
console.log(' Representing a 3-level hierarchy:');
console.log('');
console.log(' Root');
console.log(' │');
console.log(' ┌───────────┼───────────┐');
console.log(' A B C');
console.log(' ┌─┼─┐ ┌─┼─┐ ┌─┼─┐');
console.log(' 1 2 3 4 5 6 7 8 9');
console.log('');
console.log(' Problem: All leaf nodes (1-9) same distance from root');
console.log(' Siblings (1,2,3) same distance as cousins (1,4,7)');
console.log(' Hierarchy information LOST in distance!\n');
console.log('🌀 HYPERBOLIC SPACE (Poincaré Ball):\n');
console.log(' Same hierarchy in hyperbolic space:');
console.log('');
console.log(' ╔═══════════════════════════════════╗');
console.log(' ║ ║');
console.log(' ║ ●Root (0.0) ║');
console.log(' ║ │ ║');
console.log(' ║ ┌───────┼───────┐ ║');
console.log(' ║ ●A ●B ●C (0.4) ║');
console.log(' ║ ┌┼┐ ┌┼┐ ┌┼┐ ║');
console.log(' ║ ●●● ●●● ●●● (0.7) ║');
console.log(' ║ 123 456 789 ║');
console.log(' ║ ║');
console.log(' ╚═══════════════════════════════════╝');
console.log(' ^ ^');
console.log(' Center Boundary');
console.log('');
console.log(' Benefits:');
console.log(' • Siblings (1,2,3) closer than cousins (1,4,7) ✓');
console.log(' • Parent-child distance consistent ✓');
console.log(' • Root central, leaves at boundary ✓');
console.log(' • Hierarchy preserved in geometry! ✓\n');
console.log('📏 Distance Comparison:\n');
console.log(' Euclidean:');
console.log(' d(1, 2) ≈ d(1, 4) ≈ d(1, 7) ← All similar!');
console.log(' Hierarchy NOT captured\n');
console.log(' Hyperbolic (Poincaré):');
console.log(' d(1, 2) < d(1, 4) < d(1, 7) ← Reflects hierarchy!');
console.log(' Siblings closer than cousins ✓\n');
}
// ============================================================================
// PART 3: Poincaré Ball Operations
// ============================================================================
async function demonstratePoincareOperations() {
console.log('\n' + '=' .repeat(70));
console.log('\n🧮 PART 3: Poincaré Ball Operations\n');
console.log('=' .repeat(70));
console.log('\n🔧 Key Operations in Hyperbolic Geometry:\n');
// 1. Exponential Map
console.log('1⃣ EXPONENTIAL MAP (expMap)');
console.log(' Maps from tangent space → Poincaré ball');
console.log(' Moves a point in a direction with hyperbolic distance\n');
try {
const point = new Float32Array([0.1, 0.2, 0.3]);
const direction = new Float32Array([0.05, 0.05, 0.05]);
console.log(' Example: Move a point in hyperbolic space');
console.log(` Point: [${Array.from(point).map(x => x.toFixed(2)).join(', ')}]`);
console.log(` Direction: [${Array.from(direction).map(x => x.toFixed(2)).join(', ')}]`);
const result = expMap(point, direction);
console.log(` Result: [${Array.from(result).map(x => x.toFixed(2)).join(', ')}]`);
console.log(' ✓ Point moved along hyperbolic geodesic\n');
} catch (e) {
console.log(` ⚠️ ${e.message}\n`);
}
// 2. Logarithmic Map
console.log('2⃣ LOGARITHMIC MAP (logMap)');
console.log(' Maps from Poincaré ball → tangent space');
console.log(' Finds the direction from one point to another\n');
try {
const origin = new Float32Array([0.1, 0.1, 0.1]);
const target = new Float32Array([0.3, 0.2, 0.1]);
console.log(' Example: Find direction between two points');
console.log(` From: [${Array.from(origin).map(x => x.toFixed(2)).join(', ')}]`);
console.log(` To: [${Array.from(target).map(x => x.toFixed(2)).join(', ')}]`);
const direction = logMap(origin, target);
console.log(` Direction: [${Array.from(direction).map(x => x.toFixed(2)).join(', ')}]`);
console.log(' ✓ Direction in tangent space computed\n');
} catch (e) {
console.log(` ⚠️ ${e.message}\n`);
}
// 3. Möbius Addition
console.log('3⃣ MÖBIUS ADDITION (mobiusAddition)');
console.log(' "Addition" in hyperbolic space (not standard +)');
console.log(' Combines points while respecting curvature\n');
try {
const a = new Float32Array([0.2, 0.1, 0.0]);
const b = new Float32Array([0.1, 0.2, 0.0]);
console.log(' Example: Add two points hyperbolically');
console.log(` A: [${Array.from(a).map(x => x.toFixed(2)).join(', ')}]`);
console.log(` B: [${Array.from(b).map(x => x.toFixed(2)).join(', ')}]`);
const sum = mobiusAddition(a, b);
console.log(` A ⊕ B: [${Array.from(sum).map(x => x.toFixed(2)).join(', ')}]`);
console.log(' ✓ Hyperbolic addition computed\n');
} catch (e) {
console.log(` ⚠️ ${e.message}\n`);
}
// 4. Poincaré Distance
console.log('4⃣ POINCARÉ DISTANCE (poincareDistance)');
console.log(' Distance metric in hyperbolic space');
console.log(' Grows exponentially near the boundary\n');
try {
const p1 = new Float32Array([0.1, 0.1, 0.1]);
const p2Near = new Float32Array([0.2, 0.1, 0.1]);
const p2Far = new Float32Array([0.5, 0.5, 0.5]);
console.log(' Example: Measure hyperbolic distances');
console.log(` From point: [${Array.from(p1).map(x => x.toFixed(2)).join(', ')}]`);
const distNear = poincareDistance(p1, p2Near);
const distFar = poincareDistance(p1, p2Far);
console.log(` To nearby: [${Array.from(p2Near).map(x => x.toFixed(2)).join(', ')}] → distance: ${distNear.toFixed(3)}`);
console.log(` To far: [${Array.from(p2Far).map(x => x.toFixed(2)).join(', ')}] → distance: ${distFar.toFixed(3)}`);
console.log(' ✓ Hyperbolic distances computed\n');
} catch (e) {
console.log(` ⚠️ ${e.message}\n`);
}
// 5. Project to Poincaré Ball
console.log('5⃣ PROJECT TO POINCARÉ BALL (projectToPoincareBall)');
console.log(' Ensures points stay inside the unit ball');
console.log(' Boundary represents infinite distance\n');
try {
const outside = new Float32Array([1.5, 1.5, 1.5]);
console.log(' Example: Project point outside ball');
console.log(` Outside: [${Array.from(outside).map(x => x.toFixed(2)).join(', ')}]`);
const projected = projectToPoincareBall(outside);
console.log(` Projected: [${Array.from(projected).map(x => x.toFixed(2)).join(', ')}]`);
console.log(' ✓ Point now inside unit ball\n');
} catch (e) {
console.log(` ⚠️ ${e.message}\n`);
}
}
// ============================================================================
// PART 4: Hyperbolic Attention in Action
// ============================================================================
async function demonstrateHyperbolicAttention() {
console.log('\n' + '=' .repeat(70));
console.log('\n🧠 PART 4: Hyperbolic Attention Mechanism\n');
console.log('=' .repeat(70));
console.log('\n🎯 How Hyperbolic Attention Works:\n');
console.log('Standard Attention (Euclidean):');
console.log(' Attention(Q, K, V) = softmax(QK^T / √d) V');
console.log(' • Operates in flat Euclidean space');
console.log(' • All points treated equally');
console.log(' • No hierarchical bias\n');
console.log('Hyperbolic Attention (Poincaré):');
console.log(' 1. Map Q, K, V to Poincaré ball');
console.log(' 2. Compute Poincaré distances (not dot products)');
console.log(' 3. Apply attention using hyperbolic geometry');
console.log(' 4. Combine values respecting curvature');
console.log(' • Naturally preserves hierarchies');
console.log(' • Similar ancestors attend to each other');
console.log(' • Hierarchical relationships maintained\n');
console.log('🔧 Creating Hierarchical Data...\n');
// Create a knowledge hierarchy
const hierarchy = {
'Science': {
level: 0,
radius: 0.0,
children: ['Physics', 'Chemistry', 'Biology']
},
'Physics': {
level: 1,
radius: 0.35,
children: ['Quantum', 'Classical', 'Relativity']
},
'Chemistry': {
level: 1,
radius: 0.35,
children: ['Organic', 'Inorganic', 'Physical']
},
'Biology': {
level: 1,
radius: 0.35,
children: ['Molecular', 'Ecology', 'Evolution']
}
};
console.log('📚 Knowledge Hierarchy:');
console.log(' Science (root, r=0.0)');
console.log(' ├─ Physics (r=0.35)');
console.log(' │ ├─ Quantum');
console.log(' │ ├─ Classical');
console.log(' │ └─ Relativity');
console.log(' ├─ Chemistry (r=0.35)');
console.log(' │ ├─ Organic');
console.log(' │ ├─ Inorganic');
console.log(' │ └─ Physical');
console.log(' └─ Biology (r=0.35)');
console.log(' ├─ Molecular');
console.log(' ├─ Ecology');
console.log(' └─ Evolution\n');
// Create embeddings in hyperbolic space
function createHierarchicalEmbedding(level, index, totalAtLevel, dim = 64) {
const vec = new Float32Array(dim);
// Radius based on level (0 = center, deeper = closer to boundary)
const radius = level * 0.3;
// Angle based on position among siblings
const angle = (index / totalAtLevel) * 2 * Math.PI;
// First few dimensions encode position
vec[0] = radius * Math.cos(angle);
vec[1] = radius * Math.sin(angle);
vec[2] = level * 0.1; // Depth encoding
// Remaining dimensions for semantic content
for (let i = 3; i < dim; i++) {
vec[i] = Math.sin(i * angle) * (1 - radius);
}
return vec;
}
console.log('🌀 Testing Hyperbolic Attention...\n');
// Create test data
const dim = 64;
const curvature = -1.0; // Negative for hyperbolic space
// Query: "Physics" (level 1, position 0)
const query = createHierarchicalEmbedding(1, 0, 3, dim);
// Keys: All topics
const keys = [
createHierarchicalEmbedding(0, 0, 1, dim), // Science (parent)
createHierarchicalEmbedding(1, 0, 3, dim), // Physics (self)
createHierarchicalEmbedding(1, 1, 3, dim), // Chemistry (sibling)
createHierarchicalEmbedding(1, 2, 3, dim), // Biology (sibling)
createHierarchicalEmbedding(2, 0, 3, dim), // Quantum (child)
];
const values = keys.map(k => Float32Array.from(k));
console.log('Query: "Physics"');
console.log('Comparing attention to:');
console.log(' - Science (parent)');
console.log(' - Physics (self)');
console.log(' - Chemistry (sibling)');
console.log(' - Biology (sibling)');
console.log(' - Quantum (child)\n');
// Hyperbolic Attention
const hyperbolicAttn = new HyperbolicAttention(dim, curvature);
const start = performance.now();
const output = hyperbolicAttn.compute(query, keys, values);
const duration = performance.now() - start;
console.log(`✅ Hyperbolic Attention computed in ${duration.toFixed(3)}ms`);
console.log(` Output dimension: ${output.length}`);
console.log(` Curvature: ${curvature}`);
console.log(` Geometry: Poincaré ball model\n`);
// Compare with standard Multi-Head Attention
const standardAttn = new MultiHeadAttention(dim, 1);
const standardStart = performance.now();
const standardOutput = standardAttn.compute(query, keys, values);
const standardDuration = performance.now() - standardStart;
console.log(`✅ Standard Attention computed in ${standardDuration.toFixed(3)}ms`);
console.log(` Output dimension: ${standardOutput.length}\n`);
console.log('🔍 Expected Behavior:\n');
console.log('Hyperbolic Attention should attend more to:');
console.log(' ✓ Self (Physics) - highest weight');
console.log(' ✓ Parent (Science) - structural relationship');
console.log(' ✓ Children (Quantum, Classical, Relativity) - hierarchical');
console.log(' ✓ Siblings (Chemistry, Biology) - same level\n');
console.log('Standard Attention treats all equally:');
console.log(' • No hierarchical bias');
console.log(' • Pure semantic similarity');
console.log(' • Ignores tree structure\n');
}
// ============================================================================
// PART 5: Use Cases for Hyperbolic Attention
// ============================================================================
function explainUseCases() {
console.log('\n' + '=' .repeat(70));
console.log('\n💼 PART 5: When to Use Hyperbolic Attention\n');
console.log('=' .repeat(70));
console.log('\n✅ PERFECT For:\n');
console.log('1⃣ Knowledge Graphs & Taxonomies');
console.log(' • WordNet (concepts → synonyms → words)');
console.log(' • Wikipedia categories');
console.log(' • Product catalogs (Electronics → Computers → Laptops)');
console.log(' • Medical ontologies (Disease → Symptom → Treatment)\n');
console.log('2⃣ Organizational Hierarchies');
console.log(' • Company org charts');
console.log(' • Military command structures');
console.log(' • Government organizations');
console.log(' • Academic departments\n');
console.log('3⃣ Skill & Technology Trees');
console.log(' • Game skill trees');
console.log(' • Programming dependencies');
console.log(' • Course prerequisites');
console.log(' • Research paper citations\n');
console.log('4⃣ Natural Language Hierarchies');
console.log(' • Parse trees (sentence → phrase → word)');
console.log(' • Document structure (book → chapter → section)');
console.log(' • Code ASTs (program → function → statement)');
console.log(' • File systems (root → dir → file)\n');
console.log('❌ NOT Ideal For:\n');
console.log(' • Flat data (no hierarchy)');
console.log(' • Grid/mesh structures');
console.log(' • Fully connected networks');
console.log(' • Time series (use temporal attention)\n');
console.log('🎯 Key Advantages:\n');
console.log(' ✓ Preserves hierarchical relationships');
console.log(' ✓ Efficient embedding of trees');
console.log(' ✓ Natural distance metric for hierarchies');
console.log(' ✓ Better generalization on tree-structured data');
console.log(' ✓ Lower dimensional embeddings possible');
console.log(' ✓ Mathematically elegant and proven\n');
}
// ============================================================================
// Main Execution
// ============================================================================
async function main() {
try {
// Part 1: Theory
explainPoincareModel();
// Part 2: Visualization
visualizeSpaceComparison();
// Part 3: Operations
await demonstratePoincareOperations();
// Part 4: Attention in Action
await demonstrateHyperbolicAttention();
// Part 5: Use Cases
explainUseCases();
// Summary
console.log('\n' + '=' .repeat(70));
console.log('\n🎓 SUMMARY: Hyperbolic Attention & Poincaré Ball\n');
console.log('=' .repeat(70));
console.log('\n📚 What We Learned:\n');
console.log(' 1. Hyperbolic space has negative curvature (saddle-shaped)');
console.log(' 2. Poincaré ball maps infinite space to unit ball');
console.log(' 3. Hierarchies embed naturally without distortion');
console.log(' 4. Distance preserves parent-child relationships');
console.log(' 5. Exponentially more space near boundary (for leaves)\n');
console.log('🔧 Key Operations:\n');
console.log(' • expMap: Move in hyperbolic space');
console.log(' • logMap: Find direction between points');
console.log(' • mobiusAddition: Combine points hyperbolically');
console.log(' • poincareDistance: Measure hyperbolic distance');
console.log(' • projectToPoincareBall: Keep points in valid range\n');
console.log('🧠 Why It Matters:\n');
console.log(' Hyperbolic Attention understands STRUCTURE, not just content.');
console.log(' Perfect for knowledge graphs, org charts, taxonomies, and trees.\n');
console.log('💡 Remember:\n');
console.log(' "In hyperbolic space, hierarchies are geometry."');
console.log(' "Distance tells you not just similarity, but relationship."\n');
console.log('=' .repeat(70));
console.log('\n✅ Hyperbolic Attention Exploration Complete!\n');
} catch (error) {
console.error('\n❌ Error:', error);
console.error('\nStack:', error.stack);
process.exit(1);
}
}
main();