Merge commit 'd803bfe2b1fe7f5e219e50ac20d6801a0a58ac75' as 'vendor/ruvector'
This commit is contained in:
231
vendor/ruvector/examples/exo-ai-2025/research/docs/07-causal-emergence.md
vendored
Normal file
231
vendor/ruvector/examples/exo-ai-2025/research/docs/07-causal-emergence.md
vendored
Normal file
@@ -0,0 +1,231 @@
|
||||
# 07 - Causal Emergence
|
||||
|
||||
## Overview
|
||||
|
||||
Implementation of causal emergence theory for detecting when macro-level descriptions have more causal power than micro-level ones, using effective information metrics and coarse-graining optimization.
|
||||
|
||||
## Key Innovation
|
||||
|
||||
**Causal Emergence Detection**: Automatically find the level of description at which a system has maximum causal power, revealing emergent macro-dynamics.
|
||||
|
||||
```rust
|
||||
pub struct CausalEmergence {
|
||||
/// Transition probability matrix (micro level)
|
||||
micro_tpm: TransitionMatrix,
|
||||
/// Coarse-graining mappings
|
||||
coarse_grainings: Vec<CoarseGraining>,
|
||||
/// Effective information at each level
|
||||
ei_levels: Vec<f64>,
|
||||
}
|
||||
```
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────┐
|
||||
│ Micro-Level System │
|
||||
│ ┌─────────────────────────────────┐ │
|
||||
│ │ States: s₁, s₂, ..., sₙ │ │
|
||||
│ │ TPM: P(sⱼ|sᵢ) │ │
|
||||
│ │ EI_micro = I(effect|cause) │ │
|
||||
│ └─────────────────────────────────┘ │
|
||||
├─────────────────────────────────────────┤
|
||||
│ Coarse-Graining │
|
||||
│ ┌─────────────────────────────────┐ │
|
||||
│ │ Macro states: S₁, S₂, ..., Sₘ │ │
|
||||
│ │ Mapping: μ: micro → macro │ │
|
||||
│ │ Macro TPM: P(Sⱼ|Sᵢ) │ │
|
||||
│ └─────────────────────────────────┘ │
|
||||
├─────────────────────────────────────────┤
|
||||
│ Emergence Detection │
|
||||
│ ┌─────────────────────────────────┐ │
|
||||
│ │ EI_macro > EI_micro ? │ │
|
||||
│ │ Causal emergence = YES! │ │
|
||||
│ └─────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Effective Information
|
||||
|
||||
```rust
|
||||
impl EffectiveInformation {
|
||||
/// Compute EI for a transition matrix
|
||||
pub fn compute(&self, tpm: &TransitionMatrix) -> f64 {
|
||||
let n = tpm.size();
|
||||
let mut ei = 0.0;
|
||||
|
||||
// EI = average mutual information between cause and effect
|
||||
// under maximum entropy intervention
|
||||
for i in 0..n {
|
||||
for j in 0..n {
|
||||
let p_joint = tpm.get(i, j) / n as f64; // Max entropy cause
|
||||
let p_effect = tpm.column_sum(j) / n as f64;
|
||||
let p_cause = 1.0 / n as f64;
|
||||
|
||||
if p_joint > 0.0 && p_effect > 0.0 {
|
||||
ei += p_joint * (p_joint / (p_cause * p_effect)).log2();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ei
|
||||
}
|
||||
|
||||
/// Compute causal emergence
|
||||
pub fn causal_emergence(
|
||||
&self,
|
||||
micro_tpm: &TransitionMatrix,
|
||||
macro_tpm: &TransitionMatrix,
|
||||
) -> f64 {
|
||||
let ei_micro = self.compute(micro_tpm);
|
||||
let ei_macro = self.compute(macro_tpm);
|
||||
|
||||
// Normalize by log of state space size
|
||||
let norm_micro = ei_micro / (micro_tpm.size() as f64).log2();
|
||||
let norm_macro = ei_macro / (macro_tpm.size() as f64).log2();
|
||||
|
||||
norm_macro - norm_micro
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Coarse-Graining Optimization
|
||||
|
||||
```rust
|
||||
impl CoarseGraining {
|
||||
/// Find optimal coarse-graining that maximizes EI
|
||||
pub fn optimize(&mut self, micro_tpm: &TransitionMatrix) -> CoarseGraining {
|
||||
let n = micro_tpm.size();
|
||||
let mut best_cg = self.clone();
|
||||
let mut best_ei = 0.0;
|
||||
|
||||
// Try different numbers of macro states
|
||||
for m in 2..n {
|
||||
// Use spectral clustering to find groupings
|
||||
let grouping = self.spectral_partition(micro_tpm, m);
|
||||
|
||||
// Compute macro TPM
|
||||
let macro_tpm = self.induce_macro_tpm(micro_tpm, &grouping);
|
||||
|
||||
// Compute EI
|
||||
let ei = EffectiveInformation::new().compute(¯o_tpm);
|
||||
|
||||
if ei > best_ei {
|
||||
best_ei = ei;
|
||||
best_cg = CoarseGraining::from_grouping(grouping);
|
||||
}
|
||||
}
|
||||
|
||||
best_cg
|
||||
}
|
||||
|
||||
/// Spectral clustering for state grouping
|
||||
fn spectral_partition(&self, tpm: &TransitionMatrix, k: usize) -> Vec<usize> {
|
||||
// Compute Laplacian
|
||||
let laplacian = tpm.laplacian();
|
||||
|
||||
// Find k smallest eigenvectors
|
||||
let eigenvecs = laplacian.eigenvectors(k);
|
||||
|
||||
// K-means on eigenvector space
|
||||
kmeans(&eigenvecs, k)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Causal Hierarchy
|
||||
|
||||
```rust
|
||||
pub struct CausalHierarchy {
|
||||
/// Levels of description
|
||||
levels: Vec<HierarchyLevel>,
|
||||
/// EI at each level
|
||||
ei_profile: Vec<f64>,
|
||||
/// Emergence peaks
|
||||
peaks: Vec<usize>,
|
||||
}
|
||||
|
||||
impl CausalHierarchy {
|
||||
/// Build hierarchy and detect emergence peaks
|
||||
pub fn build(&mut self, micro_tpm: &TransitionMatrix) {
|
||||
let mut current_tpm = micro_tpm.clone();
|
||||
|
||||
for level in 0..self.max_levels {
|
||||
// Compute EI at this level
|
||||
let ei = EffectiveInformation::new().compute(¤t_tpm);
|
||||
self.ei_profile.push(ei);
|
||||
|
||||
// Find optimal coarse-graining for next level
|
||||
let cg = CoarseGraining::new().optimize(¤t_tpm);
|
||||
current_tpm = cg.induce_macro_tpm(¤t_tpm);
|
||||
|
||||
self.levels.push(HierarchyLevel {
|
||||
tpm: current_tpm.clone(),
|
||||
coarse_graining: cg,
|
||||
effective_info: ei,
|
||||
});
|
||||
}
|
||||
|
||||
// Find peaks (levels with local maximum EI)
|
||||
self.peaks = self.find_peaks(&self.ei_profile);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Performance
|
||||
|
||||
| Micro States | Optimization Time | Peak Detection |
|
||||
|--------------|-------------------|----------------|
|
||||
| 16 | 10ms | 1ms |
|
||||
| 64 | 200ms | 5ms |
|
||||
| 256 | 5s | 50ms |
|
||||
| 1024 | 2min | 500ms |
|
||||
|
||||
## Usage
|
||||
|
||||
```rust
|
||||
use causal_emergence::{CausalEmergence, EffectiveInformation, CausalHierarchy};
|
||||
|
||||
// Define micro-level system
|
||||
let micro_tpm = TransitionMatrix::from_data(&state_transitions);
|
||||
|
||||
// Compute effective information
|
||||
let ei = EffectiveInformation::new();
|
||||
let ei_micro = ei.compute(µ_tpm);
|
||||
|
||||
// Find optimal coarse-graining
|
||||
let cg = CoarseGraining::new().optimize(µ_tpm);
|
||||
let macro_tpm = cg.induce_macro_tpm(µ_tpm);
|
||||
let ei_macro = ei.compute(¯o_tpm);
|
||||
|
||||
// Check for causal emergence
|
||||
let emergence = ei_macro - ei_micro;
|
||||
if emergence > 0.0 {
|
||||
println!("Causal emergence detected! Δ EI = {:.3} bits", emergence);
|
||||
}
|
||||
|
||||
// Build full hierarchy
|
||||
let mut hierarchy = CausalHierarchy::new(10);
|
||||
hierarchy.build(µ_tpm);
|
||||
|
||||
for (level, ei) in hierarchy.ei_profile.iter().enumerate() {
|
||||
let marker = if hierarchy.peaks.contains(&level) { " ← PEAK" } else { "" };
|
||||
println!("Level {}: EI = {:.3}{}", level, ei, marker);
|
||||
}
|
||||
```
|
||||
|
||||
## Interpretation
|
||||
|
||||
| Emergence Value | Interpretation |
|
||||
|-----------------|----------------|
|
||||
| < 0 | Micro level is more causal |
|
||||
| = 0 | No emergence |
|
||||
| 0 to 0.5 | Weak emergence |
|
||||
| 0.5 to 1.0 | Moderate emergence |
|
||||
| > 1.0 | Strong causal emergence |
|
||||
|
||||
## References
|
||||
|
||||
- Hoel, E.P. et al. (2013). "Quantifying causal emergence shows that macro can beat micro"
|
||||
- Tononi, G. & Sporns, O. (2003). "Measuring information integration"
|
||||
- Klein, B. & Hoel, E.P. (2020). "The Emergence of Informative Higher Scales"
|
||||
Reference in New Issue
Block a user