m_sort.f90 Source File

This File Depends On

sourcefile~~m_sort.f90~~EfferentGraph sourcefile~m_sort.f90 m_sort.f90 sourcefile~m_variablekind.f90 m_variableKind.f90 sourcefile~m_variablekind.f90->sourcefile~m_sort.f90
Help

Files Dependent On This One

sourcefile~~m_sort.f90~~AfferentGraph sourcefile~m_sort.f90 m_sort.f90 sourcefile~m_maths.f90 m_maths.f90 sourcefile~m_sort.f90->sourcefile~m_maths.f90 sourcefile~iddynamicarray_class.f90 idDynamicArray_Class.f90 sourcefile~m_sort.f90->sourcefile~iddynamicarray_class.f90 sourcefile~scale_coretran.f90 scale_coretran.f90 sourcefile~m_sort.f90->sourcefile~scale_coretran.f90 sourcefile~rdynamicarray_class.f90 rDynamicArray_Class.f90 sourcefile~m_sort.f90->sourcefile~rdynamicarray_class.f90 sourcefile~idynamicarray_class.f90 iDynamicArray_Class.f90 sourcefile~m_sort.f90->sourcefile~idynamicarray_class.f90 sourcefile~ddynamicarray_class.f90 dDynamicArray_Class.f90 sourcefile~m_sort.f90->sourcefile~ddynamicarray_class.f90 sourcefile~m_tests.f90 m_tests.f90 sourcefile~m_sort.f90->sourcefile~m_tests.f90 sourcefile~m_maths.f90->sourcefile~scale_coretran.f90 sourcefile~m_maths.f90->sourcefile~m_tests.f90 sourcefile~m_kdtree.f90 m_KdTree.f90 sourcefile~m_maths.f90->sourcefile~m_kdtree.f90 sourcefile~iddynamicarray_class.f90->sourcefile~m_tests.f90 sourcefile~idargdynamicarray_class.f90 idArgDynamicArray_Class.f90 sourcefile~iddynamicarray_class.f90->sourcefile~idargdynamicarray_class.f90 sourcefile~rdynamicarray_class.f90->sourcefile~m_tests.f90 sourcefile~rargdynamicarray_class.f90 rArgDynamicArray_Class.f90 sourcefile~rdynamicarray_class.f90->sourcefile~rargdynamicarray_class.f90 sourcefile~idynamicarray_class.f90->sourcefile~m_tests.f90 sourcefile~idynamicarray_class.f90->sourcefile~m_kdtree.f90 sourcefile~idynamicarray_class.f90->sourcefile~idargdynamicarray_class.f90 sourcefile~idynamicarray_class.f90->sourcefile~rargdynamicarray_class.f90 sourcefile~dargdynamicarray_class.f90 dArgDynamicArray_Class.f90 sourcefile~idynamicarray_class.f90->sourcefile~dargdynamicarray_class.f90 sourcefile~iargdynamicarray_class.f90 iArgDynamicArray_Class.f90 sourcefile~idynamicarray_class.f90->sourcefile~iargdynamicarray_class.f90 sourcefile~ddynamicarray_class.f90->sourcefile~m_tests.f90 sourcefile~ddynamicarray_class.f90->sourcefile~dargdynamicarray_class.f90 sourcefile~test_coretran.f90 test_coretran.f90 sourcefile~m_tests.f90->sourcefile~test_coretran.f90 sourcefile~m_kdtree.f90->sourcefile~scale_coretran.f90 sourcefile~m_kdtree.f90->sourcefile~m_tests.f90 sourcefile~idargdynamicarray_class.f90->sourcefile~m_tests.f90 sourcefile~rargdynamicarray_class.f90->sourcefile~m_tests.f90 sourcefile~dargdynamicarray_class.f90->sourcefile~m_tests.f90 sourcefile~dargdynamicarray_class.f90->sourcefile~m_kdtree.f90 sourcefile~iargdynamicarray_class.f90->sourcefile~m_tests.f90
Help

Source Code


