Scipy.linalg.eig() giving different eigenvectors from GNU Octave's eig()

江枫思渺然 提交于 2019-12-22 12:26:50

问题


I want to compute the eigenvalues for a generalized eigenvalue problem with lambda * M * v = K * v, where lambda is the eigenvalue, v is an eigenvector, and M and K are matrices. Let's say we have

K =

   1.8000 + 0.0000i  -1.0970 + 0.9550i
  -1.0970 - 0.9550i   1.8000 + 0.0000i

M = 

   209     0
     0   209

In Octave, if I do [V,D]=eig(K,M), I get:

V =

   0.53332 - 0.46429i  -0.53332 + 0.46429i
   0.70711 + 0.00000i   0.70711 + 0.00000i

D =

Diagonal Matrix

   0.34555         0
         0   3.25445

However, if I do scipy.linalg.eig(K, b=M) using Scipy in python, I get a different result:

>>> import numpy as np
>>> import scipy as sp
>>> import scipy.linalg
>>> K = np.mat([[1.8, -1.097+0.995j], [-1.097-0.955j, 1.8]])
>>> M = np.mat([[209., 0.], [0., 209.]])
>>> M
matrix([[ 209.,    0.],
        [   0.,  209.]])
>>> K
matrix([[ 1.800+0.j   , -1.097+0.955j],
        [-1.097-0.955j,  1.800+0.j   ]])
>>> D, V = sp.linalg.eig(K, b=M)
>>> D
array([ 0.00165333 -1.99202696e-19j,  0.01557155 +0.00000000e+00j])
>>> V
array([[ 0.70710678 +0.00000000e+00j, -0.53332494 +4.64289256e-01j],
       [ 0.53332494 +4.64289256e-01j,  0.70710678 -8.38231384e-18j]])

The eigenvalues should be the ones in the D array.

Why are the eigenvalues different in these two examples? Am I misunderstanding something?

edit: corrected typo and redid calculation.

edit: I used Octave 3.8.2. in Mac OS X 10.10.3.


回答1:


I think I understand what's going on. Scipy is probably providing the correct eigenvalues. Octave accepts a second matrix in its eig() function but doesn't specify what it does. Matlab's documentation does say it's for a generalized eigenvalue problem, but in Octave adding the second matrix appears to have no affect on the eigenvalues. This looks like a bug in Octave.




回答2:


Out of curiosity, I have tried the same calculation with the eig() routine in Julia. (Here, for clarity, I have used symbols A and B for the generalized eigenvalue problem.)

A = [ 1.8000 + 0.0000im  -1.0970 + 0.9550im ;
     -1.0970 - 0.9550im   1.8000 + 0.0000im ]

B = [  209.0    0.0 ;
         0.0   209.0 ]

D, V = eig( A, B )

err = A * V - B * V * diagm(D)
@show vecnorm( err )

The result seems essentially the same as Scipy.

D = [0.0016533341538531843,0.015571546228921934]

V[:,1] = Complex{Float64}[0.03689085719366286 - 0.03211555936184871im,
                          0.048911598804451846 + 0.0im]
V[:,2] = Complex{Float64}[-0.03689085719366286 + 0.03211555936184871im,
                           0.048911598804451846 + 0.0im]

vecnorm(err) = 3.768784066493578e-17

On the other hand, if I try Octave with a B matrix having off-diagonal elements,

A = [ 1.8000 + 0.0000i  -1.0970 + 0.9550i ;
     -1.0970 - 0.9550i   1.8000 + 0.0000i ]

B = [ 1.0 5.0 ;
      5.0 3.0 ]

[ V, D ] = eig( A, B );

err = A * V - B * V * D ;
printf( "error = %20.10g\n", norm( err ) )

it gives the correct result:

V =
   0.73147 - 0.19955i  -0.96401 - 0.03599i
   0.74058 + 0.25942i   0.72711 - 0.17996i

D =
   Diagonal Matrix
   0.057841 - 0.000000i                      0
   0                     -0.883750 + 0.000000i

error =      1.814738616e-15

If I set B to diag( 209.0, 209.0 ) (as in the original post), Octave gives

V =
    0.53332 - 0.46429i  -0.53332 + 0.46429i
    0.70711 + 0.00000i   0.70711 + 0.00000i

D =
    Diagonal Matrix
    0.34555         0
    0               3.25445

error =          676.9262577

In fact, the above V and D are found to be the solution of a standard eigenvalue problem A V = V D. So it seems that when B is a diagonal matrix, Octave simply neglects it by assuming the unit matrix...

I used Octave3.4.3 (on Linux x86_64) and the result may be different for more recent versions.



来源:https://stackoverflow.com/questions/31327630/scipy-linalg-eig-giving-different-eigenvectors-from-gnu-octaves-eig

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!