pysindy.SINDy

class pysindy.SINDy(optimizer: BaseOptimizer | None = None, feature_library: BaseFeatureLibrary | None = None, differentiation_method: BaseDifferentiation | None = None)[source]

Sparse Identification of Nonlinear Dynamical Systems (SINDy). Uses sparse regression to learn a dynamical systems model from measurement data.

Parameters:
Attributes:
  • model (sklearn.multioutput.MultiOutputRegressor) – The fitted SINDy model.

  • n_input_features_ (int) – The total number of input features.

  • n_output_features_ (int) – The total number of output features. This number is a function of self.n_input_features and the feature library being used.

  • n_control_features_ (int) – The total number of control input features.

Examples

>>> import numpy as np
>>> from scipy.integrate import solve_ivp
>>> from pysindy import SINDy
>>> lorenz = lambda z,t : [10*(z[1] - z[0]),
>>>                        z[0]*(28 - z[2]) - z[1],
>>>                        z[0]*z[1] - 8/3*z[2]]
>>> t = np.arange(0,2,.002)
>>> x = solve_ivp(lorenz, [-8,8,27], t)
>>> model = SINDy()
>>> model.fit(x, t=t[1]-t[0])
>>> model.print()
x0' = -10.000 1 + 10.000 x0
x1' = 27.993 1 + -0.999 x0 + -1.000 1 x1
x2' = -2.666 x1 + 1.000 1 x0
>>> model.coefficients()
array([[ 0.        ,  0.        ,  0.        ],
       [-9.99969193, 27.99344519,  0.        ],
       [ 9.99961547, -0.99905338,  0.        ],
       [ 0.        ,  0.        , -2.66645651],
       [ 0.        ,  0.        ,  0.        ],
       [ 0.        ,  0.        ,  0.99990257],
       [ 0.        , -0.99980268,  0.        ],
       [ 0.        ,  0.        ,  0.        ],
       [ 0.        ,  0.        ,  0.        ],
       [ 0.        ,  0.        ,  0.        ]])
>>> model.score(x, t=t[1]-t[0])
0.999999985520653
>>> import numpy as np
>>> from scipy.integrate import solve_ivp
>>> from pysindy import SINDy
>>> u = lambda t : np.sin(2 * t)
>>> lorenz_c = lambda z,t : [
            10 * (z[1] - z[0]) + u(t) ** 2,
            z[0] * (28 - z[2]) - z[1],
            z[0] * z[1] - 8 / 3 * z[2],
    ]
>>> t = np.arange(0,2,0.002)
>>> x = solve_ivp(lorenz_c, [-8,8,27], t)
>>> u_eval = u(t)
>>> model = SINDy()
>>> model.fit(x, u_eval, t=t[1]-t[0])
>>> model.print()
x0' = -10.000 x0 + 10.000 x1 + 1.001 u0^2
x1' = 27.994 x0 + -0.999 x1 + -1.000 x0 x2
x2' = -2.666 x2 + 1.000 x0 x1
>>> model.coefficients()
array([[ 0.        , -9.99969851,  9.99958359,  0.        ,  0.        ,
         0.        ,  0.        ,  0.        ,  0.        ,  0.        ,
         0.        ,  0.        ,  0.        ,  0.        ,  1.00120331],
       [ 0.        , 27.9935177 , -0.99906375,  0.        ,  0.        ,
         0.        ,  0.        , -0.99980455,  0.        ,  0.        ,
         0.        ,  0.        ,  0.        ,  0.        ,  0.        ],
       [ 0.        ,  0.        ,  0.        , -2.666437  ,  0.        ,
         0.        ,  0.99990137,  0.        ,  0.        ,  0.        ,
         0.        ,  0.        ,  0.        ,  0.        ,  0.        ]])
>>> model.score(x, u_eval, t=t[1]-t[0])
0.9999999855414495

Methods

fit

Fit a SINDy model.

print

Print the SINDy model equations.

score

Returns a score for the time derivative prediction produced by the model.

set_fit_request

Configure whether metadata should be requested to be passed to the fit method.

set_predict_request

Configure whether metadata should be requested to be passed to the predict method.

set_score_request

Configure whether metadata should be requested to be passed to the score method.

simulate

Simulate the SINDy model forward in time.

Attributes

complexity

Complexity of the model measured as the number of nonzero parameters.

feature_library

optimizer

feature_names

property complexity

Complexity of the model measured as the number of nonzero parameters.

fit(x, t, x_dot=None, u=None, feature_names: list[str] | None = None, sample_weight: TrajectoryType | None = None)[source]

Fit a SINDy model.

