LAPACK例程ZGEEV - 给出错误的特征值

时间:2013-06-20 08:24:55

标签: fortran90 lapack

我在fortran中编写了以下程序,该程序使用名为ZGEEV的lapack子例程。我们的想法是看看矩阵matrix to diagonalised的特征值如何随着k从实数变为复数而发生变化。从分析上看,答案应该是2和0,k是否复杂。但我得到了一个显示出很多变化的情节 特别是对于真实的k,情节看起来像这样 -
Plot for eigenvalues vs k 这是我写的代码 -

           program main
             implicit none
       !**********************************************                 
             complex(8) :: k,mat(2,2)
             complex(8) :: eigenvals(2)
             real(8), parameter    :: kmax = 2.d0 
             real(8), parameter    :: dk = 1.d-1 
             real(8)               :: kr,ki
       !**********************************************
             kr=-kmax
             do while (kr.le.kmax)
                ki= -1.d-3
                do while (ki.le.1.d-3)
                   k=cmplx(kr,ki)
                   call init_mat(k,mat)
                   call diagonalize(mat,eigenvals)
                   print*, real(k), real(eigenvals(2)),aimag(eigenvals(2))
                   ki=ki+1.d-4
                end do
                kr=kr+dk
             end do
           end program main





           subroutine init_mat(k,mat)
             implicit none
             complex(8),intent(in) :: k
             complex(8),intent(out):: mat(2,2)
             complex(8),parameter  :: di=(0.d0,1.d0)
             complex(8),parameter  :: d1=(1.d0,0.d0)
        !**********************************************
             mat(1,1) = d1 
             mat(1,2) = exp(di*k)
             mat(2,1) = exp(di*k) 
             mat(2,2) = d1 
             return
           end subroutine init_mat

           subroutine diagonalize(mat,eigenvals)
             implicit none
             complex(8),intent(in) :: mat(2,2)
             complex(8),intent(out):: eigenvals(2)
             complex(8)            :: vl(2,2),vr(2,2)
             complex(8),allocatable:: work(:)
             integer(4)            :: lwork
             complex(8)            :: rwork(4)
             complex(8)            :: mat2(2,2)
             integer(4)            :: info
        !**********************************************
             mat2(:,:) = mat(:,:)
             allocate(work(6))
             call zgeev('N', 'N', 2, mat2, 2, eigenvals, vl, 2, vr, 2, work, -1, rwork, info)
             lwork = work(1)
             deallocate(work)
             allocate(work(lwork))
             call zgeev('V', 'V', 2, mat2, 2, eigenvals, vl, 2, vr, 2, work, lwork, rwork, info)
             if (info.ne.0) print*, info
             stop 'diagonalize failed'
           end subroutine diagonalize

评论中欢迎任何关于这种失常原因的懒惰理论!

PS:我在python中编写了一个类似的代码,在y = 2和y = 0时,特征值是两条常数行。

1 个答案:

答案 0 :(得分:3)

在子程序init_mat(k,mat)

mat(1,2)= exp(di * k) 和 mat(2,1)= exp(di * k)

但是其中一个,例如mat(2,1)应该= exp(-di * k)

虽然你的数学项目需要在非对角线上使用e ^ ik和e ^ -ik的矩阵,但是显示的代码是在两个非对角线上创建一个带有e ^ ik的矩阵。实际编码的矩阵具有复杂的特征值,因此用于查找特征值的子程序可能正常工作,并且所示的输入具有错误的规范。

那么[[1,e ^ ik],[e ^ ik,1]的特征值是什么?

嗯,迹线仍然是2,所以特征值总和为2。

决定因素是1-e ^(2ik),因此产品很复杂。

这表明矩阵实际输入的特征值是复数共轭,总和为2.通过检验,特征值似乎是1 +/- e ^ ik