Skip to content

Commit 9cf9d28

Browse files
committed
DOC: Update documentation for DiscreteSINDy
1 parent 7a093b4 commit 9cf9d28

File tree

1 file changed

+91
-20
lines changed

1 file changed

+91
-20
lines changed

pysindy/pysindy.py

Lines changed: 91 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,6 @@ class _BaseSINDy(BaseEstimator, ABC):
6060
def fit(self, x: TrajectoryType, t: TrajectoryType, *args, **kwargs) -> Self:
6161
...
6262

63-
@abstractmethod
64-
def predict(self, x: np.ndarray) -> np.ndarray:
65-
...
66-
6763
@abstractmethod
6864
def simulate(self, x0: np.ndarray, t: np.ndarray) -> np.ndarray:
6965
...
@@ -534,14 +530,10 @@ def _process_trajectories(self, x, t, x_dot):
534530
Returns
535531
-------
536532
x_out: np.ndarray or list
537-
Validated version of x. If return_array is True, x_out will be an
538-
np.ndarray of concatenated trajectories. If False, x_out will be
539-
a list.
533+
Validated version of x.
540534
541535
x_dot_out: np.ndarray or list
542-
Validated derivative measurements.If return_array is True, x_dot_out
543-
will be an np.ndarray of concatenated trajectories.
544-
If False, x_out will be a list.
536+
Validated derivative measurements
545537
"""
546538
x, x_dot = zip(
547539
*[
@@ -715,11 +707,83 @@ def complexity(self):
715707

716708
class DiscreteSINDy(_BaseSINDy):
717709
"""
718-
discrete_time : boolean, optional (default False)
719-
If True, dynamical system is treated as a map. Rather than predicting
720-
derivatives, the right hand side functions step the system forward by
721-
one time step. If False, dynamical system is assumed to be a flow
722-
(right-hand side functions predict continuous time derivatives).
710+
Sparse Identification of Nonlinear Dynamical Systems (SINDy) for discrete time systems.
711+
712+
Parameters
713+
----------
714+
optimizer : optimizer object, optional
715+
Optimization method used to fit the SINDy model. This must be a class
716+
extending :class:`pysindy.optimizers.BaseOptimizer`.
717+
The default is :class:`STLSQ`.
718+
719+
feature_library : feature library object, optional
720+
Feature library object used to specify candidate right-hand side features.
721+
This must be a class extending
722+
:class:`pysindy.feature_library.base.BaseFeatureLibrary`.
723+
The default option is :class:`PolynomialLibrary`.
724+
725+
Attributes
726+
----------
727+
model : ``sklearn.multioutput.MultiOutputRegressor`` object
728+
The fitted SINDy model.
729+
730+
n_input_features_ : int
731+
The total number of input features.
732+
733+
n_output_features_ : int
734+
The total number of output features. This number is a function of
735+
``self.n_input_features`` and the feature library being used.
736+
737+
n_control_features_ : int
738+
The total number of control input features.
739+
740+
Examples
741+
--------
742+
>>> import numpy as np
743+
>>> import pysindy as ps
744+
>>> def f(x):
745+
>>> return 3.6 * x * (1 - x)
746+
>>> n_steps = 20
747+
>>> eps = 0.001
748+
>>> x_map = np.zeros((n_steps))
749+
>>> x_map[0] = 0.5
750+
>>> for i in range(1, n_steps):
751+
>>> x_map[i] = f(x_map[i - 1]) + eps * np.random.randn()
752+
>>> x_train_map = x_map[:16]
753+
>>> x_test_map = x_map[16:]
754+
>>> model = ps.DiscreteSINDy()
755+
>>> model.fit(x_train_map, t=1)
756+
>>> model.print()
757+
(x0)[k+1] = 0.006 1 + 3.581 x0[k] + -3.586 x0[k]^2
758+
>>> model.coefficients()
759+
>>> model.predict(x_test_map)
760+
AxesArray([[0.8268863 ],
761+
[0.51884209],
762+
[0.89919392],
763+
[0.33532148]])
764+
>>> model.score(x_test_map, t=1)
765+
0.9998547755296847
766+
>>> model.simulate(x0=0.5, t=20)
767+
array([[0.5 ],
768+
[0.90037072],
769+
[0.32376537],
770+
[0.78980964],
771+
[0.59788467],
772+
[0.86556721],
773+
[0.41950949],
774+
[0.877508 ],
775+
[0.38763939],
776+
[0.85561537],
777+
[0.44528986],
778+
[0.88988815],
779+
[0.35351698],
780+
[0.8241012 ],
781+
[0.52224203],
782+
[0.89849516],
783+
[0.32914646],
784+
[0.79648209],
785+
[0.58382694],
786+
[0.87479097]])
723787
"""
724788

725789
def __init__(
@@ -738,8 +802,8 @@ def fit(
738802
self,
739803
x,
740804
t,
741-
u=None,
742805
x_next=None,
806+
u=None,
743807
feature_names: Optional[list[str]] = None,
744808
):
745809
"""
@@ -748,9 +812,9 @@ def fit(
748812
Parameters
749813
----------
750814
x: array-like or list of array-like, shape (n_samples, n_input_features)
751-
Training data. If training data contains multiple trajectories,
752-
x should be a list containing data for each trajectory. Individual
753-
trajectories may contain different numbers of samples.
815+
Training data of the current state of the system. If training data
816+
contains multiple trajectories, x should be a list containing data for
817+
each trajectory. Individual trajectories may contain different numbers of samples.
754818
755819
t: float, numpy array of shape (n_samples,), or list of numpy arrays
756820
If t is a float, it specifies the timestep between each sample.
@@ -761,6 +825,13 @@ def fit(
761825
of arrays containing the collection times for each individual
762826
trajectory.
763827
828+
x_next: array-like or list of array-like, shape (n_samples, n_input_features), \
829+
optional (default None)
830+
Optional data of the system forwarded by one time step. If not provided, the
831+
next will be computed by taking the training data by one time step.
832+
If x_next is provided, it must match the shape of the training data and these
833+
values will be used as the next state.
834+
764835
u: array-like or list of array-like, shape (n_samples, n_control_features), \
765836
optional (default None)
766837
Control variables/inputs. Include this variable to use sparse
@@ -948,7 +1019,7 @@ def simulate(
9481019
stop_condition=None,
9491020
):
9501021
"""
951-
Simulate the SINDy model forward in time.
1022+
Simulate the DiscreteSINDy model forward in time.
9521023
9531024
Parameters
9541025
----------

0 commit comments

Comments
 (0)