2015-09-04 120 views
1

我已经在使用cgeev的写了下面的代码矩阵的获得特征值和特征决定在FORTRAN:与cgeev不正确的特征值

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) 

这是怎么回事?

回答

4

您正在使用错误的过程。 cgeevzgeev之间的参数类型相同,但种类不同。对于zgeev,阵列RWORK的类型和种类为double precision,并且阵列A,VL,VR,WWORKcomplex*16cgeev的种类和种类分别为realcomplex

你隐式输入实数为real*8,这是非便携式的双精度。同样,您的复杂变量键入为complex*16。你的变量与zgeev的参数列表相匹配,这就是为什么它适用于你并且cgeev不适用。要使用cgeev将您的隐式类型更改为realcomplex,您会发现cgeev现在可以使用,而zgeev不会。

从BLAS命名约定:

中的BLAS库中的每个程序有四种口味,分别由字母S,d,C和Z,分别为前缀。每个字母表示输入数据的格式:

  • S表示单精度(32位IEEE浮点数),
  • d表示双精度(64位IEEE浮点数),
  • C代表复数(通过对32位IEEE浮点数表示),
  • Z代表双复数
(由64位IEEE的对浮点数表示)

对于双精度复变量,您需要使用Z函数变体而不是C

-3

我找到了解决这个问题的方法,但cgeev似乎被打破。如果您将cgeev替换为另一个拉包程序zgeev它可以很好地工作。最令人愉快的部分是我只能改变一个字母。

+1

'cgeev'没有被破坏,它在复数有32位分量时使用,'zgeev'用于64位分量的复杂参数。您没有仔细阅读文档。 Lapack使用的例程命名遵循BLAS中建立的约定,使用第一个字符来指示所需参数的类型。例如,请参阅https://software.intel.com/en-us/node/521147 –