52 lines
1.6 KiB
FortranFixed
52 lines
1.6 KiB
FortranFixed
subroutine eigen_sym_up(N,A,W)
|
|
implicit none
|
|
!
|
|
!compute the eigenvalues and eigenvectors of a symmetrical matrix.
|
|
!A: On entry, A is a symmetrical matrix with its upper triangle filled.
|
|
! on exit, A contains the normalized eigenvectors in its columns.
|
|
!W: contains the eigenvalues in descending order.
|
|
|
|
CHARACTER JOBZ, UPLO
|
|
INTEGER INFO, LDA, LWORK, N
|
|
DOUBLE PRECISION A(N, N), W( N ), WORK(3*N-1)
|
|
double precision p
|
|
integer i,j
|
|
|
|
JOBZ='V'
|
|
UPLO='U'
|
|
LWORK=3*N-1
|
|
LDA=N
|
|
call DSYEV(JOBZ,UPLO,N,A(1:N,1:N),LDA,W,WORK,LWORK,INFO)
|
|
* INFO (output) INTEGER
|
|
* = 0: successful exit
|
|
* < 0: if INFO = -i, the i-th argument had an illegal value
|
|
* > 0: if INFO = i, the algorithm failed to converge; i
|
|
* off-diagonal elements of an intermediate tridiagonal
|
|
* form did not converge to zero.
|
|
if(INFO.lt.0)then
|
|
write(*,*)'The ',-INFO,
|
|
& 'th argument in DSYEV has an illegal value'
|
|
stop
|
|
endif
|
|
if(INFO.gt.0)then
|
|
write(*,*)'The algorithm failed to converge'
|
|
stop
|
|
endif
|
|
|
|
! Change the eigenvalue array from ascending to descending order and rearrange
|
|
! the eigen vectors accordingly.
|
|
!---------------------------------------------
|
|
do i=1,N/2
|
|
p=W(i)
|
|
W(i)=W(N-i+1)
|
|
W(N-i+1)=p
|
|
do j=1,N
|
|
p=A(j,i)
|
|
A(j,i)=A(j,N-i+1)
|
|
A(j,N-i+1)=p
|
|
enddo
|
|
enddo
|
|
!---------------------------------------------
|
|
return
|
|
end
|