我正在尝试使用lapack的zheevd来对齐复杂的Hermitian矩阵。我写了一个小例子,它不会产生任何编译或运行时错误,但会给出特征值的错误结果......这是代码:
program test
implicit none
INTEGER, PARAMETER :: N=4
INTEGER, PARAMETER :: LDA = N
INTEGER, PARAMETER :: LWMAX = 1000
INTEGER :: INFO, LWORK, LIWORK, LRWORK,i,j
INTEGER :: IWORK( LWMAX )
REAL(8) :: W(N), RWORK( LWMAX )
COMPLEX(16) :: A(LDA, N), WORK(LWMAX), zero
character(len=1) :: job,uplo
! the matrix I want to diagonalize is:
! ( 3.40, 0.00) ( -2.36, -1.93) ( -4.68, 9.55) ( 5.37, -1.23)
! A= ( -2.36, 1.93) ( 6.94, 0.00) ( 8.13, -1.47) ( 2.07, -5.78)
! ( -4.68, -9.55) ( 8.13, 1.47) ( -2.14, 0.00) ( 4.68, 7.44)
! ( 5.37, 1.23) ( 2.07, 5.78) ( 4.68, -7.44) ( -7.42, 0.00)
zero=dcmplx(0.0d0,0.0d0)
A=zero
A(1,1)= dcmplx( 3.40d0, 0.0d0); A(1,2)=dcmplx(-2.36d0, -1.93d0); A(1,3)= dcmplx(-4.68d0,9.55d0)
A(1,4)= dcmplx( 5.37d0, -1.23d0)
A(2,2)= dcmplx( 6.94d0, 0.0d0); A(2,3)=dcmplx( 8.13d0, -1.47d0); A(2,4)= dcmplx( 2.07d0, -5.78d0)
A(3,3)= dcmplx(-2.14d0, 0.0d0); A(3,4)=dcmplx( 4.68d0, 7.44d0); A(4,4)= dcmplx(-7.42d0, 0.0d0)
job='V'; uplo='U'
LWORK= N**2 + 2*N; LRWORK= 2*N**2 + 5*N + 1; LIWORK= 5*N+3
CALL ZHEEVD( job, uplo, N, A, LDA, W, WORK, LWORK, RWORK,LRWORK,IWORK,LIWORK, INFO )
IF( INFO > 0 ) THEN
WRITE(*,*)'The algorithm failed to compute eigenvalues.'
STOP
END IF
print*, 'eigenvalues found'
do i=1,N
print*, W(i)
end do
open(1, file='eigenvectors.dat')
write(1,10) ((A(i,j),j=1,N),i=1,N)
10 format(4(F10.5,2X,F10.5))
end program test
当我运行代码时,我得到的特征值的结果是: -2.8413,0,0,2.8413
而实际特征值为:-21.968,16.3387,6.45946,-0.0501069
我一直看到例行程序的参考指南,看来我的一切都是正确的,所以它应该正常工作,期望它不...有人知道我的代码有什么问题吗?
由于
答案 0 :(得分:1)
我可以看到三个主要问题:
COMPLEX*16
类型翻译为COMPLEX(16)
。那是不对的。您应该使用COMPLEX(8)
。我不知道你的工具链是否实际上有一个扩展的精度复杂类型,但你的代码和LAPACK调用之间可能存在大小不匹配ZHEEVD
定义接口(或将其声明为外部接口)。这将导致编译器猜到隐式接口,并且很可能在代码中传递的参数与LAPACK期望的参数之间存在不一致。特别是考虑到复杂论证中的类型不匹配。我希望这三者的某些组合能够解决问题。