我正在尝试进行精确的动态模式分解(参考:https://arxiv.org/pdf/1312.0041.pdf)。我已经在Matlab中完成了代码,它按照我期望的方式工作,但在Python中却没有。我在计算正确的阿蒂德矩阵时遇到问题,这些值不可用,然后当我检查特征值时,它们不是正确的值。
因此,我在SVD之后评估了S,U,V矩阵,它们看起来是正确的,并且与Matlab中的正确矩阵相对应。当我尝试计算Atilde矩阵时,它们处于关闭状态。由于无法使用标准*命令,我尝试使用点和矩阵的乘法计算Atlide矩阵。
import math as m
import numpy as np
from numpy import diag, power, dot, matmul
from scipy.linalg import expm, sinm, cosm, svd, inv, eig, pinv
import matplotlib.pyplot as plt
import pandas as pd
import scipy.io as sc
###########################. Import Data from Excel Sheet. ###################################
df = pd.read_excel('DataDMD.xlsx', header=None) #Insert your own excel file in between '__', if header is desired, delete header=None.
data = df #Make sure the data file will be a numpy array.
###########################. Define Function . ###############################################
def ExactDMD(X,Y,relTol):
# Define Data matrix X and Y
# X = [Do D1 ... Dn-1] & Y = [D1 D2 ... Dn]
# m = data.shape[0] #rows of data matrix
# n = data.shape[1] #columns of data matrix
# X = data[:,:-1] # take X_o to X_n-1
# Y = data[:,1:] # take X_1 to X_n
#Compute SVD of data matrix X
U, Sdiag, Vh = svd(X, False)
S = np.zeros((Sdiag.shape[0], Sdiag.shape[0])) # Create S matrix with zeros based on Diag of S
np.fill_diagonal(S, Sdiag) # Fill diagonal of S matrix with the nonzero values
V = Vh.conj().T # Create V matrix, we are given Vh which is conjugate transpose of V (convert back to V)
r = np.count_nonzero(np.diag(S) > S[0, 0] * relTol) # Find the diminsion of the subspace we are using- truncation
# Apply truncation/ subspace diminsion
U = U[:,:r]
S = S[:r,:r]
V = V[:,:r]
#Create Atilde
##################### PROBLEM
#Atilde = dot(dot(dot(U.T, Y), V),inv(S))
Atilde = matmul(matmul(matmul(U.T,Y),V),inv(S))
print(Atilde[0:5,0:5]) #<- not right
# print(Atilde2[0:4,0:4])
# print(Atilde[0:4,0:4])
#Get Eigenvalues and Vectors from Atilde (eigen pairs)
Evalue, Wvector = eig(Atilde)
print(Evalue[0:5]) #<- not right
##################### PROBLEM
#Koopman Eigenvalues
DEv = Evalue
return DEv
relTol = 10**-6
numDelays = 300
data = data.iloc[0::6, :].values
Data = np.array(data,'float')
X = np.zeros(((numDelays + 1) * data.shape[0], data.shape[1] - (numDelays + 1)))
Y = np.zeros(X.shape)
for i in range(1, numDelays + 2):
X[0 + (i - 1) * Data.shape[0]:i * Data.shape[0], :] = Data[:, (i):Data.shape[1] - (numDelays + 1) + (i - 0)]
Y[0 + (i - 1) * Data.shape[0]:i * Data.shape[0], :] = Data[:, (i + 0):Data.shape[1] - (numDelays + 1) + (i)]
print(X[0:3,0:3])
DEv = ExactDMD(X,Y,relTol)
###########################. Plots . #################################################
real_part = DEv.real
imaginary_part = DEv.imag
plt.figure()
plt.plot(real_part,imaginary_part,'o')
plt.show()
data = data(1:6:end,:);
%% Choose number of delays observables to use for each experimental
% observable (coordinates of feature points). Setting to zero means only
% experimental observables will be used.
numDelays = 300;
retol= 10^-6;
%% Create first and second snap shot matrices for DMD. Any columns with missing
% data are not used.
disp('Constructing Data Matricies:')
X = zeros((numDelays+1)*size(data,1),size(data,2)-(numDelays+1));
Y = zeros(size(X));
for i = 1:numDelays+1
X(1 + (i-1)*size(data,1):i*size(data,1),:) = ...
data(:,(i):size(data,2)-(numDelays+1) + (i-1));
Y(1 + (i-1)*size(data,1):i*size(data,1),:) = ...
data(:,(i+1):size(data,2)-(numDelays+1) + (i));
end
[U,S,V] = svd(X,0);
r = find(diag(S)>S(1,1)*relTol,1,'last');
disp(['DMD subspace dimension:',num2str(r)])
U = U(:,1:r);
S = S(1:r,1:r);
V = V(:,1:r);
%%%%%%%%%%%%%%%%%%%%%% Correct Atilde
Atilde = ((U'*Y)*V)*(S^-1);
Atilde(1:4,1:4)
[W,lambda] = eig(Atilde);
%%%%%% Standard DMD %%%%%
DEv = diag(lambda);
DEv(1:5)
错误仅在于计算Atilde,因为在特征分解之后,我的特征值是错误的。我可以想象问题出在矩阵乘法中,但是我不确定为什么点或matmul命令都不都是错误的。