DMD en Python 1D

introduction

La décomposition en mode dynamique (DMD) a été annoncée en 2008 [^ 1] [^ 2]. La DMD est une méthode de décomposition qui combine l'analyse des composantes principales et la transformée de Fourier, et est une méthode qui peut séparer les données en entités dans les directions dimensionnelle et temporelle.

Les articles de commentaire auxquels j'ai fait référence sont ci-dessous.

Les valeurs propres et les vecteurs propres de DMD sont des nombres complexes, et les composantes complexes des valeurs propres représentent la décomposition dans la direction du temps. Cependant, il existe un problème en ce qu'il ne peut pas être bien séparé s'il s'agit d'une onde stationnaire unidimensionnelle. L'explication est dans l'article suivant.

Je ne pense pas que DMD sera utilisé pour les données unidimensionnelles, mais comme le code Python n'a pas été publié, je le décrirai pour référence. Voici quelques exemples qui ne peuvent pas être bien décomposés et d'autres qui le peuvent. Le document de base est Tu 2014 [^ 3], et le code est DMD Book. Il est basé sur le code Matlab de.

environnement

Objectif de démontage

Trouvez la période à partir des données numériques de l'onde sinusoïdale unidimensionnelle. La période est de 1j $ pour les nombres complexes. $ y = \sin(x) $ sin_org.png

Exemple DMD qui ne fonctionne pas

Dans l'exemple qui n'a pas abouti, puisque les données ne sont qu'unidimensionnelles, la valeur propre devient un nombre réel et aucun nombre complexe n'apparaît. Par conséquent, la composante périodique ne peut pas être décomposée.

import numpy as np
import numpy.linalg as LA
import matplotlib.pyplot as plt
%matplotlib inline

t = np.arange(0, 10.01, 0.01)
x = np.sin(t)
dt = t[2] - t[1]

#Matrice de données
X1 = x[:-1]
X2 = x[1:]

#SVD
U,S,Vh = LA.svd(X1[np.newaxis,:],False)
V = Vh.T

#Atilde avec A réduit en dimension par le vecteur singulier gauche
Atilde = np.dot(np.dot(np.dot(U.T, X2[np.newaxis,:]), V), LA.inv(np.diag(S)))

#Trouver la valeur propre et le vecteur propre d'Atilde
Lam, W = LA.eig(Atilde)

print("valeur propre:",Lam)#Lam:1.00025541 est un nombre réel

#Trouver le vecteur propre de A à partir du vecteur propre d'Atilde
Phi = np.dot(np.dot(np.dot(X2[np.newaxis,:], V), LA.inv(np.diag(S))), W)

#Exp discrète à continue(**)de**Cherchant
Omega = np.log(Lam)/dt

#Restaurez la fonction d'origine d'Omega et de Phi.
b = np.dot(LA.pinv(Phi * np.exp(Omega * t)).T, x)
x_dmd = b * Phi * np.exp(Omega * t)

plt.plot(t, x_dmd[0,:])
plt.show()

dmd_no.png

Exemple DMD qui fonctionne

Il est introduit dans Article explicatif, mais les données sont décalées dans le sens du temps. Créez une autre dimension et faites-en des données bidimensionnelles. En faisant cela, un composant complexe apparaît dans la valeur propre, et $ \ sin (x) $ peut être trouvé dans les données numériques. C'est tout.

import numpy as np
import numpy.linalg as LA
import matplotlib.pyplot as plt
%matplotlib inline

t = np.arange(0, 10.01, 0.01)
x = np.sin(t)
dt = t[2] - t[1]

#Matrice de données
#La principale différence est ici. C'est bidimensionnel.
X_aug1 = np.array([x[:-2], x[1:-1]])
X_aug2 = np.array([x[1:-1], x[2:]])

#SVD
U,S,Vh = LA.svd(X_aug1,False)
V = Vh.conj().T

#Atilde avec A réduit en dimension par le vecteur singulier gauche
#U prend un conjugué complexe pour créer une matrice de translocation.
Atilde = np.dot(np.dot(np.dot(U.conj().T, X_aug2), V), LA.inv(np.diag(S)))

#Trouver la valeur propre et le vecteur propre d'Atilde
Lam, W = LA.eig(Atilde)

print("valeur propre:", Lam)#Lam:[0.9995+0.00999983j 0.9995-0.00999983j]Nombre complexe

#Trouver le vecteur propre de A à partir du vecteur propre d'Atilde
Phi = np.dot(np.dot(np.dot(X_aug2, V), LA.inv(np.diag(S))), W)

#Exp discrète à continue(**)de**Cherchant
Omega = np.diag(np.log(Lam)/dt)

print("Omega:", Omega)#Juste au cas où, ce sera 1j

#Restaurez la fonction d'origine d'Omega et de Phi.
#Ce que vous faites est le même que dans 1D, mais le style d'écriture est différent.
b = np.dot(LA.pinv(Phi), X_aug1[:,0])
x_dmd = np.zeros([2,len(t)], dtype='complex')
for i, _t in enumerate(t):
    x_dmd[:,i] = np.dot(np.dot(Phi, np.exp(Omega * _t)), b)

plt.plot(t, x_dmd[0,:].real)
plt.show()

dmd_ok.png

Les références

Recommended Posts

DMD en Python 1D
Une doublure en Python
Fizzbuzz en Python (en une ligne)
Segfo python en une ligne
Quadtree en Python --2
Python en optimisation
CURL en Python
Géocodage en python
SendKeys en Python
CGI Server (1) édition python en une ligne
Méta-analyse en Python
Unittest en Python
Époque en Python
Discord en Python
Allemand en Python
DCI en Python
tri rapide en python
nCr en python
N-Gram en Python
Programmation avec Python
Plink en Python
Constante en Python
Un serveur Web de ligne (avec CGI) en python
FizzBuzz en Python
Sqlite en Python
Étape AIC en Python
Décomposer les arguments de commande en une seule ligne en Python
LINE-Bot [0] en Python
CSV en Python
Assemblage inversé avec Python
Réflexion en Python
[Python] Inversion de valeur booléenne en une ligne
Constante en Python
nCr en Python.
format en python
Scons en Python 3
Puyopuyo en python
python dans virtualenv
PPAP en Python
Quad-tree en Python
Réflexion en Python
Chimie avec Python
Hashable en Python
DirectLiNGAM en Python
LiNGAM en Python
Aplatir en Python
Aplatir en python
Une doublure qui produit quatre-vingt-dix-neuf en Python
Essayez d'implémenter deux piles en Python sur un seul tableau
Une doublure qui rend l'utilisation du cœur du CPU 1 à 100% en Python
Créez un jeu Janken en une seule ligne (python)
Plusieurs graphiques sont affichés dans une seule fenêtre (python)
Celui qui affiche la barre de progression en Python
Exemple pour mettre Python Kivy dans un fichier
Liste triée en Python
AtCoder # 36 quotidien avec Python
Texte de cluster en Python
AtCoder # 2 tous les jours avec Python
Daily AtCoder # 32 en Python