m01ndf searches a strictly ordered vector of real numbers and returns the indices of the largest numbers in the vector which are smaller than or equal to the sought-after items.
The routine may be called by the names m01ndf or nagf_sort_realvec_vec_search.
3Description
m01ndf searches an array, $X$, of $n$ strictly-increasing real numbers, ${X}_{i}<{X}_{i+1}$, $i=1\dots (n-1)$, for the elements of an unordered array of $m$ real numbers, $Z$. If a value equal to a sought-after item ${Z}_{i}$ is not found in $X$, the index of the immediate lower value is returned. If ${Z}_{i}$ is less than ${X}_{1}$, $0$ is returned.
The routine implements the direct search algorithm presented as Algorithm 8 in Cannizzo (2018). It precomputes a scalar, $H$, and a reference vector of indices, $K$, that it uses to speed up searches of $X$. The length of $K$ is a function of the number of entries in $X$ and their values, and the routine provides a mechanism to compute what this length should be.
If the amount of memory required for $K$ is infeasible, m01ndf
implements offset-based binary search (Algorithm 5 in Cannizzo (2018)) as an alternative that does not require $K$ to be used.
See Section 9 for more information on the relative time complexities of the two search algorithms.
4References
Cannizzo F (2018) A fast and vectorizable alternative to binary search in O(1) with wide applicability to arrays of floating point numbers Journal of Parallel and Distributed Computing113 37–54
5Arguments
1: $\mathbf{valid}$ – LogicalInput
On entry: if valid is set to .TRUE. argument checking will be performed. If valid is set to .FALSE. m01ndf will be called without argument checking (which includes checking that array rv is sorted in strictly ascending order). See Section 9 for further details.
2: $\mathbf{mode}$ – IntegerInput
On entry: a code for selecting the operation to be performed by the routine. The first call to m01ndf must be made with ${\mathbf{mode}}=0$. This must be followed by a second setup call with ${\mathbf{mode}}=1$ or a combined setup and search call with ${\mathbf{mode}}=4$. Thereafter repeated searches of rv can be made through repeated calls with ${\mathbf{mode}}=2$.
${\mathbf{mode}}=0$
Compute h and lk. Following a call with ${\mathbf{mode}}=0$, k must be allocated to hold lk elements and then the routine must be called again with ${\mathbf{mode}}=1$ or $4$.
${\mathbf{mode}}=1$
Set up k (the reference vector) using the values of h and lk returned from a prior call to m01ndf with ${\mathbf{mode}}=0$.
${\mathbf{mode}}=2$
Direct search using h and k set up in prior calls to m01ndf with ${\mathbf{mode}}=0$, $1$ or $4$.
${\mathbf{mode}}=3$
Search using offset-based binary search, which does not require h or k to be used.
${\mathbf{mode}}=4$
Set up as with ${\mathbf{mode}}=1$ and follow by a single direct search as with ${\mathbf{mode}}=2$.
Constraint:
${\mathbf{mode}}=0$, $1$, $2$, $3$ or $4$.
3: $\mathbf{rv}\left({\mathbf{n}}\right)$ – Real (Kind=nag_wp) arrayInput
On entry: $X$, the real values to be searched.
Constraint:
elements of rv must be sorted in strictly ascending order.
4: $\mathbf{n}$ – IntegerInput
On entry: $n$, the number of real values to be searched.
Constraint:
${\mathbf{n}}\ge 2$.
5: $\mathbf{m1}$ – IntegerInput
On entry: the index of the first element of rv to be searched.
Constraint:
${\mathbf{m1}}\ge 1$.
6: $\mathbf{m2}$ – IntegerInput
On entry: the index of the last element of rv to be searched.
On exit: if ${\mathbf{mode}}\ne 0$, ${\mathbf{idx}}\left(i\right)$ contains the index of the largest entry in rv which is smaller than or equal to ${\mathbf{item}}\left(i\right)$.
10: $\mathbf{h}$ – Real (Kind=nag_wp)Communication
On entry: $H$, the reference scalar required by the direct search algorithm. If ${\mathbf{mode}}=0$, m01ndf calculates the value of h required by the direct search routine for the given values in rv. Otherwise, the value of h as declared in the (sub)routine from which m01ndf is called. If ${\mathbf{mode}}=0$, h is not referenced.
On exit: the value of h required by the direct search routine for the given values in rv.
Constraint:
if ${\mathbf{mode}}=1$, $2$ or $4$, h must be unchanged from the previous call to m01ndf.
On entry: if ${\mathbf{mode}}=2$, k, the reference vector from the previous call to m01ndf. If ${\mathbf{mode}}=0$ or $3$, k is not referenced.
On exit: if ${\mathbf{mode}}=1$, $2$ or $4$, the reference vector.
Constraint:
if ${\mathbf{mode}}=2$, k must be unchanged from the previous call to m01ndf.
12: $\mathbf{lk}$ – IntegerInput/Output
On entry: if ${\mathbf{mode}}=0$, m01ndf calculates the dimension of k required by the direct search routine for the given values in rv. Otherwise, the dimension of the array k as declared in the (sub)routine from which m01ndf is called. If ${\mathbf{mode}}=3$, lk is not referenced.
On exit: if ${\mathbf{mode}}=0$, the dimension of the array k required by the direct search routine for the given values in rv. Otherwise, the dimension of the array k as declared in the (sub)routine from which m01ndf is called.
Constraint:
if ${\mathbf{mode}}=1$, $2$ or $4$, lk must be unchanged from the previous call to m01ndf.
13: $\mathbf{ifail}$ – IntegerInput/Output
On entry: ifail must be set to $0$, $\mathrm{-1}$ or $1$ to set behaviour on detection of an error; these values have no effect when no error is detected.
A value of $0$ causes the printing of an error message and program execution will be halted; otherwise program execution continues. A value of $\mathrm{-1}$ means that an error message is printed while a value of $1$ means that it is not.
If halting is not appropriate, the value $\mathrm{-1}$ or $1$ is recommended. If message printing is undesirable, then the value $1$ is recommended. Otherwise, the value $0$ is recommended. When the value $-\mathbf{1}$ or $\mathbf{1}$ is used it is essential to test the value of ifail on exit.
On exit: ${\mathbf{ifail}}={\mathbf{0}}$ unless the routine detects an error or a warning has been flagged (see Section 6).
6Error Indicators and Warnings
If on entry ${\mathbf{ifail}}=0$ or $\mathrm{-1}$, explanatory error messages are output on the current error message unit (as defined by x04aaf).
Errors or warnings detected by the routine:
${\mathbf{ifail}}=1$
On entry, ${\mathbf{mode}}=\u27e8\mathit{\text{value}}\u27e9$. Constraint: ${\mathbf{mode}}=0$, $1$, $2$, $3$ or $4$.
${\mathbf{ifail}}=2$
On entry, rv must be sorted in strictly ascending order: ${\mathbf{rv}}\text{ element}\u27e8\mathit{\text{value}}\u27e9>\text{ element}\u27e8\mathit{\text{value}}\u27e9$.
${\mathbf{ifail}}=3$
On entry, ${\mathbf{m1}}=\u27e8\mathit{\text{value}}\u27e9$. Constraint: ${\mathbf{m1}}\ge 1$.
${\mathbf{ifail}}=4$
On entry, ${\mathbf{m1}}=\u27e8\mathit{\text{value}}\u27e9$, ${\mathbf{m2}}=\u27e8\mathit{\text{value}}\u27e9$, ${\mathbf{n}}=\u27e8\mathit{\text{value}}\u27e9$. Constraint: ${\mathbf{m1}}\le {\mathbf{m2}}\le {\mathbf{n}}$.
${\mathbf{ifail}}=5$
On entry, ${\mathbf{n}}=\u27e8\mathit{\text{value}}\u27e9$. Constraint: ${\mathbf{n}}\ge 2$.
${\mathbf{ifail}}=6$
On entry, ${\mathbf{m}}=\u27e8\mathit{\text{value}}\u27e9$. Constraint: ${\mathbf{m}}\ge 1$.
${\mathbf{ifail}}=7$
On entry, the values in rv are such that the required value of lk would overflow the current platform's largest positive integer value. This error should only appear when m01ndf is called with ${\mathbf{mode}}=0$ (i.e., when the routine is asked to calculate the required value of lk for the given rv).
${\mathbf{ifail}}=8$
Either m01ndf was not called with ${\mathbf{mode}}=0$, $1$ or $4$, or the values of h, k or lk may have become corrupted.
${\mathbf{ifail}}=-99$
An unexpected error has been triggered by this routine. Please
contact NAG.
See Section 7 in the Introduction to the NAG Library FL Interface for further information.
${\mathbf{ifail}}=-399$
Your licence key may have expired or may not have been installed correctly.
See Section 8 in the Introduction to the NAG Library FL Interface for further information.
${\mathbf{ifail}}=-999$
Dynamic memory allocation failed.
See Section 9 in the Introduction to the NAG Library FL Interface for further information.
7Accuracy
Not applicable.
8Parallelism and Performance
m01ndf is threaded by NAG for parallel execution in multithreaded implementations of the NAG Library.
Please consult the X06 Chapter Introduction for information on how to control and interrogate the OpenMP environment used within this routine. Please also consult the Users' Note for your implementation for any additional implementation-specific information.
9Further Comments
The argument valid should be used with caution. Set it to .FALSE. only if you are confident that the other arguments are correct, in particular that array rv is in fact arranged in strictly ascending order. If you wish to search the same array rv many times, you are recommended to set valid to .TRUE. on the first call of m01ndf and to .FALSE. on subsequent calls, in order to minimize the amount of time spent checking rv, which may be significant if rv is large.
The time taken by m01ndf to construct the reference vector (i.e., when the routine is called with ${\mathbf{mode}}=1$ or $4$) is $\mathit{O}\left(n\right)$. Note that the values stored in k depend on all entries of rv, and not just those in the interval $[{\mathbf{m1}},{\mathbf{m2}}]$. Thereafter, searching for m items using direct search (i.e., when the routine is called with ${\mathbf{mode}}=2$ or $4$) is $\mathit{O}\left(m\right)$. In contrast offset-based binary search (i.e., when the routine is called with ${\mathbf{mode}}=3$), does not require construction of the reference vector and has time complexity $\mathit{O}(m\hspace{0.17em}\mathrm{log}\left(n\right))$. Although this is the same as classical binary search, offset-based binary search may be faster in practice because the implementation does not feature conditional branches. Direct search is preferable when the overhead of constructing the reference vector can be offset by conducting multiple searches on an unchanged rv.
10Example
This example reads a list of real numbers and a list of sought-after items and performs the search for these items. The example demonstrates how to use m01ndf for both direct search (i.e., ${\mathbf{mode}}=4$) and offset-based binary search (${\mathbf{mode}}=3$).