-
Notifications
You must be signed in to change notification settings - Fork 0
/
near_neighbour.pro
132 lines (98 loc) · 3.25 KB
/
near_neighbour.pro
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
;+
; NAME:
;
; NEAR_NEIGHBOUR.PRO
;
; PURPOSE:
;
; NEAR_NEIGHBOUR is used to find elements of
; an array that most closely correspond to the eleements
; another array. Especially useful for matching arrays
; containing times.
;
; KEYWORDS:
;
; NO_SORT: If this keyword is set, the inputs f and array
; are already sorted from lowest to highest value, so
; presorting the data is not required.
;
; INPUT:
;
; f: single variable or array of values to be matched to
;
; array: array to be matched to data with
; near_neighbour
;
; OUTPUT:
;
; an array or single value with dimension = n_elements(f),
; containing indices that point to the nearest_neighbour in variable 'array'
;
; If either the number being compared to or its nearest neighbour is NAN, then
; the corresponding output index is set to -1. WARNING: when referencing a single
; index of an array with -1, an error occurs, BUT if an array is referenced with an
; array of indices each occurence of -1 will return the first element of the array.
; ---> so check for -1s in the output before plotting
;
; EXAMPLE:
;
; matching_index = near_neighbour(f, array)
; plot, f, array[matching_index], psym = 3
;
; FILENAME:
;
; NEAR_NEIGHBOUR.PRO
;
; MOD HISTORY:
;
; Nov 3 2011: Stuart Bale's near_neighbour.pro adapted by
; Kosta Horaites to handle input arrays as well as scalars.
;
; Aug 16 2016: added NO_SORT keyword, to speed up program
; when inputs f and array are already sorted
;
;-
FUNCTION near_neighbour, f, array, NO_SORT = no_sort
n = n_elements(f)
IF n EQ 1 THEN BEGIN
IF (finite(f) EQ 0) THEN RETURN, -1
diff = abs(f - array)
ind = WHERE(diff EQ min(diff))
RETURN, ind[0]
ENDIF ELSE BEGIN
output = lonarr(n) - 1L ; -1 default for matching to non-finite numbers
ind = 0L
n = n_elements(f)
n_array_1 = n_elements(array) - 1L
IF KEYWORD_SET(no_sort) THEN BEGIN
FOR i = 0L, n - 1L DO BEGIN
check = 1
WHILE check AND (ind NE n_array_1) DO BEGIN
IF abs(array[ind + 1] - f[i]) LE $
abs(array[ind] - f[i]) $
THEN ind++ ELSE check = 0
ENDWHILE
IF FINITE(array[ind]) $
AND FINITE(f[i]) THEN $
output[i] = ind $
ELSE output[i] = -1
ENDFOR
ENDIF ELSE BEGIN
sorted_indices_f = sort(f)
sorted_indices_array = sort(array)
FOR i = 0L, n - 1L DO BEGIN
check = 1
WHILE check AND (ind NE n_array_1) DO BEGIN
IF abs(array[sorted_indices_array[ind + 1]] - f[sorted_indices_f[i]]) LE $
abs(array[sorted_indices_array[ind]] - f[sorted_indices_f[i]]) $
THEN ind++ ELSE check = 0
ENDWHILE
IF FINITE(array[sorted_indices_array[ind]]) $
AND FINITE(f[sorted_indices_f[i]]) THEN $
output[sorted_indices_f[i]] = sorted_indices_array[ind] $
ELSE output[sorted_indices_f[i]] = -1
ENDFOR
ENDELSE
RETURN, output
ENDELSE
END