I am having some problems using the subroutine DSYGV of Lapack:
DSYGV( ITYPE, JOBZ, UPLO, N, A, LDA, B, LDB, W, WORK,LWORK, INFO )
This is the diagonalization I want to carry out:
v_mat*x = eig*t_mat*x
This is the crucial piece of my code:
program pruebadiago
real, dimension(:,:), allocatable :: v_mat, t_mat
real, dimension(:), allocatable :: eig,WORK
real , parameter :: k=3.0,m=4.0
integer, parameter :: n=2
integer :: i
! EXPECTED EIGENVALUES AND EIGENVECTORS
!eig = 0.286475 ------> u = (0.262866 , 0.425325)
!eig = 1.96353 ------> u = (0.425325, -0.262866)
allocate(v_mat(n,n),t_mat(n,n),eig(n))
!--------------------------
v_mat(1,1:2) = (/2.0*k,-k/)
v_mat(2,1:2) = (/-k,k/)
!--------------------------
!--------------------------
t_mat(1,1:2) = (/m,0.0/)
t_mat(2,1:2) = (/0.0,m/)
!---------------------------
!diagonalizacion
call DSYGV( 1, 'v', 'u', n , v_mat, 2 , t_mat, 2, eig, WORK,-1, INF )
LWORK=WORK(1)
allocate(WORK(LWORK))
call DSYGV( 1, 'v', 'u', n , v_mat, 2 , t_mat, 2, eig, WORK,LWORK, INF )
open(unit=100,file="pruebadiago.dat",status="replace",action="write")
do i = 1,n
write(unit=100,fmt=*) "E",i,"=",eig(i),(v_mat(i,j),j=1,n)
!autofuntzioak zutabeka doaz"(100f12.6)"
enddo
close(unit=100)
deallocate(v_mat,t_mat,eig,WORK)
end program pruebadiago
I think I understood everything given in this document:
http://www.netlib.org/lapack/lapack-3.1.1/html/dsygv.f.html
But the argument LWORK which I did not understand so I just try different values.
I know something is wrong because I know what are the eigenvalues and eigenvectors of this matrix and I get wrong eigenvalues and eigenvectors, and I am doing such a simple calculation in order to understand the way it works and then compute huge diagonalizations.
Does anybody see what is the problem?
Thank you
There are missing some elements from the code you posted. Basically the array declarations of WORK,eig,v_mat and t_mat.
Anyway, LWORK argument actually is the size of WORK vector. ie
DOUBLE PRECISION WORK(100)
LWORK=100
Lapack specifies as minimum value of LWORK=3*N-1
. In your case N=2
.
For this example case I would suggested to use a big WORK vector (ie 100) so that you will not encounter any problems from that.
For large matrices you should use double call of DSYGV
.
LWORK=-1
and get suggested size from WORK(1)
NEW WORK
vector with suggested size. DSYGV
. Sample code is:
CALL DSYGV( 1, 'V', 'U', 2 , v_mat, 2 , t_mat, 2, eig, W, -1, INF )
LWORK=W(1)
ALLOCATE ( WORK(LWORK) )
CALL DSYGV( 1, 'V', 'U', 2 , v_mat, 2 , t_mat, 2, eig, WORK, LWORK, INF )
Additionally, you need to check INF
value after DSYGV
call. If it is not zero then an error occurred.
EDIT : Fixed source code
program pruebadiago
double precision, dimension(:,:), allocatable :: v_mat, t_mat
double precision, dimension(:), allocatable :: eig,WORK
double precision :: W
double precision , parameter :: k=3.0,m=4.0
integer, parameter :: n=2
integer :: i
! EXPECTED EIGENVALUES AND EIGENVECTORS
!eig = 0.286475 ------> u = (0.262866 , 0.425325)
!eig = 1.96353 ------> u = (0.425325, -0.262866)
allocate(v_mat(n,n),t_mat(n,n),eig(n))
!--------------------------
v_mat(1,1:2) = (/2.0*k,-k/)
v_mat(2,1:2) = (/-k,k/)
!--------------------------
t_mat(1,1:2) = (/m,0.0d0/)
t_mat(2,1:2) = (/0.0d0,m/)
!---------------------------
call DSYGV( 1, 'v', 'u', n , v_mat, 2 , t_mat, 2, eig, W,-1, INF )
LWORK=W
allocate(WORK(LWORK))
call DSYGV( 1, 'v', 'u', n , v_mat, 2 , t_mat, 2, eig, WORK,LWORK, INF )
open(unit=100,file="pruebadiago.dat",status="replace",action="write")
do i = 1,n
write(unit=100,fmt=*) "E",i,"=",eig(i),(v_mat(i,j),j=1,n)
enddo
close(unit=100)
deallocate(v_mat,t_mat,eig,WORK)
end program pruebadiago
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.