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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
//
// GENERATED FILE
//
use super::*;
use crate::SpiceContext;
use f2rust_std::*;
/// Last closest double precision array element
///
/// Find the index of the array element closest to a given number X
/// in an array of non-decreasing numbers.
///
/// # Brief I/O
///
/// ```text
/// VARIABLE I/O DESCRIPTION
/// -------- --- --------------------------------------------------
/// X I Search value.
/// N I Number of elements in ARRAY.
/// ARRAY I Array to be searched.
///
/// The function returns the index of the element of ARRAY
/// whose value is closest to X.
/// ```
///
/// # Detailed Input
///
/// ```text
/// X is the value to be compared with the elements of ARRAY.
///
/// N is the number of elements in ARRAY.
///
/// ARRAY is an array of double precision numbers such that
///
/// ARRAY( I ) <= ARRAY( J )
///
/// for all I < J.
/// ```
///
/// # Detailed Output
///
/// ```text
/// LSTCLD is the index of the element of the non-decreasing
/// sequence: {ARRAY(I) : 1 <= I <= N} that is closest
/// to X. In other words, ARRAY( LSTCLD( X, N, ARRAY ) )
/// is the element of ARRAY whose value is closest to X.
///
/// If X falls precisely on the midpoint of consecutive array
/// elements, the index of the larger of the two values is
/// returned.
///
/// If X is closest to a value which appears more than
/// once in the array (since the array is ordered, these
/// elements would have to be consecutive), the highest index
/// for that value will be returned.
///
/// LSTCLD = I for some I in the range 1 to N, unless N is
/// less than or equal to zero, in which case LSTCLD is zero.
/// ```
///
/// # Exceptions
///
/// ```text
/// Error free.
///
/// 1) If the value of N is non-positive, LSTCLD returns the value
/// zero.
/// ```
///
/// # Particulars
///
/// ```text
/// LSTCLD uses a binary search algorithm to locate the value closest
/// to X in the non-decreasing sequence of double precision numbers
/// represented by the elements of ARRAY.
/// ```
///
/// # Examples
///
/// ```text
/// Suppose ARRAY contains the following double precision elements:
///
/// ARRAY: -1 0 1 1.5 1.5 2 3 9 9.5 100
///
/// index: 1 2 3 4 5 6 7 8 9 10
///
/// The following table shows the values of LSTCLD that would be
/// returned for various values of X, and the corresponding closest
/// array element values.
///
/// X LSTCLD( X,10,ARRAY ) ARRAY( LSTCLD( X,10,ARRAY ))
/// ----- -------------------- ---------------------------
/// 0.12 2 0
/// -0.12 2 0
/// -2.0 1 -1
/// 2.5 7 3
/// 1.3 5 1.5
/// 100.0 10 100
/// 100.1 10 100
/// ```
///
/// # Restrictions
///
/// ```text
/// 1) If the sequence is not non-decreasing, the routine will run
/// to completion but the index found will not mean anything.
/// ```
///
/// # Author and Institution
///
/// ```text
/// J. Diaz del Rio (ODC Space)
/// W.L. Taber (JPL)
/// R.E. Thurman (JPL)
/// ```
///
/// # Version
///
/// ```text
/// - SPICELIB Version 1.1.0, 26-OCT-2021 (JDR)
///
/// Added IMPLICIT NONE statement.
///
/// Edited the header to comply with NAIF standard.
///
/// - SPICELIB Version 1.0.1, 10-MAR-1992 (WLT)
///
/// Comment section for permuted index source lines was added
/// following the header.
///
/// - SPICELIB Version 1.0.0, 07-SEP-1990 (RET)
/// ```
///
/// # Revisions
///
/// ```text
/// - Beta Version 1.1.0, 30-AUG-1990 (MJS)
///
/// The following changes were made as a result of the
/// NAIF CK Code and Documentation Review:
///
/// 1) The name of this routine was changed from CLOSTD to
/// LSTCLD because it was a more descriptive name.
/// 2) All references (comments and code) were changed to reflect
/// the name change.
///
/// - Beta Version 1.0.0, 15-MAY-1990 (RET)
/// ```
pub fn lstcld(x: f64, n: i32, array: &[f64]) -> i32 {
let ret = LSTCLD(x, n, array);
ret
}
//$Procedure LSTCLD ( Last closest double precision array element )
pub fn LSTCLD(X: f64, N: i32, ARRAY: &[f64]) -> i32 {
let ARRAY = DummyArray::new(ARRAY, 1..);
let mut LSTCLD: i32 = 0;
let mut J: i32 = 0;
let mut BEGIN: i32 = 0;
let mut END: i32 = 0;
let mut MIDDLE: i32 = 0;
let mut ITEMS: i32 = 0;
//
// Local variables
//
//
// Save the size of the array and point to the beginning and ending
// positions. The pointers delimit the current search interval.
//
ITEMS = N;
BEGIN = 1;
END = N;
if (N <= 0) {
//
// There is nothing in the array to compare against. Zero is the
// only sensible thing to return.
//
LSTCLD = 0;
return LSTCLD;
} else if (X <= ARRAY[BEGIN]) {
//
// All elements of the array are at least as big as X. So the
// first element is the closest to X.
//
LSTCLD = 1;
} else if (ARRAY[END] <= X) {
//
// X is at least as big as all elements of the array. So the last
// element is the closest to X.
//
LSTCLD = END;
} else {
//
// X lies between some pair of elements of the array.
//
while (ITEMS > 2) {
J = (ITEMS / 2);
MIDDLE = (BEGIN + J);
if (ARRAY[MIDDLE] < X) {
BEGIN = MIDDLE;
} else {
END = MIDDLE;
}
ITEMS = (1 + (END - BEGIN));
}
//
// Which of the two is closest?
//
if ((X - ARRAY[BEGIN]) < (ARRAY[END] - X)) {
LSTCLD = BEGIN;
} else {
LSTCLD = END;
}
}
//
// March down the array to find the last element equal to the
// closet value.
//
while ((LSTCLD < N) && (ARRAY[LSTCLD] == ARRAY[(LSTCLD + 1)])) {
LSTCLD = (LSTCLD + 1);
}
LSTCLD
}