| name | sindy-skill |
| description | Sparse Identification of Nonlinear Dynamical Systems (SINDy) using PySINDy. Use this skill when the user wants to (1) discover governing equations from time-series data, (2) perform sparse regression on dynamical systems, (3) identify ODEs or PDEs from measurement data, (4) use PySINDy for system identification, (5) build SINDy models with different optimizers or feature libraries, (6) simulate or predict dynamical system behavior from discovered equations. Trigger when user mentions SINDy, PySINDy, sparse identification, system identification from data, equation discovery, data-driven dynamics, or governing equation learning. |
SINDy Skill
Discover sparse governing equations (ODEs/PDEs) from time-series data using PySINDy.
Environment Setup
Before using PySINDy, ensure the environment is ready:
bash scripts/setup_env.sh [optional/venv/path]
This creates a venv with pysindy[cvxpy], matplotlib, and scipy. If the user already has pysindy installed, skip this step.
Minimum install (no venv script):
pip install pysindy matplotlib scipy
For advanced optimizers:
pip install "pysindy[cvxpy]"
pip install "pysindy[miosr]"
pip install "pysindy[sbr]"
Quick Start Workflow
SINDy solves: dX/dt = Theta(X) * Xi, where Theta is a feature library and Xi are sparse coefficients.
1. Prepare Data
import numpy as np
import pysindy as ps
2. Build and Fit Model
model = ps.SINDy(
differentiation_method=ps.FiniteDifference(order=2),
feature_library=ps.PolynomialLibrary(degree=3),
optimizer=ps.STLSQ(threshold=0.1),
)
model.fit(X, t=t, feature_names=["x", "y"])
model.print()
3. Evaluate and Use
score = model.score(X, t=t)
x_dot = model.predict(X)
x_sim = model.simulate(X[0], t)
coeffs = model.coefficients()
CLI Tool
For quick analysis from CSV data, run scripts/sindy_analyze.py:
python scripts/sindy_analyze.py data.csv --degree 3 --threshold 0.1 --simulate
The CSV must have a time (or t) column. All other columns are treated as state variables.
Options: --library poly|fourier|poly+fourier, --optimizer stlsq|sr3|ssr|frols, --output equations.txt, --simulate.
Component Selection Guide
Differentiation (compute dX/dt from X)
| Data Quality | Method |
|---|
| Clean | FiniteDifference(order=2) (default) |
| Mild noise | SmoothedFiniteDifference() |
| Periodic | SpectralDerivative() |
| Noisy | SINDyDerivative(kind="kalman", alpha=0.05) |
| Known derivatives | Pass x_dot= to fit() directly |
Feature Library (candidate functions Theta)
| System Type | Library |
|---|
| General nonlinear | PolynomialLibrary(degree=2-5) |
| Oscillatory | FourierLibrary(n_frequencies=3) |
| Mixed | ConcatLibrary([PolynomialLibrary(), FourierLibrary()]) |
| Domain-specific | CustomLibrary(library_functions=[...]) |
| PDEs | PDELibrary(...) or WeakPDELibrary(...) |
Optimizer (sparse regression for Xi)
| Scenario | Optimizer |
|---|
| Default / simple | STLSQ(threshold=0.1) |
| Flexible regularization | SR3(threshold=0.1) (needs cvxpy) |
| Known constraints | ConstrainedSR3(...) (needs cvxpy) |
| Stability guarantee | TrappingSR3(...) (needs cvxpy) |
| Fast greedy | SSR() or FROLS() |
| Exact L0 sparsity | MIOSR(l0_bound=10) (needs gurobipy) |
| Noisy data | EnsembleOptimizer(opt=STLSQ(), bagging=True, n_models=20) |
Common Patterns
Lorenz System Example
from scipy.integrate import solve_ivp
from pysindy.utils.odes import lorenz
sol = solve_ivp(lorenz, (0, 10), [-8, 8, 27],
t_eval=np.linspace(0, 10, 2000), max_step=0.01)
model = ps.SINDy(optimizer=ps.STLSQ(threshold=0.2))
model.fit(sol.y.T, t=sol.t, feature_names=["x", "y", "z"])
model.print()
Multiple Trajectories
model.fit([X1, X2, X3], t=[t1, t2, t3])
With Control Inputs
model.fit(X, t=t, u=U)
model.simulate(x0, t, u=u_func)
References