lapack routin zheev 的危险行为
dangerous behavior of lapack routin zheev
我在使用 lapack 例程时偶然发现了一个奇怪的行为 zheev()
。有两个问题我不明白
1) 我的一个全局变量似乎被 zheev()
覆盖了。下面的小程序展示了它:
[用 gfortran -o test test.f90 -llapack -lblas
编译]
program test
implicit none
integer, parameter :: dp = 8
integer, parameter :: dim = 3
integer :: l
real(dp), parameter :: kmin = -0.03_dp
real(dp), parameter :: kmax = 0.03_dp
integer, parameter :: steps = 100
real(dp) :: stepD = (kmax - kmin)/real(steps)
complex(dp) :: matrix(dim,dim)=0.
integer :: info
integer :: rwork=3*dim-2, lwork, lwmax=100
real(dp) :: evals(dim)
complex(dp) :: work(3*dim-2)
lwork=-1
call zheev('N','U',size(matrix,1), matrix, dim, evals, work, lwork, &
rwork, info)
lwork = min( lwmax, int( work(1) ))
do l = 0, 3
write(*,*) stepD
call zheev('N', 'U', size(matrix,1), matrix, dim, evals, work, &
lwork, rwork, info)
write(*,*) stepD
end do
end program test
输出为
5.9999999999999995E-004
0.0000000000000000
0.0000000000000000
0.0000000000000000
0.0000000000000000
0.0000000000000000
0.0000000000000000
0.0000000000000000
这可以通过将 stepD 设置为参数来解决。但我不明白这种行为。越来越奇怪了:
2) 将定义中的 lwork
设置为某个值,如
integer :: rwork=3*dim-2, lwork=10, lwmax=100
(只需将上面对应的行改一下即可)
给出以下结果:
5.9999999999999995E-004
5.9999991208314896E-004
5.9999991208314896E-004
5.9999991208314896E-004
5.9999991208314896E-004
5.9999991208314896E-004
5.9999991208314896E-004
5.9999991208314896E-004
怎么会这样?将 lwork
设置为 10 应该没有任何效果,因为稍后它会设置为 -1。一个重要的概念是:如果删除
lwork=-1
call zheev('N','U',size(matrix,1), matrix, dim, evals, work, lwork, &
rwork, info)
lwork = min( lwmax, int( work(1) ))
代码运行良好。
subroutine zheev ( character JOBZ,
character UPLO,
integer N,
complex*16, dimension( lda, * ) A,
integer LDA,
double precision, dimension( * ) W,
complex*16, dimension( * ) WORK,
integer LWORK,
double precision, dimension( * ) RWORK,
integer INFO
)
这里我们看到 RWORK
是一个双精度类型的数组,但在提供的代码中 rwork
是一个标量整数
我在使用 lapack 例程时偶然发现了一个奇怪的行为 zheev()
。有两个问题我不明白
1) 我的一个全局变量似乎被 zheev()
覆盖了。下面的小程序展示了它:
[用 gfortran -o test test.f90 -llapack -lblas
编译]
program test
implicit none
integer, parameter :: dp = 8
integer, parameter :: dim = 3
integer :: l
real(dp), parameter :: kmin = -0.03_dp
real(dp), parameter :: kmax = 0.03_dp
integer, parameter :: steps = 100
real(dp) :: stepD = (kmax - kmin)/real(steps)
complex(dp) :: matrix(dim,dim)=0.
integer :: info
integer :: rwork=3*dim-2, lwork, lwmax=100
real(dp) :: evals(dim)
complex(dp) :: work(3*dim-2)
lwork=-1
call zheev('N','U',size(matrix,1), matrix, dim, evals, work, lwork, &
rwork, info)
lwork = min( lwmax, int( work(1) ))
do l = 0, 3
write(*,*) stepD
call zheev('N', 'U', size(matrix,1), matrix, dim, evals, work, &
lwork, rwork, info)
write(*,*) stepD
end do
end program test
输出为
5.9999999999999995E-004
0.0000000000000000
0.0000000000000000
0.0000000000000000
0.0000000000000000
0.0000000000000000
0.0000000000000000
0.0000000000000000
这可以通过将 stepD 设置为参数来解决。但我不明白这种行为。越来越奇怪了:
2) 将定义中的 lwork
设置为某个值,如
integer :: rwork=3*dim-2, lwork=10, lwmax=100
(只需将上面对应的行改一下即可) 给出以下结果:
5.9999999999999995E-004
5.9999991208314896E-004
5.9999991208314896E-004
5.9999991208314896E-004
5.9999991208314896E-004
5.9999991208314896E-004
5.9999991208314896E-004
5.9999991208314896E-004
怎么会这样?将 lwork
设置为 10 应该没有任何效果,因为稍后它会设置为 -1。一个重要的概念是:如果删除
lwork=-1
call zheev('N','U',size(matrix,1), matrix, dim, evals, work, lwork, &
rwork, info)
lwork = min( lwmax, int( work(1) ))
代码运行良好。
subroutine zheev ( character JOBZ,
character UPLO,
integer N,
complex*16, dimension( lda, * ) A,
integer LDA,
double precision, dimension( * ) W,
complex*16, dimension( * ) WORK,
integer LWORK,
double precision, dimension( * ) RWORK,
integer INFO
)
这里我们看到 RWORK
是一个双精度类型的数组,但在提供的代码中 rwork
是一个标量整数