Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
8aa8fe2
docs: Tier 0 scientific-core repair design spec
bshepp May 17, 2026
ed1bf6c
docs: Tier 0 scientific-core implementation plan
bshepp May 17, 2026
db2da1b
feat: add AttractorType.UNDETERMINED
bshepp May 17, 2026
a754db8
test: RK4 Lorenz/Rössler fixtures replacing Euler Lorenz
bshepp May 17, 2026
25f04f5
test: harden Rössler fixture assertions + clarify _rk4 helper
bshepp May 17, 2026
f01413a
feat: embedding module (MI delay, Cao dimension, Theiler window)
bshepp May 17, 2026
acc0f44
fix: Cao value-threshold saturation, consistent 2D handling, MI loop …
bshepp May 17, 2026
79008af
feat: Rosenstein largest_lyapunov + exploratory Sano-Sawada spectrum
bshepp May 17, 2026
aa555c7
fix: data-driven Rosenstein scaling-region detector + generalisation …
bshepp May 17, 2026
06e7b5b
fix: reject single-step-jump as lambda1; scope maps out; noisy-period…
bshepp May 17, 2026
6f8229e
test: broaden noisy-periodic regression gate; clarify _FLAT_LEN comme…
bshepp May 17, 2026
b5293a9
feat: IAAFT surrogates + two-sided rank+effect-size gate, fixed share…
bshepp May 17, 2026
c6c8014
feat: surrogate-gated classify_attractor + Kaplan-Yorke (moved)
bshepp May 17, 2026
e3603e2
fix: cast kaplan_yorke_dimension return to float (mypy no-any-return)
bshepp May 17, 2026
52adb27
refactor: clean-break removal of old Lyapunov API; new mneme.core exp…
bshepp May 17, 2026
944f549
test: trim test_attractors to recurrence/clustering/correlation; fix …
bshepp May 17, 2026
64723b6
refactor: migrate analysis scripts to Tier 0 API + import-and-run smo…
bshepp May 17, 2026
01896ec
docs: update API snippets to Tier 0; withdraw unvalidated Lyapunov cl…
bshepp May 17, 2026
c7a6c71
fix: avoid list->ndarray rebinding in mutual_information_delay (mypy)
bshepp May 17, 2026
74179fb
docs: migrate MkDocs API reference to Tier 0 module layout (fix build…
bshepp May 17, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,17 @@
All notable changes to this project will be documented in this file.

- Unreleased
- ### Changed (Tier 0 — scientific core repair)
- **BREAKING:** removed `compute_lyapunov_spectrum` and `classify_attractor_by_lyapunov`.
- Added `largest_lyapunov` (Rosenstein 1993), exploratory `lyapunov_spectrum`
(corrected Sano-Sawada), `surrogate_test` (IAAFT, two-sided rank + effect-size
gate, shared embedding), and surrogate-gated `classify_attractor` with the new
`AttractorType.UNDETERMINED`.
- Added `mneme.core.embedding` (true-MI delay, Cao-1997 dimension, Theiler window).
- Chaos / strange-attractor labels now require a passed surrogate test.
- Discrete maps are out of scope for `largest_lyapunov` (continuous flows only).
- Previous PhysioNet headline numbers (λ₁≈0.12, D_KY≈2.35) are withdrawn pending
re-validation under the corrected estimators.
- **fix(data.loaders)**: `BaseDataLoader.get_info()` now reads dtype from `Field.data` (numpy ndarray) instead of attempting `Field.dtype` (which does not exist).
- **fix(analysis.results)**: `_create_html_report()` switched to f-string with escaped CSS braces, fixing `KeyError` on report generation; previously skipped test re-enabled.
- **refactor(core.attractors)**: Removed unused `compute_basin_of_attraction()` placeholder. Design notes and a suggested signature for a future re-implementation are preserved in [docs/FUTURE_IDEAS.md](docs/FUTURE_IDEAS.md).
Expand Down
31 changes: 14 additions & 17 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ The core system is in **active development** with all major components implement
- **Field Reconstruction**: Sparse GP (default, scalable), Dense IFT, Standard GP, Neural Fields
- **Topology Analysis**: Full GUDHI integration (cubical, Rips, Alpha complexes)
- **Attractor Detection**: Recurrence, Lyapunov, and clustering methods
- **Lyapunov Spectrum**: Full Wolf algorithm with `compute_lyapunov_spectrum()`, `kaplan_yorke_dimension()`, `classify_attractor_by_lyapunov()`
- **Lyapunov Spectrum**: Rosenstein-1993 `largest_lyapunov()`, exploratory `lyapunov_spectrum()`, `surrogate_test()`, surrogate-gated `classify_attractor()`, `kaplan_yorke_dimension()`
- **Symbolic Regression**: Full PySR integration with `discover_field_dynamics()`
- **Latent Space Analysis**: Convolutional VAE with training, encoding, interpolation
- **Pipeline**: End-to-end analysis with visualization and HDF5 export
- **Real Data Validation**: Tested on PhysioNet ECG/HRV data with results matching literature
- **Real Data Validation**: PhysioNet ECG/HRV validation pending re-run under Tier 0 corrected estimators
- **BETSE Integration**: Loader for BETSE bioelectric tissue simulation output (`betse_loader.py`)
- **Test Suite**: Unit and integration tests with CI via GitHub Actions

Expand Down Expand Up @@ -147,27 +147,24 @@ python scripts/analyze_betse.py path/to/Vmem2D_TextExport/ --resolution 64 --out
## Known Issues / TODOs

- Import order warning: import juliacall before torch to avoid potential segfault
- Lyapunov spectrum requires >100 timesteps (hard error) and emits a `RuntimeWarning` below 1000 (recommended); short BETSE simulations (e.g. `betse try`) will fail this check
- `lyapunov_spectrum()` (exploratory) requires >100 timesteps (hard error) and emits a `RuntimeWarning` below 1000 (recommended); short BETSE simulations (e.g. `betse try`) will fail this check
- GUDHI Wasserstein distance requires the `POT` package (`pip install POT`); bottleneck distance works without it
- Test coverage is 63.92%; target is 70%+ for JOSS submission
- `compute_basin_of_attraction()` was removed in this revision; design notes preserved in [docs/FUTURE_IDEAS.md](docs/FUTURE_IDEAS.md) for future re-implementation

## Lyapunov Spectrum Usage

```python
from mneme.core import compute_lyapunov_spectrum, classify_attractor_by_lyapunov, kaplan_yorke_dimension

# Compute spectrum from any trajectory (1D or embedded)
spectrum = compute_lyapunov_spectrum(trajectory, dt=0.01, n_neighbors=15)

# Interpret results
attractor_type = classify_attractor_by_lyapunov(spectrum) # FIXED_POINT, LIMIT_CYCLE, STRANGE, etc.
d_ky = kaplan_yorke_dimension(spectrum) # Fractal dimension

# What the spectrum means:
# - Positive exponent → chaos (trajectories diverge)
# - Zero exponent → neutral (flow direction)
# - Negative exponents → stability (trajectories converge)
from mneme.core import (
largest_lyapunov, surrogate_test, classify_attractor,
lyapunov_spectrum, kaplan_yorke_dimension,
)

res = largest_lyapunov(trajectory, dt=0.01) # robust λ₁ (Rosenstein 1993)
sur = surrogate_test(trajectory, statistic="lambda1", n=200, dt=0.01)
attractor_type = classify_attractor(res.lambda1, surrogate=sur) # STRANGE only if sur.significant
spectrum = lyapunov_spectrum(trajectory, dt=0.01) # EXPLORATORY full spectrum (RuntimeWarning)
d_ky = kaplan_yorke_dimension(spectrum)
```

**Validated on real data:** PhysioNet ECG heart rate variability shows λ₁=+0.12/s, D_KY=2.35, matching published literature on cardiac chaos.
> **Validation status:** Lyapunov/attractor results are **pending re-validation** under the Tier 0 corrected estimators. The previous PhysioNet headline numbers were produced by the now-removed estimator and are **not asserted**. Chaos is never reported without a passed surrogate-significance test.
35 changes: 13 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Mneme seeks to uncover attractor states, regulatory logic, and latent architectu
- **Field Reconstruction**: Scalable Sparse GP reconstruction (default), with dense IFT, standard GP, and neural field backends available. Handles 256×256 fields in sub-second time.
- **Topology Analysis**: Full GUDHI integration for cubical, Rips, and Alpha complexes. Computes persistence diagrams, landscapes, and images with Wasserstein/bottleneck distances.
- **Attractor Detection**: Recurrence-based, Lyapunov, and clustering detectors for identifying stable states in temporal field data.
- **Lyapunov Spectrum**: Full Wolf algorithm implementation for computing Lyapunov exponents from trajectory data. Includes `kaplan_yorke_dimension()` for fractal dimension and automatic attractor classification.
- **Lyapunov Spectrum**: Rosenstein-1993 `largest_lyapunov()` for robust λ₁, exploratory `lyapunov_spectrum()`, surrogate significance testing via `surrogate_test()`, and surrogate-gated `classify_attractor()`. Includes `kaplan_yorke_dimension()` for fractal dimension.
- **Symbolic Regression**: Full PySR integration for discovering governing equations from field dynamics. Includes `discover_field_dynamics()` for automatic PDE discovery.
- **Latent Space Analysis**: Convolutional VAE (`FieldAutoencoder`) for learning compressed field representations, with training loop, interpolation, and sampling capabilities.

Expand Down Expand Up @@ -46,28 +46,13 @@ For detailed setup instructions, see [docs/DEVELOPMENT_SETUP.md](docs/DEVELOPMEN

**Previous milestones (2025-11-27):**
- ✅ Sparse GP reconstruction as scalable default (O(nm²) instead of O(n³))
- ✅ Full Lyapunov spectrum computation (Wolf algorithm) with real data validation
- ✅ Lyapunov analysis (Rosenstein λ₁, exploratory spectrum, surrogate gating) — re-validation pending under Tier 0 estimators
- ✅ Full PySR integration for symbolic regression with Julia backend
- ✅ Convolutional VAE with proper training loop and latent space utilities
- ✅ GUDHI integration for Rips, Alpha, and cubical complexes
- ✅ Dense IFT preserved as option for exact computation on small fields

### Validated on Real Biological Data

The Lyapunov spectrum implementation has been tested on real ECG data from PhysioNet:

```
Heart Rate Variability Analysis (MIT-BIH Record 100):
λ₁ = +0.123 /s (chaos - healthy!)
λ₂ = -0.007 /s (near-zero)
λ₃ = -0.330 /s (contraction)
λ₄ = -0.953 /s (contraction)

Kaplan-Yorke Dimension: 2.35
Predictability Horizon: ~8 seconds
```

This matches published literature on HRV chaos and validates the algorithm for biological time series.
Lyapunov and attractor results are **pending re-validation** under the Tier 0 corrected estimators. Chaos/strange-attractor labels are gated behind a surrogate-significance test (IAAFT, two-sided) — the tool does not report chaos without passed surrogate evidence.

## Quick Start

Expand Down Expand Up @@ -103,11 +88,17 @@ from mneme.models import discover_field_dynamics
result = discover_field_dynamics(data, dt=1.0, niterations=50)
print(f"Discovered equation: {result['best_equation']}")

# Compute Lyapunov spectrum (chaos analysis)
from mneme.core import compute_lyapunov_spectrum, kaplan_yorke_dimension
# Compute Lyapunov exponent (chaos analysis)
from mneme.core import (
largest_lyapunov, surrogate_test, classify_attractor,
lyapunov_spectrum, kaplan_yorke_dimension,
)
trajectory = latent # Use VAE latent space as phase space
spectrum = compute_lyapunov_spectrum(trajectory, dt=1.0)
print(f"Lyapunov spectrum: {spectrum}")
res = largest_lyapunov(trajectory, dt=1.0)
sur = surrogate_test(trajectory, statistic="lambda1", n=200, dt=1.0)
attractor_type = classify_attractor(res.lambda1, surrogate=sur) # STRANGE only if sur.significant
spectrum = lyapunov_spectrum(trajectory, dt=1.0) # EXPLORATORY full spectrum (RuntimeWarning)
print(f"λ₁ = {res.lambda1:.4f}, attractor = {attractor_type}")
print(f"Kaplan-Yorke dimension: {kaplan_yorke_dimension(spectrum):.2f}")
```

Expand Down
23 changes: 8 additions & 15 deletions docs/api/core/attractors.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
# Attractors

Attractor detection and dynamical systems analysis for field time series.
Recurrence- and clustering-based attractor detection for field time series.

(For the corrected Lyapunov estimator and surrogate-significance gate, see
[Lyapunov](lyapunov.md), [Surrogates](surrogates.md), and
[Classification](classify.md). For embedding-parameter selection see
[Embedding](embedding.md).)

## Recurrence Analysis

::: mneme.core.attractors.RecurrenceAnalysis

## Lyapunov Analysis
## Lyapunov Analysis (detector)

::: mneme.core.attractors.LyapunovAnalysis

## Convenience Functions

::: mneme.core.attractors.compute_lyapunov_spectrum

::: mneme.core.attractors.classify_attractor_by_lyapunov

::: mneme.core.attractors.kaplan_yorke_dimension
## Correlation Dimension

::: mneme.core.attractors.compute_correlation_dimension

Expand All @@ -27,9 +26,3 @@ Attractor detection and dynamical systems analysis for field time series.
## Dispatcher

::: mneme.core.attractors.AttractorDetector

## Embedding Utilities

::: mneme.core.attractors.embed_trajectory

::: mneme.core.attractors.estimate_embedding_parameters
11 changes: 11 additions & 0 deletions docs/api/core/classify.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Classification

Surrogate-gated attractor classification and Kaplan-Yorke dimension.

## Classify Attractor

::: mneme.core.classify.classify_attractor

## Kaplan-Yorke Dimension

::: mneme.core.classify.kaplan_yorke_dimension
23 changes: 23 additions & 0 deletions docs/api/core/embedding.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Embedding

Phase-space embedding and parameter selection (true-MI delay, Cao-1997 dimension, Theiler window).

## Delay Embedding

::: mneme.core.embedding.embed_trajectory

## Parameter Selection

::: mneme.core.embedding.estimate_embedding_parameters

## Mutual Information Delay

::: mneme.core.embedding.mutual_information_delay

## Cao Embedding Dimension

::: mneme.core.embedding.cao_embedding_dimension

## Theiler Window

::: mneme.core.embedding.theiler_window
15 changes: 15 additions & 0 deletions docs/api/core/lyapunov.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Lyapunov

Largest Lyapunov exponent (Rosenstein 1993) and an exploratory full spectrum.

## Result Type

::: mneme.core.lyapunov.LyapunovResult

## Largest Lyapunov Exponent

::: mneme.core.lyapunov.largest_lyapunov

## Exploratory Spectrum

::: mneme.core.lyapunov.lyapunov_spectrum
15 changes: 15 additions & 0 deletions docs/api/core/surrogates.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Surrogates

IAAFT surrogate data and the rank + effect-size significance gate.

## IAAFT Surrogates

::: mneme.core.surrogates.iaaft_surrogates

## Result Type

::: mneme.core.surrogates.SurrogateResult

## Significance Test

::: mneme.core.surrogates.surrogate_test
6 changes: 5 additions & 1 deletion docs/api/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ The foundation of Mneme's analysis capabilities:

- [**Field Theory**](core/field_theory.md) -- Field reconstruction from sparse observations (Sparse GP, Dense IFT, Neural Fields)
- [**Topology**](core/topology.md) -- Persistent homology, persistence diagrams, Wasserstein/bottleneck distances
- [**Attractors**](core/attractors.md) -- Recurrence analysis, Lyapunov spectrum, clustering-based attractor detection
- [**Attractors**](core/attractors.md) -- Recurrence- and clustering-based attractor detection
- [**Lyapunov**](core/lyapunov.md) -- Largest Lyapunov exponent (Rosenstein 1993) and exploratory spectrum
- [**Surrogates**](core/surrogates.md) -- IAAFT surrogate-data significance testing
- [**Classification**](core/classify.md) -- Surrogate-gated attractor classification, Kaplan-Yorke dimension
- [**Embedding**](core/embedding.md) -- Delay/dimension selection (MI delay, Cao 1997, Theiler window)

## Models

Expand Down
Loading
Loading