问题
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