2015-09-04 119 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 –