1 /* lstcld.f -- translated by f2c (version 19980913).
2 You must link the resulting object file with the libraries:
3 -lf2c -lm (in that order)
4 */
5
6 #include "f2c.h"
7
8 /* $Procedure LSTCLD ( Last closest double precision array element ) */
lstcld_(doublereal * x,integer * n,doublereal * array)9 integer lstcld_(doublereal *x, integer *n, doublereal *array)
10 {
11 /* System generated locals */
12 integer ret_val;
13
14 /* Local variables */
15 integer j, begin, items, middle, end;
16
17 /* $ Abstract */
18
19 /* Given a number X and an array of non-decreasing numbers, find */
20 /* the index of the array element whose value is closest to X. */
21
22 /* $ Disclaimer */
23
24 /* THIS SOFTWARE AND ANY RELATED MATERIALS WERE CREATED BY THE */
25 /* CALIFORNIA INSTITUTE OF TECHNOLOGY (CALTECH) UNDER A U.S. */
26 /* GOVERNMENT CONTRACT WITH THE NATIONAL AERONAUTICS AND SPACE */
27 /* ADMINISTRATION (NASA). THE SOFTWARE IS TECHNOLOGY AND SOFTWARE */
28 /* PUBLICLY AVAILABLE UNDER U.S. EXPORT LAWS AND IS PROVIDED "AS-IS" */
29 /* TO THE RECIPIENT WITHOUT WARRANTY OF ANY KIND, INCLUDING ANY */
30 /* WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A */
31 /* PARTICULAR USE OR PURPOSE (AS SET FORTH IN UNITED STATES UCC */
32 /* SECTIONS 2312-2313) OR FOR ANY PURPOSE WHATSOEVER, FOR THE */
33 /* SOFTWARE AND RELATED MATERIALS, HOWEVER USED. */
34
35 /* IN NO EVENT SHALL CALTECH, ITS JET PROPULSION LABORATORY, OR NASA */
36 /* BE LIABLE FOR ANY DAMAGES AND/OR COSTS, INCLUDING, BUT NOT */
37 /* LIMITED TO, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND, */
38 /* INCLUDING ECONOMIC DAMAGE OR INJURY TO PROPERTY AND LOST PROFITS, */
39 /* REGARDLESS OF WHETHER CALTECH, JPL, OR NASA BE ADVISED, HAVE */
40 /* REASON TO KNOW, OR, IN FACT, SHALL KNOW OF THE POSSIBILITY. */
41
42 /* RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF */
43 /* THE SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY */
44 /* CALTECH AND NASA FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE */
45 /* ACTIONS OF RECIPIENT IN THE USE OF THE SOFTWARE. */
46
47 /* $ Required_Reading */
48
49 /* None. */
50
51 /* $ Keywords */
52
53 /* ARRAY */
54 /* SEARCH */
55
56 /* $ Declarations */
57 /* $ Brief_I/O */
58
59 /* VARIABLE I/O DESCRIPTION */
60 /* -------- --- -------------------------------------------------- */
61 /* X I Search value. */
62 /* N I Number of elements in ARRAY. */
63 /* ARRAY I Array to be searched. */
64
65 /* The function returns the index of the element of ARRAY */
66 /* whose value is closest to X. */
67
68 /* $ Detailed_Input */
69
70 /* X is the value to be compared with the elements of ARRAY. */
71
72 /* N is the number of elements in ARRAY. */
73
74 /* ARRAY is an array of double precision numbers such that */
75
76 /* ARRAY( I ) <= ARRAY( J ) */
77
78 /* for all I < J. */
79
80 /* $ Detailed_Output */
81
82 /* LSTCLD is the index of the element of the non-decreasing */
83 /* sequence: {ARRAY(I) : 1 <= I <= N} that is closest */
84 /* to X. In other words, ARRAY( LSTCLD( X, N, ARRAY ) ) */
85 /* is the element of ARRAY whose value is closest to X. */
86
87 /* If X falls precisely on the midpoint of consecutive array */
88 /* elements, the index of the larger of the two values is */
89 /* returned. */
90
91 /* If X is closest to a value which appears more than */
92 /* once in the array (since the array is ordered, these */
93 /* elements would have to be consecutive), the highest index */
94 /* for that value will be returned. */
95
96 /* LSTCLD = I for some I in the range 1 to N, unless N is */
97 /* less than or equal to zero, in which case LSTCLD is zero. */
98
99 /* $ Parameters */
100
101 /* None. */
102
103 /* $ Particulars */
104
105 /* LSTCLD uses a binary search algorithm to locate the value closest */
106 /* to X in the non-decreasing sequence of double precision numbers */
107 /* represented by the elements of ARRAY. */
108
109 /* $ Examples */
110
111 /* Suppose ARRAY contains the following double precision elements: */
112
113 /* ARRAY: -1 0 1 1.5 1.5 2 3 9 9.5 100 */
114
115 /* index: 1 2 3 4 5 6 7 8 9 10 */
116
117 /* The following table shows the values of LSTCLD that would be */
118 /* returned for various values of X, and the corresponding closest */
119 /* array element values. */
120
121 /* X LSTCLD( X,10,ARRAY ) ARRAY( LSTCLD( X,10,ARRAY )) */
122 /* ----- -------------------- --------------------------- */
123 /* 0.12 2 0 */
124 /* -0.12 2 0 */
125 /* -2.0 1 -1 */
126 /* 2.5 7 3 */
127 /* 1.3 5 1.5 */
128 /* 100.0 10 100 */
129 /* 100.1 10 100 */
130
131 /* $ Restrictions */
132
133 /* If the sequence is not non-decreasing, the routine will run */
134 /* to completion but the index found will not mean anything. */
135
136 /* $ Exceptions */
137
138 /* Error free. */
139
140 /* 1) If the value of N is non-positive, LSTCLD returns the value */
141 /* zero. */
142
143 /* $ Files */
144
145 /* None. */
146
147 /* $ Literature_References */
148
149 /* None. */
150
151 /* $ Author_and_Institution */
152
153 /* M.J. Spencer (JPL) */
154 /* R.E. Thurman (JPL) */
155
156 /* $ Version */
157
158 /* - SPICELIB Version 1.0.1, 10-MAR-1992 (WLT) */
159
160 /* Comment section for permuted index source lines was added */
161 /* following the header. */
162
163 /* - SPICELIB Version 1.0.0, 07-SEP-1990 (RET) */
164
165 /* -& */
166 /* $ Index_Entries */
167
168 /* last closest d.p. array element */
169
170 /* -& */
171 /* $ Revisions */
172
173 /* - Beta Version 1.1.0, 30-AUG-1990 (MJS) */
174
175 /* The following changes were made as a result of the */
176 /* NAIF CK Code and Documentation Review: */
177
178 /* 1) The name of this routine was changed from CLOSTD to */
179 /* LSTCLD because it was a more descriptive name. */
180 /* 2) All references (comments and code) were changed to reflect */
181 /* the name change. */
182
183 /* - Beta Version 1.0.0, 15-MAY-1990 (RET) */
184
185 /* -& */
186
187 /* Local variables */
188
189
190 /* Save the size of the array and point to the beginning and ending */
191 /* positions. The pointers delimit the current search interval. */
192
193 items = *n;
194 begin = 1;
195 end = *n;
196 if (*n <= 0) {
197
198 /* There is nothing in the array to compare against. Zero is the */
199 /* only sensible thing to return. */
200
201 ret_val = 0;
202 return ret_val;
203 } else if (*x <= array[begin - 1]) {
204
205 /* All elements of the array are at least as big as X. So the */
206 /* first element is the closest to X. */
207
208 ret_val = 1;
209 } else if (array[end - 1] <= *x) {
210
211 /* X is at least as big as all elements of the array. So the last */
212 /* element is the closest to X. */
213
214 ret_val = end;
215 } else {
216
217 /* X lies between some pair of elements of the array. */
218
219 while(items > 2) {
220 j = items / 2;
221 middle = begin + j;
222 if (array[middle - 1] < *x) {
223 begin = middle;
224 } else {
225 end = middle;
226 }
227 items = end - begin + 1;
228 }
229
230 /* Which of the two is closest? */
231
232 if (*x - array[begin - 1] < array[end - 1] - *x) {
233 ret_val = begin;
234 } else {
235 ret_val = end;
236 }
237 }
238
239 /* March down the array to find the last element equal to the */
240 /* closet value. */
241
242 while(ret_val < *n && array[ret_val - 1] == array[ret_val]) {
243 ++ret_val;
244 }
245 return ret_val;
246 } /* lstcld_ */
247
248