array_operations_invert_symmetric_matrix_submod.f90 Source File


This file depends on

sourcefile~~array_operations_invert_symmetric_matrix_submod.f90~~EfferentGraph sourcefile~array_operations_invert_symmetric_matrix_submod.f90 array_operations_invert_symmetric_matrix_submod.f90 sourcefile~array_operations_mod.f90 array_operations_mod.f90 sourcefile~array_operations_invert_symmetric_matrix_submod.f90->sourcefile~array_operations_mod.f90 sourcefile~utility_functions_mod.f90 utility_functions_mod.f90 sourcefile~array_operations_invert_symmetric_matrix_submod.f90->sourcefile~utility_functions_mod.f90

Contents


Source Code

submodule (array_operations_mod) array_operations_invert_symmetric_matrix_submod
   !! a submodule for append subroutines
   use utility_functions_mod, only: integer_to_character, write_message,       &
      write_error
   implicit none
   !---------------------------------------------------------------------------!
   contains
      !------------------------------------------------------------------------!
      !------------------------------------------------------------------------!
      module subroutine invert_symmetric_matrix_int32(matrix_)
         !! invert a symmetric matrix using DSYTRI method (integer version)
         integer(int32), intent(inout) :: matrix_(:,:)
         !---------------------------------------------------------------------!
         call write_error("Integer version of Lapack inversion procedures " // &
            "does not exist: convert the integer arrays to real")
         !---------------------------------------------------------------------!
      end subroutine invert_symmetric_matrix_int32
      !------------------------------------------------------------------------!
      !------------------------------------------------------------------------!
      module subroutine invert_symmetric_matrix_sp(matrix_)
         !! invert a symmetric matrix using SSYTRI method
         !! (single precision version)
         real(sp), intent(inout) :: matrix_(:,:)
         !---------------------------------------------------------------------!
         integer(int32) :: size_1_, size_2_, size_, lwork_, nb_, ok_, ILAENV
         integer(int32), allocatable :: pivot_(:)
         real(sp), allocatable :: work_(:)
         !---------------------------------------------------------------------!
         size_1_ = size(matrix_, dim = 1)
         size_2_ = size(matrix_, dim = 2)
         if (size_1_ .eq. size_2_) then
            size_ = size_1_
         else
            call write_message("Error in invert_symmetric_matrix_sp: size "    &
               // "in dim = 1 ("//trim(adjustl(integer_to_character(size_1_))) &
               // ") is different than in dim = 2 (" //                        &
               trim(adjustl(integer_to_character(size_2_))) // ")")
            call write_error("Adapt this subroutine to rectangle matrices")
         endif
         !---------------------------------------------------------------------!
         if (allocated(pivot_)) deallocate(pivot_)
         allocate(pivot_(size_))
         !---------------------------------------------------------------------!
         nb_ = ILAENV(1,'SSYTRF','L',size_,-1,-1,-1)
         lwork_ = nb_ * size_
         if (allocated(work_)) deallocate(work_)
         allocate(work_(lwork_))
         work_ = 0
         !---------------------------------------------------------------------!
         call SSYTRF('L',size_,matrix_,size_,pivot_,work_,lwork_,ok_)
         if (ok_ /= 0) then
            call write_error("SSYTRF failed with status: " //                  &
               trim(adjustl(integer_to_character(ok_))) )
         endif
         !---------------------------------------------------------------------!
         call SSYTRI('L',size_,matrix_,size_,pivot_,work_,ok_)
         if (ok_ /= 0) then
            call write_error("SSYTRI failed with status: " //                  &
               trim(adjustl(integer_to_character(ok_))) )
         endif
         !---------------------------------------------------------------------!
      end subroutine invert_symmetric_matrix_sp
      !------------------------------------------------------------------------!
      !------------------------------------------------------------------------!
      module subroutine invert_symmetric_matrix_dp(matrix_)
         !! invert a symmetric matrix using DSYTRI method (double precision version)
         real(dp), intent(inout) :: matrix_(:,:)
         !---------------------------------------------------------------------!
         integer(int32) :: size_1_, size_2_, size_, lwork_, nb_, ok_, ILAENV, i_size_, i_size_2_
         integer(int32), allocatable :: pivot_(:)
         real(dp), allocatable :: work_(:)
         !---------------------------------------------------------------------!
         size_1_ = size(matrix_, dim = 1)
         size_2_ = size(matrix_, dim = 2)
         if (size_1_ .eq. size_2_) then
            size_ = size_1_
         else
            call write_message("Error in invert_symmetric_matrix_dp: size "    &
               // "in dim = 1 ("//trim(adjustl(integer_to_character(size_1_))) &
               // ") is different than in dim = 2 (" //                        &
               trim(adjustl(integer_to_character(size_2_))) // ")")
            call write_error("Adapt this subroutine to rectangle matrices")
         endif
         !---------------------------------------------------------------------!
         if (allocated(pivot_)) deallocate(pivot_)
         allocate(pivot_(size_))
         !---------------------------------------------------------------------!
         nb_ = ILAENV(1,'DSYTRF','L',size_,-1,-1,-1)
         lwork_ = nb_ * size_
         if (allocated(work_)) deallocate(work_)
         allocate(work_(lwork_))
         work_ = 0
         !---------------------------------------------------------------------!
         call DSYTRF('L',size_,matrix_,size_,pivot_,work_,lwork_,ok_)
         if (ok_ /= 0) then
            call write_error("DSYTRF failed with status: " //                  &
               trim(adjustl(integer_to_character(ok_))) )
         endif
         !---------------------------------------------------------------------!
         call DSYTRI('L',size_,matrix_,size_,pivot_,work_,ok_)
         if (ok_ /= 0) then
            call write_error("DSYTRI failed with status: " //                  &
               trim(adjustl(integer_to_character(ok_))) )
         endif
         !---------------------------------------------------------------------!
      end subroutine invert_symmetric_matrix_dp
   !---------------------------------------------------------------------------!
end submodule array_operations_invert_symmetric_matrix_submod