Skip to content

Commit 9b7d2dd

Browse files
Merge branch 'master' of github.com:dynamicslab/pysindy
2 parents 60f520c + 472e5a2 commit 9b7d2dd

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+3803
-2039
lines changed

.github/workflows/main.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ jobs:
5151
- name: "Set up Python"
5252
uses: actions/setup-python@v4
5353
with:
54-
python-version: "3.10"
54+
python-version: "3.11"
5555
- name: Install doc dependencies
5656
run: |
5757
sudo apt-get update -y

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ prof/
1111
# Environments
1212
.env
1313
.venv
14-
env/
14+
env*/
1515
venv/
1616
ENV/
1717
env.bak/

README.rst

Lines changed: 45 additions & 325 deletions
Large diffs are not rendered by default.

citation.cff

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
cff-version: 1.2.0
2+
title: pysindy
3+
message: >-
4+
If you use this software, please cite it using the
5+
metadata from this file.
6+
type: software
7+
authors:
8+
- given-names: Alan
9+
family-names: Kaptanoglu
10+
11+
affiliation: New York University
12+
- given-names: Jacob
13+
family-names: Stevens-Haas
14+
15+
affiliation: University of Washington
16+
orcid: 'https://orcid.org/0000-0003-4142-5550'
17+
- given-names: Kathleen
18+
family-names: Champion
19+
20+
- given-names: Brian
21+
family-names: de Silva
22+
23+
- given-names: Markus
24+
family-names: Quade
25+
26+
repository-code: 'https://github.com/dynamicslab/pysindy'
27+
url: 'https://pysindy.readthedocs.org/'
28+
abstract: >-
29+
PySINDy is a sparse regression package with several
30+
implementations for the Sparse Identification of Nonlinear
31+
Dynamical systems (SINDy) method introduced in Brunton et
32+
al. (2016).
33+
license: MIT

docs/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
generated/