Parameters:
  • x (array-like or list of array-like, shape (n_samples, n_input_features)) – Training data. If training data contains multiple trajectories, x should be a list containing data for each trajectory. Individual trajectories may contain different numbers of samples.

  • t (float, numpy array of shape (n_samples,), or list of numpy arrays) – If t is a float, it specifies the timestep between each sample. If array-like, it specifies the time at which each sample was collected. In this case the values in t must be strictly increasing. In the case of multi-trajectory training data, t may also be a list of arrays containing the collection times for each individual trajectory.

  • x_dot (array-like or list of array-like, shape (n_samples, n_input_features), optional (default None)) – Optional pre-computed derivatives of the training data. If not provided, the time derivatives of the training data will be computed using the specified differentiation method. If x_dot is provided, it must match the shape of the training data and these values will be used as the time derivatives.

  • u (array-like or list of array-like, shape (n_samples, n_control_features), optional (default None)) – Control variables/inputs. Include this variable to use sparse identification for nonlinear dynamical systems for control (SINDYc). If training data contains multiple trajectories (i.e. if x is a list of array-like), then u should be a list containing control variable data for each trajectory. Individual trajectories may contain different numbers of samples.

  • feature_names (list of string, length n_input_features, optional) – Names for the input features (e.g. ['x', 'y', 'z']). If None, will use ['x0', 'x1', ...].

  • sample_weight (list of array-like) – Each entry must match the spatial/time shape of the corresponding trajectory (i.e., have the same axes as x with the coordinate axis collapsed to length 1). Automatic broadcasting is not applied. Weights to give to the samples to give more importance to less noisy or more informative samples.

Returns:

self

Return type:

a fitted SINDy instance

print(lhs=None, precision=3, **kwargs)[source]

Print the SINDy model equations.

Parameters:
  • lhs (list of strings, optional (default None)) – List of variables to print on the left-hand sides of the learned equations. By default self.input_features are used.

  • precision (int, optional (default 3)) – Precision to be used when printing out model coefficients.

  • **kwargs (Additional keyword arguments passed to the builtin print function)

score(x, t, x_dot=None, u=None, metric=<function r2_score>, sample_weight: ~pysindy._core.TrajectoryType | None = None, **metric_kws)[source]

Returns a score for the time derivative prediction produced by the model.

Parameters:
  • x (array-like or list of array-like, shape (n_samples, n_input_features)) – Samples from which to make predictions.

  • t (float, numpy array of shape (n_samples,), or list of numpy arrays) – Time step between samples or array of collection times. Optional, used to compute the time derivatives of the samples if x_dot is not provided.

  • x_dot (array-like or list of array-like, shape (n_samples, n_input_features), optional (default None)) – Optional pre-computed derivatives of the samples. If provided, these values will be used to compute the score. If not provided, the time derivatives of the training data will be computed using the specified differentiation method.

  • u (array-like or list of array-like, shape(n_samples, n_control_features), optional (default None)) – Control variables. If multiple_trajectories==True then u must be a list of control variable data from each trajectory. If the model was fit with control variables then u is not optional.

  • metric (callable, optional) – Metric function with which to score the prediction. Default is the R^2 coefficient of determination. See Scikit-learn for more options.

  • sample_weight (list of array-like) – Each entry must match the spatial/time shape of the corresponding trajectory (same axes as x with the coordinate axis collapsed to length 1). Automatic broadcasting is not applied. Weights to give to the samples to give more importance to less noisy or more informative samples.

  • metric_kws (dict, optional) – Optional keyword arguments to pass to the metric function.

Returns:

score – Metric function value for the model prediction of x_dot.

Return type:

float

set_fit_request(*, feature_names: bool | None | str = '$UNCHANGED$', sample_weight: bool | None | str = '$UNCHANGED$', t: bool | None | str = '$UNCHANGED$', u: bool | None | str = '$UNCHANGED$', x: bool | None | str = '$UNCHANGED$', x_dot: bool | None | str = '$UNCHANGED$') SINDy

Configure whether metadata should be requested to be passed to the fit method.

Note that this method is only relevant when this estimator is used as a sub-estimator within a meta-estimator and metadata routing is enabled with enable_metadata_routing=True (see sklearn.set_config). Please check the User Guide on how the routing mechanism works.

The options for each parameter are:

  • True: metadata is requested, and passed to fit if provided. The request is ignored if metadata is not provided.

  • False: metadata is not requested and the meta-estimator will not pass it to fit.

  • None: metadata is not requested, and the meta-estimator will raise an error if the user provides it.

  • str: metadata should be passed to the meta-estimator with this given alias instead of the original name.

The default (sklearn.utils.metadata_routing.UNCHANGED) retains the existing request. This allows you to change the request for some parameters and not others.

Added in version 1.3.

Parameters:
  • feature_names (str, True, False, or None, default=sklearn.utils.metadata_routing.UNCHANGED) – Metadata routing for feature_names parameter in fit.

  • sample_weight (str, True, False, or None, default=sklearn.utils.metadata_routing.UNCHANGED) – Metadata routing for sample_weight parameter in fit.

  • t (str, True, False, or None, default=sklearn.utils.metadata_routing.UNCHANGED) – Metadata routing for t parameter in fit.

  • u (str, True, False, or None, default=sklearn.utils.metadata_routing.UNCHANGED) – Metadata routing for u parameter in fit.

  • x (str, True, False, or None, default=sklearn.utils.metadata_routing.UNCHANGED) – Metadata routing for x parameter in fit.

  • x_dot (str, True, False, or None, default=sklearn.utils.metadata_routing.UNCHANGED) – Metadata routing for x_dot parameter in fit.

