I want to compute the eigenvalues and eigenvectors of a matrix. I'm using sgeev
of MKL lapack.
I have this very simple test code:
integer :: i,n, info
real, allocatable:: A(:,:), B(:,:), C(:,:)
real, allocatable:: wr(:), wi(:), vl(:, :), vr(:, :), work(:)
n=3
allocate(vr(n,n), vl(n,n), wr(n), wi(n), work(4*n))
allocate(A(n,n),B(n,n), C(n,n))
A(1,:)=(/-1.0,3.0,-1.0/)
A(2,:)=(/-3.0,5.0,-1.0/)
A(3,:)=(/-3.0,3.0,1.0/)
call sgeev('V','V',n,A,n,wr,wi,vl,n,vr,n,work,size(work,1),info)
print*,info
do i=1,n
print*,i,wr(i),wi(i)
enddo
print*,'vr'
do i=1, n
print*, vr(i,:)
enddo
print*,'vl'
do i=1, n
print*, vl(i,:)
enddo
It gives the right eigenvalues (2, 2, 1
) but the wrong eigenvectors.
I have:
vr
-0.577350259 0.557844639 -0.539340019
-0.577350557 0.704232574 -0.273908198
-0.577349961 0.439164847 0.796295524
vl
-0.688247085 -0.617912114 -0.815013587
0.688247383 0.771166325 0.364909053
-0.229415640 -0.153254643 0.450104564
when vr should be
-1 1 1
0 1 1
3 0 1
What am I doing the wrong way?
Your matrix is degenerate (has two eigenvalues which are the same as one another), so the corresponding eigenvectors can be an arbitrary linear combination of the two degenerate eigenvectors.
Also, the output of sgeev
normalises the eigenvectors, whereas the eigenvectors you have given are not normalised.
The first eigenvalue given is 1
, and the corresponding eigenvector is the first column of vr
, l1=(-0.57..., -0.57..., -0.57...)
. This is proportional to the third eigenvector you have given, (1, 1, 1)
.
The second and third eigenvalues are both 2
. The corresponding eigenvectors are the second and third columns of vr
, l2=(0.55..., 0.70..., 0.43...)
and l3=(-0.53..., -0.27..., 0.79...)
. Taking 0.27...*l2+0.70...*l3
gives (-0.22..., 0, 0.66...)
, proportional to (-1, 0, 3)
, and taking 0.79...*l2-0.43...*l3
gives (0.66..., 0.66..., 0)
, proportional to (1, 1, 0)
.