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