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) | |||
| type(w90_error_type), | intent(out), | allocatable | :: | error | ||
| type(w90_comm_type), | intent(in) | :: | comm |
subroutine utility_diagonalize(mat, dim, eig, rot, error, comm) !================================================! ! !! 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_error, only: w90_error_type, set_error_fatal 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) type(w90_error_type), allocatable, intent(out) :: error type(w90_comm_type), intent(in) :: comm 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) character(len=120) :: errormsg do j = 1, dim do i = 1, j mat_pack(i + ((j - 1)*j)/2) = mat(i, j) end do end do 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 (errormsg, '(a,i3,a)') 'Error in utility_diagonalize: THE ', -info, & ' ARGUMENT OF ZHPEVX HAD AN ILLEGAL VALUE' call set_error_fatal(error, errormsg, comm) return end if if (info > 0) then write (errormsg, '(a,i3,a)') 'Error in utility_diagonalize: ', info, & ' EIGENVECTORS FAILED TO CONVERGE' call set_error_fatal(error, errormsg, comm) return end if end subroutine utility_diagonalize