1use crate::Accelerator;
2use crate::DomainError;
3use crate::z_idx;
4
5#[derive(Debug, Clone, Copy)]
6pub struct Cache<T> {
21 acc_indices: (usize, usize),
22 xgrid_values: (T, T),
23 ygrid_values: (T, T),
24 zgrid_values: (T, T, T, T),
25 zx_values: (T, T, T, T),
26 zy_values: (T, T, T, T),
27 zxy_values: (T, T, T, T),
28 partials: (T, T),
29 uninit: bool,
30}
31
32impl<T> Cache<T>
33where
34 T: crate::Num,
35{
36 pub fn new() -> Self {
38 let def = T::nan();
39 Self {
40 acc_indices: (0, 0),
41 xgrid_values: (def, def),
42 ygrid_values: (def, def),
43 zgrid_values: (def, def, def, def),
44 zx_values: (def, def, def, def),
45 zy_values: (def, def, def, def),
46 zxy_values: (def, def, def, def),
47 partials: (def, def),
48 uninit: true,
49 }
50 }
51
52 pub fn reset(&mut self) {
53 *self = Self::new()
54 }
55
56 pub fn soft_reset(&mut self) {
59 self.acc_indices = (0, 0)
60 }
61
62 pub(crate) fn is_uptodate(&mut self, xa: &[T], ya: &[T], x: T, y: T) -> bool {
63 if self.uninit {
69 self.uninit = false;
70 return false;
71 }
72
73 let xi = self.acc_indices.0;
74 let yi = self.acc_indices.1;
75 let x_inbounds: bool = (x > xa[xi]) && (x < xa[xi + 1]);
76 let y_inbounds: bool = (y > ya[yi]) && (y < ya[yi + 1]);
77 x_inbounds && y_inbounds
78 }
79
80 #[allow(clippy::too_many_arguments)]
81 pub(crate) fn update_step1(
82 &mut self,
83 xa: &[T],
84 ya: &[T],
85 za: &[T],
86 x: T,
87 y: T,
88 xacc: &mut Accelerator,
89 yacc: &mut Accelerator,
90 ) -> Result<(), DomainError> {
91 self.update_acc_indices(xa, ya, x, y, xacc, yacc);
92 self.update_xy_grid_values(xa, ya);
93 self.update_z_grid_values(za, xa.len(), ya.len())?;
94 self.update_partials();
95 Ok(())
96 }
97
98 #[allow(clippy::too_many_arguments)]
99 pub(crate) fn update_step2(
100 &mut self,
101 xa: &[T],
102 ya: &[T],
103 zx: &[T],
104 zy: &[T],
105 zxy: &[T],
106 dt: T,
107 du: T,
108 ) -> Result<(), DomainError> {
109 self.update_zxminmaxing(zx, xa.len(), ya.len(), dt)?;
110 self.update_zyminmaxing(zy, xa.len(), ya.len(), du)?;
111 self.update_zxyminmaxing(zxy, xa.len(), ya.len(), dt * du)?;
112 Ok(())
113 }
114}
115
116impl<T> Cache<T>
118where
119 T: crate::Num,
120{
121 fn update_acc_indices(
122 &mut self,
123 xa: &[T],
124 ya: &[T],
125 x: T,
126 y: T,
127 xacc: &mut Accelerator,
128 yacc: &mut Accelerator,
129 ) {
130 self.acc_indices.0 = xacc.find(xa, x);
131 self.acc_indices.1 = yacc.find(ya, y);
132 }
133
134 fn update_xy_grid_values(&mut self, xa: &[T], ya: &[T]) {
135 let xi = self.acc_indices.0;
136 let yi = self.acc_indices.1;
137 self.xgrid_values = (xa[xi], xa[xi + 1]);
138 self.ygrid_values = (ya[yi], ya[yi + 1]);
139 }
140
141 fn update_z_grid_values(
142 &mut self,
143 za: &[T],
144 xlen: usize,
145 ylen: usize,
146 ) -> Result<(), DomainError> {
147 let xi = self.acc_indices.0;
148 let yi = self.acc_indices.1;
149 self.zgrid_values.0 = za[z_idx(xi, yi, xlen, ylen)?];
150 self.zgrid_values.1 = za[z_idx(xi, yi + 1, xlen, ylen)?];
151 self.zgrid_values.2 = za[z_idx(xi + 1, yi, xlen, ylen)?];
152 self.zgrid_values.3 = za[z_idx(xi + 1, yi + 1, xlen, ylen)?];
153 Ok(())
154 }
155
156 fn update_partials(&mut self) {
157 self.partials.0 = self.xgrid_values.1 - self.xgrid_values.0;
158 self.partials.1 = self.ygrid_values.1 - self.ygrid_values.0;
159 }
160
161 fn update_zxminmaxing(
162 &mut self,
163 zx: &[T],
164 xsize: usize,
165 ysize: usize,
166 d: T,
167 ) -> Result<(), DomainError> {
168 let xi = self.acc_indices.0;
169 let yi = self.acc_indices.1;
170 self.zx_values.0 = zx[z_idx(xi, yi, xsize, ysize)?] / d;
171 self.zx_values.1 = zx[z_idx(xi, yi + 1, xsize, ysize)?] / d;
172 self.zx_values.2 = zx[z_idx(xi + 1, yi, xsize, ysize)?] / d;
173 self.zx_values.3 = zx[z_idx(xi + 1, yi + 1, xsize, ysize)?] / d;
174 Ok(())
175 }
176
177 fn update_zyminmaxing(
178 &mut self,
179 zy: &[T],
180 xsize: usize,
181 ysize: usize,
182 d: T,
183 ) -> Result<(), DomainError> {
184 let xi = self.acc_indices.0;
185 let yi = self.acc_indices.1;
186 self.zy_values.0 = zy[z_idx(xi, yi, xsize, ysize)?] / d;
187 self.zy_values.1 = zy[z_idx(xi, yi + 1, xsize, ysize)?] / d;
188 self.zy_values.2 = zy[z_idx(xi + 1, yi, xsize, ysize)?] / d;
189 self.zy_values.3 = zy[z_idx(xi + 1, yi + 1, xsize, ysize)?] / d;
190 Ok(())
191 }
192
193 fn update_zxyminmaxing(
194 &mut self,
195 zxy: &[T],
196 xsize: usize,
197 ysize: usize,
198 d: T,
199 ) -> Result<(), DomainError> {
200 let xi = self.acc_indices.0;
201 let yi = self.acc_indices.1;
202 self.zxy_values.0 = zxy[z_idx(xi, yi, xsize, ysize)?] / d;
203 self.zxy_values.1 = zxy[z_idx(xi, yi + 1, xsize, ysize)?] / d;
204 self.zxy_values.2 = zxy[z_idx(xi + 1, yi, xsize, ysize)?] / d;
205 self.zxy_values.3 = zxy[z_idx(xi + 1, yi + 1, xsize, ysize)?] / d;
206 Ok(())
207 }
208}
209
210impl<T> Cache<T>
212where
213 T: crate::Num,
214{
215 pub(crate) fn get_xy_indices(&self) -> (usize, usize) {
216 (self.acc_indices.0, self.acc_indices.1)
217 }
218
219 pub(crate) fn get_xy_grid_values(&self) -> (T, T, T, T) {
220 (
221 self.xgrid_values.0,
222 self.xgrid_values.1,
223 self.ygrid_values.0,
224 self.ygrid_values.1,
225 )
226 }
227
228 pub(crate) fn get_z_grid_values(&self) -> (T, T, T, T) {
229 self.zgrid_values
230 }
231
232 pub(crate) fn get_partials(&self) -> (T, T) {
233 self.partials
234 }
235
236 pub(crate) fn get_zxminmaxxing(&self) -> (T, T, T, T) {
237 self.zx_values
238 }
239
240 pub(crate) fn get_zyminmaxxing(&self) -> (T, T, T, T) {
241 self.zy_values
242 }
243
244 pub(crate) fn get_zxyminmaxxing(&self) -> (T, T, T, T) {
245 self.zxy_values
246 }
247}
248
249impl<T> Default for Cache<T>
250where
251 T: crate::Num,
252{
253 fn default() -> Self {
254 Self::new()
255 }
256}