Как отличить, если Python или Matlab ошибочны / неисправны? - PullRequest
1 голос
/ 07 июня 2019

Я пытаюсь использовать SVD и собственную декомпозицию для анализа некоторых данных с использованием декомпозиции в динамическом режиме. Я сталкиваюсь с простой проблемой получения разных результатов от Matlab и Python. Я запутался и не знаю, почему Python дает мне неправильные результаты / значения матрицы, но все выглядит (я думаю, что это) правильно.

Таким образом, вместо использования реальных данных на этот раз и просмотра больших наборов данных, я генерировал данные. Я постараюсь посмотреть на график собственных значений после собственного разложения. Я также использую вложение задержки для данных, потому что я буду работать с вектором данных, который является только (2x100), поэтому я буду выполнять тип матрицы Ханкеля для обогащения данных с 10 задержками.

clear all; close all; clc;
data = linspace(1,100);
data2 = linspace(2,101);
data = [data;data2];
numDelays = 10;
relTol= 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);
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);
Atil = (U'*Y)*V*(S^-1);
[what,lambda] = eig(Atil);
Phi = (Y*V)*(S^-1)*what;

Keigs = diag(lambda);
tt = linspace(0,2*pi,101);
figure;
plot(real(Keigs),imag(Keigs),'ro')
hold on
plot(cos(tt),sin(tt),'--')
import scipy.io as sc
import math as m
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import sys
from numpy import dot, multiply, diag, power, pi, exp, sin, cos, cosh, tanh, real, imag
from scipy.linalg import expm, sinm, cosm, fractional_matrix_power, svd, eig, inv


def dmd(X, Y, relTol):
    U2,Sig2,Vh2 = svd(X, False) # SVD of input matrix
    S = np.zeros((Sig2.shape[0], Sig2.shape[0]))  # Create S matrix with zeros based on Diag of S
    np.fill_diagonal(S, Sig2)  # Fill diagonal of S matrix with the nonzero values
    r = np.count_nonzero(np.diag(S) > S[0,0] * relTol) # rank truncation
    U = U2[:,:r]
    Sig = diag(Sig2)[:r,:r]     #GOOD =)
    V = Vh2.conj().T[:,:r]
    Atil = dot(dot(dot(U.conj().T, Y), V), inv(Sig)) # build A tilde
    print(Atil)
    mu,W = eig(Atil)
    Phi = dot(dot(dot(Y, V), inv(Sig)), W) # build DMD modes
    return mu, Phi

data = np.array([(np.linspace(1,100,100)),(np.linspace(2,101,100))])
Data = np.array(data)
#########           Choose number of Delays         ###########
# observable (coordinates of feature points). Setting to zero means only
# experimental observables will be used.
numDelays = 10
relTol = 10**-6
##########      Create Data Matrices for DMD        ###############
# Create first and second snap shot matrices for DMD. Any columns with missing
# data are not used.
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)]
Keigs, Phi = dmd(X, Y, relTol)

tt = np.linspace(0,2*np.pi,101)
plt.figure()
plt.plot(np.cos(tt),np.sin(tt),'--')
plt.plot(Keigs.real,Keigs.imag,'ro')
plt.title('DMD Eigenvalues')
plt.xlabel(r'Real $\ lambda$')
plt.ylabel(r'Imaginary $\ lambda$')
# plt.axes().set_aspect('equal')
plt.show()

Итак, в matlab и python я получаю свои собственные значения для всех, сидящих на круге единицы (как и ожидалось), и получаю ровно одно, сидя на 1.

Так что проблема возникает, когда я смотрю на матрицы из SVD, они, кажется, имеют разные значения. Единственная одинаковая матрица - это матрица S или Sig. Остальные будут отличаться числом или знаком +/-. Самое большое, что вызвало у меня интерес - это матрица Атиля. В Matlab это выглядит так, [1,0157, -0,3116; 7,91229e-4, 0,9843] И Python выглядит так, [1.0, -4.508e-15; -4,439e-18, 1,0]

Теперь это может немного выглядеть из-за числовой ошибки, возможно, но когда я смотрю на реальные данные, и они отличаются, это портит мой анализ.

1 Ответ

2 голосов
/ 07 июня 2019

SVD неквадратной матрицы не является уникальным в U и V. Даже если у вас есть квадратная матрица с ненулевыми невырожденными сингулярными значениями, сингулярные векторы в U и V уникальны только с точностью до знакового фактора,https://math.stackexchange.com/questions/644327/how-unique-on-non-unique-are-u-and-v-in-singular-value-decomposition-svd

Более того, Matlab (LAPACK + BLAS) и scipy.linalg.svd могут использовать разные алгоритмы для SVD.Это может привести к различиям, которые вы испытали.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...