0
votes

I'm trying to calculate eigenvalues and eigenvectors of a 3x3 hermitian matrix (named coh). Here is the matlab code I'm using,


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

I use eig() function in matlab in documentaion it says "When A is real and symmetric or complex Hermitian, the values of e that satisfy Av = λv are real."

To compare the results with python, I used 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)

The result of eigenvalues and eigen vectors in python are,

%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)

There is a significant difference between matlab "eig()" and python "np.linalg.eigh()". I think it is not a normalization problem. Because, when I use the same functions with a symmetric matrix (not hermitian - real valued), the results are exactly the same.

Additional Comment

When I check whether coh matrix (original input as given above) is hermitian or not, matlab returns logical 0.

ishermitian(coh)
ans =
  logical
   0

But, when I round the input matrix by 16, matlab returns logical 1. *Higher rounding value from 16 returns logical 0.

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

Even if I get real valued eigenvalues with rounded input matrix, eigenvectors are still different from 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
Does your matrix have a repeated eigenvalue?Simon Crane
Please provide some code that includes an example of the matrix you're seeing the problems with.Nico Schlömer
If the duplicate doesn't explain your problem, please edit your question to include the matrix, the code, and the outputs for the two programs.Cris Luengo
@CrisLuengo, I edited my question. It in not a duplicated and not explain my problem.Mehmet Furkan ÇELİK

1 Answers

0
votes

If you write imag(D), you'll see that the imaginary component of the eigenvalues are in the order of 1e-18. That is within rounding error of 0 (when compared to the magnitude of the eigenvalues). But because MATLAB doesn't know the eigenvalues are supposed to be real-valued, it gives them to you as complex numbers.

If you know the eigenvalues are supposed to be real-valued, simply take their real part:

D = real(D);

Regarding the edited question:

The matrix coh is almost Hermitian, but not exactly. You can check for example this way:

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

This returns 1.9e-15. This is an order of magnitude larger than eps, which is the reason that MATLAB does not consider it Hermitian.

The matrix entered in the Python code is slightly different. If I copy those values to MATLAB, I see this:

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, [])))

This code returns 0. Also ishermitian(coh2) returns true.

Finally, comparing the eigenvalues of coh and coh2, we find a difference of the order of magnitude 1e-8:

flip(real(eig(coh))) - eig(coh2) % `flip` fixes the ordering difference
ans =
   1.0e-08 *
   0.085548579158157
   0.539922194800480
  -0.238091968363108