2015-04-17 84 views
4

我使用LAPACK库中的DSYEV和DSYEVD来查找特征值和特征向量(编译语法:gfortran -llapack)。但是,我发现特定矩阵的错误特征值(-0.44,0.35,0.88)。出了什么问题?LAPACK给我不正确的特征值

人们可以很容易地看到矩阵有零行列式,所以至少有一个特征值必须为零。

这里是我的代码(希望这不是太大):

Program Real_Eigenvec 
    implicit none 

    integer, parameter:: n=3 
    integer:: i,j, flag 
    real*8:: A(n,n),X(n,n) 
    real*8:: lambda(n) 
    real*8, parameter:: p=0.5d0/dsqrt(2.d0), q=1.d0-1.d0/dsqrt(2.d0) 


    Print*,'Enter flag: 0 for DSYEV, 1 for DSYEVD' 
    Read*, flag 


    A= transpose(reshape((/ 0.d0, 1.d0, 0.d0, p, q, p, 0.5d0, 0.0d0, 0.5d0 /), shape(A))) 


    print*,'Dimension of the matrix, n=',int(sqrt(float(size(A)))) 

    Print*,'A matrix in full form:' 
    Do i=1,n 
     print 100, (A(i,j),j=1,n) 
    End Do 

    call Eigen(A,lambda,X,n,flag) 

    ! Print the eigenvalues and eigenvectors. 

    PRINT 200 
    DO i = 1, n 
     PRINT 201, lambda(i), (X(i,j), j=1,n) 
    END DO 

100 FORMAT (1X,10(:2X,F10.2)) 
200 FORMAT (/1X, 'Eigenvalue', 16X, 'Eigenvector^T') 
201 FORMAT (1X, F10.2,4X,6(:f10.2)) 

    End Program Real_Eigenvec 



!!!  SUBROUTINES ----------------------------------------- 


    Subroutine Eigen(A,lambda,X,n,flag) 
    implicit none 

    integer:: i,n,flag 
    real*8:: A(n,n),Ap(n,n),X(n,n) 
    real*8:: lambda(n) 
    real*8, allocatable :: work(:) 
     integer, allocatable :: iwork(:) 
    integer:: lwork,liwork,info 

    print*,'n in Eiegen routine=',n 

    lwork=3*n-1  ! DSYEV for flag=0 
    if (flag==1) then ! DSYEVD for flag=1 
     lwork=1+6*n+2*n**2 
    end if 

    liwork=3+5*n 


    allocate(work(lwork)) 
    allocate(iwork(liwork)) 

    Ap=A 

    if (flag==0) then 
     CALL DSYEV ('v', 'l', n, Ap, n, lambda, work, lwork, info) 
    else 
     CALL DSYEVD ('V', 'U', n, Ap, n, lambda, work, & 
       & lwork, iwork, liwork, info) 
     ! For doumentation visit: http://www.netlib.org/lapack/explore-html/d1/da2/dsyevd_8f.html 
    end if 

    X=Ap 

    print*,'info=',info 

    deallocate(work) 
    deallocate(iwork) 

    End Subroutine Eigen 
+0

没有多少人关注[tag:fortran90],如果你想有人帮助你,最好只在必要时使用[tag:fortran]和版本标签(这里不是这种情况)。 –

+0

谢谢@VladimirF。我将为未来的职位保留这一点。 – hbaromega

回答

7

如LAPACK documentationDSYEV可用于对称矩阵表示。

DSYEV计算所有特征值和,任选地,一个真正的对称矩阵A.

的特征向量在该例子中矩阵A不是对称

Dimension of the matrix, n=   3 
A matrix in full form: 
    0.00  1.00  0.00 
    0.35  0.29  0.35 
    0.50  0.00  0.50 

在这种情况下,你应使用DGEEV用于非对称matrices

DGEEV计算N乘N实非对称矩阵A,特征值和可选的左和/或右特征向量。

一般使用的特征值是复数,所以你必须提供WRWL。此外,您需要定义是否要离开VL或右侧的VR特征向量。

A * v(j) = lambda(j) * v(j) 
u(j)**H * A = lambda(j) * u(j)**H 

函数的定义是:

DGEEV(JOBVL, JOBVR, N, A, LDA, WR, WI, VL, LDVL, VR, LDVR, WORK, LWORK, INFO) 

我建议使用它像

LWORK = 4*N 
CALL DGEEV('N', 'V', n, A, n, wr, wl, Ap, n, Ap, n, work, lwork, info) 

为了获得左,右特征向量使用

real*8:: A(n,n),VL(n,n),VR(n,n) 
real*8:: wr(n),wl(n) 
lwork = 4*N 
allocate(work(lwork)) 
CALL DGEEV('V', 'V', n, A, n, wr, wl, VL, n, VR, n, work, lwork, info) 

对于你的矩阵imagi所有特征值的nary部分是零。所以特征值是(1.00, -0.21, 0.00)

+0

非常感谢。我完全不知道DSYEV只适用于对称矩阵。然而,使用'CALL DGEEV'('N','V',n,A,n,wr,wl,Ap,n,Ap,n,work,lwork,info)'我仍然收到错误消息: **在进入DGEEV时,参数号13有非法值 info = -13'。我已经宣布了'real * 8 :: wr(n),wi(n)'。 – hbaromega

+1

该消息告诉您检查参数号13.您是否这样做?哪一个是它的价值? –

+0

既然你需要特征向量@hbaromega,你必须设置LWORK> = 4 * N。我会在对 – ztik

相关问题