docs/academic.rst

Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
Use in academic work
2+
================================
3+
4+
Pysindy as a dependency for your research
5+
---------------------------------------------
6+
It's important to specify the dependencies of any project,
7+
and research projects are no exception.
8+
Pysindy on pypi and github have various standard versions, e.g. 2.0.0
9+
that follow `semantic versioning`_.
10+
If you can use one of those versions, it's easy to use standard version ranges,
11+
or pin pysindy to a specific version
12+
(e.g. in pyproject.toml, requirements.txt, or environment.yml).
13+
14+
.. _semantic versioning: https://semver.org/
15+
16+
There are situations when something is wrong or missing in pysindy,
17+
and you want a specific version off of github that does not have an associated
18+
git tag or pypi release. In those cases, it's possible to use a `direct
19+
reference`_ to a github version, e.g
20+
21+
.. code-block:: text
22+
23+
pysindy[miosr] @ https://github.com/dynamicslab/pysindy@c1da1f9
24+
25+
.. _direct reference: https://peps.python.org/pep-0440/#direct-references
26+
27+
Most challengingly, you may want to make fixes and changes to pysindy
28+
during the course of a research project. In these cases, the direct url works,
29+
however you may need to pause your project each time you change pysindy,
30+
as a new direct url will only be created once the pull request is merged.
31+
In these cases, it's possible to include pysindy as a `git submodule`_
32+
of your research project.
33+
This way, your project keeps track of which *local* pysindy
34+
hash is required.
35+
Changes to your local pysindy will appear in the super-project's ``git diff``
36+
so you'll never forget to update your dependencies.
37+
In parallel, you can push your local changes to a fork of pysindy
38+
and pull request them in.
39+
This way, everyone can benefit from improvements you make to pysindy,
40+
while you don't have to wait to use fixes downstream,
41+
and you won't forget to edit your dependencies.
42+
43+
.. _git submodule: https://git-scm.com/book/en/v2/Git-Tools-Submodules
44+
45+
Regardless, in mast cases, you'll want to `cite <Citation>`_ pysindy. On occasion, you may want to
46+
`add your method to pysindy <Adding your new method to pysindy>`_.
47+
48+
Citation
49+
---------------------
50+
Pysindy is the result of academic work.
51+
If you are using pysindy in a paper, there are a different documents that you can cite:
52+
53+
* The Journal of Open-Source Software (JOSS) papers (`1 <joss1>`_, `2 <joss2>`_) on pysindy
54+
* This repository, via the citation.cff
55+
* The `original SINDy paper`_.
56+
* Papers introducing innovations that you use, e.g. WeakSINDy, Trapping, or Kalman SINDy.
57+
References for these can be found in the docstrings for the relevant functionality.
58+
59+
.. _joss1: https://joss.theoj.org/papers/10.21105/joss.02104
60+
61+
.. _joss2: https://joss.theoj.org/papers/10.21105/joss.03994
62+
63+
.. _original SINDy paper: https://www.pnas.org/doi/10.1073/pnas.1517384113
64+
65+
The JOSS papers have the Bibtex:
66+
67+
.. code-block:: text
68+
69+
@article{desilva2020,
70+
doi = {10.21105/joss.02104},
71+
url = {https://doi.org/10.21105/joss.02104},
72+
year = {2020},
73+
publisher = {The Open Journal},
74+
volume = {5},
75+
number = {49},
76+
pages = {2104},
77+
author = {Brian de Silva and Kathleen Champion and Markus Quade and Jean-Christophe Loiseau and J. Kutz and Steven Brunton},
78+
title = {PySINDy: A Python package for the sparse identification of nonlinear dynamical systems from data},
79+
journal = {Journal of Open Source Software}
80+
}
81+
82+
.. code-block:: text
83+
84+
@article{Kaptanoglu2022,
85+
doi = {10.21105/joss.03994},
86+
url = {https://doi.org/10.21105/joss.03994},
87+
year = {2022},
88+
publisher = {The Open Journal},
89+
volume = {7},
90+
number = {69},
91+
pages = {3994},
92+
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},
93+
title = {PySINDy: A comprehensive Python package for robust sparse system identification},
94+
journal = {Journal of Open Source Software}
95+
}
96+
97+
98+
Citation, however, be ambiguous. See the section on `ambiguity <Ambiguity>`_
99+
100+
Adding your new method to pysindy
101+
----------------------------------
102+
If you're publishing a new approach for learning differential equations from data,
103+
we believe that adding an implementation to pysindy helps promote the new research
104+
and advance the state of the art.
105+
By making the approach API-compatible with existing approaches, it allows researchers
106+
to evaluate new methods against old ones
107+
and facilitates more rapid development of the field.
108+
When things are not API compatible, it means that experiments need to be rewritten
109+
in order to adapt to each different API, coupling the experiment to the method,
110+
and making the experiment more fragile to changes in either dependency.
111+
112+
Although API compatibility is good, there are drawbacks.
113+
If something is added to pysindy, someone needs to take on the maintenance burden.
114+
Not everyone publishing a method needs or wants to develop tests or benchmarks
115+
to make sure that future refactorings and changes don't subtly break the method.
116+
Moreover, if your method is compatible with certain other innovations or shares
117+
functionality, a refactor may be required in order to make maintenance easier.
118+
119+
This is all good and important work, but if its a bridge too far, the
120+
innovation can still be useful as a separate `distribution package`_.
121+
The above difficulties all center around maintenance and dependency management.
122+
If the API is compatible, nothing prevents:
123+
124+
.. _distribution package: https://packaging.python.org/en/latest/discussions/distribution-package-vs-import-package/
125+
126+
.. code-block:: python
127+
128+
from your_package import YourOptimizer
129+
import pysindy as ps
130+
131+
ps.SINDy(optimizer=YourOptimizer())
132+
133+
It is also possible to use `plugins`_ to distribute your method separately but import
134+
via pysindy.
135+
In either case, if nobody is claiming maintenance, it may be useful
136+
to pin the pysindy dependency in your distribution package to a narrow range.
137+
And we would love to to your package in our documentation!
138+
139+
.. _plugins: https://packaging.python.org/en/latest/specifications/entry-points/
140+
141+
So TL;DR: Let us know if you have a new SINDy method!
142+
It could be something we want to merge, or it could be something we want to link to.
143+
But either way, thank you for your contribution to the field!
144+
145+
146+
Ambiguity
147+
----------------------
148+
Rarely, a pull request adds significant functionality and original description,
149+
but either the author of the code was not an author on the relevant paper
150+
(e.g. ``SBR``), or the relevant paper has yet to be published,
151+
or the method is not significant enough to be published on its own,
152+
but provides a lot of code that would otherwise need to be written for certain applications (eg. ``StabilizedLinearSR3``).
153+
Other times, a separate author fixes mathematically significant implementation flaws;
154+
these occur without publishing the equivalent of a corrigenda or journal letter.
155+
Equally rarely, someone adds a new paper's functionality to pysindy
156+
in order to support an associated manuscript,
157+
but implementing that functionality requires substantial refactoring work
158+
from other package maintainers.
159+
160+
There are largely three ways to give credit to this kind of academic work:
161+
authorship, acknowledgment, and citation.
162+
It's hard to match these levels to the wide range of academic work
163+
in an open source setting.
164+
Ultimately, we believe that sharing wins motivates a better research product
165+
and drives the field forwards.
166+
What that looks like is your decision.
167+
168+
If you want help with git archeaology to understand how features were added,
169+
please add a discussion.
170+
171+
References
172+
----------------------
173+
The following is a partial list of references used in pysindy:
174+
175+
- de Silva, Brian M., Kathleen Champion, Markus Quade,
176+
Jean-Christophe Loiseau, J. Nathan Kutz, and Steven L. Brunton.
177+
*PySINDy: a Python package for the sparse identification of
178+
nonlinear dynamics from data.* arXiv preprint arXiv:2004.08424 (2020)
179+
`[arXiv] <https://arxiv.org/abs/2004.08424>`__
180+
181+
- Kaptanoglu, Alan A., Brian M. de Silva, Urban Fasel, Kadierdan Kaheman, Andy J. Goldschmidt
182+
Jared L. Callaham, Charles B. Delahunt, Zachary G. Nicolaou, Kathleen Champion,
183+
Jean-Christophe Loiseau, J. Nathan Kutz, and Steven L. Brunton.
184+
*PySINDy: A comprehensive Python package for robust sparse system identification.*
185+
arXiv preprint arXiv:2111.08481 (2021).
186+
`[arXiv] <https://arxiv.org/abs/2111.08481>`__
187+
188+
- Brunton, Steven L., Joshua L. Proctor, and J. Nathan Kutz.
189+
*Discovering governing equations from data by sparse identification
190+
of nonlinear dynamical systems.* Proceedings of the National
191+
Academy of Sciences 113.15 (2016): 3932-3937.
192+
`[DOI] <http://dx.doi.org/10.1073/pnas.1517384113>`__
193+
194+
- Champion, K., Zheng, P., Aravkin, A. Y., Brunton, S. L., & Kutz, J. N. (2020).
195+
*A unified sparse optimization framework to learn parsimonious physics-informed
196+
models from data.* IEEE Access, 8, 169259-169271.
197+
`[DOI] <https://doi.org/10.1109/ACCESS.2020.3023625>`__
198+
199+
- Brunton, Steven L., Joshua L. Proctor, and J. Nathan Kutz.
200+
*Sparse identification of nonlinear dynamics with control (SINDYc).*
201+
IFAC-PapersOnLine 49.18 (2016): 710-715.
202+
`[DOI] <https://doi.org/10.1016/j.ifacol.2016.10.249>`__
203+
204+
- Kaheman, K., Kutz, J. N., & Brunton, S. L. (2020).
205+
*SINDy-PI: a robust algorithm for parallel implicit sparse identification
206+
of nonlinear dynamics.* Proceedings of the Royal Society A, 476(2242), 20200279.
207+
`[DOI] <https://doi.org/10.1098/rspa.2020.0279>`__
208+
209+
- Kaptanoglu, A. A., Callaham, J. L., Aravkin, A., Hansen, C. J., & Brunton, S. L. (2021).
210+
*Promoting global stability in data-driven models of quadratic nonlinear dynamics.*
211+
Physical Review Fluids, 6(9), 094401.
212+
`[DOI] <https://doi.org/10.1103/PhysRevFluids.6.094401>`__

