我尝试对齐矩阵:
在我的分析中,我设置$ \ hbar = 1 $。代码是:
MODULE FUNCTION_CONTAINER
IMPLICIT NONE
SAVE
INTEGER, PARAMETER :: DBL = SELECTED_REAL_KIND(P = 15,R = 200)
COMPLEX(KIND = DBL), PARAMETER :: IMU = (0.0D0, 1.0D0)
REAL(KIND = DBL), PARAMETER :: S = 1.0D0
INTEGER, PARAMETER :: TEMP1 = NINT((2.0D0 * S) + 1.0D0)
INTEGER, PARAMETER :: DIMJ = TEMP1
INTEGER, PARAMETER :: TEMP2 = TEMP1*TEMP1
INTEGER, PARAMETER :: DIMMAT = TEMP2
CONTAINS
INTEGER FUNCTION KRONDELTAR(K,L)
IMPLICIT NONE
REAL(KIND = DBL), INTENT(IN)::K,L
REAL(KIND = DBL) :: TEMP
TEMP = DABS(K - L)
IF (TEMP < 0.000001D0) THEN
KRONDELTAR = 1
ELSE
KRONDELTAR = 0
END IF
END FUNCTION KRONDELTAR
SUBROUTINE MATJplus(MATOUT)
IMPLICIT NONE
COMPLEX(KIND = DBL),DIMENSION(DIMJ,DIMJ),INTENT(OUT)::MATOUT
INTEGER::K,L
REAL(KIND = DBL)::M,MP
DO K = 1,DIMJ
DO L = 1,DIMJ
MP = (S + 1.0D0) - L
M = (S + 1.0D0) - K
MATOUT(K,L) = DSQRT(S * (S + 1.0D0) - M * (M + 1.0D0)) * KRONDELTAR(MP,M + 1)
END DO
END DO
END SUBROUTINE MATJplus
SUBROUTINE MATJminus(MATOUT)
IMPLICIT NONE
COMPLEX(KIND = DBL),DIMENSION(DIMJ,DIMJ),INTENT(OUT)::MATOUT
INTEGER::K,L
REAL(KIND = DBL)::MP,M
DO K = 1,DIMJ
DO L = 1,DIMJ
MP = (S + 1) - L
M = (S + 1) - K
MATOUT(K,L) = DSQRT(S* (S + 1.0D0) - M * (M - 1.0D0)) * KRONDELTAR(MP,M - 1)
END DO
END DO
END SUBROUTINE MATJminus
SUBROUTINE MATJy(MATOUT)
IMPLICIT NONE
COMPLEX(KIND = DBL),DIMENSION(DIMJ,DIMJ),INTENT(OUT)::MATOUT
COMPLEX(KIND = DBL),DIMENSION(DIMJ,DIMJ)::Jp,Jm
CALL MATJplus(Jp)
CALL MATJminus(Jm)
MATOUT = (Jp - Jm)/(2.0D0 * IMU)
END SUBROUTINE MATJy
SUBROUTINE DIAGONALIZEJy(EIGENSTATESJy,EIGENVALUESJY)
IMPLICIT NONE
COMPLEX(KIND = DBL),DIMENSION(DIMJ,DIMJ),INTENT(OUT)::EIGENSTATESJy
REAL(KIND = DBL), DIMENSION(DIMJ),INTENT(OUT)::EIGENVALUESJY
COMPLEX(KIND = DBL),DIMENSION(DIMJ,DIMJ)::JyTEMP,Jy
COMPLEX(KIND = DBL),DIMENSION(2*DIMJ)::D1
REAL(KIND = DBL),DIMENSION(3*DIMJ - 2)::D2
INTEGER::D3
CALL MATJy(Jy)
JyTEMP = Jy
CALL ZHEEV('V','U',DIMJ,JyTEMP,DIMJ,EIGENVALUESJy,D1,2*DIMJ,D2,D3)
EIGENSTATESJy = JyTEMP
END SUBROUTINE DIAGONALIZEJy
END MODULE FUNCTION_CONTAINER
PROGRAM TEST
USE FUNCTION_CONTAINER
IMPLICIT NONE
COMPLEX(KIND = DBL), DIMENSION(DIMJ,DIMJ) :: EIGENSTATESJy, MatrixJy
REAL(KIND = DBL), DIMENSION(DIMJ) :: EIGENVALUESJy
CALL DIAGONALIZEJy(EIGENSTATESJy,EIGENVALUESJY)
CALL MATJy(MatrixJy)
OPEN(1, FILE = 'EIGENVALUESJy.DAT')
OPEN(2, FILE = 'EIGENSTATESJyREAL.DAT')
OPEN(3,FILE = 'EIGENSTATESJyCOMPLEX.DAT')
WRITE (1,*) EIGENVALUESJy
WRITE (2,*) REAL(EIGENSTATESJy)
WRITE (3,*) AIMAG(EIGENSTATESJy)
CLOSE(1)
CLOSE(2)
CLOSE(3)
END PROGRAM TEST
直到子程序DIAGONALIZEJy,
我只是构建上述矩阵。通过简单地编写子例程MatJy.
的结果,我可以很容易地检查Fortran构造。我将数据传输到 Mathematica。结果是:
{{-1., -9.19403*10^-17, 1.}}
这是特征值列表。特征向量列表是:
{{-0.5 + 0. I, 0. - 0.707107 I, 0.5 + 0. I}, {0.707107 + 0. I,
0. + 1.04083*10^-16 I, 0.707107 + 0. I}, {-0.5 + 0. I,
0. + 0.707107 I, 0.5 + 0. I}}
第一个特征向量对应于第一个特征值(至少是我从EigenvectorsJy
逐个打印列向量得到的)。
http://www.wolframalpha.com/widgets/view.jsp?id=9aa01caf50c9307e9dabe159c9068c41
我希望该链接显示使用小部件完成的特征值问题的结果。特征值是正确的,但所有特征向量都是偏离的。
另外,当我只运行在我的主程序中对矩阵进行对角化的子程序时,该子程序包含许多其他东西,结果是:
{{0.885212, 0., -0.920222}}
和
{{0.0439691 + 0. I, -0.388918 + 0. I, 0.5 + 0. I}, {0.707107 + 0. I,
0. + 1.04083*10^-16 I, 0.707107 + 0. I}, {-0.5 + 0. I,
0. + 0.707107 I, 0.5 + 0. I}}
正如您所看到的,非零特征值有点偏离,特征向量也是(并且仍然不正确)。为什么主程序会产生不同的结果,perhaph会加剧错误?另外,首先(最小的例子,见上文),为什么我得到错误的答案?
修改:显然,该链接未显示结果,因此这是一个片段:
答案 0 :(得分:0)
简而言之,代码中的Jy
矩阵似乎是所需内容的复杂共轭(即问题中发布的图像),这导致特征向量与正确的共轭结合。
上述错误似乎源于OP的假设,即列表导向输出(如write(*,*) A
)打印&#34; row-major&#34;中的矩阵元素。订单,而实际上它们是打印在&#34;列专业&#34;订单(见下面的评论)。通过注意这一点并相应地更正程序,我认为该程序将按预期工作。
更具体地说,添加以下实用程序例程来打印矩阵
subroutine printmat( msg, mat )
implicit none
character(*), intent(in) :: msg
complex(DBL), intent(in) :: mat( dimJ, dimJ )
integer i1, i2
print *
print *, msg
do i1 = 1, dimJ
print "(3('(',f10.6,',',f10.6,' ) '))", ( mat( i1, i2 ), i2 = 1,dimJ )
enddo
end subroutine
并检查子例程Jp
Jm
,Jy
,MATJy()
的值
Jp:
( 0.000000, 0.000000 ) ( 0.000000, 0.000000 ) ( 0.000000, 0.000000 )
( 1.414214, 0.000000 ) ( 0.000000, 0.000000 ) ( 0.000000, 0.000000 )
( 0.000000, 0.000000 ) ( 1.414214, 0.000000 ) ( 0.000000, 0.000000 )
Jm:
( 0.000000, 0.000000 ) ( 1.414214, 0.000000 ) ( 0.000000, 0.000000 )
( 0.000000, 0.000000 ) ( 0.000000, 0.000000 ) ( 1.414214, 0.000000 )
( 0.000000, 0.000000 ) ( 0.000000, 0.000000 ) ( 0.000000, 0.000000 )
Jy * sqrt(2):
( 0.000000, 0.000000 ) ( 0.000000, 1.000000 ) ( 0.000000, 0.000000 )
( 0.000000, -1.000000 ) ( 0.000000, 0.000000 ) ( 0.000000, 1.000000 )
( 0.000000, 0.000000 ) ( 0.000000, -1.000000 ) ( 0.000000, 0.000000 )
eigenvaluesJy(1) = -1.000000
eigvec:
( -0.500000, 0.000000 )
( 0.000000, -0.707107 )
( 0.500000, 0.000000 )
eigenvaluesJy(2) = -0.000000
eigvec:
( 0.707107, 0.000000 )
( 0.000000, 0.000000 )
( 0.707107, 0.000000 )
eigenvaluesJy(3) = 1.000000
eigvec:
( -0.500000, 0.000000 )
( 0.000000, 0.707107 )
( 0.500000, 0.000000 )
我们看到上面的Jy
矩阵是所需矩阵的复共轭(在问题中作为图像给出)。原因似乎是Jp
和Jm
矩阵作为正确矩阵的转置给出(根据this和this等一些页面。例如,如果我们将其索引更改为
SUBROUTINE MATJplus(MATOUT)
IMPLICIT NONE
COMPLEX(KIND = DBL),DIMENSION(DIMJ,DIMJ),INTENT(OUT)::MATOUT
INTEGER::K,L
REAL(KIND = DBL)::M,MP
DO K = 1,DIMJ
DO L = 1,DIMJ
MP = (S + 1.0D0) - L !! 1, 0, -1 ("m_prime")
M = (S + 1.0D0) - K !! 1, 0, -1 ("m")
!>>> Here, we swap the indices K and L in the LHS
!! MATOUT(K,L) = DSQRT(S * (S + 1.0D0) - M * (M + 1.0D0)) * KRONDELTAR(MP, M + 1)
MATOUT(L,K) = DSQRT(S * (S + 1.0D0) - M * (M + 1.0D0)) * KRONDELTAR(MP, M + 1)
END DO
END DO
call printmat( "Jplus:", matout )
END SUBROUTINE
(并且类似地修改MATJminus()
),我们获得了预期的结果:
Jp:
( 0.000000, 0.000000 ) ( 1.414214, 0.000000 ) ( 0.000000, 0.000000 )
( 0.000000, 0.000000 ) ( 0.000000, 0.000000 ) ( 1.414214, 0.000000 )
( 0.000000, 0.000000 ) ( 0.000000, 0.000000 ) ( 0.000000, 0.000000 )
Jm:
( 0.000000, 0.000000 ) ( 0.000000, 0.000000 ) ( 0.000000, 0.000000 )
( 1.414214, 0.000000 ) ( 0.000000, 0.000000 ) ( 0.000000, 0.000000 )
( 0.000000, 0.000000 ) ( 1.414214, 0.000000 ) ( 0.000000, 0.000000 )
Jy * sqrt(2):
( 0.000000, 0.000000 ) ( 0.000000, -1.000000 ) ( 0.000000, 0.000000 )
( 0.000000, 1.000000 ) ( 0.000000, 0.000000 ) ( 0.000000, -1.000000 )
( 0.000000, 0.000000 ) ( 0.000000, 1.000000 ) ( 0.000000, 0.000000 )
eigenvaluesJy(1) = -1.000000
eigvec:
( -0.500000, 0.000000 )
( 0.000000, 0.707107 )
( 0.500000, 0.000000 )
eigenvaluesJy(2) = -0.000000
eigvec:
( 0.707107, 0.000000 )
( 0.000000, -0.000000 )
( 0.707107, 0.000000 )
eigenvaluesJy(3) = 1.000000
eigvec:
( -0.500000, 0.000000 )
( 0.000000, -0.707107 )
( 0.500000, 0.000000 )
为方便起见,以下是从以上页面中获取的一些矩阵(可以直接与上述Jp
,Jm
,Jy
进行比较):