我遇到了解决广义特征问题的子程序的问题:
A * x = lambda * B * x,
其中A和B应该是对称矩阵,B是正定的。我正在尝试解决以下测试用例2x2
program prog
implicit none
integer, parameter :: n=2
integer :: work,lwork,info
real(8) :: a(n,n), b(n,n), e(n)
a(1,1) = -3
a(1,2) = 4
a(2,2) = 3
b(1,1) = 1
b(1,2) = 0
b(2,2) = 1
call dsygv(1, 'v', 'u', n, a, n, b, n, e, WORK, LWORK, INFO)
write(6,*) info
write(6,*) e
write(6,*) a
end program
并获得以下输出:
0
-5.0000000000000000 5.0000000000000000
-Infinity 0.44721359549995793 Infinity 0.89442719099991586
特征值是正确的,其中一个eivenvector是正确的,但我无法避免无穷大并获得另一个特征向量。
答案 0 :(得分:1)
work
和lwork
应该是数组(双精度和整数),并且必须根据手册正确调整大小。否则,LAPACK将使用一些不应该使用的内存部分,一切都会爆炸。
也可能有其他错误的论点。请参阅源代码并附上说明:http://www.netlib.org/lapack/lapack-3.1.1/html/dsygv.f.html
对Fortran初学者的建议:
不要使用write(6,*)
,而是使用write(*,*)
并且不要使用real(8)
,而real(dp)
dp
是一个具有正确值的整数常量(使用selected_real_kind()
或其他方法获取值,或者如果你坚持,只需将其设置为8。
答案 1 :(得分:1)
下面我建议更新您的代码,其中包括:
wp
); Print
; work
。下面:
Program prog
Implicit None
Integer, Parameter :: n = 2
Integer, Parameter :: wp = kind(0.0D0)
Integer :: info, lwork
Real (Kind=wp) :: a(n, n), b(n, n), dummy_work(1), e(n)
Real (Kind=wp), Allocatable :: work(:)
External :: dsygv
Intrinsic :: int, kind, max
! Workspace query:
lwork = -1
Call dsygv(1, 'v', 'u', n, a, n, b, n, e, dummy_work, lwork, info)
lwork = int(dummy_work(1))
Allocate (work(max(1,lwork)))
a(1, 1) = -3
a(1, 2) = 4
a(2, 2) = 3
b(1, 1) = 1
b(1, 2) = 0
b(2, 2) = 1
Call dsygv(1, 'v', 'u', n, a, n, b, n, e, work, lwork, info)
Print *, 'info: ', info
If (info==0) then
Print *, 'e: ', e
Print *, 'a: ', a
end If
End Program
使用我的编译器,我得到了输出
info: 0
e: -5.0000000000000000 5.0000000000000000
a: -0.8944271909999159 0.4472135954999579 0.4472135954999579 0.8944271909999159
请注意,某些供应商为LAPACK(和BLAS)例程提供显式接口。如果可用,您应该始终使用它们。 (这样做可能会在编译时诊断出错误输入的工作空间数组。)