rsl_interpolation/
accel.rs1#[doc(alias = "gsl_interp_accel")]
24#[derive(Clone, Copy)]
25pub struct Accelerator {
26 pub(crate) cache: usize,
28 pub(crate) hits: usize,
30 pub(crate) misses: usize,
32}
33
34impl Accelerator {
35 pub fn new() -> Self {
37 Accelerator {
38 cache: 0,
39 hits: 0,
40 misses: 0,
41 }
42 }
43
44 #[doc(alias = "gsl_interp_bsearch")]
47 pub(crate) fn bsearch<T>(&self, xarray: &[T], x: T, ilo: usize, ihi: usize) -> usize
48 where
49 T: num::Float,
50 {
51 let mut ilo = ilo;
52 let mut ihi = ihi;
53 while ihi > ilo + 1 {
54 let i = (ihi + ilo) / 2;
55 if xarray[i] > x {
56 ihi = i;
57 } else {
58 ilo = i;
59 }
60 }
61 ilo
62 }
63
64 #[doc(alias = "gsl_interp_accel_find")]
67 pub(crate) fn find<T>(&mut self, xarray: &[T], x: T) -> usize
68 where
69 T: num::Float,
70 {
71 if x < xarray[self.cache] {
72 self.misses += 1;
73 self.cache = self.bsearch(xarray, x, 0, self.cache);
74 } else if x >= xarray[self.cache + 1] {
75 self.misses += 1;
76 self.cache = self.bsearch(xarray, x, self.cache, xarray.len() - 1);
77 } else {
78 self.hits += 1;
79 }
80 self.cache
81 }
82
83 #[doc(alias = "gsl_interp_accel_reset")]
85 pub fn reset(&mut self) {
86 self.cache = 0;
87 self.hits = 0;
88 self.misses = 0;
89 }
90}
91
92impl std::fmt::Debug for Accelerator {
93 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
94 f.debug_struct("Accelerator")
95 .field("cache", &self.cache)
96 .field("hits ", &self.hits)
97 .field("misses", &self.misses)
98 .finish()
99 }
100}
101
102impl Default for Accelerator {
103 fn default() -> Self {
104 Self::new()
105 }
106}
107
108#[cfg(test)]
109mod test {
110 use super::*;
111
112 #[test]
113 fn test_instantiation() {
114 let _ = Accelerator::new();
115 }
116
117 #[test]
118 fn test_reset() {
119 let mut acc = Accelerator::new();
120 acc.cache = 1;
121 acc.hits = 1;
122 acc.misses = 1;
123 acc.reset();
124
125 assert_eq!(acc.cache, 0);
126 assert_eq!(acc.hits, 0);
127 assert_eq!(acc.misses, 0);
128 }
129}