Returns:

self – The updated object.

Return type:

object

set_predict_request(*, u: bool | None | str = '$UNCHANGED$', x: bool | None | str = '$UNCHANGED$') SINDy

Configure whether metadata should be requested to be passed to the predict method.

Note that this method is only relevant when this estimator is used as a sub-estimator within a meta-estimator and metadata routing is enabled with enable_metadata_routing=True (see sklearn.set_config). Please check the User Guide on how the routing mechanism works.

The options for each parameter are:

  • True: metadata is requested, and passed to predict if provided. The request is ignored if metadata is not provided.

  • False: metadata is not requested and the meta-estimator will not pass it to predict.

  • None: metadata is not requested, and the meta-estimator will raise an error if the user provides it.

  • str: metadata should be passed to the meta-estimator with this given alias instead of the original name.

The default (sklearn.utils.metadata_routing.UNCHANGED) retains the existing request. This allows you to change the request for some parameters and not others.

Added in version 1.3.

Parameters:
  • u (str, True, False, or None, default=sklearn.utils.metadata_routing.UNCHANGED) – Metadata routing for u parameter in predict.

  • x (str, True, False, or None, default=sklearn.utils.metadata_routing.UNCHANGED) – Metadata routing for x parameter in predict.

Returns:

self – The updated object.

Return type:

object

set_score_request(*, metric: bool | None | str = '$UNCHANGED$', sample_weight: bool | None | str = '$UNCHANGED$', t: bool | None | str = '$UNCHANGED$', u: bool | None | str = '$UNCHANGED$', x: bool | None | str = '$UNCHANGED$', x_dot: bool | None | str = '$UNCHANGED$') SINDy

Configure whether metadata should be requested to be passed to the score method.

Note that this method is only relevant when this estimator is used as a sub-estimator within a meta-estimator and metadata routing is enabled with enable_metadata_routing=True (see sklearn.set_config). Please check the User Guide on how the routing mechanism works.

The options for each parameter are:

  • True: metadata is requested, and passed to score if provided. The request is ignored if metadata is not provided.

  • False: metadata is not requested and the meta-estimator will not pass it to score.

  • None: metadata is not requested, and the meta-estimator will raise an error if the user provides it.

  • str: metadata should be passed to the meta-estimator with this given alias instead of the original name.

The default (sklearn.utils.metadata_routing.UNCHANGED) retains the existing request. This allows you to change the request for some parameters and not others.

Added in version 1.3.

Parameters:
  • metric (str, True, False, or None, default=sklearn.utils.metadata_routing.UNCHANGED) – Metadata routing for metric parameter in score.

  • sample_weight (str, True, False, or None, default=sklearn.utils.metadata_routing.UNCHANGED) – Metadata routing for sample_weight parameter in score.

  • t (str, True, False, or None, default=sklearn.utils.metadata_routing.UNCHANGED) – Metadata routing for t parameter in score.

  • u (str, True, False, or None, default=sklearn.utils.metadata_routing.UNCHANGED) – Metadata routing for u parameter in score.

  • x (str, True, False, or None, default=sklearn.utils.metadata_routing.UNCHANGED) – Metadata routing for x parameter in score.

  • x_dot (str, True, False, or None, default=sklearn.utils.metadata_routing.UNCHANGED) – Metadata routing for x_dot parameter in score.

Returns:

self – The updated object.

Return type:

object

simulate(x0, t, u=None, integrator='solve_ivp', interpolator=None, integrator_kws={'atol': 1e-12, 'method': 'LSODA', 'rtol': 1e-12}, interpolator_kws={})[source]

Simulate the SINDy model forward in time.

Parameters:
  • x0 (numpy array, size [n_features]) – Initial condition from which to simulate.

  • t (numpy array of size [n_samples]) – Array of time points at which to simulate.

  • u (function from R^1 to R^{n_control_features} or list/array, optional (default None)) – Control inputs. u can be a function that would take time as input and output the values of each of the n_control_features control features as a list or numpy array. Alternatively, u can also be an array of control inputs at each time step. In this case, the array is fit with the interpolator specified by interpolator.

  • integrator (string, optional (default solve_ivp)) – Function to use to integrate the system. Default is scipy.integrate.solve_ivp. The only options currently supported are solve_ivp and odeint.

  • interpolator (callable, optional (default interp1d)) – Function used to interpolate control inputs if u is an array. Default is scipy.interpolate.interp1d.

  • integrator_kws (dict, optional (default {})) – Optional keyword arguments to pass to the integrator

  • interpolator_kws (dict, optional (default {})) – Optional keyword arguments to pass to the control input interpolator

Returns:

x – Simulation results

Return type:

numpy array, shape (n_samples, n_features)