Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] add HOEDMD #408

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open

[WIP] add HOEDMD #408

wants to merge 10 commits into from

Conversation

jieli-matrix
Copy link

@jieli-matrix jieli-matrix commented May 14, 2023

Description:
Add a new dmd-variant for pyDMD, HOEDMD. Here is the paper link and the Matlab implementation version can be found in jieli-matrix/HOEDMD. We extended HODMD to HOEDMD and designed efficient numerical implementation by solving the Structured Total Least Squares problem. Thus, the implementation of HOEDMD is quite similar to HODMD overall while we need to rewrite the DMDOperator part.

ToDo:

  • add class 'HOEDMD'
  • add class 'HOEDMDOperator'
  • implement non-svd option
  • implement Guassian kernel option
  • add tutorials
  • add tests

Help:
Weiyang Ding and I want to thank PyDMD because it is convenient to compare our method with the existing DMD variants. We hope to add HOEDMD to PyDMD though we have developed HOEDMD in Matlab. Since I am a new developer at PyDMD, please feel free to comment on the bugs and give guidelines. Thanks!

@fandreuz
Copy link
Contributor

Hi @jieli-matrix, thanks a lot for your contribution! Could you please format your code with black ?

pydmd/hoedmd.py Outdated
As a reference consult this work by Weiyang and Jie:
https://doi.org/10.1137/21M1463665
"""
from __future__ import division
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove this import

@jieli-matrix
Copy link
Author

Code format & remove import done. cc: @fAndreuzzi @mtezzele

Copy link
Contributor

@fandreuz fandreuz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @jieli-matrix, I've left some comments. They are mainly related to code style, for instance in PyDMD we try to simplify indexing expressions (you've some quite complex ones) by skipping the trailing : when not needed. Could you please fix all the occurrences in your code?

I'll finish reviewing the PR after you're ready for the next round. Thanks!

pydmd/hoedmd.py Outdated
self._compute_modes(U, V, inprodUV)

else:
raise ValueError("Invalid value for alg_type: {}".format(alg_type))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
raise ValueError("Invalid value for alg_type: {}".format(alg_type))
raise ValueError(f"Invalid value for alg_type: {alg_type}")


:param numpy.ndarray Psi: the time-delay data matrix containing the snapshots x0,..x{n} by column.
:param int d: order in HOEDMD.
:param string alg_type: Algorithm type in HOEDMD. Default is 'stls'.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please document briefly all possible values for alg_type.

pydmd/hoedmd.py Outdated
Comment on lines 69 to 70
Px = P[:-d, :]
Py = P[d:, :]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need the trailing :

Suggested change
Px = P[:-d, :]
Py = P[d:, :]
Px = P[:-d]
Py = P[d:]

pydmd/hoedmd.py Outdated
self._compute_eigenquantities()
U = self.eigenvectors_r
V = self.eigenvectors_l
inprodUV = self.eigenvalues.conj() * ((U.conj() * V).sum(0))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
inprodUV = self.eigenvalues.conj() * ((U.conj() * V).sum(0))
inprodUV = self.eigenvalues.conj() * (U.conj() * V).sum(0)

pydmd/hoedmd.py Outdated
U = self.eigenvectors_r
V = self.eigenvectors_l
inprodUV = self.eigenvalues.conj() * ((U.conj() * V).sum(0))
U = P[m : 2 * m, :].dot(U)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need the trailing :

Suggested change
U = P[m : 2 * m, :].dot(U)
U = P[m : 2 * m].dot(U)

pydmd/hoedmd.py Outdated
Comment on lines 87 to 89
Gxx = np.dot(Psi[:-d, :].T.conj(), Psi[:-d, :])
Gxy = np.dot(Psi[:-d, :].T.conj(), Psi[d:, :])
Gpp = np.dot(Psi[m * d :, :].T.conj(), Psi[m * d :, :])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above:

Suggested change
Gxx = np.dot(Psi[:-d, :].T.conj(), Psi[:-d, :])
Gxy = np.dot(Psi[:-d, :].T.conj(), Psi[d:, :])
Gpp = np.dot(Psi[m * d :, :].T.conj(), Psi[m * d :, :])
Gxx = np.dot(Psi[:-d].T.conj(), Psi[:-d])
Gxy = np.dot(Psi[:-d].T.conj(), Psi[d:])
Gpp = np.dot(Psi[m * d :].T.conj(), Psi[m * d :])

pydmd/hoedmd.py Outdated
Gpp = np.dot(Psi[m * d :, :].T.conj(), Psi[m * d :, :])
sigma, Q = np.linalg.eig(Gxx Gpp)
ind = np.sort(-sigma)
sigma = sigma(ind)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please clarify what this part is doing? Why are you using round brackets to index sigma? Is it running without errors?

pydmd/hoedmd.py Outdated
self._compute_eigenquantities()
U = self.eigenvectors_r
V = self.eigenvectors_l
inprodUV = self.eigenvalues.conj() * ((U.conj() * V).sum(0))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
inprodUV = self.eigenvalues.conj() * ((U.conj() * V).sum(0))
inprodUV = self.eigenvalues.conj() * (U.conj() * V).sum(0)

pydmd/hoedmd.py Outdated
Comment on lines 103 to 104
U = Psi[m : 2 * m, :] * (Q * U)
V = Psi[: m * d, :] * (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
U = Psi[m : 2 * m, :] * (Q * U)
V = Psi[: m * d, :] * (
U = Psi[m : 2 * m] * (Q * U)
V = Psi[: m * d] * (

@mtezzele
Copy link
Contributor

Hi @jieli-matrix, I suggest focusing on the tests as the main priority so we can merge this PR. Later you can add the Guassian kernel option and the tutorial showcasing your method.

@mtezzele
Copy link
Contributor

Hi @jieli-matrix, could you please update us on this PR?

@jieli-matrix
Copy link
Author

jieli-matrix commented Aug 22, 2023

Hi @jieli-matrix, could you please update us on this PR?

Sorry for late response! I will update this PR in this week. cc: @mtezzele

@jieli-matrix
Copy link
Author

I have fixed the trailing occurrences in the code and planned to add tests for stls first in the next round. cc: @fandreuz @mtezzele

@mtezzele
Copy link
Contributor

@jieli-matrix you need to rebase this branch and fix the conflicts (see __init__.py). Since when you first opened this PR a lot of PRs were merged.
Moreover we can't merge this without any tests.

@mtezzele
Copy link
Contributor

@jieli-matrix Do you have any updates on this PR?

@jieli-matrix
Copy link
Author

jieli-matrix commented Oct 17, 2023

Sorry for update. I will add all tests in this week.
I read the tests of edmd and hodmd since hoedmd was a combination of the two methods. It seems that the two tests don't keep the same style.
edmd test
hodmd test
So which one does PyDMD now prefer to?
cc: @mtezzele @fandreuz

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants