foreig.f90 Source File


Files dependent on this one

sourcefile~~foreig.f90~~AfferentGraph sourcefile~foreig.f90 foreig.f90 sourcefile~benchmark.f90 benchmark.f90 sourcefile~benchmark.f90->sourcefile~foreig.f90 sourcefile~test1.f90 test1.f90 sourcefile~test1.f90->sourcefile~foreig.f90

Source Code

module foreig

   use kinds

   implicit none

   private
   public :: eig

   !===============================================================================
   interface eig
      procedure :: eig_rel
   end interface
   !===============================================================================

contains

   !===============================================================================
   !> author: Seyed Ali Ghasemi
   pure subroutine eig_rel(matrix, eig_vecr, eig_val, eig_vecl, method)
      real(rk), dimension(:,:),              intent(in)            :: matrix
      character(*),                          intent(in), optional  :: method
      real(rk), dimension(:,:), allocatable, intent(out)           :: eig_vecr
      real(rk), dimension(:,:), allocatable, intent(out), optional :: eig_vecl
      real(rk), dimension(:),   allocatable, intent(out)           :: eig_val

      if (.not. present(method)) then
         call dgeev_rel(matrix, eig_vecr, eig_val)
      else

         select case (method)
          case ('syev')
            call dsyev_rel(matrix, eig_vecr, eig_val)
          case ('geev')
            call dgeev_rel(matrix, eig_vecr, eig_val, eig_vecl)
          case ('ggev')
            call dggev_rel(matrix, eig_vecr, eig_val, eig_vecl)
         end select

      end if

   end subroutine eig_rel
   !===============================================================================


   !===============================================================================
   !> author: Seyed Ali Ghasemi
   pure subroutine dsyev_rel(matrix, eig_vecr, eig_val)
      real(rk), dimension(:,:),              intent(in)  :: matrix
      real(rk), dimension(:,:), allocatable, intent(out) :: eig_vecr
      real(rk), dimension(:),   allocatable, intent(out) :: eig_val
      real(rk), dimension(:),   allocatable              :: work
      real(rk), dimension(size(matrix,1),size(matrix,1)) :: A
      integer                                            :: lwork, m, info
      real(rk)                                           :: work1(1)

      interface
         pure subroutine dsyev(fjobz, fuplo, fn, fA, flda, fw, fwork, flwork, finfo)
            import rk
            character, intent(in)    :: fjobz, fuplo
            integer,   intent(in)    :: fn
            integer,   intent(in)    :: flda
            integer,   intent(in)    :: flwork
            integer,   intent(out)   :: finfo
            real(rk),  intent(inout) :: fA(flda,*)
            real(rk),  intent(out)   :: fw(*)
            real(rk),  intent(out)   :: fwork(*)
         end subroutine
      end interface

      m = size(matrix,1)
      A = matrix

      call dsyev('V', 'U', m, A, m, eig_val, work1, -1, info)
      lwork = nint(work1(1))
      allocate(work(lwork))

      allocate(eig_vecr(m,m), eig_val(m))

      call dsyev('V', 'U', m, A, m, eig_val, work, lwork, info)

      eig_vecr = A

      deallocate(work)
   end subroutine dsyev_rel
   !===============================================================================


   !===============================================================================
   !> author: Seyed Ali Ghasemi
   pure subroutine dgeev_rel(matrix, eig_vecr, eig_val, eig_vecl)
      real(rk), dimension(:,:), intent(in)                         :: matrix
      real(rk), dimension(:),   allocatable, intent(out)           :: eig_val
      real(rk), dimension(:,:), allocatable, intent(out)           :: eig_vecr
      real(rk), dimension(:,:), allocatable, intent(out), optional :: eig_vecl
      real(rk), dimension(size(matrix,1))                          :: wr, wi
      real(rk), dimension(size(matrix,1),size(matrix,1))           :: vl, vr
      real(rk), dimension(size(matrix,1),size(matrix,1))           :: A
      real(rk), dimension(:), allocatable                          :: work
      integer                                                      :: m, lwork, info
      real(rk)                                                     :: work1(1)

      interface
         pure subroutine dgeev(fjobvl, fjobvr, fn, fA, flda, fwr, fwi, fvl, fldvl, fvr, fldvr, fwork, flwork, finfo)
            import :: rk
            character, intent(in)    :: fjobvl, fjobvr
            integer,   intent(in)    :: fn, flda, fldvl, fldvr, flwork, finfo
            real(rk),  intent(inout) :: fA(flda, *)
            real(rk),  intent(out)   :: fwr(fn), fwi(fn), fvl(fldvl, *), fvr(fldvr, *), fwork(flwork)
         end subroutine
      end interface

      m = size(matrix, 1)
      A = matrix

      if (present(eig_vecl)) then
         eig_vecl = matrix
         call dgeev('V', 'V', m, A, m, wr, wi, vl, m, vr, m, work1, -1, info)
      else
         call dgeev('N', 'V', m, A, m, wr, wi, vl, m, vr, m, work1, -1, info)
      end if

      lwork = nint(work1(1))
      allocate(work(lwork))

      if (present(eig_vecl)) then
         call dgeev('V', 'V', m, A, m, wr, wi, vl, m, vr, m, work, lwork, info)
         eig_vecl = vl
      else
         call dgeev('N', 'V', m, A, m, wr, wi, vl, m, vr, m, work, lwork, info)
      end if

      eig_val  = wr
      eig_vecr = vr

      deallocate(work)

   end subroutine dgeev_rel
   !===============================================================================


   !===============================================================================
   !> author: Seyed Ali Ghasemi
   pure subroutine dggev_rel(matrix, eig_vecr, eig_val, eig_vecl)
      real(rk), dimension(:,:), intent(in)                         :: matrix
      real(rk), dimension(:),   allocatable, intent(out)           :: eig_val
      real(rk), dimension(:,:), allocatable, intent(out)           :: eig_vecr
      real(rk), dimension(:,:), allocatable, intent(out), optional :: eig_vecl
      real(rk), dimension(size(matrix,1))                          :: alphar, alphai, beta
      real(rk), dimension(size(matrix,1),size(matrix,1))           :: vl, vr
      real(rk), dimension(:), allocatable                          :: work
      integer                                                      :: m, lwork, info
      real(rk)                                                     :: work1(1)
      real(rk), dimension(size(matrix,1),size(matrix,1))           :: A

      interface
         pure subroutine dggev(fjobvl, fjobvr, fn, fa, flda, fb, ldb, &
            falphar, falphai, fbeta, fvl, fldvl, fvr, fldvr, fwork, flwork, finfo)
            import :: rk
            character, intent(in)    :: fjobvl, fjobvr
            integer,   intent(in)    :: fn, flda, ldb, fldvl, fldvr, flwork, finfo
            real(rk),  intent(inout) :: fa(flda, *), fb(ldb, *)
            real(rk),  intent(out)   :: falphar(fn), falphai(fn), fbeta(fn)
            real(rk),  intent(inout) :: fvl(fldvl, *), fvr(fldvr, *)
            real(rk),  intent(out)   :: fwork(flwork)
         end subroutine
      end interface

      m = size(matrix, 1)
      allocate(eig_val(m), eig_vecr(m, m))
      eig_vecr = matrix
      A = matrix

      if (present(eig_vecl)) then
         eig_vecl = matrix
         call dggev('V', 'V', m, eig_vecl, m,&
            eig_vecr, m, alphar, alphai, beta, vl, m, vr, m, work1, -1, info)
      else
         call dggev('N', 'V', m, eig_vecr, m,&
            A, m, alphar, alphai, beta, vl, m, vr, m, work1, -1, info)
      end if

      lwork = nint(work1(1))
      allocate(work(lwork))

      if (present(eig_vecl)) then
         call dggev('V', 'V', m, eig_vecl, m, &
            eig_vecr, m, alphar, alphai, beta, vl, m, vr, m, work, lwork, info)
      else
         call dggev('N', 'V', m, eig_vecr, m,&
            A, m, alphar, alphai, beta, vl, m, vr, m, work, lwork, info)
      end if

      eig_val = alphar / beta

      deallocate(work)

   end subroutine dggev_rel
   !===============================================================================

end module foreig