docs/api.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
:orphan:
2+
3+
pysindy package
4+
===============
5+
6+
.. autosummary::
7+
:toctree: generated/
8+
:template: module.rst
9+
:recursive:
10+
11+
pysindy

docs/conf.py

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -14,40 +14,32 @@
1414
from sphinx.util.docutils import SphinxDirective
1515

1616
author = "dynamicslab"
17-
project = "pysindy" # package name
18-
19-
20-
# no need to edit below this line
21-
17+
project = "pysindy"
2218
copyright = f"2020, {author}"
23-
2419
module = importlib.import_module(project)
2520
version = release = getattr(module, "__version__")
2621

2722
master_doc = "index"
2823

2924
extensions = [
30-
"nbsphinx",
31-
"sphinxcontrib.apidoc",
3225
"sphinx.ext.autodoc",
33-
"sphinx.ext.todo",
34-
"sphinx.ext.viewcode",
3526
"sphinx.ext.autosummary",
27+
"nbsphinx",
28+
"sphinx.ext.todo",
3629
"sphinx.ext.napoleon",
30+
"sphinx.ext.viewcode",
3731
"sphinx.ext.mathjax",
3832
"sphinx.ext.intersphinx",
3933
"IPython.sphinxext.ipython_console_highlighting",
4034
]
4135

4236
nb_execution_mode = "off"
4337

44-
apidoc_module_dir = f"../{project}"
45-
apidoc_excluded_paths = ["tests"]
46-
apidoc_toc_file = False
38+
templates_path = ["templates"]
39+
autosummary_generate = True
40+
autosummary_ignore_module_all = False
4741

48-
autodoc_default_options = {"members": True}
49-
autodoc_member_order = "bysource"
50-
autoclass_content = "init"
42+
autoclass_content = "both"
5143

5244
language = "en"
5345

@@ -69,10 +61,22 @@
6961
html_sourcelink_suffix = ""
7062

7163
intersphinx_mapping = {
72-
"derivative": ("https://derivative.readthedocs.io/en/latest/", None),
73-
"sklearn": ("https://scikit-learn.org/stable/", None),
64+
"derivative": ("https://derivative.readthedocs.io/en/latest", None),
65+
"sklearn": ("https://scikit-learn.org/stable", None),
66+
"numpy": ("https://numpy.org/doc/stable", None),
7467
}
7568

69+
show_warning_types = True
70+
suppress_warnings = [
71+
"ref.python",
72+
"ref.exc",
73+
"ref.class",
74+
"ref.obj",
75+
"ref.meth",
76+
"ref.any",
77+
"ref",
78+
]
79+
7680
# -- Extensions to the Napoleon GoogleDocstring class ---------------------
7781
# michaelgoerz.net/notes/extending-sphinx-napoleon-docstring-sections.html
7882
from sphinx.ext.napoleon.docstring import GoogleDocstring # noqa: E402

0 commit comments

Comments
 (0)