Skip to content

stdlib_selection: correction of typos and addition of some checks #585

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Dec 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions doc/specs/stdlib_selection.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ which implements selection algorithms.
## Overview of the module

The module `stdlib_selection` defines two generic subroutines:

* `select` is used to find the k-th smallest entry of an array. The input
array is also modified in-place, and on return will be partially sorted
such that `all(array(1:k) <= array(k)))` and `all(array(k) <= array((k+1):size(array)))` is true.
Expand Down Expand Up @@ -159,7 +160,7 @@ Generic subroutine.

`array` : shall be a rank one array of any of the types:
`integer(int8)`, `integer(int16)`, `integer(int32)`, `integer(int64)`,
`real(sp)`, `real(dp)`, `real(xdp), `real(qp)`. It is an `intent(in)` argument. On input it is
`real(sp)`, `real(dp)`, `real(xdp)`, `real(qp)`. It is an `intent(in)` argument. On input it is
the array in which we search for the k-th smallest entry.

`indx`: shall be a rank one array with the same size as `array`, containing all integers
Expand Down Expand Up @@ -198,7 +199,7 @@ The code does not support `NaN` elements in `array`; it will run, but there is
no consistent interpretation given to the order of `NaN` entries of `array`
compared to other entries.

While it is essential that that `indx` contains a permutation of the integers `1:size(array)`,
While it is essential that `indx` contains a permutation of the integers `1:size(array)`,
the code does not check for this. For example if `size(array) == 4`, then we could have
`indx = [4, 2, 1, 3]` or `indx = [1, 2, 3, 4]`, but not `indx = [2, 1, 2, 4]`. It is the user's
responsibility to avoid such errors.
Expand Down
16 changes: 10 additions & 6 deletions src/stdlib_selection.fypp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
! The index arrays are of all INT_KINDS_TYPES

module stdlib_selection
!! Quickly find the k-th smallest value of an array, or the index of the k-th smallest value.
!! ([Specification](../page/specs/stdlib_selection.html))
!
! This code was modified from the "Coretran" implementation "quickSelect" by
! Leon Foks, https://github.com/leonfoks/coretran/tree/master/src/sorting
Expand Down Expand Up @@ -85,9 +87,10 @@ contains
r = size(a, kind=ip)
if(present(right)) r = right

if(k < 1_ip .or. k > size(a, kind=ip) .or. l > r .or. l < 1_ip .or. &
r > size(a, kind=ip)) then
error stop "select must have 1 <= k <= size(a), and 1 <= left <= right <= size(a)";
if(l > r .or. l < 1_ip .or. r > size(a, kind=ip) &
.or. k < l .or. k > r & !i.e. if k is not in the interval [l; r]
) then
error stop "select must have 1 <= left <= k <= right <= size(a)";
end if

searchk: do
Expand Down Expand Up @@ -201,9 +204,10 @@ contains
error stop "arg_select must have size(a) == size(indx)"
end if

if(k < 1_ip .or. k > size(a, kind=ip) .or. l > r .or. l < 1_ip .or. &
r > size(a, kind=ip)) then
error stop "arg_select must have 1 <= k <= size(a), and 1 <= left <= right <= size(a)";
if(l > r .or. l < 1_ip .or. r > size(a, kind=ip) &
.or. k < l .or. k > r & !i.e. if k is not in the interval [l; r]
) then
error stop "arg_select must have 1 <= left <= k <= right <= size(a)";
end if

searchk: do
Expand Down