различные собственные векторы одной и той же эрмитовой матрицы в matlab & python - PullRequest
0 голосов
/ 01 октября 2019

Я пытаюсь вычислить собственные значения и собственные векторы эрмитовой матрицы 3x3 (названной coh). Вот код matlab, который я использую,


coh = [0.327064707875252 + 0.00000000000000i    -0.00770057737827301 + 0.0178948268294334i  -0.00368526462214552 - 0.00615056270163515i
-0.00770057737827302 - 0.0178948268294334i  0.0122797042131420 + 0.00000000000000i  -0.000822583499745789 + 0.000295265015599135i
-0.00368526462214553 + 0.00615056270163516i -0.000822583499745789 - 0.000295265015599135i   0.00526291178539395 + 0.00000000000000i];

[V,D]=eig(coh);

V =

   0.9979 + 0.0000i   0.0229 - 0.0580i   0.0141 + 0.0140i
  -0.0243 - 0.0565i   0.9937 + 0.0000i   0.0936 + 0.0093i
  -0.0114 + 0.0192i  -0.0929 + 0.0104i   0.9954 + 0.0000i

% It should be real valued eigenvalue??
D =

   0.3284 - 0.0000i   0.0000 + 0.0000i   0.0000 + 0.0000i
   0.0000 + 0.0000i   0.0111 - 0.0000i   0.0000 + 0.0000i
   0.0000 + 0.0000i   0.0000 + 0.0000i   0.0050 + 0.0000i

Я использую функцию eig () в matlab в документации, где говорится: «Когда A является действительным и симметричным или сложным эрмитовым, значения e, удовлетворяющие Av =λv действительны. "

Чтобы сравнить результаты с python, я использовал np.linalg.eigh ().

import numpy as np
import scipy

coh = np.array([[ 0.32706471+0.j, -0.00770058+0.01789483j,-0.00368526-0.00615056j],
       [-0.00770058-0.01789483j,  0.0122797 +0.j,-0.00082258+0.00029527j],
       [-0.00368526+0.00615056j, -0.00082258-0.00029527j,0.00526291+0.j]])

eigenh = np.linalg.eigh(coh)

Результат собственных значений и собственных векторов в python:

%eigenvalue
0.00504925
0.0111318
0.328426

%eigenvector
 (-0.01992713254631731+0.0j)     (0.0623407637085597+0.0j)   (-0.9978559708538679-0.0j)
 (-0.07298515890572027+0.05929161455059334j)     (0.3655270698873978+0.9239915820830416j)    (0.02429370804648004+0.05654205684315627j)
 (-0.706622215529945+0.7010318287578136j)    (-0.043891589739820214-0.08256315733761976j)    (0.011369094995309527-0.01915767907577206j)

Существует значительное различие между matlab "eig ()" и python "np.linalg.eigh ()». Я думаю, что это не проблема нормализации. Потому что, когда я использую те же функции с симметричной матрицей (не эрмитовой - действительной), результаты в точности совпадают.

Дополнительный комментарий

Когда я проверяю, есть ли матрица Коха (исходный вводкак указано выше) является эрмитовым или нет, matlab возвращает логическое 0.

ishermitian(coh)
ans =
  logical
   0

Но когда я округляю входную матрицу на 16, matlab возвращает логическое 1. * Более высокое значение округления из 16 возвращает логическое 0.

coh2 = round(coh,16)
ishermitian(coh2)
ans =
  logical
   1

Даже если я получу реальные значения собственных значений с закругленной входной матрицей, собственные векторы все равно отличаются от python

[V2,D2]=eig(coh2);
V2 =
   0.0141 + 0.0140i   0.0293 - 0.0550i   0.5093 + 0.8581i
   0.0936 + 0.0093i   0.9874 + 0.1110i   0.0362 - 0.0497i
   0.9954 + 0.0000i  -0.0935 + 0.0000i  -0.0223 + 0.0000i

D2 =
    0.0050         0         0
         0    0.0111         0
         0         0    0.3284

1 Ответ

0 голосов
/ 02 октября 2019

Если вы напишите imag(D), вы увидите, что мнимая составляющая собственных значений имеет порядок 1e-18. Это в пределах погрешности округления 0 (по сравнению с величиной собственных значений). Но поскольку MATLAB не знает, что собственные значения должны быть действительными, он выдает их вам как комплексные числа.

Если вы знаете, что собственные значения должны быть действительными, просто примите их действительную часть:

D = real(D);

По поводу отредактированного вопроса:

Матрица coh почти эрмитова, но не совсем. Вы можете проверить, например, так:

max(abs(reshape((coh - coh')./coh, 1, [])))

Это возвращает 1.9e-15. Это на порядок больше eps, поэтому MATLAB не считает его эрмитовым.

Матрица, введенная в код Python, немного отличается. Если я скопирую эти значения в MATLAB, я увижу следующее:

coh2 = [0.32706471+0.0j, -0.00770058+0.01789483j, -0.00368526-0.00615056j
       -0.00770058-0.01789483j,  0.0122797+0.0j, -0.00082258+0.00029527j
       -0.00368526+0.00615056j, -0.00082258-0.00029527j, 0.00526291+0.0j];
max(abs(reshape((coh2 - coh2')./coh2, 1, [])))

Этот код возвращает 0. Также ishermitian(coh2) возвращает true.

Наконец, сравнивая собственные значения cohи coh2, мы находим разность порядка 1e-8:

flip(real(eig(coh))) - eig(coh2) % `flip` fixes the ordering difference
ans =
   1.0e-08 *
   0.085548579158157
   0.539922194800480
  -0.238091968363108
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...