diff --git a/doc/specs/stdlib_selection.md b/doc/specs/stdlib_selection.md index b6694047c..8523ef289 100644 --- a/doc/specs/stdlib_selection.md +++ b/doc/specs/stdlib_selection.md @@ -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. @@ -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 @@ -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. diff --git a/src/stdlib_selection.fypp b/src/stdlib_selection.fypp index 4a963c5b8..277fd2eb4 100644 --- a/src/stdlib_selection.fypp +++ b/src/stdlib_selection.fypp @@ -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 @@ -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 @@ -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