我在使用Lapack的子程序DSYGV时遇到了一些问题:
DSYGV( ITYPE, JOBZ, UPLO, N, A, LDA, B, LDB, W, WORK,LWORK, INFO )
这是我想要执行的对角化:
v_mat*x = eig*t_mat*x
这是我的代码的关键部分:
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
我想我理解了本文件中的所有内容:
http://www.netlib.org/lapack/lapack-3.1.1/html/dsygv.f.html
但我不理解LWORK的论点,所以我只是尝试不同的值。
我知道有些事情是错的,因为我知道这个矩阵的特征值和特征向量是什么,我得到了错误的特征值和特征向量,我正在做这么简单的计算,以便理解它的工作方式,然后计算巨大的对角化。
有人看到了什么问题吗?
谢谢
答案 0 :(得分:3)
您发布的代码中缺少一些元素。基本上是WORK,eig,v_mat和t_mat。
的数组声明无论如何,LWORK参数实际上是WORK矢量的大小。即
DOUBLE PRECISION WORK(100)
LWORK=100
Lapack指定为LWORK=3*N-1
的最小值。在您的情况下N=2
。
对于这个例子,我建议使用一个大的工作向量(即100),这样你就不会遇到任何问题。
对于大型矩阵,您应该使用DSYGV
的双重调用。
LWORK=-1
致电,并从WORK(1)
NEW WORK
向量。DSYGV
解决本征问题。示例代码为:
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 )
此外,您需要在INF
来电后检查DSYGV
值。如果它不为零则发生错误。
编辑:修复了源代码
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