This module implements overloaded sorting subroutines named ORD_SORT,
SORT_INDEX, and SORT, that each can be used to sort two kinds
of INTEGER arrays, two kinds of REAL arrays, character(len=*) arrays
By default sorting is in order of
increasing value, but there is an option to sort in decreasing order.
All the subroutines have worst case run time performance of O(N Ln(N)),
but on largely sorted data ORD_SORT and SORT_INDEX can have a run time
performance of O(N).
ORD_SORT is a translation of the "Rust" sort sorting algorithm in
slice.rs:
https://github.com/rust-lang/rust/blob/90eb44a5897c39e3dff9c7e48e3973671dcd9496/src/liballoc/slice.rs
which in turn is inspired by the timsort algorithm of Tim Peters,
http://svn.python.org/projects/python/trunk/Objects/listsort.txt.
ORD_SORT is a hybrid stable comparison algorithm combining merge sort,
and insertion sort. It is always at worst O(N Ln(N)) in sorting random
data, having a performance about 25% slower than SORT on such
data, but has much better performance than SORT on partially
sorted data, having O(N) performance on uniformly non-increasing or
non-decreasing data.
SORT_INDEX is a modification of ORD_SORT so that in addition to
sorting the input array, it returns the indices that map to a
stable sort of the original array. These indices are
intended to be used to sort data that is correlated with the input
array, e.g., different arrays in a database, different columns of a
rank 2 array, different elements of a derived type. It is less
efficient than ORD_SORT at sorting a simple array.
SORT uses the INTROSORT sorting algorithm of David Musser,
http://www.cs.rpi.edu/~musser/gp/introsort.ps. introsort is a hybrid
unstable comparison algorithm combining quicksort, insertion sort, and
heap sort. While this algorithm is always O(N Ln(N)) it is relatively
fast on randomly ordered data, but inconsistent in performance on partly
sorted data, sometimes having merge sort performance, sometimes having
better than quicksort performance. UNORD_SOORT is about 25%
more efficient than ORD_SORT at sorting purely random data, but af an
order of Ln(N) less efficient at sorting partially sorted data.
The generic subroutine implementing the SORT algorithm to return
an input array with its elements sorted in order of (non-)decreasing
value. Its use has the syntax:
call sort( array[, reverse] )
with the arguments:
intent(inout)
argument of any of the types integer(int8), integer(int16),
integer(int32), integer(int64), real(real32), real(real64),
real(real128), character(*), type(string_type),
type(bitset_64), type(bitset_large). If both the type
of array is real and at least one of the elements is a NaN, then
the ordering of the result is undefined. Otherwise it is defined to be the
original elements in non-decreasing order.reverse (optional): shall be a scalar of type default logical. It
is an intent(in) argument. If present with a value of .true. then
array will be sorted in order of non-increasing values in unstable
order. Otherwise index will sort array in order of non-decreasing
values in unstable order. ...
! Read random data from a file
call read_file( 'dummy_file', array )
! Sort the random data
call sort( array )
! Process the sorted data
call array_search( array, values )
...
The generic subroutine interface implementing the ORD_SORT algorithm,
a translation to Fortran 2008, of the "Rust" sort algorithm found in
slice.rs
https://github.com/rust-lang/rust/blob/90eb44a5897c39e3dff9c7e48e3973671dcd9496/src/liballoc/slice.rs#L2159
ORD_SORT is a hybrid stable comparison algorithm combining merge sort,
and insertion sort.
It is always at worst O(N Ln(N)) in sorting random
data, having a performance about 25% slower than SORT on such
data, but has much better performance than SORT on partially
sorted data, having O(N) performance on uniformly non-increasing or
non-decreasing data.
char_ord_sort( array ) sorts the input ARRAY of type character(len=*)
using a hybrid sort based on the "Rust" sort algorithm found in slice.rs
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| character(len=*), | intent(inout) | :: | array(0:) | |||
| character(len=len), | intent(out), | optional | :: | work(0:) | ||
| logical, | intent(in), | optional | :: | reverse |
dp_ord_sort( array ) sorts the input ARRAY of type real(dp)
using a hybrid sort based on the "Rust" sort algorithm found in slice.rs
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=dp), | intent(inout) | :: | array(0:) | |||
| real(kind=dp), | intent(out), | optional | :: | work(0:) | ||
| logical, | intent(in), | optional | :: | reverse |
int32_ord_sort( array ) sorts the input ARRAY of type integer(int32)
using a hybrid sort based on the "Rust" sort algorithm found in slice.rs
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer(kind=int32), | intent(inout) | :: | array(0:) | |||
| integer(kind=int32), | intent(out), | optional | :: | work(0:) | ||
| logical, | intent(in), | optional | :: | reverse |
int64_ord_sort( array ) sorts the input ARRAY of type integer(int64)
using a hybrid sort based on the "Rust" sort algorithm found in slice.rs
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer(kind=int64), | intent(inout) | :: | array(0:) | |||
| integer(kind=int64), | intent(out), | optional | :: | work(0:) | ||
| logical, | intent(in), | optional | :: | reverse |
sp_ord_sort( array ) sorts the input ARRAY of type real(sp)
using a hybrid sort based on the "Rust" sort algorithm found in slice.rs
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=sp), | intent(inout) | :: | array(0:) | |||
| real(kind=sp), | intent(out), | optional | :: | work(0:) | ||
| logical, | intent(in), | optional | :: | reverse |
The generic subroutine interface implementing the LSD radix sort algorithm, see https://en.wikipedia.org/wiki/Radix_sort for more details. It is always O(N) in sorting random data, but need a O(N) buffer. (Specification)
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=dp), | intent(inout), | dimension(:), target | :: | array | ||
| real(kind=dp), | intent(inout), | optional, | dimension(:), target | :: | work | |
| logical, | intent(in), | optional | :: | reverse |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer(kind=int32), | intent(inout), | dimension(:) | :: | array | ||
| integer(kind=int32), | intent(inout), | optional, | dimension(:), target | :: | work | |
| logical, | intent(in), | optional | :: | reverse |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer(kind=int64), | intent(inout), | dimension(:) | :: | array | ||
| integer(kind=int64), | intent(inout), | optional, | dimension(:), target | :: | work | |
| logical, | intent(in), | optional | :: | reverse |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=sp), | intent(inout), | dimension(:), target | :: | array | ||
| real(kind=sp), | intent(inout), | optional, | dimension(:), target | :: | work | |
| logical, | intent(in), | optional | :: | reverse |
The generic subroutine interface implementing the SORT algorithm, based
on the introsort of David Musser.
(Specification)
char_sort( array[, reverse] ) sorts the input ARRAY of type character(len=*)
using a hybrid sort based on the introsort of David Musser.
The algorithm is of order O(N Ln(N)) for all inputs.
Because it relies on quicksort, the coefficient of the O(N Ln(N))
behavior is small for random data compared to other sorting algorithms.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| character(len=*), | intent(inout) | :: | array(0:) | |||
| logical, | intent(in), | optional | :: | reverse |
dp_sort( array[, reverse] ) sorts the input ARRAY of type real(dp)
using a hybrid sort based on the introsort of David Musser.
The algorithm is of order O(N Ln(N)) for all inputs.
Because it relies on quicksort, the coefficient of the O(N Ln(N))
behavior is small for random data compared to other sorting algorithms.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=dp), | intent(inout) | :: | array(0:) | |||
| logical, | intent(in), | optional | :: | reverse |
int32_sort( array[, reverse] ) sorts the input ARRAY of type integer(int32)
using a hybrid sort based on the introsort of David Musser.
The algorithm is of order O(N Ln(N)) for all inputs.
Because it relies on quicksort, the coefficient of the O(N Ln(N))
behavior is small for random data compared to other sorting algorithms.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer(kind=int32), | intent(inout) | :: | array(0:) | |||
| logical, | intent(in), | optional | :: | reverse |
int64_sort( array[, reverse] ) sorts the input ARRAY of type integer(int64)
using a hybrid sort based on the introsort of David Musser.
The algorithm is of order O(N Ln(N)) for all inputs.
Because it relies on quicksort, the coefficient of the O(N Ln(N))
behavior is small for random data compared to other sorting algorithms.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer(kind=int64), | intent(inout) | :: | array(0:) | |||
| logical, | intent(in), | optional | :: | reverse |
sp_sort( array[, reverse] ) sorts the input ARRAY of type real(sp)
using a hybrid sort based on the introsort of David Musser.
The algorithm is of order O(N Ln(N)) for all inputs.
Because it relies on quicksort, the coefficient of the O(N Ln(N))
behavior is small for random data compared to other sorting algorithms.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=sp), | intent(inout) | :: | array(0:) | |||
| logical, | intent(in), | optional | :: | reverse |
The generic subroutine interface implementing the SORT_INDEX algorithm,
based on the "Rust" sort algorithm found in slice.rs
https://github.com/rust-lang/rust/blob/90eb44a5897c39e3dff9c7e48e3973671dcd9496/src/liballoc/slice.rs#L2159
but modified to return an array of indices that would provide a stable
sort of the rank one ARRAY input.
The indices by default correspond to a
non-decreasing sort, but if the optional argument REVERSE is present
with a value of .TRUE. the indices correspond to a non-increasing sort.
char_sort_index_default( array, index[, work, iwork, reverse] ) sorts
an input ARRAY of type character(len=*)
using a hybrid sort based on the "Rust" sort algorithm found in slice.rs
and returns the sorted ARRAY and an array INDEX of indices in the
order that would sort the input ARRAY in the desired direction.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| character(len=*), | intent(inout) | :: | array(0:) | |||
| integer(kind=int_index), | intent(out) | :: | index(0:) | |||
| character(len=len), | intent(out), | optional | :: | work(0:) | ||
| integer(kind=int_index), | intent(out), | optional | :: | iwork(0:) | ||
| logical, | intent(in), | optional | :: | reverse |
char_sort_index_low( array, index[, work, iwork, reverse] ) sorts
an input ARRAY of type character(len=*)
using a hybrid sort based on the "Rust" sort algorithm found in slice.rs
and returns the sorted ARRAY and an array INDEX of indices in the
order that would sort the input ARRAY in the desired direction.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| character(len=*), | intent(inout) | :: | array(0:) | |||
| integer(kind=int_index_low), | intent(out) | :: | index(0:) | |||
| character(len=len), | intent(out), | optional | :: | work(0:) | ||
| integer(kind=int_index_low), | intent(out), | optional | :: | iwork(0:) | ||
| logical, | intent(in), | optional | :: | reverse |
dp_sort_index_default( array, index[, work, iwork, reverse] ) sorts
an input ARRAY of type real(dp)
using a hybrid sort based on the "Rust" sort algorithm found in slice.rs
and returns the sorted ARRAY and an array INDEX of indices in the
order that would sort the input ARRAY in the desired direction.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=dp), | intent(inout) | :: | array(0:) | |||
| integer(kind=int_index), | intent(out) | :: | index(0:) | |||
| real(kind=dp), | intent(out), | optional | :: | work(0:) | ||
| integer(kind=int_index), | intent(out), | optional | :: | iwork(0:) | ||
| logical, | intent(in), | optional | :: | reverse |
dp_sort_index_low( array, index[, work, iwork, reverse] ) sorts
an input ARRAY of type real(dp)
using a hybrid sort based on the "Rust" sort algorithm found in slice.rs
and returns the sorted ARRAY and an array INDEX of indices in the
order that would sort the input ARRAY in the desired direction.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=dp), | intent(inout) | :: | array(0:) | |||
| integer(kind=int_index_low), | intent(out) | :: | index(0:) | |||
| real(kind=dp), | intent(out), | optional | :: | work(0:) | ||
| integer(kind=int_index_low), | intent(out), | optional | :: | iwork(0:) | ||
| logical, | intent(in), | optional | :: | reverse |
int32_sort_index_default( array, index[, work, iwork, reverse] ) sorts
an input ARRAY of type integer(int32)
using a hybrid sort based on the "Rust" sort algorithm found in slice.rs
and returns the sorted ARRAY and an array INDEX of indices in the
order that would sort the input ARRAY in the desired direction.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer(kind=int32), | intent(inout) | :: | array(0:) | |||
| integer(kind=int_index), | intent(out) | :: | index(0:) | |||
| integer(kind=int32), | intent(out), | optional | :: | work(0:) | ||
| integer(kind=int_index), | intent(out), | optional | :: | iwork(0:) | ||
| logical, | intent(in), | optional | :: | reverse |
int32_sort_index_low( array, index[, work, iwork, reverse] ) sorts
an input ARRAY of type integer(int32)
using a hybrid sort based on the "Rust" sort algorithm found in slice.rs
and returns the sorted ARRAY and an array INDEX of indices in the
order that would sort the input ARRAY in the desired direction.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer(kind=int32), | intent(inout) | :: | array(0:) | |||
| integer(kind=int_index_low), | intent(out) | :: | index(0:) | |||
| integer(kind=int32), | intent(out), | optional | :: | work(0:) | ||
| integer(kind=int_index_low), | intent(out), | optional | :: | iwork(0:) | ||
| logical, | intent(in), | optional | :: | reverse |
int64_sort_index_default( array, index[, work, iwork, reverse] ) sorts
an input ARRAY of type integer(int64)
using a hybrid sort based on the "Rust" sort algorithm found in slice.rs
and returns the sorted ARRAY and an array INDEX of indices in the
order that would sort the input ARRAY in the desired direction.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer(kind=int64), | intent(inout) | :: | array(0:) | |||
| integer(kind=int_index), | intent(out) | :: | index(0:) | |||
| integer(kind=int64), | intent(out), | optional | :: | work(0:) | ||
| integer(kind=int_index), | intent(out), | optional | :: | iwork(0:) | ||
| logical, | intent(in), | optional | :: | reverse |
int64_sort_index_low( array, index[, work, iwork, reverse] ) sorts
an input ARRAY of type integer(int64)
using a hybrid sort based on the "Rust" sort algorithm found in slice.rs
and returns the sorted ARRAY and an array INDEX of indices in the
order that would sort the input ARRAY in the desired direction.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer(kind=int64), | intent(inout) | :: | array(0:) | |||
| integer(kind=int_index_low), | intent(out) | :: | index(0:) | |||
| integer(kind=int64), | intent(out), | optional | :: | work(0:) | ||
| integer(kind=int_index_low), | intent(out), | optional | :: | iwork(0:) | ||
| logical, | intent(in), | optional | :: | reverse |
sp_sort_index_default( array, index[, work, iwork, reverse] ) sorts
an input ARRAY of type real(sp)
using a hybrid sort based on the "Rust" sort algorithm found in slice.rs
and returns the sorted ARRAY and an array INDEX of indices in the
order that would sort the input ARRAY in the desired direction.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=sp), | intent(inout) | :: | array(0:) | |||
| integer(kind=int_index), | intent(out) | :: | index(0:) | |||
| real(kind=sp), | intent(out), | optional | :: | work(0:) | ||
| integer(kind=int_index), | intent(out), | optional | :: | iwork(0:) | ||
| logical, | intent(in), | optional | :: | reverse |
sp_sort_index_low( array, index[, work, iwork, reverse] ) sorts
an input ARRAY of type real(sp)
using a hybrid sort based on the "Rust" sort algorithm found in slice.rs
and returns the sorted ARRAY and an array INDEX of indices in the
order that would sort the input ARRAY in the desired direction.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=sp), | intent(inout) | :: | array(0:) | |||
| integer(kind=int_index_low), | intent(out) | :: | index(0:) | |||
| real(kind=sp), | intent(out), | optional | :: | work(0:) | ||
| integer(kind=int_index_low), | intent(out), | optional | :: | iwork(0:) | ||
| logical, | intent(in), | optional | :: | reverse |