SF_SPARSE_COMMON.f90 Source File


This file depends on

sourcefile~~sf_sparse_common.f90~~EfferentGraph sourcefile~sf_sparse_common.f90 SF_SPARSE_COMMON.f90 sourcefile~sf_linalg.f90 SF_LINALG.f90 sourcefile~sf_sparse_common.f90->sourcefile~sf_linalg.f90 sourcefile~sf_blacs.f90 SF_BLACS.f90 sourcefile~sf_linalg.f90->sourcefile~sf_blacs.f90 sourcefile~sf_mpi.f90 SF_MPI.f90 sourcefile~sf_linalg.f90->sourcefile~sf_mpi.f90

Files dependent on this one

sourcefile~~sf_sparse_common.f90~~AfferentGraph sourcefile~sf_sparse_common.f90 SF_SPARSE_COMMON.f90 sourcefile~sf_sparse_array_algebra.f90 SF_SPARSE_ARRAY_ALGEBRA.f90 sourcefile~sf_sparse_array_algebra.f90->sourcefile~sf_sparse_common.f90 sourcefile~sf_sparse_array_csc.f90 SF_SPARSE_ARRAY_CSC.f90 sourcefile~sf_sparse_array_algebra.f90->sourcefile~sf_sparse_array_csc.f90 sourcefile~sf_sparse_array_csr.f90 SF_SPARSE_ARRAY_CSR.f90 sourcefile~sf_sparse_array_algebra.f90->sourcefile~sf_sparse_array_csr.f90 sourcefile~sf_sparse_array_coo.f90 SF_SPARSE_ARRAY_COO.f90 sourcefile~sf_sparse_array_coo.f90->sourcefile~sf_sparse_common.f90 sourcefile~sf_sparse_array_csc.f90->sourcefile~sf_sparse_common.f90 sourcefile~sf_sparse_array_csr.f90->sourcefile~sf_sparse_common.f90 sourcefile~sf_sparse.f90 SF_SPARSE.f90 sourcefile~sf_sparse.f90->sourcefile~sf_sparse_array_csc.f90 sourcefile~sf_sparse.f90->sourcefile~sf_sparse_array_csr.f90

Source Code

MODULE SF_SPARSE_COMMON
  USE SF_LINALG, only: deye,zeye
  
  implicit none
  
  interface append
     module procedure :: append_I
     module procedure :: append_D
     module procedure :: append_Z
  end interface append


  
  !SPARSE MATRIX
  type sparse_matrix
     integer                                   :: Nrow
     integer                                   :: Ncol
     integer                                   :: Nelements
     logical                                   :: status=.false.
   contains
     procedure,pass :: shape     => shape_matrix
  end type sparse_matrix

  !RETURN SHAPE OF THE SPARSE MATRIX [Nrow,Ncol]
  interface shape
     module procedure :: shape_matrix
  end interface shape
  
  public :: shape
  