Source Code

  module m_sort
    !! Module containing in-place and indirect routines to sort an array of numbers.
    !!
    !! Uses an introspective sort on a set of number. See this http://www.geeksforgeeks.org/know-your-sorting-algorithm-set-2-introsort-cs-sorting-weapon/ for more information
    !!
    !! To begin, a quicksort with a median of three pivot is used until the size of the array is less than 16.  At this point, an insertion sort is used to reduce cache overhead and tail recursion.
    !! Unfortunately, a quicksort is not ideal for sorted/almost sorted arrays or arrays with duplicate values.  Therefore if the number of iterations exceededs a threshold, a heapsort is used instead.
    !! This provides a robust sorting algorithm that is still very fast for almost sorted arrays.
    !!
    !! In this implementation, the quicksort and heapsort are unstable sorts. A stable merge sort is therefore provided as an alternative but it has an order(N) memory overhead.
    !!
    !! Often, the numbers wish to be maintained in their given order, so with an O(N) memory overhead we can sort an integer array instead by calling argsort()
    !!
    !! See [[sort]] and [[argSort]] for more information.
  use variableKind
  
  implicit none

  private

  public  :: sort

  interface sort
    !!Use an in-place introspection sort on an array of numbers
    !!
    !!Example usage
    !!```fortran
    !!program sortTest
    !!use variableKind, only: i32, r64
    !!use m_strings, only: str
    !!use m_allocate, only: allocate
    !!use m_random, only: rngInteger, rngNormal
    !!use m_arrays, only: arange, isSorted
    !!use m_sort, only: sort
    !!real(r64),allocatable :: d1D(:)
    !!integer(i32),allocatable :: i1D(:)
    !!integer(i32) :: N
    !!
    !!N = 10000
    !!write(*,'(a)') 'In-place sort a 10000 length array of random double precision numbers'
    !!call allocate(d1D,N)
    !!call rngNormal(d1D)
    !!call sort(d1D)
    !!write(*,'(a)') 'Double array is sorted? '//str(isSorted(d1D))
    !!write(*,'(a)') 'In-place sort a 10000 length array of random integers''
    !!call allocate(i1D,N)
    !!call rngInteger(i1D)
    !!call sort(i1D)
    !!write(*,'(a)') 'Integer array is sorted? '//str(isSorted(i1D))
    !!end program
    !!```
    module subroutine sort_i1D(this, stable)
      !! Interfaced with [[sort]]
      integer(i32) :: this(:)
      logical, optional :: stable
    end subroutine
    module subroutine sort_id1D(this, stable)
      !! Interfaced with [[sort]]
      integer(i64) :: this(:)
      logical, optional :: stable
    end subroutine
    module subroutine sort_r1D(this, stable)
      !! Interfaced with [[sort]]
      real(r32) :: this(:)
      logical, optional :: stable
    end subroutine
    module subroutine sort_d1D(this, stable)
      !! Interfaced with [[sort]]
      real(r64) :: this(:)
      logical, optional :: stable
    end subroutine
  end interface
  private :: sort_i1D, sort_id1D, sort_r1D, sort_d1D

  public :: argSort

  interface argSort
    !!Use an indirect introspection sort on an array of numbers
    !!
    !!Example usage
    !!```fortran
    !!program argSortTest
    !!use variableKind
    !!use m_strings, only: str
    !!use m_random, only: rngInteger, rngNormal
    !!use m_arrays, only: arange, isSorted
    !!use m_Sort, only: argSort
    !!real(r64),allocatable :: d1D(:)
    !!integer(i32),allocatable :: i1D(:)
    !!integer(i32),allocatable :: indx(:)
    !!integer(i32) :: i, N
    !!
    !!N=10000
    !!call allocate(indx, N)
    !!call arange(indx, 1, N)
    !!call allocate(d1D, N)
    !!call rngNormal(d1D)
    !!call argSort(d1D, indx)
    !!write(*,'(a)') 'Double array is indirectly sorted? '//str(isSorted(d1D(indx)))
    !!
    !!call arange(indx, 1, N)
    !!call allocate(i1D,N)
    !!call rngInteger(i1D)
    !!call argSort(i1D, indx)
    !!write(*,'(a)') 'Integer array is indirectly sorted? '//str(isSorted(i1D(indx)))
    !!end program
    !!```
    module subroutine argSort_i1D(this, i, stable)
      !! Interfaced with [[argSort]]
      integer(i32) :: this(:) !! 1D array
      integer(i32) :: i(:) !! Index to sort
      logical, optional :: stable !! Stable sort?
    end subroutine
    module subroutine argSort_id1D(this, i, stable)
      !! Interfaced with [[argSort]]
      integer(i64) :: this(:) !! 1D array
      integer(i32) :: i(:) !! Index to sort
      logical, optional :: stable !! Stable sort?
    end subroutine
    module subroutine argSort_r1D(this, i, stable)
      !! Interfaced with [[argSort]]
      real(r32) :: this(:) !! 1D array
      integer(i32) :: i(:) !! Index to sort
      logical, optional :: stable !! Stable sort?
    end subroutine
    module subroutine argSort_d1D(this, i, stable)
      !! Interfaced with [[argSort]]
      real(r64) :: this(:) !! 1D array
      integer(i32) :: i(:) !! Index to sort
      logical, optional :: stable !! Stable sort?
    end subroutine
  end interface
  private :: argSort_i1D, argSort_id1D, argSort_r1D, argSort_d1D

  private :: introsort
  interface introsort
    !! Perform an in-place introspective sort on an array
    module subroutine introsort_r1D(this)
      !! Interfaced with [[introsort]]
      real(r32) :: this(:) !! 1D array
    end subroutine
    module subroutine introsort_d1D(this)
      !! Interfaced with [[introsort]]
      real(r64) :: this(:) !! 1D array
    end subroutine
    module subroutine introsort_i1D(this)
      !! Interfaced with [[introsort]]
      integer(i32) :: this(:) !! 1D array
    end subroutine
    module subroutine introsort_id1D(this)
      !! Interfaced with [[introsort]]
      integer(i64) :: this(:) !! 1D array
    end subroutine
  end interface

  private :: argIntrosort
  interface argintrosort
    !! Perform an indirect introsort on an array
    module subroutine argintrosort_r1D(this,i)
      !! Interfaced with [[argIntrosort]]
      real(r32) :: this(:) !! 1D array
      integer(i32) :: i(:) !! Sort this integer key
    end subroutine
    module subroutine argintrosort_d1D(this,i)
      !! Interfaced with [[argIntrosort]]
      real(r64) :: this(:) !! 1D array
      integer(i32) :: i(:) !! Sort this integer key
    end subroutine
    module subroutine argintrosort_i1D(this,i)
      !! Interfaced with [[argIntrosort]]
      integer(i32) :: this(:) !! 1D array
      integer(i32) :: i(:) !! Sort this integer key
    end subroutine
    module subroutine argintrosort_id1D(this,i)
      !! Interfaced with [[argIntrosort]]
      integer(i64) :: this(:) !! 1D array
      integer(i32) :: i(:) !! Sort this integer key
    end subroutine
  end interface

  interface MergeSort
    !! Perform an in-place stable merge sort on an array
    module subroutine mergesort_r1D(this)
      !! Interf aced with [[mergesort]]
      real(r32):: this(:) !! 1D array
    end subroutine
    module subroutine mergesort_d1D(this)
      !! Interfaced with [[mergesort]]
      real(r64) :: this(:) !! 1D array
    end subroutine
    module subroutine mergesort_i1D(this)
      !! Interfaced with [[mergesort]]
      integer(i32) :: this(:) !! 1D array
    end subroutine
    module subroutine mergesort_id1D(this)
      !! Interfaced with [[mergesort]]
      integer(i64) :: this(:) !! 1D array
    end subroutine
  end interface

  interface argMergeSort
    !! Perform an indirect stable merge sort on an array
    module subroutine argmergesort_r1D(this,i)
      !! Interfaced with [[argmergesort]]
      real(r32) :: this(:) !! 1D array
      integer(i32) :: i(:) !! Sort this integer key
    end subroutine
    module subroutine argmergesort_d1D(this,i)
      !! Interfaced with [[argmergesort]]
      real(r64) :: this(:) !! 1D array
      integer(i32) :: i(:) !! Sort this integer key
    end subroutine
    module subroutine argmergesort_i1D(this,i)
      !! Interfaced with [[argmergesort]]
      integer(i32) :: this(:) !! 1D array
      integer(i32) :: i(:) !! Sort this integer key
    end subroutine
    module subroutine argmergesort_id1D(this,i)
      !! Interfaced with [[argmergesort]]
      integer(i64) :: this(:) !! 1D array
      integer(i32) :: i(:) !! Sort this integer key
    end subroutine
  end interface

  public :: insertionSort

  interface insertionsort
    !! Perform an in-place insertion sort on an array
    module subroutine insertionsort_r1D(this,iLeft,iRight)
      !! Interfaced with [[insertionsort]]
      real(r32) :: this(:) !! 1D array
      integer(i32) :: iLeft !! Left index
      integer(i32) :: iRight !! Right index
    end subroutine
    module subroutine insertionsort_d1D(this,iLeft,iRight)
      !! Interfaced with [[insertionsort]]
      real(r64) :: this(:) !! 1D array
      integer(i32) :: iLeft !! Left index
      integer(i32) :: iRight !! Right index
    end subroutine
    module subroutine insertionsort_i1D(this,iLeft,iRight)
      !! Interfaced with [[insertionsort]]
      integer(i32) :: this(:) !! 1D array
      integer(i32) :: iLeft !! Left index
      integer(i32) :: iRight !! Right index
    end subroutine
    module subroutine insertionsort_id1D(this,iLeft,iRight)
      !! Interfaced with [[insertionsort]]
      integer(i64) :: this(:) !! 1D array
      integer(i32) :: iLeft !! Left index
      integer(i32) :: iRight !! Right index
    end subroutine
  end interface
  private :: insertionsort_r1D, insertionsort_d1D, insertionsort_i1D, insertionsort_id1D

  public :: argInsertionsort

  interface argInsertionsort
    !! Perform an indirect insertion sort on an array
    module subroutine argInsertionsort_r1D(this,indx,iLeft,iRight)
      !! Interfaced with [[arginsertionsort]]
      real(r32) :: this(:) !! 1D array
      integer(i32) :: indx(:) !! Sort this integer key
      integer(i32) :: iLeft !! Left index
      integer(i32) :: iRight !! Right index
    end subroutine
    module subroutine argInsertionsort_d1D(this,indx,iLeft,iRight)
      !! Interfaced with [[arginsertionsort]]
      real(r64) :: this(:) !! 1D array
      integer(i32) :: indx(:) !! Sort this integer key
      integer(i32) :: iLeft !! Left index
      integer(i32) :: iRight !! Right index
    end subroutine
    module subroutine argInsertionsort_i1D(this,indx,iLeft,iRight)
      !! Interfaced with [[arginsertionsort]]
      integer(i32) :: this(:) !! 1D array
      integer(i32) :: indx(:) !! Sort this integer key
      integer(i32) :: iLeft !! Left index
      integer(i32) :: iRight !! Right index
    end subroutine
    module subroutine argInsertionsort_id1D(this,indx,iLeft,iRight)
      !! Interfaced with [[arginsertionsort]]
      integer(i64) :: this(:) !! 1D array
      integer(i32) :: indx(:) !! Sort this integer key
      integer(i32) :: iLeft !! Left index
      integer(i32) :: iRight !! Right index
    end subroutine
  end interface
  private :: argInsertionsort_r1D, argInsertionsort_d1D, argInsertionsort_i1D, argInsertionsort_id1D

  private :: heapsort
  interface heapsort
    !! Perform an in-place heapsort on an array
    module subroutine heapsort_r1D(this)
      !! Interfaced with heapsort()
      real(r32) :: this(0:) !! 1D array
    end subroutine
    module subroutine heapsort_d1D(this)
      !! Interfaced with heapsort()
      real(r64):: this(0:) !! 1D array
    end subroutine
    module subroutine heapsort_i1D(this)
      !! Interfaced with heapsort()
      integer(i32):: this(0:) !! 1D array
    end subroutine
    module subroutine heapsort_id1D(this)
      !! Interfaced with heapsort()
      integer(i64):: this(0:) !! 1D array
    end subroutine
  end interface

  private :: argHeapsort
  interface argHeapsort
    !! Perform an indirect heapsort on an array
    module subroutine argHeapsort_r1D(this,indx)
      !! Interfaced with argHeapsort()
      real(r32) :: this(:) !! 1D array
      integer(i32) :: indx(0:) !! Sort this integer key
    end subroutine
    module subroutine argHeapsort_d1D(this,indx)
      !! Interfaced with argHeapsort()
      real(r64):: this(:) !! 1D array
      integer(i32) :: indx(0:) !! Sort this integer key
    end subroutine
    module subroutine argHeapsort_i1D(this,indx)
      !! Interfaced with argHeapsort()
      integer(i32):: this(:) !! 1D array
      integer(i32) :: indx(0:) !! Sort this integer key
    end subroutine
    module subroutine argHeapsort_id1D(this,indx)
      !! Interfaced with argHeapsort()
      integer(i64):: this(:) !! 1D array
      integer(i32) :: indx(0:) !! Sort this integer key
    end subroutine
  end interface
  
  end module