PySINDy
=========
|BuildCI| |RTD| |PyPI| |Codecov| |JOSS1| |JOSS2| |DOI|
**PySINDy** is a sparse regression package with several implementations for the Sparse Identification of Nonlinear Dynamical systems (SINDy) method introduced in Brunton et al. (2016a), including the unified optimization approach of Champion et al. (2019), SINDy with control from Brunton et al. (2016b), Trapping SINDy from Kaptanoglu et al. (2021), SINDy-PI from Kaheman et al. (2020), PDE-FIND from Rudy et al. (2017), and so on. A comprehensive literature review is given in de Silva et al. (2020) and Kaptanoglu, de Silva et al. (2021).
.. contents:: Table of contents
System identification
---------------------
System identification refers to the process of leveraging measurement data to infer governing equations, in the form of dynamical systems, describing the data. Once discovered, these equations can make predictions about future states, can inform control inputs, or can enable the theoretical study using analytical techniques.
Dynamical systems are a flexible, well-studied class of mathematical objects for modeling systems evolving in time.
SINDy is a model discovery method which uses *sparse regression* to infer nonlinear dynamical systems from measurement data.
The resulting models are inherently *interpretable* and *generalizable*.
How it works
^^^^^^^^^^^^
Suppose, for some physical system of interest, we have measurements of state variables ``x(t)`` (a vector of length n) at different points in time. Examples of state variables include the position, velocity, or acceleration of objects; lift, drag, or angle of attack of aerodynamic objects; and concentrations of different chemical species. If we suspect that the system could be well-modeled by a dynamical system of the form
.. code-block:: text
x'(t) = f(x(t)),
then we can use SINDy to learn ``f(x)`` from the data (``x'(t)`` denotes the time derivative of ``x(t)``). Note that both ``f(x)`` and ``x(t)`` are typically vectors. The fundamental assumption SINDy employs is that each component of ``f(x)``, ``f_i(x)`` can be represented as a *sparse* linear combination of basis functions ``theta_j(x)``
.. code-block:: text
f_i(x) = theta_1(x) * xi_{1,i} + theta_2(x) * xi_{2,i} + ... + theta_k * xi{k,i}
Concatenating all the objects into matrices (denoted with capitalized names) helps to simplify things.
To this end we place all measurements of the state variables into a data matrix ``X`` (with a row per time measurement and a column per variable), the derivatives of the state variables into a matrix ``X'``, all basis functions evaluated at all points in time into a matrix ``Theta(X)`` (each basis function gets a column), and all coefficients into a third matrix ``Xi`` (one column per state variable).
The approximation problem to be solved can then be compactly written as
.. code-block:: text
X' = Theta(X) * Xi.
Each row of this matrix equation corresponds to one coordinate function of ``f(x)``.
SINDy employs sparse regression techniques to find a solution ``Xi`` with sparse column vectors.
For a more in-depth look at the mathematical foundations of SINDy, please see our `introduction to SINDy <https://pysindy.readthedocs.io/en/latest/examples/2_introduction_to_sindy.html>`__.
Relation to PySINDy
^^^^^^^^^^^^^^^^^^^
The PySINDy package revolves around the ``SINDy`` class which consists of three primary components; one for each term in the above matrix approximation problem.
* ``differentiation_method``: computes ``X'``, though if derivatives are known or measured directly, they can be used instead
* ``feature_library``: specifies the candidate basis functions to be used to construct ``Theta(X)``
* ``optimizer``: implements a sparse regression method for solving for ``Xi``
Once a ``SINDy`` object has been created it must be fit to measurement data, similar to a ``scikit-learn`` model. It can then be used to predict derivatives given new measurements, evolve novel initial conditions forward in time, and more. PySINDy has been written to be as compatible with ``scikit-learn`` objects and methods as possible.
Example
^^^^^^^
Suppose we have measurements of the position of a particle obeying the following dynamical system at different points in time
.. code-block:: text
x' = -2x
y' = y
Note that this system of differential equations decouples into two differential equations whose solutions are simply ``x(t) = x_0 * exp(-2 * t)`` and ``y(t) = y_0 * exp(t)``, where ``x_0 = x(0)`` and ``y_0 = y(0)`` are the initial conditions.
Using the initial conditions ``x_0 = 3`` and ``y_0 = 0.5``, we construct the data matrix ``X``.
.. code-block:: python
import numpy as np
import pysindy as ps
t = np.linspace(0, 1, 100)
x = 3 * np.exp(-2 * t)
y = 0.5 * np.exp(t)
X = np.stack((x, y), axis=-1) # First column is x, second is y
To instantiate a ``SINDy`` object with the default differentiation method, feature library, and optimizer and then fit it to the data, we invoke
.. code-block:: python
model = ps.SINDy(feature_names=["x", "y"])
model.fit(X, t=t)
We use the ``feature_names`` argument so that the model prints out the correct labels for ``x`` and ``y``. We can inspect the governing equations discovered by the model and check whether they seem reasonable with the ``print`` function.
.. code-block:: python
model.print()
which prints the following
.. code-block:: text
x' = -2.000 x
y' = 1.000 y
PySINDy provides numerous other features not shown here. We recommend the `feature overview <https://pysindy.readthedocs.io/en/latest/examples/1_feature_overview.html>`__ section of the documentation for a more exhaustive summary of additional features.
Installation
------------
Installing with pip
^^^^^^^^^^^^^^^^^^^
If you are using Linux or macOS you can install PySINDy with pip:
.. code-block:: bash
pip install pysindy
Installing from source
^^^^^^^^^^^^^^^^^^^^^^
First clone this repository:
.. code-block:: bash
git clone https://github.com/dynamicslab/pysindy.git
Then, to install the package, run
.. code-block:: bash
pip install .
If you do not have pip you can instead use
.. code-block:: bash
python setup.py install
If you do not have root access, you should add the ``--user`` option to the above lines.
Caveats
^^^^^^^
If you would like to use the ``SINDy-PI`` optimizer, the ``Trapping SINDy`` optimizer (TrappingSR3), or the other SR3 optimizations with inequality constraints, you will also need to install the cvxpy package, e.g. with ``pip install cvxpy``.
To run the unit tests, example notebooks, or build a local copy of the documentation, you should install the additional dependencies in ``requirements-dev.txt``
.. code-block:: bash
pip install -r requirements-dev.txt
Documentation
-------------
The documentation site for PySINDy can be found `here <https://pysindy.readthedocs.io/en/latest/>`__. There are numerous `examples <https://pysindy.readthedocs.io/en/latest/examples/index.html>`_ of PySINDy in action to help you get started. Examples are also available as `Jupyter notebooks <https://github.com/dynamicslab/pysindy/tree/master/examples>`__. A video overview of PySINDy can be found on `Youtube <https://www.youtube.com/watch?v=DvbbXX8Bd90>`__. We have also created a `video playlist <https://www.youtube.com/playlist?list=PLN90bHJU-JLoOfEk0KyBs2qLTV7OkMZ25>`__ with practical PySINDy tips.
PySINDy implements a lot of advanced functionality that may be overwhelming for new users or folks who are unfamiliar with these methods. Below (see here if image does not render https://github.com/dynamicslab/pysindy/blob/master/docs/JOSS2/Fig3.png), we provide a helpful flowchart for figuring out which methods to use, given the characteristics of your dataset:
.. image:: https://github.com/dynamicslab/pysindy/blob/master/docs/JOSS2/Fig3.png
This flow chart summarizes how ``PySINDy`` users can start with a dataset and systematically choose the proper candidate library and sparse regression optimizer that are tailored for a specific scientific task. The ``GeneralizedLibrary`` class allows for tensoring, concatenating, and otherwise combining many different candidate libraries.
Community guidelines
--------------------
Contributing examples
^^^^^^^^^^^^^^^^^^^^^
We love seeing examples of PySINDy being used to solve interesting problems! If you would like to contribute an example, reach out to us by creating an issue.
At a minimum, we need to be able to run the example notebooks in the normal mode as well as in a test mode that uses smaller data in order to run faster and simply verify that cells execute without error. In order to do that, your example should obey the following directory tree
.. code-block::
./<name_of_example>/
\
|-example.py # save your notebook as a python script
|-example_data.py # has functions to create/load data
|-mock_data.py # has functions with same name as in example_data.py which create/load smaller datasets
|-example.ipynb # run python examples/publish_notebook/<name_of_example> to generate this. Needs packages in requirements-dev.txt
|-utils.py (Any other names example.py needs to import. Any additional local modules imported by example.py need to be submodules of utils.py, e.g. utils.plotting)
You can optimize your notebook for testing by checking ``__name__``. When our tests run ``example.py`` they set the ``__name__`` global to ``"testing"``. For instance, your notebook should determine whether to import from ``mock_data`` or ``example_data`` using this method (another example: you could also use this method to set ``max_iter``). It's a bit arbitrary, but try to make your examples run in under ten seconds using the mock data. You can use our test to verify your example in testing mode:
.. code-block::
pytest -k test_external --external-notebook="path/to/<name_of_example>"
Contributing code
^^^^^^^^^^^^^^^^^
We welcome contributions to PySINDy. To contribute a new feature please submit a pull request. To get started we recommend installing the packages in ``requirements-dev.txt`` via
.. code-block:: bash
pip install -r requirements-dev.txt
This will allow you to run unit tests and automatically format your code. To be accepted your code should conform to PEP8 and pass all unit tests. Code can be tested by invoking
.. code-block:: bash
pytest
We recommend using ``pre-commit`` to format your code. Once you have staged changes to commit
.. code-block:: bash
git add path/to/changed/file.py
you can run the following to automatically reformat your staged code
.. code-block:: bash
pre-commit
Note that you will then need to re-stage any changes ``pre-commit`` made to your code.
Building documentation requires [pandoc](https://pandoc.org/installing.html) as a separate install. Once installed, run
.. code-block:: bash
python -m sphinx -TEb html -d _build/doctrees -D language=en . ./build
Or check the build step in the most recent CI run or [RTD build](https://readthedocs.org/projects/pysindy/builds/).
There are a number of SINDy variants and advanced functionality that would be great to implement in future releases:
1. Bayesian SINDy, for instance that from Hirsh, Seth M., David A. Barajas-Solano, and J. Nathan Kutz. "Sparsifying Priors for Bayesian Uncertainty Quantification in Model Discovery." arXiv preprint arXiv:2107.02107 (2021).
2. Tensor SINDy, using the methods in Gelß, Patrick, et al. "Multidimensional approximation of nonlinear dynamical systems." Journal of Computational and Nonlinear Dynamics 14.6 (2019).
3. Stochastic SINDy, using the methods in Brückner, David B., Pierre Ronceray, and Chase P. Broedersz. "Inferring the dynamics of underdamped stochastic systems." Physical review letters 125.5 (2020): 058103.
4. Integration of PySINDy with a Python model-predictive control (MPC) code.
5. The PySINDy weak formulation is based on the work in Reinbold, Patrick AK, Daniel R. Gurevich, and Roman O. Grigoriev. "Using noisy or incomplete data to discover models of spatiotemporal dynamics." Physical Review E 101.1 (2020): 010203. It might be useful to additionally implement the weak formulation from Messenger, Daniel A., and David M. Bortz. "Weak SINDy for partial differential equations." Journal of Computational Physics (2021): 110525. The weak formulation in PySINDy is also fairly slow and computationally intensive, so finding ways to speed up the code would be great.
6. The blended conditional gradients (BCG) algorithm for solving the constrained LASSO problem, Carderera, Alejandro, et al. "CINDy: Conditional gradient-based Identification of Non-linear Dynamics--Noise-robust recovery." arXiv preprint arXiv:2101.02630 (2021).
Reporting issues or bugs
^^^^^^^^^^^^^^^^^^^^^^^^
If you find a bug in the code or want to request a new feature, please open an issue.
Getting help
^^^^^^^^^^^^
For help using PySINDy please consult the `documentation <https://pysindy.readthedocs.io/en/latest/>`__ and/or our `examples <https://github.com/dynamicslab/pysindy/tree/master/examples>`__, or create an issue.
Citing PySINDy
--------------
PySINDy has been published in the Journal of Open Source Software (JOSS). The paper can be found `here <https://joss.theoj.org/papers/10.21105/joss.02104>`__.
If you use PySINDy in your work, please cite it using the following two references:
Brian M. de Silva, Kathleen Champion, Markus Quade, Jean-Christophe Loiseau, J. Nathan Kutz, and Steven L. Brunton., (2020). *PySINDy: A Python package for the sparse identification of nonlinear dynamical systems from data.* Journal of Open Source Software, 5(49), 2104, https://doi.org/10.21105/joss.02104
Kaptanoglu et al., (2022). PySINDy: A comprehensive Python package for robust sparse system identification. Journal of Open Source Software, 7(69), 3994, https://doi.org/10.21105/joss.03994
Bibtex:
.. code-block:: text
@article{desilva2020,
doi = {10.21105/joss.02104},
url = {https://doi.org/10.21105/joss.02104},
year = {2020},
publisher = {The Open Journal},
volume = {5},
number = {49},
pages = {2104},
author = {Brian de Silva and Kathleen Champion and Markus Quade and Jean-Christophe Loiseau and J. Kutz and Steven Brunton},
title = {PySINDy: A Python package for the sparse identification of nonlinear dynamical systems from data},
journal = {Journal of Open Source Software}
}
Bibtex:
.. code-block:: text
@article{Kaptanoglu2022,
doi = {10.21105/joss.03994},
url = {https://doi.org/10.21105/joss.03994},
year = {2022},
publisher = {The Open Journal},
volume = {7},
number = {69},
pages = {3994},
author = {Alan A. Kaptanoglu and Brian M. de Silva and Urban Fasel and Kadierdan Kaheman and Andy J. Goldschmidt and Jared Callaham and Charles B. Delahunt and Zachary G. Nicolaou and Kathleen Champion and Jean-Christophe Loiseau and J. Nathan Kutz and Steven L. Brunton},
title = {PySINDy: A comprehensive Python package for robust sparse system identification},
journal = {Journal of Open Source Software}
}
References
----------------------
- de Silva, Brian M., Kathleen Champion, Markus Quade,
Jean-Christophe Loiseau, J. Nathan Kutz, and Steven L. Brunton.
*PySINDy: a Python package for the sparse identification of
nonlinear dynamics from data.* arXiv preprint arXiv:2004.08424 (2020)
`[arXiv] <https://arxiv.org/abs/2004.08424>`__
- Kaptanoglu, Alan A., Brian M. de Silva, Urban Fasel, Kadierdan Kaheman, Andy J. Goldschmidt
Jared L. Callaham, Charles B. Delahunt, Zachary G. Nicolaou, Kathleen Champion,
Jean-Christophe Loiseau, J. Nathan Kutz, and Steven L. Brunton.
*PySINDy: A comprehensive Python package for robust sparse system identification.*
arXiv preprint arXiv:2111.08481 (2021).
`[arXiv] <https://arxiv.org/abs/2111.08481>`__
- Brunton, Steven L., Joshua L. Proctor, and J. Nathan Kutz.
*Discovering governing equations from data by sparse identification
of nonlinear dynamical systems.* Proceedings of the National
Academy of Sciences 113.15 (2016): 3932-3937.
`[DOI] <http://dx.doi.org/10.1073/pnas.1517384113>`__
- Champion, K., Zheng, P., Aravkin, A. Y., Brunton, S. L., & Kutz, J. N. (2020).
*A unified sparse optimization framework to learn parsimonious physics-informed
models from data.* IEEE Access, 8, 169259-169271.
`[DOI] <https://doi.org/10.1109/ACCESS.2020.3023625>`__
- Brunton, Steven L., Joshua L. Proctor, and J. Nathan Kutz.
*Sparse identification of nonlinear dynamics with control (SINDYc).*
IFAC-PapersOnLine 49.18 (2016): 710-715.
`[DOI] <https://doi.org/10.1016/j.ifacol.2016.10.249>`__
- Kaheman, K., Kutz, J. N., & Brunton, S. L. (2020).
*SINDy-PI: a robust algorithm for parallel implicit sparse identification
of nonlinear dynamics.* Proceedings of the Royal Society A, 476(2242), 20200279.
`[DOI] <https://doi.org/10.1098/rspa.2020.0279>`__
- Kaptanoglu, A. A., Callaham, J. L., Aravkin, A., Hansen, C. J., & Brunton, S. L. (2021).
*Promoting global stability in data-driven models of quadratic nonlinear dynamics.*
Physical Review Fluids, 6(9), 094401.
`[DOI] <https://doi.org/10.1103/PhysRevFluids.6.094401>`__
Related packages
----------------
* `Deeptime <https://github.com/deeptime-ml/deeptime>`_ - A Python library for the analysis of time series data with methods for dimension reduction, clustering, and Markov model estimation.
* `PyDMD <https://github.com/mathLab/PyDMD/>`_ - A Python package using the Dynamic Mode Decomposition (DMD) for a data-driven model simplification based on spatiotemporal coherent structures. DMD is a great alternative to SINDy.
* `PySINDyGUI <https://github.com/hyumo/pysindy-gui>`_ - A slick-looking GUI for PySINDy.
* `SEED <https://github.com/M-Vause/SEED2.0>`_ - Software for the Extraction of Equations from Data: a GUI for many of the methods provided by PySINDy.
* `SymINDy <https://github.com/andreikitaitsev/SymINDy/>`_ - A Python package combining SINDy with genetic programming-based symbolic regression, used for the functions library optimization.
Contributors
------------
This repository is a fork from `original work <https://github.com/Ohjeah/sparsereg>`_ by `Markus Quade <https://github.com/Ohjeah>`_.
Thanks to the members of the community who have contributed to PySINDy!
+-------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+
| `billtubbs <https://github.com/kopytjuk>`_ | Bug fix `#68 <https://github.com/dynamicslab/pysindy/issues/68>`_ |
+-------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+
| `kopytjuk <https://github.com/kopytjuk>`_ | Concatenation feature for libraries `#72 <https://github.com/dynamicslab/pysindy/pull/72>`_ |
+-------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+
| `andgoldschmidt <https://github.com/andgoldschmidt>`_ | `derivative <https://derivative.readthedocs.io/en/latest/>`_ package for numerical differentiation `#85 <https://github.com/dynamicslab/pysindy/pull/85>`_ |
+-------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+
.. |BuildCI| image:: https://github.com/dynamicslab/pysindy/workflows/Build%20CI/badge.svg
:target: https://github.com/dynamicslab/pysindy/actions?query=workflow%3A%22Build+CI%22
.. |RTD| image:: https://readthedocs.org/projects/pysindy/badge/?version=latest
:target: https://pysindy.readthedocs.io/en/latest/?badge=latest
:alt: Documentation Status
.. |PyPI| image:: https://badge.fury.io/py/pysindy.svg
:target: https://badge.fury.io/py/pysindy
.. |Codecov| image:: https://codecov.io/gh/dynamicslab/pysindy/branch/master/graph/badge.svg
:target: https://codecov.io/gh/dynamicslab/pysindy
.. |JOSS1| image:: https://joss.theoj.org/papers/82d080bbe10ac3ab4bc03fa75f07d644/status.svg
:target: https://joss.theoj.org/papers/82d080bbe10ac3ab4bc03fa75f07d644
.. |JOSS2| image:: https://joss.theoj.org/papers/10.21105/joss.03994/status.svg
:target: https://doi.org/10.21105/joss.03994
.. |DOI| image:: https://zenodo.org/badge/186055899.svg
:target: https://zenodo.org/badge/latestdoi/186055899
Raw data
{
"_id": null,
"home_page": "https://github.com/dynamicslab/pysindy",
"name": "pysindy",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.7",
"maintainer_email": "",
"keywords": "",
"author": "Brian de Silva, Kathleen Champion, Markus Quade, Alan Kaptanoglu",
"author_email": "bdesilva@uw.edu, kpchamp@uw.edu, info@markusqua.de, akaptano@uw.edu",
"download_url": "https://files.pythonhosted.org/packages/5d/ce/7b5895cb57cc9c2f46ce928755a46aafb31d1f00a74997a38c101864fe44/pysindy-1.7.5.tar.gz",
"platform": null,
"description": "PySINDy\n=========\n\n|BuildCI| |RTD| |PyPI| |Codecov| |JOSS1| |JOSS2| |DOI|\n\n**PySINDy** is a sparse regression package with several implementations for the Sparse Identification of Nonlinear Dynamical systems (SINDy) method introduced in Brunton et al. (2016a), including the unified optimization approach of Champion et al. (2019), SINDy with control from Brunton et al. (2016b), Trapping SINDy from Kaptanoglu et al. (2021), SINDy-PI from Kaheman et al. (2020), PDE-FIND from Rudy et al. (2017), and so on. A comprehensive literature review is given in de Silva et al. (2020) and Kaptanoglu, de Silva et al. (2021).\n\n.. contents:: Table of contents\n\nSystem identification\n---------------------\nSystem identification refers to the process of leveraging measurement data to infer governing equations, in the form of dynamical systems, describing the data. Once discovered, these equations can make predictions about future states, can inform control inputs, or can enable the theoretical study using analytical techniques.\nDynamical systems are a flexible, well-studied class of mathematical objects for modeling systems evolving in time.\nSINDy is a model discovery method which uses *sparse regression* to infer nonlinear dynamical systems from measurement data.\nThe resulting models are inherently *interpretable* and *generalizable*.\n\nHow it works\n^^^^^^^^^^^^\nSuppose, for some physical system of interest, we have measurements of state variables ``x(t)`` (a vector of length n) at different points in time. Examples of state variables include the position, velocity, or acceleration of objects; lift, drag, or angle of attack of aerodynamic objects; and concentrations of different chemical species. If we suspect that the system could be well-modeled by a dynamical system of the form\n\n.. code-block:: text\n\n x'(t) = f(x(t)),\n\nthen we can use SINDy to learn ``f(x)`` from the data (``x'(t)`` denotes the time derivative of ``x(t)``). Note that both ``f(x)`` and ``x(t)`` are typically vectors. The fundamental assumption SINDy employs is that each component of ``f(x)``, ``f_i(x)`` can be represented as a *sparse* linear combination of basis functions ``theta_j(x)``\n\n.. code-block:: text\n\n f_i(x) = theta_1(x) * xi_{1,i} + theta_2(x) * xi_{2,i} + ... + theta_k * xi{k,i}\n\nConcatenating all the objects into matrices (denoted with capitalized names) helps to simplify things.\nTo this end we place all measurements of the state variables into a data matrix ``X`` (with a row per time measurement and a column per variable), the derivatives of the state variables into a matrix ``X'``, all basis functions evaluated at all points in time into a matrix ``Theta(X)`` (each basis function gets a column), and all coefficients into a third matrix ``Xi`` (one column per state variable).\nThe approximation problem to be solved can then be compactly written as\n\n.. code-block:: text\n\n X' = Theta(X) * Xi.\n\nEach row of this matrix equation corresponds to one coordinate function of ``f(x)``.\nSINDy employs sparse regression techniques to find a solution ``Xi`` with sparse column vectors.\nFor a more in-depth look at the mathematical foundations of SINDy, please see our `introduction to SINDy <https://pysindy.readthedocs.io/en/latest/examples/2_introduction_to_sindy.html>`__.\n\nRelation to PySINDy\n^^^^^^^^^^^^^^^^^^^\nThe PySINDy package revolves around the ``SINDy`` class which consists of three primary components; one for each term in the above matrix approximation problem.\n\n* ``differentiation_method``: computes ``X'``, though if derivatives are known or measured directly, they can be used instead\n* ``feature_library``: specifies the candidate basis functions to be used to construct ``Theta(X)``\n* ``optimizer``: implements a sparse regression method for solving for ``Xi``\n\nOnce a ``SINDy`` object has been created it must be fit to measurement data, similar to a ``scikit-learn`` model. It can then be used to predict derivatives given new measurements, evolve novel initial conditions forward in time, and more. PySINDy has been written to be as compatible with ``scikit-learn`` objects and methods as possible.\n\nExample\n^^^^^^^\nSuppose we have measurements of the position of a particle obeying the following dynamical system at different points in time\n\n.. code-block:: text\n\n x' = -2x\n y' = y\n\nNote that this system of differential equations decouples into two differential equations whose solutions are simply ``x(t) = x_0 * exp(-2 * t)`` and ``y(t) = y_0 * exp(t)``, where ``x_0 = x(0)`` and ``y_0 = y(0)`` are the initial conditions.\n\nUsing the initial conditions ``x_0 = 3`` and ``y_0 = 0.5``, we construct the data matrix ``X``.\n\n.. code-block:: python\n\n import numpy as np\n import pysindy as ps\n\n t = np.linspace(0, 1, 100)\n x = 3 * np.exp(-2 * t)\n y = 0.5 * np.exp(t)\n X = np.stack((x, y), axis=-1) # First column is x, second is y\n\nTo instantiate a ``SINDy`` object with the default differentiation method, feature library, and optimizer and then fit it to the data, we invoke\n\n.. code-block:: python\n\n model = ps.SINDy(feature_names=[\"x\", \"y\"])\n model.fit(X, t=t)\n\nWe use the ``feature_names`` argument so that the model prints out the correct labels for ``x`` and ``y``. We can inspect the governing equations discovered by the model and check whether they seem reasonable with the ``print`` function.\n\n.. code-block:: python\n\n model.print()\n\nwhich prints the following\n\n.. code-block:: text\n\n x' = -2.000 x\n y' = 1.000 y\n\nPySINDy provides numerous other features not shown here. We recommend the `feature overview <https://pysindy.readthedocs.io/en/latest/examples/1_feature_overview.html>`__ section of the documentation for a more exhaustive summary of additional features.\n\nInstallation\n------------\n\nInstalling with pip\n^^^^^^^^^^^^^^^^^^^\n\nIf you are using Linux or macOS you can install PySINDy with pip:\n\n.. code-block:: bash\n\n pip install pysindy\n\nInstalling from source\n^^^^^^^^^^^^^^^^^^^^^^\nFirst clone this repository:\n\n.. code-block:: bash\n\n git clone https://github.com/dynamicslab/pysindy.git\n\nThen, to install the package, run\n\n.. code-block:: bash\n\n pip install .\n\nIf you do not have pip you can instead use\n\n.. code-block:: bash\n\n python setup.py install\n\nIf you do not have root access, you should add the ``--user`` option to the above lines.\n\nCaveats\n^^^^^^^\nIf you would like to use the ``SINDy-PI`` optimizer, the ``Trapping SINDy`` optimizer (TrappingSR3), or the other SR3 optimizations with inequality constraints, you will also need to install the cvxpy package, e.g. with ``pip install cvxpy``.\n\nTo run the unit tests, example notebooks, or build a local copy of the documentation, you should install the additional dependencies in ``requirements-dev.txt``\n\n.. code-block:: bash\n\n pip install -r requirements-dev.txt\n\n\nDocumentation\n-------------\nThe documentation site for PySINDy can be found `here <https://pysindy.readthedocs.io/en/latest/>`__. There are numerous `examples <https://pysindy.readthedocs.io/en/latest/examples/index.html>`_ of PySINDy in action to help you get started. Examples are also available as `Jupyter notebooks <https://github.com/dynamicslab/pysindy/tree/master/examples>`__. A video overview of PySINDy can be found on `Youtube <https://www.youtube.com/watch?v=DvbbXX8Bd90>`__. We have also created a `video playlist <https://www.youtube.com/playlist?list=PLN90bHJU-JLoOfEk0KyBs2qLTV7OkMZ25>`__ with practical PySINDy tips.\n\nPySINDy implements a lot of advanced functionality that may be overwhelming for new users or folks who are unfamiliar with these methods. Below (see here if image does not render https://github.com/dynamicslab/pysindy/blob/master/docs/JOSS2/Fig3.png), we provide a helpful flowchart for figuring out which methods to use, given the characteristics of your dataset:\n\n.. image:: https://github.com/dynamicslab/pysindy/blob/master/docs/JOSS2/Fig3.png\n\nThis flow chart summarizes how ``PySINDy`` users can start with a dataset and systematically choose the proper candidate library and sparse regression optimizer that are tailored for a specific scientific task. The ``GeneralizedLibrary`` class allows for tensoring, concatenating, and otherwise combining many different candidate libraries.\n\nCommunity guidelines\n--------------------\n\nContributing examples\n^^^^^^^^^^^^^^^^^^^^^\nWe love seeing examples of PySINDy being used to solve interesting problems! If you would like to contribute an example, reach out to us by creating an issue.\n\nAt a minimum, we need to be able to run the example notebooks in the normal mode as well as in a test mode that uses smaller data in order to run faster and simply verify that cells execute without error. In order to do that, your example should obey the following directory tree\n\n.. code-block::\n\n ./<name_of_example>/\n \\\n |-example.py # save your notebook as a python script\n |-example_data.py # has functions to create/load data\n |-mock_data.py # has functions with same name as in example_data.py which create/load smaller datasets\n |-example.ipynb # run python examples/publish_notebook/<name_of_example> to generate this. Needs packages in requirements-dev.txt\n |-utils.py (Any other names example.py needs to import. Any additional local modules imported by example.py need to be submodules of utils.py, e.g. utils.plotting)\n\nYou can optimize your notebook for testing by checking ``__name__``. When our tests run ``example.py`` they set the ``__name__`` global to ``\"testing\"``. For instance, your notebook should determine whether to import from ``mock_data`` or ``example_data`` using this method (another example: you could also use this method to set ``max_iter``). It's a bit arbitrary, but try to make your examples run in under ten seconds using the mock data. You can use our test to verify your example in testing mode:\n\n.. code-block::\n\n pytest -k test_external --external-notebook=\"path/to/<name_of_example>\"\n\n\nContributing code\n^^^^^^^^^^^^^^^^^\nWe welcome contributions to PySINDy. To contribute a new feature please submit a pull request. To get started we recommend installing the packages in ``requirements-dev.txt`` via\n\n.. code-block:: bash\n\n pip install -r requirements-dev.txt\n\nThis will allow you to run unit tests and automatically format your code. To be accepted your code should conform to PEP8 and pass all unit tests. Code can be tested by invoking\n\n.. code-block:: bash\n\n pytest\n\nWe recommend using ``pre-commit`` to format your code. Once you have staged changes to commit\n\n.. code-block:: bash\n\n git add path/to/changed/file.py\n\nyou can run the following to automatically reformat your staged code\n\n.. code-block:: bash\n\n pre-commit\n\nNote that you will then need to re-stage any changes ``pre-commit`` made to your code.\n\nBuilding documentation requires [pandoc](https://pandoc.org/installing.html) as a separate install. Once installed, run\n\n.. code-block:: bash\n\n python -m sphinx -TEb html -d _build/doctrees -D language=en . ./build\n\nOr check the build step in the most recent CI run or [RTD build](https://readthedocs.org/projects/pysindy/builds/).\n\nThere are a number of SINDy variants and advanced functionality that would be great to implement in future releases:\n\n1. Bayesian SINDy, for instance that from Hirsh, Seth M., David A. Barajas-Solano, and J. Nathan Kutz. \"Sparsifying Priors for Bayesian Uncertainty Quantification in Model Discovery.\" arXiv preprint arXiv:2107.02107 (2021).\n\n2. Tensor SINDy, using the methods in Gel\u00df, Patrick, et al. \"Multidimensional approximation of nonlinear dynamical systems.\" Journal of Computational and Nonlinear Dynamics 14.6 (2019).\n\n3. Stochastic SINDy, using the methods in Br\u00fcckner, David B., Pierre Ronceray, and Chase P. Broedersz. \"Inferring the dynamics of underdamped stochastic systems.\" Physical review letters 125.5 (2020): 058103.\n\n4. Integration of PySINDy with a Python model-predictive control (MPC) code.\n\n5. The PySINDy weak formulation is based on the work in Reinbold, Patrick AK, Daniel R. Gurevich, and Roman O. Grigoriev. \"Using noisy or incomplete data to discover models of spatiotemporal dynamics.\" Physical Review E 101.1 (2020): 010203. It might be useful to additionally implement the weak formulation from Messenger, Daniel A., and David M. Bortz. \"Weak SINDy for partial differential equations.\" Journal of Computational Physics (2021): 110525. The weak formulation in PySINDy is also fairly slow and computationally intensive, so finding ways to speed up the code would be great.\n\n6. The blended conditional gradients (BCG) algorithm for solving the constrained LASSO problem, Carderera, Alejandro, et al. \"CINDy: Conditional gradient-based Identification of Non-linear Dynamics--Noise-robust recovery.\" arXiv preprint arXiv:2101.02630 (2021).\n\nReporting issues or bugs\n^^^^^^^^^^^^^^^^^^^^^^^^\nIf you find a bug in the code or want to request a new feature, please open an issue.\n\nGetting help\n^^^^^^^^^^^^\nFor help using PySINDy please consult the `documentation <https://pysindy.readthedocs.io/en/latest/>`__ and/or our `examples <https://github.com/dynamicslab/pysindy/tree/master/examples>`__, or create an issue.\n\nCiting PySINDy\n--------------\nPySINDy has been published in the Journal of Open Source Software (JOSS). The paper can be found `here <https://joss.theoj.org/papers/10.21105/joss.02104>`__.\n\nIf you use PySINDy in your work, please cite it using the following two references:\n\nBrian M. de Silva, Kathleen Champion, Markus Quade, Jean-Christophe Loiseau, J. Nathan Kutz, and Steven L. Brunton., (2020). *PySINDy: A Python package for the sparse identification of nonlinear dynamical systems from data.* Journal of Open Source Software, 5(49), 2104, https://doi.org/10.21105/joss.02104\n\nKaptanoglu et al., (2022). PySINDy: A comprehensive Python package for robust sparse system identification. Journal of Open Source Software, 7(69), 3994, https://doi.org/10.21105/joss.03994\n\nBibtex:\n\n.. code-block:: text\n\n @article{desilva2020,\n doi = {10.21105/joss.02104},\n url = {https://doi.org/10.21105/joss.02104},\n year = {2020},\n publisher = {The Open Journal},\n volume = {5},\n number = {49},\n pages = {2104},\n author = {Brian de Silva and Kathleen Champion and Markus Quade and Jean-Christophe Loiseau and J. Kutz and Steven Brunton},\n title = {PySINDy: A Python package for the sparse identification of nonlinear dynamical systems from data},\n journal = {Journal of Open Source Software}\n }\n\nBibtex:\n\n.. code-block:: text\n\n @article{Kaptanoglu2022,\n doi = {10.21105/joss.03994},\n url = {https://doi.org/10.21105/joss.03994},\n year = {2022},\n publisher = {The Open Journal},\n volume = {7},\n number = {69},\n pages = {3994},\n author = {Alan A. Kaptanoglu and Brian M. de Silva and Urban Fasel and Kadierdan Kaheman and Andy J. Goldschmidt and Jared Callaham and Charles B. Delahunt and Zachary G. Nicolaou and Kathleen Champion and Jean-Christophe Loiseau and J. Nathan Kutz and Steven L. Brunton},\n title = {PySINDy: A comprehensive Python package for robust sparse system identification},\n journal = {Journal of Open Source Software}\n }\n\n\nReferences\n----------------------\n- de Silva, Brian M., Kathleen Champion, Markus Quade,\n Jean-Christophe Loiseau, J. Nathan Kutz, and Steven L. Brunton.\n *PySINDy: a Python package for the sparse identification of\n nonlinear dynamics from data.* arXiv preprint arXiv:2004.08424 (2020)\n `[arXiv] <https://arxiv.org/abs/2004.08424>`__\n\n- Kaptanoglu, Alan A., Brian M. de Silva, Urban Fasel, Kadierdan Kaheman, Andy J. Goldschmidt\n Jared L. Callaham, Charles B. Delahunt, Zachary G. Nicolaou, Kathleen Champion,\n Jean-Christophe Loiseau, J. Nathan Kutz, and Steven L. Brunton.\n *PySINDy: A comprehensive Python package for robust sparse system identification.*\n arXiv preprint arXiv:2111.08481 (2021).\n `[arXiv] <https://arxiv.org/abs/2111.08481>`__\n\n- Brunton, Steven L., Joshua L. Proctor, and J. Nathan Kutz.\n *Discovering governing equations from data by sparse identification\n of nonlinear dynamical systems.* Proceedings of the National\n Academy of Sciences 113.15 (2016): 3932-3937.\n `[DOI] <http://dx.doi.org/10.1073/pnas.1517384113>`__\n\n- Champion, K., Zheng, P., Aravkin, A. Y., Brunton, S. L., & Kutz, J. N. (2020).\n *A unified sparse optimization framework to learn parsimonious physics-informed\n models from data.* IEEE Access, 8, 169259-169271.\n `[DOI] <https://doi.org/10.1109/ACCESS.2020.3023625>`__\n\n- Brunton, Steven L., Joshua L. Proctor, and J. Nathan Kutz.\n *Sparse identification of nonlinear dynamics with control (SINDYc).*\n IFAC-PapersOnLine 49.18 (2016): 710-715.\n `[DOI] <https://doi.org/10.1016/j.ifacol.2016.10.249>`__\n\n- Kaheman, K., Kutz, J. N., & Brunton, S. L. (2020).\n *SINDy-PI: a robust algorithm for parallel implicit sparse identification\n of nonlinear dynamics.* Proceedings of the Royal Society A, 476(2242), 20200279.\n `[DOI] <https://doi.org/10.1098/rspa.2020.0279>`__\n\n- Kaptanoglu, A. A., Callaham, J. L., Aravkin, A., Hansen, C. J., & Brunton, S. L. (2021).\n *Promoting global stability in data-driven models of quadratic nonlinear dynamics.*\n Physical Review Fluids, 6(9), 094401.\n `[DOI] <https://doi.org/10.1103/PhysRevFluids.6.094401>`__\n\n\nRelated packages\n----------------\n* `Deeptime <https://github.com/deeptime-ml/deeptime>`_ - A Python library for the analysis of time series data with methods for dimension reduction, clustering, and Markov model estimation.\n* `PyDMD <https://github.com/mathLab/PyDMD/>`_ - A Python package using the Dynamic Mode Decomposition (DMD) for a data-driven model simplification based on spatiotemporal coherent structures. DMD is a great alternative to SINDy.\n* `PySINDyGUI <https://github.com/hyumo/pysindy-gui>`_ - A slick-looking GUI for PySINDy.\n* `SEED <https://github.com/M-Vause/SEED2.0>`_ - Software for the Extraction of Equations from Data: a GUI for many of the methods provided by PySINDy.\n* `SymINDy <https://github.com/andreikitaitsev/SymINDy/>`_ - A Python package combining SINDy with genetic programming-based symbolic regression, used for the functions library optimization.\n\nContributors\n------------\nThis repository is a fork from `original work <https://github.com/Ohjeah/sparsereg>`_ by `Markus Quade <https://github.com/Ohjeah>`_.\n\nThanks to the members of the community who have contributed to PySINDy!\n\n+-------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+\n| `billtubbs <https://github.com/kopytjuk>`_ | Bug fix `#68 <https://github.com/dynamicslab/pysindy/issues/68>`_ |\n+-------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+\n| `kopytjuk <https://github.com/kopytjuk>`_ | Concatenation feature for libraries `#72 <https://github.com/dynamicslab/pysindy/pull/72>`_ |\n+-------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+\n| `andgoldschmidt <https://github.com/andgoldschmidt>`_ | `derivative <https://derivative.readthedocs.io/en/latest/>`_ package for numerical differentiation `#85 <https://github.com/dynamicslab/pysindy/pull/85>`_ |\n+-------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+\n\n.. |BuildCI| image:: https://github.com/dynamicslab/pysindy/workflows/Build%20CI/badge.svg\n :target: https://github.com/dynamicslab/pysindy/actions?query=workflow%3A%22Build+CI%22\n\n.. |RTD| image:: https://readthedocs.org/projects/pysindy/badge/?version=latest\n :target: https://pysindy.readthedocs.io/en/latest/?badge=latest\n :alt: Documentation Status\n\n.. |PyPI| image:: https://badge.fury.io/py/pysindy.svg\n :target: https://badge.fury.io/py/pysindy\n\n.. |Codecov| image:: https://codecov.io/gh/dynamicslab/pysindy/branch/master/graph/badge.svg\n :target: https://codecov.io/gh/dynamicslab/pysindy\n\n.. |JOSS1| image:: https://joss.theoj.org/papers/82d080bbe10ac3ab4bc03fa75f07d644/status.svg\n :target: https://joss.theoj.org/papers/82d080bbe10ac3ab4bc03fa75f07d644\n\n.. |JOSS2| image:: https://joss.theoj.org/papers/10.21105/joss.03994/status.svg\n :target: https://doi.org/10.21105/joss.03994\n\n.. |DOI| image:: https://zenodo.org/badge/186055899.svg\n :target: https://zenodo.org/badge/latestdoi/186055899\n\n\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Sparse Identification of Nonlinear Dynamics",
"version": "1.7.5",
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "3f90b574bcbd68a8db8dc01b6a0098f506cf698ac2e77cfee19b43a9ed2240c8",
"md5": "5c690a5862ebed41391581569b3eae01",
"sha256": "c93177f4ddf30b400d1a573c466540f7f027b47e92720fe4ad80527dcb8b4fe2"
},
"downloads": -1,
"filename": "pysindy-1.7.5-py3-none-any.whl",
"has_sig": false,
"md5_digest": "5c690a5862ebed41391581569b3eae01",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.7",
"size": 121026,
"upload_time": "2023-04-07T15:13:03",
"upload_time_iso_8601": "2023-04-07T15:13:03.211721Z",
"url": "https://files.pythonhosted.org/packages/3f/90/b574bcbd68a8db8dc01b6a0098f506cf698ac2e77cfee19b43a9ed2240c8/pysindy-1.7.5-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "5dce7b5895cb57cc9c2f46ce928755a46aafb31d1f00a74997a38c101864fe44",
"md5": "a1b7b2f8b0f1bcd77edf6cf4a83916ce",
"sha256": "a99c99b7a1e032e53113e2174abcf22d04ce1f0404deb8994fc4e3b6d34c7820"
},
"downloads": -1,
"filename": "pysindy-1.7.5.tar.gz",
"has_sig": false,
"md5_digest": "a1b7b2f8b0f1bcd77edf6cf4a83916ce",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.7",
"size": 3212319,
"upload_time": "2023-04-07T15:13:05",
"upload_time_iso_8601": "2023-04-07T15:13:05.219579Z",
"url": "https://files.pythonhosted.org/packages/5d/ce/7b5895cb57cc9c2f46ce928755a46aafb31d1f00a74997a38c101864fe44/pysindy-1.7.5.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-04-07 15:13:05",
"github": true,
"gitlab": false,
"bitbucket": false,
"github_user": "dynamicslab",
"github_project": "pysindy",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [],
"lcname": "pysindy"
}