PRO find_elements_in_set, v1, v2, nmatch, lo_ind, hi_ind, status, V1_ALREADY_SORTED = v1_already_sorted, NO_PAR_CHECK = no_par_check
; Description: For each element in the set of data "v1", the module searches for the
; elements in the set of data "v2" that have exactly matching values. The
; module employs a fast binary search algorithm and it is for this reason
; that the set of data values "v2" must already be sorted into ascending
; order. For each element in the set of data "v1", the module returns the
; number of matching data values from "v2" via the vector "nmatch", and it
; returns the range of indices of the matching data values from "v2" via
; the vectors "lo_ind" and "hi_ind" representing the lower and upper bounds
; of the index range respectively.
;
; N.B: (i) The code for the binary search algorithm in this module is a
; copy of the code from the DanIDL module "binary_search.pro" and
; it has been written "in-line" in this module for reasons of
; efficiency. Any changes to "binary_search.pro" should therefore
; be reflected in this module aswell.
;
; (ii) This module works for any number type for the input parameters
; "v1" and "v2", and it also works if "v1" and "v2" are of string
; type.
;
; (iii) I have proved using proof by induction that the algorithm
; implemented in this code will always give the correct answer.
;
; Input Parameters:
;
; v1 - ANY SCALAR/VECTOR/ARRAY - The set of data for which exactly matching data
; values in "v2" are to be found. This parameter must
; be defined, and not a structure.
; v2 - ANY SCALAR/VECTOR/ARRAY - The set of data values to be searched for exact
; matches, already sorted into ascending order. This
; parameter should have the same variable type as the
; parameter "v1".
;
; Output Parameters:
;
; nmatch - LONG VECTOR - A one-dimensional vector with the same number of elements as
; the input parameter "v1", where each element represents the
; number of data values from "v2" that have exactly the same
; value as the corresponding element of "v1".
; lo_ind - LONG VECTOR - A one-dimensional vector with the same number of elements as
; the input parameter "v1", where each element represents the
; lower index in "v2" of the range of indices for the exactly
; matching data values from "v2" for the corresponding element
; of "v1". If there are no exactly matching data values in "v2"
; for an element of "v1", then the corresponding element of
; "lo_ind" is set to a value of "-1".
; hi_ind - LONG VECTOR - A one-dimensional vector with the same number of elements as
; the input parameter "v1", where each element represents the
; upper index in "v2" of the range of indices for the exactly
; matching data values from "v2" for the corresponding element
; of "v1". If there are no exactly matching data values in "v2"
; for an element of "v1", then the corresponding element of
; "hi_ind" is set to a value of "-1".
; status - INTEGER - If the module successfully completed its processing, then "status"
; is returned with a value of "1", otherwise it is returned with a
; value of "0".
;
; Keywords:
;
; If the keyword V1_ALREADY_SORTED is set (as "/V1_ALREADY_SORTED"), then the module
; will assume that the values of "v1" are sorted into ascending order. This option can
; be used to avoid a sort operation on the input parameter "v1", which allows the user
; to build more efficient code with this module.
;
; If the keyword NO_PAR_CHECK is set (as "/NO_PAR_CHECK"), then the module will not
; perform parameter checking on the input parameters, reducing module overheads.
;
; Author: Dan Bramich (dan.bramich@hotmail.co.uk)
;
; History:
;
; 07/10/2011 - Added the keyword V1_ALREADY_SORTED (dmb).
; 20/01/2010 - Module created (dmb).
;Set the default output parameter values
;Perform parameter checking if not instructed otherwise
;Check that "v1" is defined, and that it is not a structure
;Check that "v2" has the same variable type as "v1"
;Determine the number of elements in "v1" and "v2"
;Set up the output parameter vectors
;Determine the subscripts of "v1" when it is sorted into ascending order
;For each element of "v1"
;Determine the current element of "v1" when it is sorted into ascending order
;If the current element of "v1" is less than the minimum value of "v2", then there
;are no data values in "v2" that have exactly the same value as the current element
;of "v1", and the module will move on to the next element of "v1" when it is sorted
;into ascending order
;If the current element of "v1" is greater than the maximum value of "v2", then there
;are no data values in "v2" that have exactly the same value as "v1", and the module
;will exit the loop over the elements of "v1" because all of the remaining elements
;of "v1" when it is sorted into ascending order are also greater than the maximum
;value of "v2"
;Use a binary search algorithm to find a subscript of "v2" with a corresponding data
;value that exactly matches the value of the current element of "v1", if it exists.
;Note that for extra speed, the first index in the binary search is set to the lower
;index for the range of matching indices in "v2" for the previously considered element
;of "v1", since we are considering the elements of "v1" in ascending order.
;If there are no data values in "v2" that have exactly the same value as the current
;element of "v1", then the module will move on to the next element of "v1" when it is
;sorted into ascending order
;Determine the lowest subscript in the set of data values "v2" with a corresponding
;data value that exactly matches the value of the current element of "v1"
;Determine the highest subscript in the set of data values "v2" with a corresponding
;data value that exactly matches the value of the current element of "v1"
;Count the number of matching data values
;Save the range of indices for the exactly matching data values from "v2"
;Set "status" to "1"