Diagonalize the dim x dim hermitian matrix 'mat' and return the eigenvalues 'eig' and the unitary rotation 'rot'
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
complex(kind=dp), | intent(in) | :: | mat(dim,dim) | |||
integer, | intent(in) | :: | dim | |||
real(kind=dp), | intent(out) | :: | eig(dim) | |||
complex(kind=dp), | intent(out) | :: | rot(dim,dim) |
subroutine utility_diagonalize(mat, dim, eig, rot)
!============================================================!
! !
!! Diagonalize the dim x dim hermitian matrix 'mat' and
!! return the eigenvalues 'eig' and the unitary rotation 'rot'
! !
!============================================================!
use w90_constants, only: dp, cmplx_0
use w90_io, only: io_error, stdout
integer, intent(in) :: dim
complex(kind=dp), intent(in) :: mat(dim, dim)
real(kind=dp), intent(out) :: eig(dim)
complex(kind=dp), intent(out) :: rot(dim, dim)
complex(kind=dp) :: mat_pack((dim*(dim + 1))/2), cwork(2*dim)
real(kind=dp) :: rwork(7*dim)
integer :: i, j, info, nfound, iwork(5*dim), ifail(dim)
do j = 1, dim
do i = 1, j
mat_pack(i + ((j - 1)*j)/2) = mat(i, j)
enddo
enddo
rot = cmplx_0; eig = 0.0_dp; cwork = cmplx_0; rwork = 0.0_dp; iwork = 0
call ZHPEVX('V', 'A', 'U', dim, mat_pack, 0.0_dp, 0.0_dp, 0, 0, -1.0_dp, &
nfound, eig(1), rot, dim, cwork, rwork, iwork, ifail, info)
if (info < 0) then
write (stdout, '(a,i3,a)') 'THE ', -info, &
' ARGUMENT OF ZHPEVX HAD AN ILLEGAL VALUE'
call io_error('Error in utility_diagonalize')
endif
if (info > 0) then
write (stdout, '(i3,a)') info, ' EIGENVECTORS FAILED TO CONVERGE'
call io_error('Error in utility_diagonalize')
endif
end subroutine utility_diagonalize