2323//! let xp = [0.1, 0.65, 0.9];
2424//! assert_eq!(interp_array(&x, &y, &xp, &InterpMode::default()), [0.5, 3.25, 3.75]);
2525//! ```
26+ //!
27+ //! <div class="warning">
28+ //! **Warning:** `x` is expected to be strictly increasing, but this is not explicitly enforced.
29+ //! However, if `x` is non-increasing, interpolation results are meaningless.
30+ //! </div>
2631
2732#![ warn( missing_docs) ]
2833#![ allow( unknown_lints) ]
@@ -144,11 +149,7 @@ fn prev_index<T>(x: &[T], xp: T) -> usize
144149where
145150 T : Num + PartialOrd + Copy ,
146151{
147- x. iter ( )
148- . take_while ( |& & x| x < xp)
149- . enumerate ( )
150- . last ( )
151- . map_or ( 0 , |( i, _) | i)
152+ x. partition_point ( |& probe| probe < xp) . saturating_sub ( 1 )
152153}
153154
154155/// Linearly interpolate the data points given by the `x` and `y` slices at point `xp`,
@@ -173,6 +174,11 @@ where
173174///
174175/// assert_eq!(interp(&x, &y, 1.5, &InterpMode::Extrapolate), 3.5);
175176/// ```
177+ ///
178+ /// <div class="warning">
179+ /// **Warning:** `x` is expected to be strictly increasing, but this is not explicitly enforced.
180+ /// However, if `x` is non-increasing, interpolation results are meaningless.
181+ /// </div>
176182pub fn interp < T > ( x : & [ T ] , y : & [ T ] , xp : T , mode : & InterpMode < T > ) -> T
177183where
178184 T : Num + PartialOrd + Copy ,
@@ -240,6 +246,11 @@ where
240246///
241247/// assert_eq!(interp_slice(&x, &y, &xp, &InterpMode::FirstLast), vec![2.0, 3.0, 2.0]);
242248/// ```
249+ ///
250+ /// <div class="warning">
251+ /// **Warning:** `x` is expected to be strictly increasing, but this is not explicitly enforced.
252+ /// However, if `x` is non-increasing, interpolation results are meaningless.
253+ /// </div>
243254pub fn interp_slice < T > ( x : & [ T ] , y : & [ T ] , xp : & [ T ] , mode : & InterpMode < T > ) -> Vec < T >
244255where
245256 T : Num + PartialOrd + Copy ,
@@ -308,6 +319,11 @@ where
308319///
309320/// assert_eq!(interp_array(&x, &y, &xp, &InterpMode::Extrapolate), [2.0, 3.0, 0.0]);
310321/// ```
322+ ///
323+ /// <div class="warning">
324+ /// **Warning:** `x` is expected to be strictly increasing, but this is not explicitly enforced.
325+ /// However, if `x` is non-increasing, interpolation results are meaningless.
326+ /// </div>
311327pub fn interp_array < T , const N : usize > (
312328 x : & [ T ] ,
313329 y : & [ T ] ,
@@ -422,10 +438,10 @@ mod tests {
422438
423439 #[ test]
424440 fn test_intercepts ( ) {
425- let x = vec ! [ 0.0 , 1.0 , 3 .5, 2 .5, 6.0 ] ;
441+ let x = vec ! [ 0.0 , 1.0 , 2 .5, 3 .5, 6.0 ] ;
426442 let y = vec ! [ 0.0 , 1.0 , 6.0 , 5.0 , 8.5 ] ;
427443 let slope = vec ! [ 1.0 , 2.0 , -0.5 , 3.5 , 1.0 ] ;
428- let intercept = vec ! [ 0.0 , -1.0 , 7.75 , -3.75 , 2.5 ] ;
444+ let intercept = vec ! [ 0.0 , -1.0 , 7.25 , -7.25 , 2.5 ] ;
429445
430446 let result = intercepts ( & x, & y, & slope) ;
431447
@@ -438,13 +454,19 @@ mod tests {
438454
439455 #[ test]
440456 fn test_prev_index ( ) {
441- let x = vec ! [ 0.0 , 1.0 , 3.5 , 2.5 , 6.0 ] ;
457+ let x = vec ! [ 0.0 , 1.0 , 2.5 , 3.5 , 6.0 ] ;
458+
459+ let result = prev_index ( & x, -1.0 ) ;
460+ assert_eq ! ( result, 0 ) ;
442461
443462 let result = prev_index ( & x, 3.0 ) ;
444- assert_eq ! ( result, 1 ) ;
463+ assert_eq ! ( result, 2 ) ;
445464
446465 let result = prev_index ( & x, 4.0 ) ;
447466 assert_eq ! ( result, 3 ) ;
467+
468+ let result = prev_index ( & x, 7.0 ) ;
469+ assert_eq ! ( result, 4 ) ;
448470 }
449471
450472 #[ test]
0 commit comments