I have written the following code to get eigenvalues and determinant of the matrix in fortran with the use of 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
And this simple program to check it:
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
And I get the following quite confusing results:
( 0.0000000000000000 , 1.0000000000000000 )
( 1.2828908559913808E-319, 7.6130689002776223E-317)
What is the matter here?
You are using the wrong procedure. The argument types between cgeev
and zgeev
are the same but differ in kinds. For zgeev
, the array RWORK
is of type and kind of double precision
and the arrays A
, VL
, VR
, W
, and WORK
are complex*16
. For cgeev
the types and kinds, respectively are real
and complex
.
You are implicitly typing reals as real*8
, which are double precision in a non-portable fashion. Likewise your complex variables are typed as complex*16
. Your variables match the argument list of zgeev
, which is why it works for you and cgeev
doesn't. To use cgeev
change your implicit types to real
and complex
and you'll find cgeev
now works and zgeev
does not.
From the BLAS naming conventions:
Every routine in the BLAS library comes in four flavors, each prefixed by the letters S, D, C, and Z, respectively. Each letter indicates the format of input data:
- S stands for single-precision (32-bit IEEE floating point numbers),
- D stands for double-precision (64-bit IEEE floating point numbers),
- C stands for complex numbers (represented by pairs of 32-bit IEEE floating point numbers),
- Z stands for double complex numbers (represented by pairs of 64-bit IEEE floating point numbers)
For your double precision complex variables, you'll need to use the Z
variants of functions rather than C
.