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:
optimizer (pysindy.optimizers.base._BaseOptimizer) – Optimization method used to fit the SINDy model. This must be a class extending
pysindy.optimizers.BaseOptimizer. The default ispysindy.optimizers.STLSQ.feature_library (pysindy.feature_library.base.BaseFeatureLibrary) – Feature library object used to specify candidate right-hand side features. This must be a class extending
pysindy.feature_library.base.BaseFeatureLibrary. The default option ispysindy.feature_library.PolynomialLibrary.differentiation_method – Method for differentiating the data. This must be a class extending
pysindy.differentiation.base.BaseDifferentiationclass. The default option is centered difference.
- 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_featuresand 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 a SINDy model.
Print the SINDy model equations.
Returns a score for the time derivative prediction produced by the model.
Configure whether metadata should be requested to be passed to the
fitmethod.Configure whether metadata should be requested to be passed to the
predictmethod.Configure whether metadata should be requested to be passed to the
scoremethod.Simulate the SINDy model forward in time.
Attributes
Complexity of the model measured as the number of nonzero parameters.
feature_libraryoptimizerfeature_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
xwith 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
SINDyinstance
- 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_featuresare 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==Truethen 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
xwith 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
fitmethod.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(seesklearn.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 tofitif provided. The request is ignored if metadata is not provided.False: metadata is not requested and the meta-estimator will not pass it tofit.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_namesparameter infit.sample_weight (str, True, False, or None, default=sklearn.utils.metadata_routing.UNCHANGED) – Metadata routing for
sample_weightparameter infit.t (str, True, False, or None, default=sklearn.utils.metadata_routing.UNCHANGED) – Metadata routing for
tparameter infit.u (str, True, False, or None, default=sklearn.utils.metadata_routing.UNCHANGED) – Metadata routing for
uparameter infit.x (str, True, False, or None, default=sklearn.utils.metadata_routing.UNCHANGED) – Metadata routing for
xparameter infit.x_dot (str, True, False, or None, default=sklearn.utils.metadata_routing.UNCHANGED) – Metadata routing for
x_dotparameter infit.
- 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
predictmethod.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(seesklearn.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 topredictif provided. The request is ignored if metadata is not provided.False: metadata is not requested and the meta-estimator will not pass it topredict.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
uparameter inpredict.x (str, True, False, or None, default=sklearn.utils.metadata_routing.UNCHANGED) – Metadata routing for
xparameter inpredict.
- 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
scoremethod.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(seesklearn.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 toscoreif provided. The request is ignored if metadata is not provided.False: metadata is not requested and the meta-estimator will not pass it toscore.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
metricparameter inscore.sample_weight (str, True, False, or None, default=sklearn.utils.metadata_routing.UNCHANGED) – Metadata routing for
sample_weightparameter inscore.t (str, True, False, or None, default=sklearn.utils.metadata_routing.UNCHANGED) – Metadata routing for
tparameter inscore.u (str, True, False, or None, default=sklearn.utils.metadata_routing.UNCHANGED) – Metadata routing for
uparameter inscore.x (str, True, False, or None, default=sklearn.utils.metadata_routing.UNCHANGED) – Metadata routing for
xparameter inscore.x_dot (str, True, False, or None, default=sklearn.utils.metadata_routing.UNCHANGED) – Metadata routing for
x_dotparameter inscore.
- 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.
ucan 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,ucan also be an array of control inputs at each time step. In this case, the array is fit with the interpolator specified byinterpolator.integrator (string, optional (default
solve_ivp)) – Function to use to integrate the system. Default isscipy.integrate.solve_ivp. The only options currently supported are solve_ivp and odeint.interpolator (callable, optional (default
interp1d)) – Function used to interpolate control inputs ifuis an array. Default isscipy.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)