Asi nonlinear-dynamics-observatory
git clone https://github.com/plurigrid/asi
T=$(mktemp -d) && git clone --depth=1 https://github.com/plurigrid/asi "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/nonlinear-dynamics-observatory" ~/.claude/skills/plurigrid-asi-nonlinear-dynamics-observatory && rm -rf "$T"
skills/nonlinear-dynamics-observatory/SKILL.mdNonlinear Dynamics Observatory
<<<<<<< HEAD Topos Story #23: "every attractor is a sheaf section; learning = finding the natural transformation between systems"
Component Map
dysts ← corpus of 130+ strange attractors ↓ panda ← Patched Attention for Nonlinear Dynamics (transformer patches) ↓ geomstats ← Riemannian geometry of attractor basins (Fisher-Rao, geodesics) ↓ neuraloperator ← FNO/DeepONet for infinite-dimensional operators ↓ lolita (arxiv:2507.02608)← latent diffusion physics emulation (1000x compression) ↓ bayesian-breathing ← Bayesian state estimation (MCMC/SMC posterior over trajectory) ↓ hoi ← higher-order interactions (n-body dynamical couplings) ↓ ontology ← autopoietic ergodicity as meta-theory (attractor = identity)
GF(3) Tripartite Tag
dysts(-1) ⊗ nonlinear-dynamics-observatory(0) ⊗ lolita(+1) = 0
Validation (-1, ground truth corpus) × Bridge (0, routing) × Generation (+1, emulation) = 0.
The Core Vision
Every attractor in
dysts is a sheaf section: a locally consistent assignment of state to each time-point, globally stitched by the dynamical law. Learning a dynamical system = finding the natural transformation between two sheaves (the ground-truth attractor sheaf and the learned model sheaf).
lolita emulates this at 1000× compression via latent diffusion. bayesian-breathing maintains a probabilistic posterior over which attractor family generated the observed trajectory. geomstats measures distances between attractor basins on the Riemannian manifold of probability distributions. ontology's autopoietic ergodicity provides the thermodynamic grounding: a stable attractor IS an autopoietically ergodic state.
1. dysts — Strange Attractor Corpus
=======
Component Map
dysts <- corpus of 130+ strange attractors | panda <- Patched Attention for Nonlinear Dynamics (transformer patches) | geomstats <- Riemannian geometry of attractor basins (Fisher-Rao, geodesics) | neuraloperator <- FNO/DeepONet for infinite-dimensional operators | lolita (arxiv:2507.02608)<- latent diffusion physics emulation (1000x compression) | bayesian-breathing <- Bayesian state estimation (MCMC/SMC posterior over trajectory) | hoi <- higher-order interactions (n-body dynamical couplings)
1. dysts -- Strange Attractor Corpus
origin/main
import dysts.flows as flows from dysts.datasets import load_file <<<<<<< HEAD # Load attractor by name ======= >>>>>>> origin/main lorenz = flows.Lorenz() traj = lorenz.make_trajectory(n=10000, pts_per_period=50) # traj.shape = (10000, 3) <<<<<<< HEAD # All attractors with metadata from dysts import get_attractor_list attractors = get_attractor_list() # 130+ named attractors # GF(3) classification by Lyapunov spectrum def classify_trit(attractor): """Classify attractor by first Lyapunov exponent.""" λ = attractor.lyapunov_exponent() if λ > 0: return +1 # chaotic (Generator) if λ < 0: return -1 # stable fixed point (Validator) return 0 # marginal / limit cycle (Coordinator)
2. lolita — Latent Diffusion Physics Emulation
(NeurIPS 2025, arxiv:2507.02608): DCAE autoencoder (lat_channels=64) + ViT diffusion on latents.
from dysts import get_attractor_list attractors = get_attractor_list() # 130+ named attractors
def classify_by_lyapunov(attractor): """Classify attractor by first Lyapunov exponent.""" lam = attractor.lyapunov_exponent() if lam > 0: return +1 # chaotic if lam < 0: return -1 # stable fixed point return 0 # marginal / limit cycle
## 2. lolita -- Latent Diffusion Physics Emulation NeurIPS 2025 (arxiv:2507.02608): DCAE autoencoder (lat_channels=64) + ViT diffusion on latents. >>>>>>> origin/main ```python from lolita import LolitaEmulator <<<<<<< HEAD # Train on dysts corpus emulator = LolitaEmulator(lat_channels=64, dataset="rayleigh_benard") emulator.train(epochs=100, batch_size=32) # Generate novel physics trajectory new_trajectory = emulator.sample( initial_condition=lorenz.ic, n_steps=1000, guidance_scale=7.5 # classifier-free guidance ) # Evaluate: is the emulated trajectory on the correct attractor? ======= emulator = LolitaEmulator(lat_channels=64, dataset="rayleigh_benard") emulator.train(epochs=100, batch_size=32) new_trajectory = emulator.sample( initial_condition=lorenz.ic, n_steps=1000, guidance_scale=7.5 ) >>>>>>> origin/main from lolita.eval import rollout_error err = rollout_error(new_trajectory, lorenz.make_trajectory(1000)) # Good emulation: err < 0.05
<<<<<<< HEAD Datasets: Euler equations, Rayleigh-Bénard convection, Turbulence Gravity Cooling (from The Well).
3. panda — Patched Attention for Nonlinear Dynamics
Transformer with patches over attractor phase space:
Datasets: Euler equations, Rayleigh-Benard convection, Turbulence Gravity Cooling (from The Well).
3. panda -- Patched Attention for Nonlinear Dynamics
origin/main
from panda import PatchedAttentionModel <<<<<<< HEAD # Divide attractor trajectory into patches model = PatchedAttentionModel( patch_size=50, # time steps per patch d_model=256, n_heads=8, n_layers=6, attractor_dim=3 # dimensionality (e.g. Lorenz = 3D) ) # Train: predict next patch from context patches model.train(dysts_trajectories, epochs=50) # Extrapolate: given 200 steps, predict 800 more context = lorenz_traj[:200] prediction = model.rollout(context, n_steps=800)
4. geomstats — Riemannian Geometry of Attractor Basins
======= model = PatchedAttentionModel( patch_size=50, d_model=256, n_heads=8, n_layers=6, attractor_dim=3 ) model.train(dysts_trajectories, epochs=50) prediction = model.rollout(lorenz_traj[:200], n_steps=800)
## 4. geomstats -- Riemannian Geometry of Attractor Basins >>>>>>> origin/main ```python import geomstats.backend as gs from geomstats.geometry.spd_matrices import SPDMatrices from geomstats.statistics.frechet_mean import FrechetMean <<<<<<< HEAD # Represent each attractor as a covariance matrix (SPD) def attractor_covariance(traj): return gs.array(np.cov(traj.T)) # Fisher-Rao distance between attractors (on SPD manifold) manifold = SPDMatrices(n=3) # 3D attractors lorenz_spd = attractor_covariance(lorenz_traj) rossler_spd = attractor_covariance(rossler_traj) distance = manifold.metric.dist(lorenz_spd, rossler_spd) # Fisher-Rao distance = information-geometric separation of attractors # Fréchet mean of attractor family (centroid on manifold) ======= def attractor_covariance(traj): return gs.array(np.cov(traj.T)) manifold = SPDMatrices(n=3) # 3D attractors distance = manifold.metric.dist(lorenz_spd, rossler_spd) >>>>>>> origin/main mean_calculator = FrechetMean(manifold.metric) family_centroid = mean_calculator.fit([spd1, spd2, spd3]).estimate_
<<<<<<< HEAD Connection to BCI: Fisher-Rao distance on SPD matrices is EXACTLY what
bci-phenomenology uses for 8ch EEG covariance — the EEG manifold IS an attractor manifold.
5. neuraloperator — Infinite-Dimensional Function Operators
======= Fisher-Rao distance on SPD matrices is the same metric used by bci-phenomenology for 8ch EEG covariance.
5. neuraloperator -- Infinite-Dimensional Function Operators
origin/main
from neuraloperator.models import FNO <<<<<<< HEAD # Fourier Neural Operator for PDE learning fno = FNO( n_modes=(16, 16), # Fourier modes hidden_channels=64, in_channels=1, # initial condition out_channels=1, # solution at time T n_layers=4, ) # Train: learn the solution operator of Rayleigh-Bénard PDE # input: initial temperature field → output: field at t=1.0 fno.train(rb_dataset, epochs=200) # Evaluate at any resolution (operator != network) hi_res_solution = fno(initial_condition_64x64) # 64x64 resolution lo_res_solution = fno(initial_condition_16x16) # 16x16 resolution
Connection to lolita: lolita compresses PDE solutions via DCAE, then diffuses in latent space. FNO learns the solution operator directly. These are complementary: FNO for fast single-step, lolita for generative rollout.
6. bayesian-breathing — Bayesian State Estimation
# Which attractor generated this observed trajectory? # Posterior: P(attractor | observations) via monad-bayes SMC import pymc as pm import numpy as np ======= fno = FNO( n_modes=(16, 16), hidden_channels=64, in_channels=1, out_channels=1, n_layers=4, ) fno.train(rb_dataset, epochs=200) # Evaluate at any resolution (operator != network) hi_res = fno(initial_condition_64x64) lo_res = fno(initial_condition_16x16)
FNO learns the solution operator directly. Complementary to lolita: FNO for fast single-step, lolita for generative rollout.
6. bayesian-breathing -- Bayesian State Estimation
import pymc as pm >>>>>>> origin/main def attractor_identification_model(observations): """Identify attractor family from noisy trajectory.""" with pm.Model() as model: <<<<<<< HEAD # Prior: uniform over attractor families attractor_idx = pm.Categorical("attractor", p=[1/130] * 130) # Likelihood: Riemannian distance to attractor covariance obs_cov = np.cov(observations.T) attractor_covs = [attractor_covariance(a) for a in ALL_ATTRACTORS] # Fisher-Rao distance as likelihood (via geomstats) dist = fisher_rao_distance(obs_cov, attractor_covs[attractor_idx]) pm.Potential("likelihood", -dist**2 / (2 * 0.1**2)) # Sample posterior trace = pm.sample(2000, tune=1000, cores=4) return trace # RMSMC version (from monad-bayes) # Sequential identification as new observations arrive posterior = rmsmc_attractor_identification(streaming_traj)
7. hoi — Higher-Order Interactions
Beyond pairwise couplings in attractor networks:
attractor_idx = pm.Categorical("attractor", p=[1/130] * 130) obs_cov = np.cov(observations.T) dist = fisher_rao_distance(obs_cov, attractor_covs[attractor_idx]) pm.Potential("likelihood", -dist**2 / (2 * 0.1**2)) trace = pm.sample(2000, tune=1000, cores=4) return trace
## 7. hoi -- Higher-Order Interactions >>>>>>> origin/main ```python from hoi import Oinfo, HOI <<<<<<< HEAD # Measure n-body interactions in attractor state variables hoi_analysis = HOI(method="oinfo") # 3D Lorenz: which triplets of variables have synergistic HOI? ======= hoi_analysis = HOI(method="oinfo") >>>>>>> origin/main lorenz_data = lorenz.make_trajectory(5000) oinfo_values = hoi_analysis.fit(lorenz_data) # oinfo > 0: redundancy (attractor dimension collapse) # oinfo < 0: synergy (chaos amplification) <<<<<<< HEAD # Compare HOI across attractors def hoi_fingerprint(attractor): traj = attractor.make_trajectory(5000) return hoi_analysis.fit(traj)
8. Autopoietic Ergodicity as Meta-Theory
From
plurigrid/ontology: a stable attractor IS an autopoietically ergodic state.
def is_autopoietically_ergodic(traj, epsilon=0.05): """Check if trajectory has stabilized to an ergodic attractor.""" # Condition 1: time average ≈ ensemble average (ergodicity) time_avg = np.mean(traj, axis=0) ensemble_avg = np.mean([attractor.make_trajectory(100)[-1] for _ in range(100)], axis=0) ergodic = np.linalg.norm(time_avg - ensemble_avg) < epsilon # Condition 2: Lyapunov stability (attractor is self-maintaining) lyapunov = compute_lyapunov(traj) autopoietic = lyapunov < 0.5 # bounded chaos = stable self-organization return ergodic and autopoietic # Every attractor in dysts that passes this test is an "identity" # in the ontology sense: a self-maintaining, thermodynamically stable structure identities = [a for a in get_attractor_list() if is_autopoietically_ergodic(a.make_trajectory(10000))]
=======
>>>>>>> origin/main ## Cross-Component Wiring
dysts (corpus) <<<<<<< HEAD │── panda (transformer extrapolation) │── geomstats (Riemannian distances between attractors) │── neuraloperator (FNO solution operators) │ └── lolita (latent diffusion emulation) │── monad-bayes PMMH (parameter inference) │── Vertex AI Pipelines (scale to GCP) │ └── bayesian-breathing (posterior over attractor family) │── geomstats Fisher-Rao likelihood │── hoi (higher-order interaction diagnostics) │ └── ontology (autopoietic ergodicity test) └── GF(3) trit: +1=chaotic, 0=marginal, -1=stable
## Related ASI Skills - `dysts` / `attractor` / `chaotic-attractor` — attractor corpus and dynamics - `lolita` — latent diffusion physics emulation - `bayesian-breathing` — posterior state estimation - `trajectory` / `periodic-orbit` / `repeller` — trajectory analysis - `monad-bayes-asi-interleave` — PMMH for lolita parameter inference - `vertex-ai-protein-interleave` — KFP pipeline patterns (reuse for physics) - `catlab-asi-interleave` — AlgebraicDynamics.jl for ODE composition - `ontology-asi-interleave` — autopoietic ergodicity meta-theory - `bci-colored-operad` — Fisher-Rao on EEG = Fisher-Rao on attractors - `gay-monte-carlo` — GF(3)-colored MCMC sampling over attractor families - `abductive-monte-carlo` — which attractor generated these observations? - `ergodicity` — the convergence criterion - `lyapunov-function` / `lyapunov-stability` — stability analysis - `bifurcation` / `bifurcation-generator` — attractor birth/death - `waddington-landscape` — energy landscape = potential function of dynamics - `invariant-measure` / `invariant-set` — ergodic theory foundation - `attractor` / `stable-manifold` / `unstable-manifold` — manifold structure ======= |-- panda (transformer extrapolation) |-- geomstats (Riemannian distances between attractors) |-- neuraloperator (FNO solution operators) | +-- lolita (latent diffusion emulation) |-- monad-bayes PMMH (parameter inference) |-- Vertex AI Pipelines (scale to GCP) | +-- bayesian-breathing (posterior over attractor family) |-- geomstats Fisher-Rao likelihood |-- hoi (higher-order interaction diagnostics)
origin/main