I am using DSYEV and DSYEVD from the LAPACK library to find eigenvalues and eigenvectors (Compilation syntax: gfortran -llapack ). However, I find wrong eigenvalues (-0.44,0.35,0.88
) for a particular matrix. What's going wrong?
One can easily see the matrix has zero determinant, so at least one eigenvalue must be zero.
Here is my code (hope it's not too big):
Program Real_Eigenvec
implicit none
integer, parameter:: n=3
integer:: i,j, flag
real*8:: A(n,n),X(n,n)
real*8:: lambda(n)
real*8, parameter:: p=0.5d0/dsqrt(2.d0), q=1.d0-1.d0/dsqrt(2.d0)
Print*,'Enter flag: 0 for DSYEV, 1 for DSYEVD'
Read*, flag
A= transpose(reshape((/ 0.d0, 1.d0, 0.d0, p, q, p, 0.5d0, 0.0d0, 0.5d0 /), shape(A)))
print*,'Dimension of the matrix, n=',int(sqrt(float(size(A))))
Print*,'A matrix in full form:'
Do i=1,n
print 100, (A(i,j),j=1,n)
End Do
call Eigen(A,lambda,X,n,flag)
! Print the eigenvalues and eigenvectors.
PRINT 200
DO i = 1, n
PRINT 201, lambda(i), (X(i,j), j=1,n)
END DO
100 FORMAT (1X,10(:2X,F10.2))
200 FORMAT (/1X, 'Eigenvalue', 16X, 'Eigenvector^T')
201 FORMAT (1X, F10.2,4X,6(:f10.2))
End Program Real_Eigenvec
!!! SUBROUTINES -----------------------------------------
Subroutine Eigen(A,lambda,X,n,flag)
implicit none
integer:: i,n,flag
real*8:: A(n,n),Ap(n,n),X(n,n)
real*8:: lambda(n)
real*8, allocatable :: work(:)
integer, allocatable :: iwork(:)
integer:: lwork,liwork,info
print*,'n in Eiegen routine=',n
lwork=3*n-1 ! DSYEV for flag=0
if (flag==1) then ! DSYEVD for flag=1
lwork=1+6*n+2*n**2
end if
liwork=3+5*n
allocate(work(lwork))
allocate(iwork(liwork))
Ap=A
if (flag==0) then
CALL DSYEV ('v', 'l', n, Ap, n, lambda, work, lwork, info)
else
CALL DSYEVD ('V', 'U', n, Ap, n, lambda, work, &
& lwork, iwork, liwork, info)
! For doumentation visit: http://www.netlib.org/lapack/explore-html/d1/da2/dsyevd_8f.html
end if
X=Ap
print*,'info=',info
deallocate(work)
deallocate(iwork)
End Subroutine Eigen
As stated in lapack documentation the DSYEV
can be used for symmetric matrices.
DSYEV computes all eigenvalues and, optionally, eigenvectors of a real symmetric matrix A.
In the example the matrix A
is not symmetric
Dimension of the matrix, n= 3
A matrix in full form:
0.00 1.00 0.00
0.35 0.29 0.35
0.50 0.00 0.50
In this case you should use DGEEV
which is used for unsymmetric matrices
DGEEV computes for an N-by-N real nonsymmetric matrix A, the eigenvalues and, optionally, the left and/or right eigenvectors.
In general use the eigenvalues are complex numbers so you have to provide WR
and WL
. Also, you need to define whether you want left VL
or right VR
eigenvectors.
A * v(j) = lambda(j) * v(j)
u(j)**H * A = lambda(j) * u(j)**H
The definition of the function is:
DGEEV(JOBVL, JOBVR, N, A, LDA, WR, WI, VL, LDVL, VR, LDVR, WORK, LWORK, INFO)
I suggest to use it like
LWORK = 4*N
CALL DGEEV( 'N', 'V', n, A, n, wr, wl, Ap, n, Ap, n, work, lwork, info )
In order to get both left and right eigen vectors use
real*8:: A(n,n),VL(n,n),VR(n,n)
real*8:: wr(n),wl(n)
lwork = 4*N
allocate(work(lwork))
CALL DGEEV( 'V', 'V', n, A, n, wr, wl, VL, n, VR, n, work, lwork, info )
For your matrix the imaginary part of all eigenvalues is zero. So the eigenvalues are (1.00, -0.21, 0.00)
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With