我编写了以下代码,使用cgeev获取fortran中矩阵的特征值和行列式:
SUBROUTINE CDETS(CS,CW,CDET,N)
IMPLICIT REAL*8 (A,B,D-H,O-Z)
IMPLICIT COMPLEX*16 (C)
DIMENSION CW(*),CS(N,*)
ALLOCATABLE :: CWK(:), WK(:), CWL(:,:),CWR(:,:)
ALLOCATE (WK(2*N),CWK(10*N),CWL(N,N),CWR(N,N))
CALL CGEEV('N','N',N,CS,N,CW,CWL,N,CWR,N,CWK,10*N,
& WK,INFO)
DEALLOCATE (WK,CWK,CWL,CWR)
CDET = 1.D0
DO i=1,N
CDET = CDET*CW(i)
ENDDO
END SUBROUTINE
这个简单的程序来检查它:
PROGRAM TESTDET
IMPLICIT REAL*8 (A,B,D-H,O-Z)
IMPLICIT COMPLEX*16 (C)
DIMENSION :: CS(2,2), CW(2)
CS(1,1)=(1.D0,1.D0)
CS(1,2)=1.D0
CS(2,1)=0.D0
CS(2,2)=1.D0
CALL CDETS(CS,CW,CDET,2)
PRINT *, CW(1)
PRINT *, CW(2)
END
我得到以下令人困惑的结果:
( 0.0000000000000000 , 1.0000000000000000 )
( 1.2828908559913808E-319, 7.6130689002776223E-317)
这里有什么问题?
答案 0 :(得分:4)
您使用的是错误的程序。 cgeev
和zgeev
之间的参数类型相同但种类不同。对于zgeev
,数组RWORK
的类型和种类double precision
以及数组A
,VL
,VR
,{{1} },W
是WORK
。对于complex*16
类型和种类,分别为cgeev
和real
。
您隐式将reals键入complex
,这是非便携式的双精度。同样,复杂变量的类型为real*8
。您的变量与complex*16
的参数列表匹配,这就是为什么它适合您而zgeev
没有。要使用cgeev
将隐式类型更改为cgeev
和real
,您发现complex
现在有效且cgeev
没有。
从BLAS命名约定:
BLAS库中的每个例程都有四种形式,每种都分别以字母S,D,C和Z为前缀。每个字母表示输入数据的格式:
- S代表单精度(32位IEEE浮点数),
- D代表双精度(64位IEEE浮点数),
- C代表复数(由32位IEEE浮点数对表示),
- Z代表双复数(由64位IEEE浮点数对表示)
对于双精度复杂变量,您需要使用函数的zgeev
变体而不是Z
。
答案 1 :(得分:-3)
我找到了解决此问题的方法,但 cgeev 似乎已被打破。如果将 cgeev 替换为另一个lapack例程 zgeev ,它可以完美地运行。最令人愉快的部分是我不得不改变一个字母。