contains
  
  !+------------------------------------------------------------------+
  !PURPOSE:  Return the shape of a sparse matrix
  !+------------------------------------------------------------------+
   function shape_matrix(self) result(shape)
     class(sparse_matrix),intent(in) :: self
     integer,dimension(2)            :: shape
     shape = [self%Nrow,self%Ncol]
   end function shape_matrix


  


  !+------------------------------------------------------------------+
  !PURPOSE  : Sort an array, gives the new ordering of the label.
  !+------------------------------------------------------------------+
  subroutine sort_array(array,order)
    integer,dimension(:)                    :: array
    integer,dimension(size(array))          :: order
    integer,dimension(size(array))          :: backup
    integer                                 :: i
    forall(i=1:size(array))order(i)=i
    call qsort_sort(array, order,1, size(array))
    do i=1,size(array)
       backup(i)=array(order(i))
    enddo
    array=backup
  contains
    recursive subroutine qsort_sort( array, order, left, right )
      integer, dimension(:) :: array
      integer, dimension(:) :: order
      integer               :: left
      integer               :: right
      integer               :: i
      integer               :: last
      if ( left .ge. right ) return
      call qsort_swap( order, left, qsort_rand(left,right) )
      last = left
      do i = left+1, right
         if ( compare(array(order(i)), array(order(left)) ) .lt. 0 ) then
            last = last + 1
            call qsort_swap( order, last, i )
         endif
      enddo
      call qsort_swap( order, left, last )
      call qsort_sort( array, order, left, last-1 )
      call qsort_sort( array, order, last+1, right )
    end subroutine qsort_sort
    !---------------------------------------------!
    subroutine qsort_swap( order, first, second )
      integer, dimension(:) :: order
      integer               :: first, second
      integer               :: tmp
      tmp           = order(first)
      order(first)  = order(second)
      order(second) = tmp
    end subroutine qsort_swap
    !---------------------------------------------!
    integer function qsort_rand( lower, upper )
      integer               :: lower, upper
      real(8)               :: r
      call random_number(r)
      qsort_rand =  lower + nint(r * (upper-lower))
    end function qsort_rand
    !---------------------------------------------!
    function compare(f,g)
      implicit none
      integer               :: f,g
      integer               :: compare
      if(f<g) then
         compare=-1
      else
         compare=1
      endif
    end function compare
  end subroutine sort_array


  !##################################################################
  !              AUXILIARY COMPUTATIONAL ROUTINES
  !##################################################################
  recursive function binary_search(Ain,value) result(bsresult)
    integer,intent(in)           :: Ain(:), value
    integer                      :: bsresult, mid
    integer,dimension(size(Ain)) :: A,Order
    !
    a = ain
    call sort_array(a,Order)
    !
    mid = size(a)/2 + 1
    if (size(a) == 0) then
       bsresult = 0        ! not found
       !stop "binary_search error: value not found"
    else if (a(mid) > value) then
       bsresult= binary_search(a(:mid-1), value)
    else if (a(mid) < value) then
       bsresult = binary_search(a(mid+1:size(a)), value)
       if (bsresult /= 0) then
          bsresult = mid + bsresult
       end if
    else
       bsresult = mid      ! SUCCESS !
    end if
    !
    bsresult = Order(bsresult)
    !
  end function binary_search


  subroutine append_I(vec,val)
    integer,dimension(:),allocatable,intent(inout) :: vec
    integer,intent(in)                             :: val  
    integer,dimension(:),allocatable               :: tmp
    integer                                        :: n
    !
    if (allocated(vec)) then
       n = size(vec)
       allocate(tmp(n+1))
       tmp(:n) = vec
       call move_alloc(tmp,vec)
       n = n + 1
    else
       n = 1
       allocate(vec(n))
    end if
    !
    !Put val as last entry:
    vec(n) = val
    !
    if(allocated(tmp))deallocate(tmp)
  end subroutine append_I

  subroutine append_D(vec,val)
    real(8),dimension(:),allocatable,intent(inout) :: vec
    real(8),intent(in)                             :: val  
    real(8),dimension(:),allocatable               :: tmp
    integer                                        :: n
    !
    if (allocated(vec)) then
       n = size(vec)
       allocate(tmp(n+1))
       tmp(:n) = vec
       call move_alloc(tmp,vec)
       n = n + 1
    else
       n = 1
       allocate(vec(n))
    end if
    !
    !Put val as last entry:
    vec(n) = val
    !
    if(allocated(tmp))deallocate(tmp)
  end subroutine append_D

  subroutine append_Z(vec,val)
    complex(8),dimension(:),allocatable,intent(inout) :: vec
    complex(8),intent(in)                             :: val  
    complex(8),dimension(:),allocatable               :: tmp
    integer                                           :: n
    !
    if (allocated(vec)) then
       n = size(vec)
       allocate(tmp(n+1))
       tmp(:n) = vec
       call move_alloc(tmp,vec)
       n = n + 1
    else
       n = 1
       allocate(vec(n))
    end if
    !
    !Put val as last entry:
    vec(n) = val
    !
    if(allocated(tmp))deallocate(tmp)
  end subroutine append_Z






END MODULE SF_SPARSE_COMMON