Skip to content

PySINDy

Sparse regression over a supplied candidate library, solved in one pass.

algorithm
pysindy
score
NMSE min
cost
light
derivatives
finite_diff
equation form
EVOLUTION REGRESSION
data layout
grid tabular

Usage

import kd

dataset = kd.load_burgers()
config = kd.PySINDyConfig(
    terms=("u", "u_x", "u_xx", "mul(u,u_x)"), threshold=0.05, seed=0,
)
model = kd.Model(algorithm="pysindy", config=config)
model.fit(dataset)
print(model.result_.equation)

Main parameters

Parameter Default Resume Description
threshold 0.1 init-only STLSQ sparsity threshold.
max_iter 20 init-only Maximum STLSQ iterations.
normalize_columns False init-only Normalize library columns before STLSQ.
relative_threshold False init-only Read threshold as a fraction of the target L2 norm (requires normalize_columns).
degree 2 init-only Maximum total polynomial degree for tabular data.
All fields of PySINDyConfig
Field Type Default
terms tuple[str, ...] ('u', 'u_x', 'u_xx', 'mul(u, u_x)')
threshold float 0.1
max_iter int 20
normalize_columns bool False
relative_threshold bool False
unbias bool True
seed int 0
extra_optimizer_kwargs dict[str, Any] \| None None
degree int 2

Search space

The KD wrapper uses PySINDy's sparse optimizer over a supplied term library. terms contains KD function-call strings using the dataset's field and axis names. Supply terms for grids other than one-field u(x,t). mul and add take two arguments; nest multiplication for a cube. Terms can contain coordinates, products such as mul(u, u_x), and operators such as sin, exp or binary div. A compound derivative uses u_x_t or diff_t(u_x) rather than u_xt. Supply terms for all relevant axes and fields; dataset dimensions do not expand the library.

Use uniformly spaced axes with at least five points per axis for the finite-difference stencil. Any number of spatial axes can supply columns. Atomic derivative names support orders through three per axis; compound and open-form derivatives are computed during execution. For example, u_xxxx exceeds the atomic-order cap, while diff_x(u_xxx) uses composition. The fit refuses duplicate terms and target-derivative tautologies. A non-uniform axis or an unresolvable term fails explicitly. Smoothing noisy observations before differentiation can improve the columns used for support selection.

Tabular input selects the tabular mode. The library is then built from the table's feature columns: the constant term one first, followed by every monomial of the features from degree 1 up to degree, written as products such as mul(x, v). A terms catalog is refused on tabular data, and a non-default degree is refused on grid data, where the catalog is supplied explicitly. For ODE tables, states are the features and the derivative of one state is the target. The library contains only polynomials: a small residual on sinusoidal data can be a polynomial approximation.

The constant term is the reserved term name one, a column of ones. The tabular library always contains it, and a grid catalog can list it like any other term. Numeric literals are rejected in the term catalog in either mode; an additive constant in a law is represented as the coefficient of one. The fitted combination is restricted to the supplied columns, so a missing governing term can still produce a valid but incomplete fit.

Method

KD supplies the derivatives, candidate columns and single regression target; PySINDy supplies pysindy.optimizers.STLSQ. Atomic derivative names determine the precomputed orders on each axis. Compound derivatives and open-form calls are evaluated as expressions. The finite-difference provider uses fourth-order interior stencils for first and second derivatives, with separate boundary and third-derivative stencils. In the tabular mode no derivatives are computed: the columns are one and the monomials evaluated on the feature columns, and the target is the table's target column.

STLSQ alternates a ridge solve with hard thresholding. Coefficients below threshold in magnitude are zeroed and their columns removed, until support stabilizes or max_iter rounds have run. With unbias enabled, an unregularized least-squares solve on the retained support removes ridge shrinkage. normalize_columns changes the scale at which thresholding acts, so choose normalization and threshold together.

With relative_threshold enabled, threshold is a dimensionless fraction: KD passes STLSQ the value of threshold multiplied by the L2 norm of the regression target. The setting requires normalize_columns, so STLSQ thresholds coefficients fitted on unit-norm columns, and a term is kept in a round when its coefficient times its column norm is at least threshold times the target norm. Rescaling a column or the target therefore leaves the selected support unchanged and scales the returned coefficients accordingly. With normalization and an absolute threshold, the thresholded quantity is the same product of coefficient and column norm, which carries the target's units and grows with the number of rows, so one absolute value selects differently with and without normalization and on different datasets. The norm is that of the target the optimizer receives. With a kd.Sketch, pinned terms are deducted from that target first and anchored columns are projected out of it, so the fraction refers to the part of the target that remains for STLSQ to fit.

One sparse-regression solve answers the run; generations does not create additional solves and the seed does not randomize the optimizer. Equivalent catalog spellings can still produce collinear numeric columns: canonical syntax catches duplicate terms but does not equate u_xx and diff2_x(u). Collinear columns can split a coefficient and change threshold selection.

Result interpretation

The returned coefficients are the optimizer's own, with no intervening KD refit. model.best_score_ is NMSE evaluated with those coefficients. model.best_expr_ lists the structural terms; read the coefficient vector on model.result_.final_eval.coefficients or the terms and coefficients on model.result_.equation. The full evaluated catalog retains zero coefficients for dropped terms and records its active support and fitted left-hand side. In the tabular mode the equation has the regression form, with the target column as its left-hand side and the selected library terms on the right. A retained one carries the additive constant as its coefficient, and the rendered equation prints that constant as a number.

Interpret NMSE with the candidate library and threshold. A small value does not establish that the library contains the governing equation. If all coefficients are removed, the fit raises an empty-support error naming the threshold; reduce the threshold to retain a support. Repeating an otherwise unchanged deterministic solve does not explore another structure. A near-zero residual obtained by putting the target derivative itself in the library is a tautology.

Python setup

Construct a kd.TabularDataset for direct Model.fit() calls. kd.data.trajectories_to_tabular makes time-derivative tables from ODE trajectories, with states as features and one state's derivative as target.

References

de Silva et al. (2020). "PySINDy: A Python package for the sparse identification of nonlinear dynamical systems from data". J. Open Source Softw. 5(49), 2104. Paper

Kaptanoglu et al. (2022). "PySINDy: A comprehensive Python package for robust sparse system identification". J. Open Source Softw. 7(69), 3994. Paper

Documentation: pysindy.readthedocs.io/en/latest

Code: dynamicslab/pysindy

Implementation notes. KD uses the native STLSQ optimizer. It does not use PySINDy's SINDy model, PDELibrary, differentiation, weak formulation, ensembling or multi-target fit. A nonzero optimizer intercept is rejected: the constant belongs to the library column one, so the optimizer fits no intercept of its own. The typed settings follow STLSQ's defaults; other settings, such as ridge alpha, pass through extra_optimizer_kwargs. That mapping rejects names already represented by typed fields rather than overriding them. Threshold and iteration bounds are validated before computation. Integration checks compare the plugin with a direct STLSQ solve on identical Theta and target arrays, including their coefficient vectors.

Full report

Full HTML report from the same run, with all figures, captions and raw result data.