Skip to content

Commit 9ab7802

Browse files
DOC: Add tutorial 1 and docs/summary.rst from old example 2
1 parent 73ebd41 commit 9ab7802

File tree

11 files changed

+1648
-1628
lines changed

11 files changed

+1648
-1628
lines changed

docs/index.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,13 @@
66
:hidden:
77
:caption: User Guide
88

9-
API Documentation <api/pysindy>
9+
What is SINDy? <summary>
1010
Examples <examples/index>
1111
Practical tips <tips>
1212
Contributing <contributing>
1313
Using pysindy in academia <academic>
1414
Object Model <objects>
15+
API Documentation <api/pysindy>
1516

1617
.. toctree::
1718
:maxdepth: 1

docs/summary.rst

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
An introduction to Sparse Identification of Nonlinear Dynamical systems (SINDy)
2+
===============================================================================
3+
We give a gentle introduction to the SINDy method and how different steps
4+
in the algorithm are represented in PySINDy.
5+
6+
Main ideas
7+
-------------
8+
Suppose we have a set of measurements :math:`x(t)\in \mathbb{R}^n` from some physical system
9+
at different points in time :math:`t`.
10+
SINDy seeks to represent the time evolution of :math:`x(t)`` in terms of a nonlinear function
11+
:math:`f`:
12+
13+
.. math::
14+
15+
\frac{d}{dt}x(t) = f(x(t)).
16+
17+
This equation constitutes a *dynamical system* for the measurements :math:`x(t)`.
18+
The vector :math:`x(t)=[x_1(t), x_2(t), \dots x_n(t)]^\top` gives the state
19+
of the physical system at time :math:`t`.
20+
The function :math:`f(x(t))` constrains how the system evolves in time.
21+
22+
The key idea behind SINDy is that the function :math:`f` is often **sparse**
23+
in the space of an appropriate set of basis functions.
24+
For example, the function
25+
26+
.. math::
27+
28+
\frac{d}{dt}x = f(x)
29+
= \begin{bmatrix} f_1(x)\\f_2(x) \end{bmatrix}
30+
= \begin{bmatrix}1 - x_1 + 3x_1x_2 \\ x_2^2 - 5x_1^3 \end{bmatrix}
31+
32+
is sparse with respect to the set of polynomials of two variables
33+
in the sense that if we were to write an expansion of the component functions
34+
of :math:`f` in this basis
35+
(e.g. :math:`f_{1}(x) = \sum_{i=0}^\infty\sum_{j=0}^\infty a_{i,j}x_1^ix_2^j`),
36+
only a small number of coefficients (:math:`a_{i,j}`) would be nonzero.
37+
38+
SINDy employs **sparse regression** to find a linear combination of basis functions
39+
that best capture the dynamic behavior of the physical system.
40+
41+
Approximation problem
42+
----------------------------
43+
To apply SINDy in practice one needs a set of measurement data collected at times
44+
:math:`t_1, t_2, \dots, t_n`,
45+
and the time derivatives of these measurements
46+
(either measured directly or numerically approximated).
47+
These data are aggregated into the matrices :math:`X` and :math:`\dot X`, respectively:
48+
49+
.. math::
50+
51+
X = \begin{bmatrix}
52+
x_1(t_1) & x_2(t_1) & \dots & x_n(t_1) \\
53+
x_1(t_2) & x_2(t_2) & \dots & x_n(t_2) \\
54+
\vdots & \vdots & & \vdots \\ x_1(t_m) & x_2(t_m) & \dots & x_n(t_m)
55+
\end{bmatrix},
56+
\qquad
57+
\dot{X} = \begin{bmatrix} \dot{x_1}(t_1) & \dot{x_2}(t_1) & \dots & \dot{x_n}(t_1) \\
58+
\dot{x_1}(t_2) & \dot{x_2}(t_2) & \dots & \dot{x_n}(t_2) \\
59+
\vdots & \vdots & & \vdots \\
60+
\dot{x_1}(t_m) & \dot{x_2}(t_m) & \dots & \dot{x_n}(t_m)
61+
\end{bmatrix}.
62+
63+
Next, one forms a library matrix :math:`\Theta(X)`
64+
whose columns consist of a chosen set of basis functions applied to the data
65+
66+
.. math::
67+
68+
\Theta(X) = \begin{bmatrix}
69+
\mid & \mid & & \mid \\
70+
\theta_1(X) & \theta_2(X) & \dots & \theta_\ell(X) \\
71+
\mid & \mid & & \mid
72+
\end{bmatrix}.
73+
74+
For example, if :math:`\theta_1(x), \theta_2(x), \dots, \theta_\ell(x)`
75+
are monomials (:math:`\theta_i(x) = x^{i-1}`), then
76+
77+
.. math::
78+
79+
\theta_3(X) = \begin{bmatrix}
80+
\mid & \mid & & \mid & \mid & & \mid \\
81+
x_1(t)^2 & x_1(t)x_2(t) & \dots & x_2(t)^2 & x_2(t)x_3(t) & \dots & x_n^2(t) \\
82+
\mid & \mid & & \mid & \mid & & \mid
83+
\end{bmatrix},
84+
85+
where vector products and powers are understood to be element-wise.
86+
87+
We seek a set of sparse coefficient vectors (collected into a matrix)
88+
89+
.. math::
90+
91+
\Xi = \begin{bmatrix}
92+
\mid & \mid & & \mid \\
93+
\xi_1 & \xi_2 & \dots & \xi_n \\
94+
\mid & \mid & & \mid
95+
\end{bmatrix}.
96+
97+
The vector :math:`\xi_i` provides the coefficients for a linear combination
98+
of basis functions :math:`\theta_1(x), \theta_2(x), \dots, \theta_\ell(x)`
99+
representing the :math:`i`\ th component function of :math:`f`: :math:`f_i(x)`.
100+
That is to say, :math:`f_i(x) = \Theta\left(x^\top\right) \xi_i`,
101+
where :math:`\Theta\left(x^\top\right)` is understood to be a row vector
102+
consisting of symbolic functions
103+
(whereas :math:`\Theta(X)` is a matrix whose entries are numerical values).
104+
105+
With each of the objects :math:`X`, :math:`\dot X`, :math:`\Theta(X)`, and :math:`\Xi`
106+
being defined, we are ready to write down the approximation problem underlying SINDy:
107+
108+
109+
.. math::
110+
111+
\dot X \approx \Theta(X)\Xi.
112+
113+
Structure of PySINDy
114+
----------------------------
115+
The submodules of PySINDy are each aligned with one of the terms in
116+
the aforementioned approximation equation, :math:`\dot X \approx \Theta(X)\Xi.`
117+
118+
* ``pysindy.differentiate`` performs numerical differentiation to compute :math:`\dot X` from :math:`X`;
119+
* ``pysindy.feature_library`` allows the user to specify a set of library functions and handles the formation of :math:`\Theta(X)`;
120+
* ``pysindy.optimizers`` provides a set of sparse regression solvers for determining :math:`\Xi`.
121+
122+
The ``SINDy`` object encapsulates one class object from each of these three submodules and uses them,
123+
along with a user-supplied data matrix, to find a governing dynamical system.
124+
125+
The `beginning tutorial`_ walks through an example showing how this works using a toy dataset.
126+
127+
.. _beginning tutorial: ./examples/tutorial_1/example

0 commit comments

Comments
 (0)