|
| 1 | + |
| 2 | + |
| 3 | +Contributing to pysindy |
| 4 | +================================ |
| 5 | +We welcome all sorts of contributions! |
| 6 | +There are generally three different types of contributions. |
| 7 | +Please be aware of how to conduct yourself in an online, professional environment; |
| 8 | +We have a contributor `code of conduct`_. |
| 9 | + |
| 10 | +.. _code of conduct: https://github.com/dynamicslab/pysindy/docs/contributor_covenant.md |
| 11 | + |
| 12 | + |
| 13 | + |
| 14 | +Three types of contributions |
| 15 | +-------------------------------- |
| 16 | +The pysindy repository combines several different types of users and use cases: |
| 17 | + |
| 18 | +* You want to discover an ODE for your particular data, potentially as a research paper |
| 19 | +* You want to publish a new methods of learning differential equations from data, |
| 20 | + making it available to other users |
| 21 | +* You are learning about equation discovery from reading papers, and this repo is |
| 22 | + an educational supplement to existing papers/textbooks. |
| 23 | + |
| 24 | +There are several different ways people contribute: |
| 25 | + |
| 26 | +* Sharing a novel use case/research notebook with the wider public |
| 27 | +* Adding features or fixing bugs |
| 28 | +* Improving documentation. |
| 29 | + |
| 30 | +Contributing examples |
| 31 | +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 32 | +We love seeing examples of PySINDy being used to solve interesting problems! |
| 33 | +If you would like to contribute an example to the documentation, |
| 34 | +reach out to us by creating an issue. |
| 35 | + |
| 36 | +Examples are external repositories that |
| 37 | +`follow a structure <https://github.com/dynamicslab/pysindy-example>`_. |
| 38 | +They tend to be pinned to a set of dependencies and may not be kept up to date |
| 39 | +with breaking API changes. |
| 40 | +Pysindy has a sphinx extension that allows incorporating externally-built docs, |
| 41 | +so long as it follows that structure. |
| 42 | +Once your example repository is fully built, create a PR here that adds your repo |
| 43 | +to examples/external.yml and examples/README.rst as: |
| 44 | + |
| 45 | + |
| 46 | +.. code-block:: rst |
| 47 | + :caption: examples/README.rst |
| 48 | +
|
| 49 | + .. pysindy-example:: |
| 50 | + :key: your-example-key |
| 51 | + :title: Title of your example |
| 52 | +
|
| 53 | + A description of your example |
| 54 | +
|
| 55 | +.. code-block:: yaml |
| 56 | + :caption: external.yml |
| 57 | +
|
| 58 | + - name: "your-example-key" |
| 59 | + user: "user-or-org-owning-repo" |
| 60 | + repo: "repo-name" |
| 61 | + ref: "git hash of commit" |
| 62 | + dir: "name of folder with examples in it, e.g. 'examples' or '.'" |
| 63 | +
|
| 64 | +
|
| 65 | +.. hint:: |
| 66 | + |
| 67 | + The most frequent issue in linking external documentation is header levels. |
| 68 | + The sphinx directive adjusts section levels to fit correctly within our |
| 69 | + documentation. |
| 70 | + This means that notebooks need to have exactly one highest-level header as |
| 71 | + the document link text. |
| 72 | + Subordinate levels should proceed in a rational way, e.g. level two headers |
| 73 | + following level one headers, etc. |
| 74 | + |
| 75 | +If you want to keep your example up to date with pysindy main branch, |
| 76 | +i.e. across breaking changes, that is also possible. |
| 77 | +*This repository* has the CI job ``notify-experiments`` that sends a |
| 78 | +repository-dispatch action to repos that want to be notfied of changes to pysindy. |
| 79 | +The example repository has a CI job (``pysindy.yml``) that can be cued by such dispatch. |
| 80 | +You will have to add your repository information to the ``notify-experiments`` |
| 81 | +and add a `fine-grained PAT <https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens>`_ |
| 82 | +with permissions ``contents: read & write`` and ``metadata: read only``, |
| 83 | +then record that in pysindy's github secrets. |
| 84 | +Alternatively, you could trigger your builds based upon cron timing. |
| 85 | + |
| 86 | +Updates to an example are not automitcally used in the pysindy doc build. |
| 87 | +To update an example, you need to change the commit information |
| 88 | +in ``examples/external.yml``. |
| 89 | + |
| 90 | +Contritubing documentation |
| 91 | +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 92 | + |
| 93 | +We of course love documentation improvements! |
| 94 | +Begin by opening an issue; |
| 95 | +sometimes the problem is that the documentation is correct, but the code has a bug. |
| 96 | +Other times, the documentation is merely out of date. |
| 97 | +We attempt to follow the `divio format`_ of |
| 98 | +tutorials, how-to, reference, and explanation. |
| 99 | +We also have a section for research paper examples as a very specific form of how-to. |
| 100 | + |
| 101 | +When making a documentation PR, it helps to pass CI if you build the check that the |
| 102 | +documentation builds locally first. |
| 103 | +See `Building docs`_ |
| 104 | + |
| 105 | + |
| 106 | +.. _divio format: https://docs.divio.com/documentation-system/ |
| 107 | + |
| 108 | +Contributing code |
| 109 | +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 110 | +Similar to other open-source projects, most contributions start with a github issue |
| 111 | +in order to solicit concurrence from project maintainers. |
| 112 | +Then, the general process is: |
| 113 | +1. Fork the repository |
| 114 | +1. Step through the `Set up development environment`_. |
| 115 | +1. Hack Hack Hack according to `Coding Guidelines`_. |
| 116 | +1. Open a pull request |
| 117 | +1. Respond to reviews |
| 118 | + |
| 119 | +A good place to get started learning this process is to follow one of the issues labeled |
| 120 | +`good first issue`_. |
| 121 | + |
| 122 | +.. _good first issue: https://github.com/dynamicslab/pysindy/issues?q=is%3Aissue%20state%3Aopen%20label%3A%22good%20first%20issue%22 |
| 123 | + |
| 124 | +Development process |
| 125 | +-------------------------------- |
| 126 | + |
| 127 | +Set up development environment |
| 128 | +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 129 | +Clone the repo, then create a project isolation in your environment manager of choice |
| 130 | +(e.g. venv, conda, virtualenv). |
| 131 | +Install the project in an editable way with all optional dependencies, e.g. |
| 132 | + |
| 133 | +.. code-block:: bash |
| 134 | +
|
| 135 | + pip install -e .[dev,miosr,cvxpy,docs,sbr] |
| 136 | +
|
| 137 | +This will allow you to run unit tests and automatically format your code. |
| 138 | +To be accepted your code should conform to PEP8 and pass all unit tests. |
| 139 | +Code can be tested by invoking |
| 140 | + |
| 141 | +.. code-block:: bash |
| 142 | +
|
| 143 | + pytest |
| 144 | +
|
| 145 | +We recommend using ``pre-commit`` to format your code. The easiest approach is to install pre-commit via |
| 146 | + |
| 147 | +.. code-block:: bash |
| 148 | +
|
| 149 | + pre-commit install |
| 150 | +
|
| 151 | +After which pre-commit will automatically check all future commits. |
| 152 | + |
| 153 | + |
| 154 | + |
| 155 | +Coding Guidelines |
| 156 | +^^^^^^^^^^^^^^^^^^^^ |
| 157 | + |
| 158 | +Hack away, following PEP 484, PEP 8, and other relevant guidelines. |
| 159 | +Automated tooling (``pre-commit``) will hopefully keep you on track here. |
| 160 | + |
| 161 | +Stage your changes with: |
| 162 | + |
| 163 | +.. code-block:: bash |
| 164 | +
|
| 165 | + git add path/to/changed/file.py |
| 166 | +
|
| 167 | +Pre-commit will then automatically run all checks against your committed code. If you want to trigger this manually, you can run the following to automatically reformat your staged code |
| 168 | + |
| 169 | +.. code-block:: bash |
| 170 | +
|
| 171 | + pre-commit |
| 172 | +
|
| 173 | +Note that you will then need to re-stage any changes ``pre-commit`` made to your code. |
| 174 | + |
| 175 | +Make sure to write useful commit messages. |
| 176 | +Consider that developers years from now will use ``git log -S`` and ``git blame`` |
| 177 | +to discover when certain changes took place and unearth why you made |
| 178 | +the choices you did. |
| 179 | + |
| 180 | +For good guidance on commit messages, see `what makes a good git commit`_ or |
| 181 | +`conventional commits`_. TL;DR: Subjects in imperative tense, less than 72 characters. |
| 182 | +If necessary, body describes why the change was made, e.g. previous behavior, |
| 183 | +spooky action at a distance. If the commit resolves |
| 184 | +a github issue, use github's automatic issue-\ `closing words`_. |
| 185 | +Lines in the commit body should not exceed 80 characters. |
| 186 | + |
| 187 | +.. _conventional commits: https://www.conventionalcommits.org/en/v1.0.0/ |
| 188 | +.. _what makes a good git commit: https://www.simplethread.com/what-makes-a-good-git-commit/ |
| 189 | +.. _closing words: https://docs.github.com/en/issues/tracking-your-work-with-issues/using-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword |
| 190 | + |
| 191 | +Building docs |
| 192 | +^^^^^^^^^^^^^^^^^^ |
| 193 | +With all optional dependencies installed, run: |
| 194 | + |
| 195 | +.. code-block:: bash |
| 196 | +
|
| 197 | + python -m sphinx -TEWb html -d _build/doctrees -D language=en docs docs/_build |
| 198 | +
|
| 199 | +Or check the build step in the most recent CI run or [RTD build](https://readthedocs.org/projects/pysindy/builds/). |
| 200 | + |
| 201 | +Desired changes |
| 202 | +----------------------- |
| 203 | + |
| 204 | +There are a number of SINDy variants and advanced functionality that would be great to implement in future releases: |
| 205 | + |
| 206 | +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). |
| 207 | + |
| 208 | +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). |
| 209 | + |
| 210 | +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. |
| 211 | + |
| 212 | +4. Integration of PySINDy with a Python model-predictive control (MPC) code. |
| 213 | + |
| 214 | +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. |
| 215 | + |
| 216 | +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). |
0 commit comments