cgeev的特征值不正确

时间:2015-09-04 18:11:20

标签: fortran lapack eigenvalue

我编写了以下代码,使用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)

这里有什么问题?

2 个答案:

答案 0 :(得分:4)

您使用的是错误的程序。 cgeevzgeev之间的参数类型相同但种类不同。对于zgeev,数组RWORK的类型和种类double precision以及数组AVLVR,{{1} },WWORK。对于complex*16类型和种类,分别为cgeevreal

您隐式将reals键入complex,这是非便携式的双精度。同样,复杂变量的类型为real*8。您的变量与complex*16的参数列表匹配,这就是为什么它适合您而zgeev没有。要使用cgeev将隐式类型更改为cgeevreal,您发现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 ,它可以完美地运行。最令人愉快的部分是我不得不改变一个字母。