Skip to content

Commit 08c5c4d

Browse files
authored
Merge pull request PyDMD#522 from sichinaga/readme-updates
Readme updates
2 parents 3eebf4c + 9521d9c commit 08c5c4d

File tree

10 files changed

+154
-50
lines changed

10 files changed

+154
-50
lines changed

README.md

Lines changed: 73 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,9 @@
4747
## Table of contents
4848
* [Description](#description)
4949
* [Dependencies and installation](#dependencies-and-installation)
50-
* [Examples and Tutorials](#examples-and-tutorials)
51-
* [Using PyDMD](#using-pydmd)
50+
* [Quickstart guide](#quickstart-guide)
5251
* [Awards](#awards)
52+
* [Citing PyDMD](#citing-pydmd)
5353
* [References](#references)
5454
* [Developers and contributors](#developers-and-contributors)
5555
* [Funding](#funding)
@@ -91,44 +91,78 @@ and then install the package in [development mode](https://setuptools.pypa.io/en
9191
### Dependencies
9292
The core features of **PyDMD** depend on `numpy` and `scipy`. In order to use the plotting functionalities you will also need `matplotlib`.
9393

94-
## Examples and Tutorials
95-
You can find useful tutorials on how to use the package in the [tutorials](tutorials/README.md) folder.
94+
## Quickstart Guide
95+
To perform DMD, simply begin by initializing a PyDMD module that implements your DMD method of choice. Models may then be fitted by calling the `fit()` method and passing in the necessary data. This step performs the DMD algorithm, after which users may use PyDMD plotting tools in order to visualize their results.
9696

97-
Here we show a simple application (taken from [tutorial 2](tutorials/tutorial2/tutorial-2-adv-dmd.ipynb)): we collect few snapshots from a toy system with some noise and reconstruct the entire system evolution.
98-
<p align="center">
99-
<img src="readme/dmd-example.png" alt>
100-
<em>The original snapshots used as input for the dynamic mode decomposition</em>
101-
</p>
97+
```python3
98+
from pydmd import DMD
99+
from pydmd.plotter import plot_summary
102100

103-
<p align="center">
104-
<img src="readme/dmd-example.gif" alt></br>
105-
<em>The system evolution reconstructed with dynamic mode decomposition</em>
106-
</p>
101+
# Build an exact DMD model with 12 spatiotemporal modes.
102+
dmd = DMD(svd_rank=12)
103+
104+
# Fit the DMD model.
105+
# X = (n, m) numpy array of time-varying snapshot data.
106+
dmd.fit(X)
107+
108+
# Plot a summary of the key spatiotemporal modes.
109+
plot_summary(dmd)
110+
```
111+
112+
PyDMD modules can also be wrapped with data preprocessors if desired. These wrappers will preprocess the data and postprocess data reconstructions automatically.
113+
```python3
114+
from pydmd import DMD
115+
from pydmd.preprocessing import zero_mean_preprocessing
116+
117+
# Build and fit an exact DMD model with data centering.
118+
centered_dmd = zero_mean_preprocessing(DMD(svd_rank=12))
119+
centered_dmd.fit(X)
120+
```
107121

108-
## Using PyDMD
109-
To perform DMD, simply begin by initializing a PyDMD module that implements your DMD method of choice. Here, we demonstrate how a user might build a customized BOP-DMD model. Models may then be fitted by calling the `fit()` method and passing in the necessary data. This step performs the DMD algorithm, after which users may use PyDMD plotting tools in order to visualize their results.
122+
Users may also build highly complex DMD models with PyDMD. Below is an example of how one might build and fit a customized Optimized DMD model with bagging, eigenvalue constraints, and custom variable projection arguments.
110123
```python3
111124
from pydmd import BOPDMD
112-
from pydmd.plotter import plot_summary
113125

114-
# Build a bagging, optimized DMD (BOP-DMD) model.
115-
dmd = BOPDMD(
116-
svd_rank=15, # rank of the DMD fit
117-
num_trials=100, # number of bagging trials to perform
118-
trial_size=0.5, # use 50% of the total number of snapshots per trial
119-
eig_constraints={"imag", "conjugate_pairs"}, # constrain the eigenvalue structure
120-
varpro_opts_dict={"tol":0.2, "verbose":True}, # set variable projection parameters
126+
# Build a Bagging, Optimized DMD (BOP-DMD) model.
127+
# For Optimized DMD (without bagging), use BOPDMD(svd_rank=12, num_trials=0).
128+
bopdmd = BOPDMD(
129+
svd_rank=12, # Rank of the DMD fit.
130+
num_trials=100, # Number of bagging trials to perform.
131+
trial_size=0.5, # Use 50% of the total number of snapshots per trial.
132+
eig_constraints={"imag", "conjugate_pairs"}, # Eigenvalues must be imaginary and conjugate pairs.
133+
varpro_opts_dict={"tol":0.2, "verbose":True}, # Set convergence tolerance and use verbose updates.
121134
)
122135

123-
# Fit the DMD model.
136+
# Fit the BOP-DMD model.
124137
# X = (n, m) numpy array of time-varying snapshot data
125138
# t = (m,) numpy array of times of data collection
126-
dmd.fit(X, t)
139+
bopdmd.fit(X, t)
140+
```
127141

128-
# Display a summary of the DMD results.
129-
plot_summary(dmd)
142+
PyDMD modules and functions may be parameterized by a variety of inputs for added customization, so we generally recommend that new users refer to our [documentation](https://pydmd.github.io/PyDMD/code.html), as well as to our module-specific [tutorials](tutorials/README.md) for more examples and information.
143+
144+
Also provided below is an example call to the `plot_summary()` function when given a DMD model fitted to mean-centered flow past a cylinder data available at <ins>dmdbook.com/DATA.zip</ins>. A rank-12 exact DMD model was used to generate this figure. Eigenvalues, modes, and dynamics are color-coded to indicate associations. Eigenvalue marker sizes also indicate spatiotemporal mode amplitudes or importance.
145+
146+
Plotting tool documentation can be found [here](https://pydmd.github.io/PyDMD/plotter.html).
147+
```python3
148+
from pydmd.plotter import plot_summary
149+
150+
plot_summary(
151+
dmd, # <-- Fitted PyDMD model. Can be DMD, BOPDMD, etc.
152+
figsize=(12, 7),
153+
index_modes=(0, 2, 4),
154+
snapshots_shape=(449, 199),
155+
order="F",
156+
mode_cmap="seismic",
157+
dynamics_color="k",
158+
flip_continuous_axes=True,
159+
max_sval_plot=30,
160+
)
130161
```
131-
Note that modules and functions may be parameterized by a variety of inputs for added customization, so we generally recommend that new users refer to module documentation, plotting tool documentation, and to our module-specific [tutorials](tutorials/README.md) for more information.
162+
<p align="center">
163+
<img src="readme/summary-example.png" alt></br>
164+
<em>Sample output of the plot_summary function.</em>
165+
</p>
132166

133167
For users who are unsure of which DMD method is best for them, we provide the following flow chart, which outlines how one might choose an appropriate DMD variant based on specific problem types or data sets.
134168

@@ -140,12 +174,19 @@ For users who are unsure of which DMD method is best for them, we provide the fo
140174

141175
First prize winner in **DSWeb 2019 Contest** _Tutorials on Dynamical Systems Software_ (Junior Faculty Category). You can read the winner tutorial (PDF format) in the [tutorials](tutorials/tutorial_dsweb.pdf) folder.
142176

177+
## Citing PyDMD
178+
When citing PyDMD, please cite both of the following references:
179+
* Demo, Tezzele, Rozza. *PyDMD: Python Dynamic Mode Decomposition*. Journal of Open Source Software, 2018. [[DOI](https://doi.org/10.21105/joss.00530)][[bibitem](readme/refs/Demo2018)]
180+
* Ichinaga, Andreuzzi, Demo, Tezzele, Lapo, Rozza, Brunton, Kutz. *PyDMD: A Python package for robust dynamic mode decomposition*. arXiv preprint, 2024. [[arXiv](https://doi.org/10.48550/arXiv.2402.07463)]
181+
143182
## References
144183
To implement the various versions of the DMD algorithm we follow these works:
145184

146185
### General DMD References
147186
* Kutz, Brunton, Brunton, Proctor. *Dynamic Mode Decomposition: Data-Driven Modeling of Complex Systems*. SIAM Other Titles in Applied Mathematics, 2016. [[DOI](https://doi.org/10.1137/1.9781611974508)] [[bibitem](readme/refs/Kutz2016_1.bib)].
148-
* Brunton, Budišić, Kaiser, Kutz. *Modern Koopman Theory for Dynamical Systems*. SIAM Review, 2022. [[DOI](https://doi.org/10.1137/21M1401243)] [[bibitem](readme/refs/Brunton2022.bib)].
187+
* Schmid. *Dynamic mode decomposition of numerical and experimental data*. Journal of Fluid Mechanics, 2010. [[DOI](https://doi.org/10.1017/S0022112010001217)][[bibitem](readme/refs/Schmid2010)]
188+
* Tu, Rowley, Luchtenburg, Brunton, Kutz. *On Dynamic Mode Decomposition: Theory and Applications*. Journal of Computational Dynamics, 2014. [[DOI](https://doi.org/10.3934/jcd.2014.1.391)][[bibitem](readme/refs/Tu2014.bib)]
189+
* Schmid. *Dynamic mode decomposition and its variants*. Annual Review of Fluid Mechanics, 2022. [[DOI](https://doi.org/10.1146/annurev-fluid-030121-015835)][[bibitem](readme/refs/Schmid2022)]
149190

150191
### DMD Variants: Noise-robust Methods
151192
* **Forward-backward DMD:** Dawson, Hemati, Williams, Rowley. *Characterizing and correcting for the effect of sensor noise in the dynamic mode decomposition*. Experiments in Fluids, 2016. [[DOI](https://doi.org/10.1007/s00348-016-2127-7)] [[bibitem](readme/refs/Dawson2016.bib)].
@@ -167,11 +208,11 @@ To implement the various versions of the DMD algorithm we follow these works:
167208
* **Parametric DMD:** Andreuzzi, Demo, Rozza. *A dynamic mode decomposition extension for the forecasting of parametric dynamical systems*. SIAM Journal on Applied Dynamical Systems, 2023. [[DOI](https://doi.org/10.1137/22M1481658)] [[bibitem](readme/refs/Andreuzzi2021.bib)].
168209
* **Extended DMD:** Williams, Rowley, Kevrekidis. *A kernel-based method for data-driven koopman spectral analysis*. Journal of Computational Dynamics, 2015. [[DOI](https://doi.org/10.3934/jcd.2015005)] [[bibitem](readme/refs/Williams2015.bib)].
169210
* **LANDO:** Baddoo, Herrmann, McKeon, Brunton. *Kernel learning for robust dynamic mode decomposition: linear and nonlinear disambiguation optimization*. Proceedings of the Royal Society A, 2022. [[DOI](https://doi.org/10.1098/rspa.2021.0830)] [[bibitem](readme/refs/Baddoo2022.bib)].
211+
* **DMD with Centering:** Hirsh, Harris, Kutz, Brunton. *Centering data improves the dynamic mode decomposition*. SIAM Journal on Applied Dynamical Systems, 2020. [[DOI](https://doi.org/10.1137/19M1289881)] [[bibitem](readme/refs/Hirsh2020.bib)]
170212

171-
### Implementation Tools and Preprocessing
213+
### General Implementation Tools
172214
* Gavish, Donoho. *The optimal hard threshold for singular values is 4/sqrt(3)*. IEEE Transactions on Information Theory, 2014. [[DOI](https://doi.org/10.1109/TIT.2014.2323359)] [[bibitem](readme/refs/Gavish2014.bib)].
173215
* Matsumoto, Indinger. *On-the-fly algorithm for dynamic mode decomposition using incremental singular value decomposition and total least squares*. 2017. [[arXiv](https://arxiv.org/abs/1703.11004)] [[bibitem](readme/refs/Matsumoto2017.bib)].
174-
* Hirsh, Harris, Kutz, Brunton. *Centering data improves the dynamic mode decomposition*. SIAM Journal on Applied Dynamical Systems, 2020. [[DOI](https://doi.org/10.1137/19M1289881)] [[bibitem](readme/refs/Hirsh2020.bib)]
175216

176217
### Recent works using PyDMD
177218
You can find a list of the scientific works using **PyDMD** [here](https://scholar.google.com/scholar?oi=bibs&hl=en&cites=5544023489671534143).
@@ -214,4 +255,4 @@ Beyond this, PyDMD has also been supported by some dedicated projects that have
214255
<a href="https://numfocus.org/sponsored-projects/affiliated-projects">
215256
<img src="readme/numfocus-affiliated-project.png" width="300" />
216257
</a>
217-
</p>
258+
</p>

readme/pydmd_capabilities.svg

Lines changed: 1 addition & 1 deletion
Loading

readme/refs/Brunton2022.bib

Lines changed: 0 additions & 12 deletions
This file was deleted.

readme/refs/Demo2018.bib

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
@article{Demo2018,
2+
author = {Nicola Demo and Marco Tezzele and Gianluigi Rozza},
3+
title = {{P}y{DMD}: {P}ython Dynamic Mode Decomposition},
4+
journal = {Journal of Open Source Software},
5+
year = {2018},
6+
publisher = {The Open Journal},
7+
volume = {3},
8+
number = {22},
9+
pages = {530},
10+
doi = {10.21105/joss.00530},
11+
url = {https://doi.org/10.21105/joss.00530},
12+
}

readme/refs/Schmid2010.bib

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
@article{Schmid2010,
2+
author = {Peter J. Schmid},
3+
title = {Dynamic mode decomposition of numerical and experimental data},
4+
volume = {656},
5+
pages = {5-28},
6+
journal = {Journal of Fluid Mechanics},
7+
publisher = {Cambridge University Press},
8+
year = {2010},
9+
doi = {10.1017/S0022112010001217},
10+
url = {https://doi.org/10.1017/S0022112010001217},
11+
}

readme/refs/Schmid2022.bib

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
@article{Schmid2022,
2+
author = {Schmid, Peter J},
3+
journal = {Annual Review of Fluid Mechanics},
4+
pages = {225--254},
5+
title = {Dynamic mode decomposition and its variants},
6+
volume = {54},
7+
year = {2022},
8+
doi = {10.1146/annurev-fluid-030121-015835},
9+
url = {https://doi.org/10.1146/annurev-fluid-030121-015835},
10+
}

readme/refs/Tu2014.bib

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
@article{Tu2014,
2+
author = {Jonathan H. Tu and Clarence W. Rowley and Dirk M. Luchtenburg and Steven L. Brunton and J. N. Kutz},
3+
title = {On Dynamic Mode Decomposition: Theory and Applications},
4+
year = {2014},
5+
pages = {391-421},
6+
volume = {1},
7+
journal = {Journal of Computational Dynamics},
8+
doi = {10.3934/jcd.2014.1.391},
9+
url = {https://doi.org/10.3934/jcd.2014.1.391},
10+
}

readme/summary-example.png

341 KB
Loading
161 KB
Loading

tutorials/developers-tutorial1/developers-help-1.ipynb

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,47 @@
2323
"In this tutorial we will indeed create from scratch a new version of the original DMD; such extension will be totally useless from a scientific perspective, the only purpose is showing the suggested steps to implement new variants inside **PyDMD**."
2424
]
2525
},
26+
{
27+
"cell_type": "markdown",
28+
"metadata": {},
29+
"source": [
30+
"## The Back-end API"
31+
]
32+
},
2633
{
2734
"cell_type": "markdown",
2835
"metadata": {},
2936
"source": [
3037
"The necessary bricks for building the new DMD version are:\n",
3138
"\n",
32-
"- [`DMDBase`](https://mathlab.github.io/PyDMD/dmdbase.html), the actual backbone of all the different implemented versions;\n",
33-
"- `DMDTimeDict`, the class that manages the time window;\n",
34-
"- `DMDOperator`, the class that manages the so-called DMD operator;\n",
39+
"- [`DMDBase`](https://pydmd.github.io/PyDMD/dmdbase.html), the actual backbone of all the different implemented versions;\n",
40+
"- [`DMDTimeDict`](https://github.com/PyDMD/PyDMD/blob/7ac9f3fa855e9a5e7008daad9906eaa6e59ba80a/pydmd/dmdbase.py#L759), the class that manages the time window;\n",
41+
"- [`DMDOperator`](https://pydmd.github.io/PyDMD/dmdoperator.html), the class that manages the so-called DMD operator;\n",
42+
"\n",
43+
"The following schematic outlines the general structure of every `DMDBase` module.\n",
44+
"![](PyDMD-structure.png)\n",
45+
"In general, all `PyDMD` modules should be capable of the following tasks:\n",
46+
"1) Accepting and storing DMD algorithm parameters.\n",
47+
"2) Performing DMD given snapshot data $\\mathbf{X}$ via the `fit` method, which often does the following:\n",
48+
" - prepares and stores the input data,\n",
49+
" - sets the `DMDTimeDict`s,\n",
50+
" - computes the DMD operator and its eigendecomposition, and\n",
51+
" - (this is done by invoking the `DMDOperator`'s `compute_operator` function)\n",
52+
" - computes the DMD amplitudes using the computed operator.\n",
53+
"3) Fetching and utilizing DMD results, such as:\n",
54+
" - the reduced DMD operator $\\tilde{\\mathbf{A}}$\n",
55+
" - the spatial modes $\\mathbf{\\Phi}$ (the eigenvectors of $\\mathbf{A}$)\n",
56+
" - the temporal frequencies $\\mathbf{\\Lambda}$ (the eigenvalues of $\\mathbf{A}$)\n",
57+
" - the spatiotemporal mode amplitudes $\\mathbf{b}$\n",
58+
"\n",
59+
"Hence different modules implement different DMD variants, where any number of these steps may be performed differently."
60+
]
61+
},
62+
{
63+
"cell_type": "markdown",
64+
"metadata": {},
65+
"source": [
66+
"## Building a New PyDMD Module\n",
3567
"\n",
3668
"We start the new module by importing all these classes and the usual math environment (`matplotlib`+`numpy`)."
3769
]
@@ -393,9 +425,9 @@
393425
"name": "python",
394426
"nbconvert_exporter": "python",
395427
"pygments_lexer": "ipython3",
396-
"version": "3.9.6"
428+
"version": "3.11.5"
397429
}
398430
},
399431
"nbformat": 4,
400-
"nbformat_minor": 2
432+
"nbformat_minor": 4
401433
}

0 commit comments

Comments
 (0)