Locating a Value in an Array
QUESTION: I have a specific value in a variable. I also have an vector of numbers. I would like to know which number in the vector is closest to this specific value. Is this possible in IDL?
ANSWER: Yes it is. Any you don't even have to write much code. IDL comes supplied with a function, named VALUE_LOCATE that will locate the index or bin into which the value will fall in the vector. You only have to check the two numbers in the vector on either side of the value to find the one that is closest to the value of interest. The only requirement is that the vector be monotonic.
Here is an example. Let's create a vector of random numbers, scaled from 0 to 100. We order the numbers monotonically by sorting them. Let our number be 35.49. The code looks like this:
numbers = Randomu(-3L, 100) * 100 vector = numbers[Sort(numbers)] number = 35.49 Print, vector, Format='(5(F8.5, 2x))' 1.34482 2.30946 3.78892 4.76031 5.30457 6.03181 6.53659 7.77949 8.06289 9.60160 10.37163 12.94588 14.23935 14.41299 15.02469 15.02520 15.05062 15.24265 16.03849 16.79812 17.62360 18.16930 20.05267 20.82457 20.86735 21.80577 22.12472 24.61838 25.24579 26.00675 26.92315 27.21987 27.58947 28.45428 28.65941 29.94843 30.92342 31.06136 37.60961 39.33375 40.37521 40.72172 43.31953 45.95522 46.11599 48.19300 48.34519 49.28960 49.95216 50.21213 51.35687 52.45319 52.61188 53.49831 53.85007 53.98211 54.26877 55.82491 58.07864 58.91006 58.92422 60.33495 60.47414 61.19120 63.82545 65.41214 66.57166 69.29688 69.95847 71.33233 71.97324 72.76243 73.09625 74.11166 74.14523 76.69299 77.33408 78.73590 79.13095 79.84335 80.40787 80.79518 81.81299 82.29399 82.47205 83.12454 84.32928 87.45479 88.86303 89.49042 89.79157 91.89655 94.76508 95.45557 95.70988 95.99263 96.17569 97.31122 98.47027 99.83736
Next, we find the "bin" or "index" that our number will fall into.
bin = Value_Locate(vector, number ) Print, bin 37 Print, vector[bin], vector[bin+1] 31.0614 37.6096
To find the closest value, we simple check the two vector values that bracket our chosen number. Make sure you check to see if your number actually lies within the values of the vector.
CASE 1 OF bin EQ -1: closest = vector[0] bin EQ (N_Elements(vector)-1): closest = vector[N_Elements(vector)-1] ELSE: IF Abs(vector[bin] - number) GT Abs(vector[bin+1] - number) THEN $ closest = vector[bin+1] ELSE closest = vector[bin] ENDCASE
In this case, the nearest value is vector[38] = 37.6096.
Stepehen Hallsworth points out to me that you can do this pretty much with a single line of IDL code, like this:
near = Min(Abs(vector - number), index)
Note that in this formulation vector doesn't need to be ordered. The variable index gives the index of the value in vector nearest to number. The variable near gives the absolute difference of the vector value at index from the number. The closest value is give by vector[index].
Copyright © 2003 David W. Fanning
Last Updated 19 September 2003