argmin/core/state/iterstate.rs
1// Copyright 2018-2024 argmin developers
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
5// http://opensource.org/licenses/MIT>, at your option. This file may not be
6// copied, modified, or distributed except according to those terms.
7
8use crate::core::{ArgminFloat, Problem, State, TerminationReason, TerminationStatus};
9#[cfg(feature = "serde1")]
10use serde::{Deserialize, Serialize};
11use std::collections::HashMap;
12use web_time::Duration;
13
14/// Maintains the state from iteration to iteration of a solver
15///
16/// This struct is passed from one iteration of an algorithm to the next.
17///
18/// Keeps track of
19///
20/// * parameter vector of current and previous iteration
21/// * best parameter vector of current and previous iteration
22/// * gradient of current and previous iteration
23/// * Jacobian of current and previous iteration
24/// * Hessian of current and previous iteration
25/// * inverse Hessian of current and previous iteration
26/// * cost function value of current and previous iteration
27/// * current and previous best cost function value
28/// * target cost function value
29/// * current iteration number
30/// * iteration number where the last best parameter vector was found
31/// * maximum number of iterations that will be executed
32/// * problem function evaluation counts (cost function, gradient, jacobian, hessian,
33/// annealing,...)
34/// * elapsed time
35/// * termination status
36#[derive(Clone, Default, Debug, Eq, PartialEq)]
37#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
38pub struct IterState<P, G, J, H, R, F> {
39 /// Current parameter vector
40 pub param: Option<P>,
41 /// Previous parameter vector
42 pub prev_param: Option<P>,
43 /// Current best parameter vector
44 pub best_param: Option<P>,
45 /// Previous best parameter vector
46 pub prev_best_param: Option<P>,
47 /// Current cost function value
48 pub cost: F,
49 /// Previous cost function value
50 pub prev_cost: F,
51 /// Current best cost function value
52 pub best_cost: F,
53 /// Previous best cost function value
54 pub prev_best_cost: F,
55 /// Target cost function value
56 pub target_cost: F,
57 /// Current gradient
58 pub grad: Option<G>,
59 /// Previous gradient
60 pub prev_grad: Option<G>,
61 /// Current Hessian
62 pub hessian: Option<H>,
63 /// Previous Hessian
64 pub prev_hessian: Option<H>,
65 /// Current inverse Hessian
66 pub inv_hessian: Option<H>,
67 /// Previous inverse Hessian
68 pub prev_inv_hessian: Option<H>,
69 /// Current Jacobian
70 pub jacobian: Option<J>,
71 /// Previous Jacobian
72 pub prev_jacobian: Option<J>,
73 /// Value of residuals from recent call to apply
74 pub residuals: Option<R>,
75 /// Value of residuals from previous call to apply
76 pub prev_residuals: Option<R>,
77 /// Current iteration
78 pub iter: u64,
79 /// Iteration number of last best cost
80 pub last_best_iter: u64,
81 /// Maximum number of iterations
82 pub max_iters: u64,
83 /// Evaluation counts
84 pub counts: HashMap<String, u64>,
85 /// Update evaluation counts?
86 pub counting_enabled: bool,
87 /// Time required so far
88 pub time: Option<Duration>,
89 /// Status of optimization execution
90 pub termination_status: TerminationStatus,
91}
92
93impl<P, G, J, H, R, F> IterState<P, G, J, H, R, F>
94where
95 Self: State<Float = F>,
96 F: ArgminFloat,
97{
98 /// Set parameter vector. This shifts the stored parameter vector to the previous parameter
99 /// vector.
100 ///
101 /// # Example
102 ///
103 /// ```
104 /// # use argmin::core::{IterState, State};
105 /// # let state: IterState<Vec<f64>, (), (), (), (), f64> = IterState::new();
106 /// # let param_old = vec![1.0f64, 2.0f64];
107 /// # let state = state.param(param_old);
108 /// # assert!(state.prev_param.is_none());
109 /// # assert_eq!(state.param.as_ref().unwrap()[0].to_ne_bytes(), 1.0f64.to_ne_bytes());
110 /// # assert_eq!(state.param.as_ref().unwrap()[1].to_ne_bytes(), 2.0f64.to_ne_bytes());
111 /// # let param = vec![0.0f64, 3.0f64];
112 /// let state = state.param(param);
113 /// # assert_eq!(state.prev_param.as_ref().unwrap()[0].to_ne_bytes(), 1.0f64.to_ne_bytes());
114 /// # assert_eq!(state.prev_param.as_ref().unwrap()[1].to_ne_bytes(), 2.0f64.to_ne_bytes());
115 /// # assert_eq!(state.param.as_ref().unwrap()[0].to_ne_bytes(), 0.0f64.to_ne_bytes());
116 /// # assert_eq!(state.param.as_ref().unwrap()[1].to_ne_bytes(), 3.0f64.to_ne_bytes());
117 /// ```
118 #[must_use]
119 pub fn param(mut self, param: P) -> Self {
120 std::mem::swap(&mut self.prev_param, &mut self.param);
121 self.param = Some(param);
122 self
123 }
124
125 /// Set gradient. This shifts the stored gradient to the previous gradient.
126 ///
127 /// # Example
128 ///
129 /// ```
130 /// # use argmin::core::{IterState, State};
131 /// # let state: IterState<(), Vec<f64>, (), (), (), f64> = IterState::new();
132 /// # let grad_old = vec![1.0f64, 2.0f64];
133 /// # let state = state.gradient(grad_old);
134 /// # assert!(state.prev_grad.is_none());
135 /// # assert_eq!(state.grad.as_ref().unwrap()[0].to_ne_bytes(), 1.0f64.to_ne_bytes());
136 /// # assert_eq!(state.grad.as_ref().unwrap()[1].to_ne_bytes(), 2.0f64.to_ne_bytes());
137 /// # let grad = vec![0.0f64, 3.0f64];
138 /// let state = state.gradient(grad);
139 /// # assert_eq!(state.prev_grad.as_ref().unwrap()[0].to_ne_bytes(), 1.0f64.to_ne_bytes());
140 /// # assert_eq!(state.prev_grad.as_ref().unwrap()[1].to_ne_bytes(), 2.0f64.to_ne_bytes());
141 /// # assert_eq!(state.grad.as_ref().unwrap()[0].to_ne_bytes(), 0.0f64.to_ne_bytes());
142 /// # assert_eq!(state.grad.as_ref().unwrap()[1].to_ne_bytes(), 3.0f64.to_ne_bytes());
143 /// ```
144 #[must_use]
145 pub fn gradient(mut self, gradient: G) -> Self {
146 std::mem::swap(&mut self.prev_grad, &mut self.grad);
147 self.grad = Some(gradient);
148 self
149 }
150
151 /// Set Hessian. This shifts the stored Hessian to the previous Hessian.
152 ///
153 /// # Example
154 ///
155 /// ```
156 /// # use argmin::core::{IterState, State};
157 /// # let state: IterState<(), (), (), Vec<f64>, (), f64> = IterState::new();
158 /// # let hessian_old = vec![1.0f64, 2.0f64];
159 /// # let state = state.hessian(hessian_old);
160 /// # assert!(state.prev_hessian.is_none());
161 /// # assert_eq!(state.hessian.as_ref().unwrap()[0].to_ne_bytes(), 1.0f64.to_ne_bytes());
162 /// # assert_eq!(state.hessian.as_ref().unwrap()[1].to_ne_bytes(), 2.0f64.to_ne_bytes());
163 /// # let hessian = vec![0.0f64, 3.0f64];
164 /// let state = state.hessian(hessian);
165 /// # assert_eq!(state.prev_hessian.as_ref().unwrap()[0].to_ne_bytes(), 1.0f64.to_ne_bytes());
166 /// # assert_eq!(state.prev_hessian.as_ref().unwrap()[1].to_ne_bytes(), 2.0f64.to_ne_bytes());
167 /// # assert_eq!(state.hessian.as_ref().unwrap()[0].to_ne_bytes(), 0.0f64.to_ne_bytes());
168 /// # assert_eq!(state.hessian.as_ref().unwrap()[1].to_ne_bytes(), 3.0f64.to_ne_bytes());
169 /// ```
170 #[must_use]
171 pub fn hessian(mut self, hessian: H) -> Self {
172 std::mem::swap(&mut self.prev_hessian, &mut self.hessian);
173 self.hessian = Some(hessian);
174 self
175 }
176
177 /// Set inverse Hessian. This shifts the stored inverse Hessian to the previous inverse Hessian.
178 ///
179 /// # Example
180 ///
181 /// ```
182 /// # use argmin::core::{IterState, State};
183 /// # let state: IterState<(), (), (), Vec<f64>, (), f64> = IterState::new();
184 /// # let inv_hessian_old = vec![1.0f64, 2.0f64];
185 /// # let state = state.inv_hessian(inv_hessian_old);
186 /// # assert!(state.prev_inv_hessian.is_none());
187 /// # assert_eq!(state.inv_hessian.as_ref().unwrap()[0].to_ne_bytes(), 1.0f64.to_ne_bytes());
188 /// # assert_eq!(state.inv_hessian.as_ref().unwrap()[1].to_ne_bytes(), 2.0f64.to_ne_bytes());
189 /// # let inv_hessian = vec![0.0f64, 3.0f64];
190 /// let state = state.inv_hessian(inv_hessian);
191 /// # assert_eq!(state.prev_inv_hessian.as_ref().unwrap()[0].to_ne_bytes(), 1.0f64.to_ne_bytes());
192 /// # assert_eq!(state.prev_inv_hessian.as_ref().unwrap()[1].to_ne_bytes(), 2.0f64.to_ne_bytes());
193 /// # assert_eq!(state.inv_hessian.as_ref().unwrap()[0].to_ne_bytes(), 0.0f64.to_ne_bytes());
194 /// # assert_eq!(state.inv_hessian.as_ref().unwrap()[1].to_ne_bytes(), 3.0f64.to_ne_bytes());
195 /// ```
196 #[must_use]
197 pub fn inv_hessian(mut self, inv_hessian: H) -> Self {
198 std::mem::swap(&mut self.prev_inv_hessian, &mut self.inv_hessian);
199 self.inv_hessian = Some(inv_hessian);
200 self
201 }
202
203 /// Set Jacobian. This shifts the stored Jacobian to the previous Jacobian.
204 ///
205 /// # Example
206 ///
207 /// ```
208 /// # use argmin::core::{IterState, State};
209 /// # let state: IterState<(), (), Vec<f64>, (), (), f64> = IterState::new();
210 /// # let jacobian_old = vec![1.0f64, 2.0f64];
211 /// # let state = state.jacobian(jacobian_old);
212 /// # assert!(state.prev_jacobian.is_none());
213 /// # assert_eq!(state.jacobian.as_ref().unwrap()[0].to_ne_bytes(), 1.0f64.to_ne_bytes());
214 /// # assert_eq!(state.jacobian.as_ref().unwrap()[1].to_ne_bytes(), 2.0f64.to_ne_bytes());
215 /// # let jacobian = vec![0.0f64, 3.0f64];
216 /// let state = state.jacobian(jacobian);
217 /// # assert_eq!(state.prev_jacobian.as_ref().unwrap()[0].to_ne_bytes(), 1.0f64.to_ne_bytes());
218 /// # assert_eq!(state.prev_jacobian.as_ref().unwrap()[1].to_ne_bytes(), 2.0f64.to_ne_bytes());
219 /// # assert_eq!(state.jacobian.as_ref().unwrap()[0].to_ne_bytes(), 0.0f64.to_ne_bytes());
220 /// # assert_eq!(state.jacobian.as_ref().unwrap()[1].to_ne_bytes(), 3.0f64.to_ne_bytes());
221 /// ```
222 #[must_use]
223 pub fn jacobian(mut self, jacobian: J) -> Self {
224 std::mem::swap(&mut self.prev_jacobian, &mut self.jacobian);
225 self.jacobian = Some(jacobian);
226 self
227 }
228
229 /// Set the current cost function value. This shifts the stored cost function value to the
230 /// previous cost function value.
231 ///
232 /// # Example
233 ///
234 /// ```
235 /// # use argmin::core::{IterState, State};
236 /// # let state: IterState<(), (), Vec<f64>, (), (), f64> = IterState::new();
237 /// # let cost_old = 1.0f64;
238 /// # let state = state.cost(cost_old);
239 /// # assert_eq!(state.prev_cost.to_ne_bytes(), f64::INFINITY.to_ne_bytes());
240 /// # assert_eq!(state.cost.to_ne_bytes(), 1.0f64.to_ne_bytes());
241 /// # let cost = 0.0f64;
242 /// let state = state.cost(cost);
243 /// # assert_eq!(state.prev_cost.to_ne_bytes(), 1.0f64.to_ne_bytes());
244 /// # assert_eq!(state.cost.to_ne_bytes(), 0.0f64.to_ne_bytes());
245 /// ```
246 #[must_use]
247 pub fn cost(mut self, cost: F) -> Self {
248 std::mem::swap(&mut self.prev_cost, &mut self.cost);
249 self.cost = cost;
250 self
251 }
252
253 /// Set target cost.
254 ///
255 /// When this cost is reached, the algorithm will stop. The default is
256 /// `Self::Float::NEG_INFINITY`.
257 ///
258 /// # Example
259 ///
260 /// ```
261 /// # use argmin::core::{IterState, State, ArgminFloat};
262 /// # let state: IterState<Vec<f64>, (), (), (), (), f64> = IterState::new();
263 /// # assert_eq!(state.target_cost.to_ne_bytes(), f64::NEG_INFINITY.to_ne_bytes());
264 /// let state = state.target_cost(0.0);
265 /// # assert_eq!(state.target_cost.to_ne_bytes(), 0.0f64.to_ne_bytes());
266 /// ```
267 #[must_use]
268 pub fn target_cost(mut self, target_cost: F) -> Self {
269 self.target_cost = target_cost;
270 self
271 }
272
273 /// Set maximum number of iterations
274 ///
275 /// # Example
276 ///
277 /// ```
278 /// # use argmin::core::{IterState, State, ArgminFloat};
279 /// # let state: IterState<Vec<f64>, (), (), (), (), f64> = IterState::new();
280 /// # assert_eq!(state.max_iters, u64::MAX);
281 /// let state = state.max_iters(1000);
282 /// # assert_eq!(state.max_iters, 1000);
283 /// ```
284 #[must_use]
285 pub fn max_iters(mut self, iters: u64) -> Self {
286 self.max_iters = iters;
287 self
288 }
289
290 /// Set residuals. This shifts the stored residuals to the previous residuals.
291 ///
292 /// # Example
293 ///
294 /// ```
295 /// # use argmin::core::{IterState, State};
296 /// # let state: IterState<(), (), (), (), Vec<f64>, f64> = IterState::new();
297 /// # let residuals_old = vec![1.0f64, 2.0f64];
298 /// # let state = state.residuals(residuals_old);
299 /// # assert!(state.prev_residuals.is_none());
300 /// # assert_eq!(state.residuals.as_ref().unwrap()[0].to_ne_bytes(), 1.0f64.to_ne_bytes());
301 /// # assert_eq!(state.residuals.as_ref().unwrap()[1].to_ne_bytes(), 2.0f64.to_ne_bytes());
302 /// # let residuals = vec![0.0f64, 3.0f64];
303 /// let state = state.residuals(residuals);
304 /// # assert_eq!(state.prev_residuals.as_ref().unwrap()[0].to_ne_bytes(), 1.0f64.to_ne_bytes());
305 /// # assert_eq!(state.prev_residuals.as_ref().unwrap()[1].to_ne_bytes(), 2.0f64.to_ne_bytes());
306 /// # assert_eq!(state.residuals.as_ref().unwrap()[0].to_ne_bytes(), 0.0f64.to_ne_bytes());
307 /// # assert_eq!(state.residuals.as_ref().unwrap()[1].to_ne_bytes(), 3.0f64.to_ne_bytes());
308 /// ```
309 #[must_use]
310 pub fn residuals(mut self, residuals: R) -> Self {
311 std::mem::swap(&mut self.prev_residuals, &mut self.residuals);
312 self.residuals = Some(residuals);
313 self
314 }
315
316 /// Returns the current cost function value
317 ///
318 /// # Example
319 ///
320 /// ```
321 /// # use argmin::core::{IterState, State, ArgminFloat};
322 /// # let state: IterState<Vec<f64>, (), (), (), (), f64> = IterState::new();
323 /// # let state = state.cost(2.0);
324 /// let cost = state.get_cost();
325 /// # assert_eq!(cost.to_ne_bytes(), 2.0f64.to_ne_bytes());
326 /// ```
327 pub fn get_cost(&self) -> F {
328 self.cost
329 }
330
331 /// Returns the previous cost function value
332 ///
333 /// # Example
334 ///
335 /// ```
336 /// # use argmin::core::{IterState, State, ArgminFloat};
337 /// # let mut state: IterState<Vec<f64>, (), (), (), (), f64> = IterState::new();
338 /// # state.prev_cost = 2.0;
339 /// let prev_cost = state.get_prev_cost();
340 /// # assert_eq!(prev_cost.to_ne_bytes(), 2.0f64.to_ne_bytes());
341 /// ```
342 pub fn get_prev_cost(&self) -> F {
343 self.prev_cost
344 }
345
346 /// Returns the current best cost function value
347 ///
348 /// # Example
349 ///
350 /// ```
351 /// # use argmin::core::{IterState, State, ArgminFloat};
352 /// # let mut state: IterState<Vec<f64>, (), (), (), (), f64> = IterState::new();
353 /// # state.best_cost = 2.0;
354 /// let best_cost = state.get_best_cost();
355 /// # assert_eq!(best_cost.to_ne_bytes(), 2.0f64.to_ne_bytes());
356 /// ```
357 pub fn get_best_cost(&self) -> F {
358 self.best_cost
359 }
360
361 /// Returns the previous best cost function value
362 ///
363 /// # Example
364 ///
365 /// ```
366 /// # use argmin::core::{IterState, State, ArgminFloat};
367 /// # let mut state: IterState<Vec<f64>, (), (), (), (), f64> = IterState::new();
368 /// # state.prev_best_cost = 2.0;
369 /// let prev_best_cost = state.get_prev_best_cost();
370 /// # assert_eq!(prev_best_cost.to_ne_bytes(), 2.0f64.to_ne_bytes());
371 /// ```
372 pub fn get_prev_best_cost(&self) -> F {
373 self.prev_best_cost
374 }
375
376 /// Returns the target cost function value
377 ///
378 /// # Example
379 ///
380 /// ```
381 /// # use argmin::core::{IterState, State, ArgminFloat};
382 /// # let mut state: IterState<Vec<f64>, (), (), (), (), f64> = IterState::new();
383 /// # assert_eq!(state.target_cost.to_ne_bytes(), f64::NEG_INFINITY.to_ne_bytes());
384 /// # state.target_cost = 0.0;
385 /// let target_cost = state.get_target_cost();
386 /// # assert_eq!(target_cost.to_ne_bytes(), 0.0f64.to_ne_bytes());
387 /// ```
388 pub fn get_target_cost(&self) -> F {
389 self.target_cost
390 }
391
392 /// Moves the current parameter vector out and replaces it internally with `None`
393 ///
394 /// # Example
395 ///
396 /// ```
397 /// # use argmin::core::{IterState, State, ArgminFloat};
398 /// # let mut state: IterState<Vec<f64>, (), (), (), (), f64> = IterState::new();
399 /// # assert!(state.take_param().is_none());
400 /// # let mut state = state.param(vec![1.0, 2.0]);
401 /// # assert_eq!(state.param.as_ref().unwrap()[0].to_ne_bytes(), 1.0f64.to_ne_bytes());
402 /// # assert_eq!(state.param.as_ref().unwrap()[1].to_ne_bytes(), 2.0f64.to_ne_bytes());
403 /// let param = state.take_param(); // Option<P>
404 /// # assert!(state.take_param().is_none());
405 /// # assert!(state.param.is_none());
406 /// # assert_eq!(param.as_ref().unwrap()[0].to_ne_bytes(), 1.0f64.to_ne_bytes());
407 /// # assert_eq!(param.as_ref().unwrap()[1].to_ne_bytes(), 2.0f64.to_ne_bytes());
408 /// ```
409 pub fn take_param(&mut self) -> Option<P> {
410 self.param.take()
411 }
412
413 /// Returns a reference to previous parameter vector
414 ///
415 /// # Example
416 ///
417 /// ```
418 /// # use argmin::core::{IterState, State, ArgminFloat};
419 /// # let mut state: IterState<Vec<f64>, (), (), (), (), f64> = IterState::new();
420 /// # assert!(state.prev_param.is_none());
421 /// # state.prev_param = Some(vec![1.0, 2.0]);
422 /// # assert_eq!(state.prev_param.as_ref().unwrap()[0].to_ne_bytes(), 1.0f64.to_ne_bytes());
423 /// # assert_eq!(state.prev_param.as_ref().unwrap()[1].to_ne_bytes(), 2.0f64.to_ne_bytes());
424 /// let prev_param = state.get_prev_param(); // Option<&P>
425 /// # assert_eq!(prev_param.as_ref().unwrap()[0].to_ne_bytes(), 1.0f64.to_ne_bytes());
426 /// # assert_eq!(prev_param.as_ref().unwrap()[1].to_ne_bytes(), 2.0f64.to_ne_bytes());
427 /// ```
428 pub fn get_prev_param(&self) -> Option<&P> {
429 self.prev_param.as_ref()
430 }
431
432 /// Moves the previous parameter vector out and replaces it internally with `None`
433 ///
434 /// # Example
435 ///
436 /// ```
437 /// # use argmin::core::{IterState, State, ArgminFloat};
438 /// # let mut state: IterState<Vec<f64>, (), (), (), (), f64> = IterState::new();
439 /// # assert!(state.take_prev_param().is_none());
440 /// # state.prev_param = Some(vec![1.0, 2.0]);
441 /// # assert_eq!(state.prev_param.as_ref().unwrap()[0].to_ne_bytes(), 1.0f64.to_ne_bytes());
442 /// # assert_eq!(state.prev_param.as_ref().unwrap()[1].to_ne_bytes(), 2.0f64.to_ne_bytes());
443 /// let prev_param = state.take_prev_param(); // Option<P>
444 /// # assert!(state.take_prev_param().is_none());
445 /// # assert!(state.prev_param.is_none());
446 /// # assert_eq!(prev_param.as_ref().unwrap()[0].to_ne_bytes(), 1.0f64.to_ne_bytes());
447 /// # assert_eq!(prev_param.as_ref().unwrap()[1].to_ne_bytes(), 2.0f64.to_ne_bytes());
448 /// ```
449 pub fn take_prev_param(&mut self) -> Option<P> {
450 self.prev_param.take()
451 }
452
453 /// Returns a reference to previous best parameter vector
454 ///
455 /// # Example
456 ///
457 /// ```
458 /// # use argmin::core::{IterState, State, ArgminFloat};
459 /// # let mut state: IterState<Vec<f64>, (), (), (), (), f64> = IterState::new();
460 /// # assert!(state.prev_best_param.is_none());
461 /// # state.prev_best_param = Some(vec![1.0, 2.0]);
462 /// # assert_eq!(state.prev_best_param.as_ref().unwrap()[0].to_ne_bytes(), 1.0f64.to_ne_bytes());
463 /// # assert_eq!(state.prev_best_param.as_ref().unwrap()[1].to_ne_bytes(), 2.0f64.to_ne_bytes());
464 /// let prev_best_param = state.get_prev_best_param(); // Option<&P>
465 /// # assert_eq!(prev_best_param.as_ref().unwrap()[0].to_ne_bytes(), 1.0f64.to_ne_bytes());
466 /// # assert_eq!(prev_best_param.as_ref().unwrap()[1].to_ne_bytes(), 2.0f64.to_ne_bytes());
467 /// ```
468 pub fn get_prev_best_param(&self) -> Option<&P> {
469 self.prev_best_param.as_ref()
470 }
471
472 /// Moves the best parameter vector out and replaces it internally with `None`
473 ///
474 /// # Example
475 ///
476 /// ```
477 /// # use argmin::core::{IterState, State, ArgminFloat};
478 /// # let mut state: IterState<Vec<f64>, (), (), (), (), f64> = IterState::new();
479 /// # assert!(state.take_best_param().is_none());
480 /// # state.best_param = Some(vec![1.0, 2.0]);
481 /// # assert_eq!(state.best_param.as_ref().unwrap()[0].to_ne_bytes(), 1.0f64.to_ne_bytes());
482 /// # assert_eq!(state.best_param.as_ref().unwrap()[1].to_ne_bytes(), 2.0f64.to_ne_bytes());
483 /// let best_param = state.take_best_param(); // Option<P>
484 /// # assert!(state.take_best_param().is_none());
485 /// # assert!(state.best_param.is_none());
486 /// # assert_eq!(best_param.as_ref().unwrap()[0].to_ne_bytes(), 1.0f64.to_ne_bytes());
487 /// # assert_eq!(best_param.as_ref().unwrap()[1].to_ne_bytes(), 2.0f64.to_ne_bytes());
488 /// ```
489 pub fn take_best_param(&mut self) -> Option<P> {
490 self.best_param.take()
491 }
492
493 /// Moves the previous best parameter vector out and replaces it internally with `None`
494 ///
495 /// # Example
496 ///
497 /// ```
498 /// # use argmin::core::{IterState, State, ArgminFloat};
499 /// # let mut state: IterState<Vec<f64>, (), (), (), (), f64> = IterState::new();
500 /// # assert!(state.take_prev_best_param().is_none());
501 /// # state.prev_best_param = Some(vec![1.0, 2.0]);
502 /// # assert_eq!(state.prev_best_param.as_ref().unwrap()[0].to_ne_bytes(), 1.0f64.to_ne_bytes());
503 /// # assert_eq!(state.prev_best_param.as_ref().unwrap()[1].to_ne_bytes(), 2.0f64.to_ne_bytes());
504 /// let prev_best_param = state.take_prev_best_param(); // Option<P>
505 /// # assert!(state.take_prev_best_param().is_none());
506 /// # assert!(state.prev_best_param.is_none());
507 /// # assert_eq!(prev_best_param.as_ref().unwrap()[0].to_ne_bytes(), 1.0f64.to_ne_bytes());
508 /// # assert_eq!(prev_best_param.as_ref().unwrap()[1].to_ne_bytes(), 2.0f64.to_ne_bytes());
509 /// ```
510 pub fn take_prev_best_param(&mut self) -> Option<P> {
511 self.prev_best_param.take()
512 }
513
514 /// Returns a reference to the gradient
515 ///
516 /// # Example
517 ///
518 /// ```
519 /// # use argmin::core::{IterState, State, ArgminFloat};
520 /// # let mut state: IterState<(), Vec<f64>, (), (), (), f64> = IterState::new();
521 /// # assert!(state.grad.is_none());
522 /// # assert!(state.get_gradient().is_none());
523 /// # state.grad = Some(vec![1.0, 2.0]);
524 /// # assert_eq!(state.grad.as_ref().unwrap()[0].to_ne_bytes(), 1.0f64.to_ne_bytes());
525 /// # assert_eq!(state.grad.as_ref().unwrap()[1].to_ne_bytes(), 2.0f64.to_ne_bytes());
526 /// let grad = state.get_gradient(); // Option<&G>
527 /// # assert_eq!(grad.as_ref().unwrap()[0].to_ne_bytes(), 1.0f64.to_ne_bytes());
528 /// # assert_eq!(grad.as_ref().unwrap()[1].to_ne_bytes(), 2.0f64.to_ne_bytes());
529 /// ```
530 pub fn get_gradient(&self) -> Option<&G> {
531 self.grad.as_ref()
532 }
533
534 /// Moves the gradient out and replaces it internally with `None`
535 ///
536 /// # Example
537 ///
538 /// ```
539 /// # use argmin::core::{IterState, State, ArgminFloat};
540 /// # let mut state: IterState<(), Vec<f64>, (), (), (), f64> = IterState::new();
541 /// # assert!(state.take_gradient().is_none());
542 /// # state.grad = Some(vec![1.0, 2.0]);
543 /// # assert_eq!(state.grad.as_ref().unwrap()[0].to_ne_bytes(), 1.0f64.to_ne_bytes());
544 /// # assert_eq!(state.grad.as_ref().unwrap()[1].to_ne_bytes(), 2.0f64.to_ne_bytes());
545 /// let grad = state.take_gradient(); // Option<G>
546 /// # assert!(state.take_gradient().is_none());
547 /// # assert!(state.grad.is_none());
548 /// # assert_eq!(grad.as_ref().unwrap()[0].to_ne_bytes(), 1.0f64.to_ne_bytes());
549 /// # assert_eq!(grad.as_ref().unwrap()[1].to_ne_bytes(), 2.0f64.to_ne_bytes());
550 /// ```
551 pub fn take_gradient(&mut self) -> Option<G> {
552 self.grad.take()
553 }
554
555 /// Returns a reference to the previous gradient
556 ///
557 /// # Example
558 ///
559 /// ```
560 /// # use argmin::core::{IterState, State, ArgminFloat};
561 /// # let mut state: IterState<(), Vec<f64>, (), (), (), f64> = IterState::new();
562 /// # assert!(state.prev_grad.is_none());
563 /// # assert!(state.get_prev_gradient().is_none());
564 /// # state.prev_grad = Some(vec![1.0, 2.0]);
565 /// # assert_eq!(state.prev_grad.as_ref().unwrap()[0].to_ne_bytes(), 1.0f64.to_ne_bytes());
566 /// # assert_eq!(state.prev_grad.as_ref().unwrap()[1].to_ne_bytes(), 2.0f64.to_ne_bytes());
567 /// let prev_grad = state.get_prev_gradient(); // Option<&G>
568 /// # assert_eq!(prev_grad.as_ref().unwrap()[0].to_ne_bytes(), 1.0f64.to_ne_bytes());
569 /// # assert_eq!(prev_grad.as_ref().unwrap()[1].to_ne_bytes(), 2.0f64.to_ne_bytes());
570 /// ```
571 pub fn get_prev_gradient(&self) -> Option<&G> {
572 self.prev_grad.as_ref()
573 }
574
575 /// Moves the gradient out and replaces it internally with `None`
576 ///
577 /// # Example
578 ///
579 /// ```
580 /// # use argmin::core::{IterState, State, ArgminFloat};
581 /// # let mut state: IterState<(), Vec<f64>, (), (), (), f64> = IterState::new();
582 /// # assert!(state.take_prev_gradient().is_none());
583 /// # state.prev_grad = Some(vec![1.0, 2.0]);
584 /// # assert_eq!(state.prev_grad.as_ref().unwrap()[0].to_ne_bytes(), 1.0f64.to_ne_bytes());
585 /// # assert_eq!(state.prev_grad.as_ref().unwrap()[1].to_ne_bytes(), 2.0f64.to_ne_bytes());
586 /// let prev_grad = state.take_prev_gradient(); // Option<G>
587 /// # assert!(state.take_prev_gradient().is_none());
588 /// # assert!(state.prev_grad.is_none());
589 /// # assert_eq!(prev_grad.as_ref().unwrap()[0].to_ne_bytes(), 1.0f64.to_ne_bytes());
590 /// # assert_eq!(prev_grad.as_ref().unwrap()[1].to_ne_bytes(), 2.0f64.to_ne_bytes());
591 /// ```
592 pub fn take_prev_gradient(&mut self) -> Option<G> {
593 self.prev_grad.take()
594 }
595
596 /// Returns a reference to the current Hessian
597 ///
598 /// # Example
599 ///
600 /// ```
601 /// # use argmin::core::{IterState, State, ArgminFloat};
602 /// # let mut state: IterState<(), (), (), Vec<Vec<f64>>, (), f64> = IterState::new();
603 /// # assert!(state.hessian.is_none());
604 /// # assert!(state.get_hessian().is_none());
605 /// # state.hessian = Some(vec![vec![1.0, 2.0], vec![3.0, 4.0]]);
606 /// # assert_eq!(state.hessian.as_ref().unwrap()[0][0].to_ne_bytes(), 1.0f64.to_ne_bytes());
607 /// # assert_eq!(state.hessian.as_ref().unwrap()[0][1].to_ne_bytes(), 2.0f64.to_ne_bytes());
608 /// # assert_eq!(state.hessian.as_ref().unwrap()[1][0].to_ne_bytes(), 3.0f64.to_ne_bytes());
609 /// # assert_eq!(state.hessian.as_ref().unwrap()[1][1].to_ne_bytes(), 4.0f64.to_ne_bytes());
610 /// let hessian = state.get_hessian(); // Option<&H>
611 /// # assert_eq!(hessian.as_ref().unwrap()[0][0].to_ne_bytes(), 1.0f64.to_ne_bytes());
612 /// # assert_eq!(hessian.as_ref().unwrap()[0][1].to_ne_bytes(), 2.0f64.to_ne_bytes());
613 /// # assert_eq!(hessian.as_ref().unwrap()[1][0].to_ne_bytes(), 3.0f64.to_ne_bytes());
614 /// # assert_eq!(hessian.as_ref().unwrap()[1][1].to_ne_bytes(), 4.0f64.to_ne_bytes());
615 /// ```
616 pub fn get_hessian(&self) -> Option<&H> {
617 self.hessian.as_ref()
618 }
619
620 /// Moves the Hessian out and replaces it internally with `None`
621 ///
622 /// # Example
623 ///
624 /// ```
625 /// # use argmin::core::{IterState, State, ArgminFloat};
626 /// # let mut state: IterState<(), (), (), Vec<Vec<f64>>, (), f64> = IterState::new();
627 /// # assert!(state.hessian.is_none());
628 /// # assert!(state.take_hessian().is_none());
629 /// # state.hessian = Some(vec![vec![1.0, 2.0], vec![3.0, 4.0]]);
630 /// # assert_eq!(state.hessian.as_ref().unwrap()[0][0].to_ne_bytes(), 1.0f64.to_ne_bytes());
631 /// # assert_eq!(state.hessian.as_ref().unwrap()[0][1].to_ne_bytes(), 2.0f64.to_ne_bytes());
632 /// # assert_eq!(state.hessian.as_ref().unwrap()[1][0].to_ne_bytes(), 3.0f64.to_ne_bytes());
633 /// # assert_eq!(state.hessian.as_ref().unwrap()[1][1].to_ne_bytes(), 4.0f64.to_ne_bytes());
634 /// let hessian = state.take_hessian(); // Option<H>
635 /// # assert!(state.take_hessian().is_none());
636 /// # assert!(state.hessian.is_none());
637 /// # assert_eq!(hessian.as_ref().unwrap()[0][0].to_ne_bytes(), 1.0f64.to_ne_bytes());
638 /// # assert_eq!(hessian.as_ref().unwrap()[0][1].to_ne_bytes(), 2.0f64.to_ne_bytes());
639 /// # assert_eq!(hessian.as_ref().unwrap()[1][0].to_ne_bytes(), 3.0f64.to_ne_bytes());
640 /// # assert_eq!(hessian.as_ref().unwrap()[1][1].to_ne_bytes(), 4.0f64.to_ne_bytes());
641 /// ```
642 pub fn take_hessian(&mut self) -> Option<H> {
643 self.hessian.take()
644 }
645
646 /// Returns a reference to the previous Hessian
647 ///
648 /// # Example
649 ///
650 /// ```
651 /// # use argmin::core::{IterState, State, ArgminFloat};
652 /// # let mut state: IterState<(), (), (), Vec<Vec<f64>>, (), f64> = IterState::new();
653 /// # assert!(state.prev_hessian.is_none());
654 /// # assert!(state.get_prev_hessian().is_none());
655 /// # state.prev_hessian = Some(vec![vec![1.0, 2.0], vec![3.0, 4.0]]);
656 /// # assert_eq!(state.prev_hessian.as_ref().unwrap()[0][0].to_ne_bytes(), 1.0f64.to_ne_bytes());
657 /// # assert_eq!(state.prev_hessian.as_ref().unwrap()[0][1].to_ne_bytes(), 2.0f64.to_ne_bytes());
658 /// # assert_eq!(state.prev_hessian.as_ref().unwrap()[1][0].to_ne_bytes(), 3.0f64.to_ne_bytes());
659 /// # assert_eq!(state.prev_hessian.as_ref().unwrap()[1][1].to_ne_bytes(), 4.0f64.to_ne_bytes());
660 /// let prev_hessian = state.get_prev_hessian(); // Option<&H>
661 /// # assert_eq!(prev_hessian.as_ref().unwrap()[0][0].to_ne_bytes(), 1.0f64.to_ne_bytes());
662 /// # assert_eq!(prev_hessian.as_ref().unwrap()[0][1].to_ne_bytes(), 2.0f64.to_ne_bytes());
663 /// # assert_eq!(prev_hessian.as_ref().unwrap()[1][0].to_ne_bytes(), 3.0f64.to_ne_bytes());
664 /// # assert_eq!(prev_hessian.as_ref().unwrap()[1][1].to_ne_bytes(), 4.0f64.to_ne_bytes());
665 /// ```
666 pub fn get_prev_hessian(&self) -> Option<&H> {
667 self.prev_hessian.as_ref()
668 }
669
670 /// Moves the previous Hessian out and replaces it internally with `None`
671 ///
672 /// # Example
673 ///
674 /// ```
675 /// # use argmin::core::{IterState, State, ArgminFloat};
676 /// # let mut state: IterState<(), (), (), Vec<Vec<f64>>, (), f64> = IterState::new();
677 /// # assert!(state.prev_hessian.is_none());
678 /// # assert!(state.take_prev_hessian().is_none());
679 /// # state.prev_hessian = Some(vec![vec![1.0, 2.0], vec![3.0, 4.0]]);
680 /// # assert_eq!(state.prev_hessian.as_ref().unwrap()[0][0].to_ne_bytes(), 1.0f64.to_ne_bytes());
681 /// # assert_eq!(state.prev_hessian.as_ref().unwrap()[0][1].to_ne_bytes(), 2.0f64.to_ne_bytes());
682 /// # assert_eq!(state.prev_hessian.as_ref().unwrap()[1][0].to_ne_bytes(), 3.0f64.to_ne_bytes());
683 /// # assert_eq!(state.prev_hessian.as_ref().unwrap()[1][1].to_ne_bytes(), 4.0f64.to_ne_bytes());
684 /// let prev_hessian = state.take_prev_hessian(); // Option<H>
685 /// # assert!(state.take_prev_hessian().is_none());
686 /// # assert!(state.prev_hessian.is_none());
687 /// # assert_eq!(prev_hessian.as_ref().unwrap()[0][0].to_ne_bytes(), 1.0f64.to_ne_bytes());
688 /// # assert_eq!(prev_hessian.as_ref().unwrap()[0][1].to_ne_bytes(), 2.0f64.to_ne_bytes());
689 /// # assert_eq!(prev_hessian.as_ref().unwrap()[1][0].to_ne_bytes(), 3.0f64.to_ne_bytes());
690 /// # assert_eq!(prev_hessian.as_ref().unwrap()[1][1].to_ne_bytes(), 4.0f64.to_ne_bytes());
691 /// ```
692 pub fn take_prev_hessian(&mut self) -> Option<H> {
693 self.prev_hessian.take()
694 }
695
696 /// Returns a reference to the current inverse Hessian
697 ///
698 /// # Example
699 ///
700 /// ```
701 /// # use argmin::core::{IterState, State, ArgminFloat};
702 /// # let mut state: IterState<(), (), (), Vec<Vec<f64>>, (), f64> = IterState::new();
703 /// # assert!(state.inv_hessian.is_none());
704 /// # assert!(state.get_inv_hessian().is_none());
705 /// # state.inv_hessian = Some(vec![vec![1.0, 2.0], vec![3.0, 4.0]]);
706 /// # assert_eq!(state.inv_hessian.as_ref().unwrap()[0][0].to_ne_bytes(), 1.0f64.to_ne_bytes());
707 /// # assert_eq!(state.inv_hessian.as_ref().unwrap()[0][1].to_ne_bytes(), 2.0f64.to_ne_bytes());
708 /// # assert_eq!(state.inv_hessian.as_ref().unwrap()[1][0].to_ne_bytes(), 3.0f64.to_ne_bytes());
709 /// # assert_eq!(state.inv_hessian.as_ref().unwrap()[1][1].to_ne_bytes(), 4.0f64.to_ne_bytes());
710 /// let inv_hessian = state.get_inv_hessian(); // Option<&H>
711 /// # assert_eq!(inv_hessian.as_ref().unwrap()[0][0].to_ne_bytes(), 1.0f64.to_ne_bytes());
712 /// # assert_eq!(inv_hessian.as_ref().unwrap()[0][1].to_ne_bytes(), 2.0f64.to_ne_bytes());
713 /// # assert_eq!(inv_hessian.as_ref().unwrap()[1][0].to_ne_bytes(), 3.0f64.to_ne_bytes());
714 /// # assert_eq!(inv_hessian.as_ref().unwrap()[1][1].to_ne_bytes(), 4.0f64.to_ne_bytes());
715 /// ```
716 pub fn get_inv_hessian(&self) -> Option<&H> {
717 self.inv_hessian.as_ref()
718 }
719
720 /// Moves the inverse Hessian out and replaces it internally with `None`
721 ///
722 /// # Example
723 ///
724 /// ```
725 /// # use argmin::core::{IterState, State, ArgminFloat};
726 /// # let mut state: IterState<(), (), (), Vec<Vec<f64>>, (), f64> = IterState::new();
727 /// # assert!(state.inv_hessian.is_none());
728 /// # assert!(state.take_inv_hessian().is_none());
729 /// # state.inv_hessian = Some(vec![vec![1.0, 2.0], vec![3.0, 4.0]]);
730 /// # assert_eq!(state.inv_hessian.as_ref().unwrap()[0][0].to_ne_bytes(), 1.0f64.to_ne_bytes());
731 /// # assert_eq!(state.inv_hessian.as_ref().unwrap()[0][1].to_ne_bytes(), 2.0f64.to_ne_bytes());
732 /// # assert_eq!(state.inv_hessian.as_ref().unwrap()[1][0].to_ne_bytes(), 3.0f64.to_ne_bytes());
733 /// # assert_eq!(state.inv_hessian.as_ref().unwrap()[1][1].to_ne_bytes(), 4.0f64.to_ne_bytes());
734 /// let inv_hessian = state.take_inv_hessian(); // Option<H>
735 /// # assert!(state.take_inv_hessian().is_none());
736 /// # assert!(state.inv_hessian.is_none());
737 /// # assert_eq!(inv_hessian.as_ref().unwrap()[0][0].to_ne_bytes(), 1.0f64.to_ne_bytes());
738 /// # assert_eq!(inv_hessian.as_ref().unwrap()[0][1].to_ne_bytes(), 2.0f64.to_ne_bytes());
739 /// # assert_eq!(inv_hessian.as_ref().unwrap()[1][0].to_ne_bytes(), 3.0f64.to_ne_bytes());
740 /// # assert_eq!(inv_hessian.as_ref().unwrap()[1][1].to_ne_bytes(), 4.0f64.to_ne_bytes());
741 /// ```
742 pub fn take_inv_hessian(&mut self) -> Option<H> {
743 self.inv_hessian.take()
744 }
745
746 /// Returns a reference to the previous inverse Hessian
747 ///
748 /// # Example
749 ///
750 /// ```
751 /// # use argmin::core::{IterState, State, ArgminFloat};
752 /// # let mut state: IterState<(), (), (), Vec<Vec<f64>>, (), f64> = IterState::new();
753 /// # assert!(state.prev_inv_hessian.is_none());
754 /// # assert!(state.get_prev_inv_hessian().is_none());
755 /// # state.prev_inv_hessian = Some(vec![vec![1.0, 2.0], vec![3.0, 4.0]]);
756 /// # assert_eq!(state.prev_inv_hessian.as_ref().unwrap()[0][0].to_ne_bytes(), 1.0f64.to_ne_bytes());
757 /// # assert_eq!(state.prev_inv_hessian.as_ref().unwrap()[0][1].to_ne_bytes(), 2.0f64.to_ne_bytes());
758 /// # assert_eq!(state.prev_inv_hessian.as_ref().unwrap()[1][0].to_ne_bytes(), 3.0f64.to_ne_bytes());
759 /// # assert_eq!(state.prev_inv_hessian.as_ref().unwrap()[1][1].to_ne_bytes(), 4.0f64.to_ne_bytes());
760 /// let prev_inv_hessian = state.get_prev_inv_hessian(); // Option<&H>
761 /// # assert_eq!(prev_inv_hessian.as_ref().unwrap()[0][0].to_ne_bytes(), 1.0f64.to_ne_bytes());
762 /// # assert_eq!(prev_inv_hessian.as_ref().unwrap()[0][1].to_ne_bytes(), 2.0f64.to_ne_bytes());
763 /// # assert_eq!(prev_inv_hessian.as_ref().unwrap()[1][0].to_ne_bytes(), 3.0f64.to_ne_bytes());
764 /// # assert_eq!(prev_inv_hessian.as_ref().unwrap()[1][1].to_ne_bytes(), 4.0f64.to_ne_bytes());
765 /// ```
766 pub fn get_prev_inv_hessian(&self) -> Option<&H> {
767 self.prev_inv_hessian.as_ref()
768 }
769
770 /// Moves the previous Hessian out and replaces it internally with `None`
771 ///
772 /// # Example
773 ///
774 /// ```
775 /// # use argmin::core::{IterState, State, ArgminFloat};
776 /// # let mut state: IterState<(), (), (), Vec<Vec<f64>>, (), f64> = IterState::new();
777 /// # assert!(state.prev_inv_hessian.is_none());
778 /// # assert!(state.take_prev_inv_hessian().is_none());
779 /// # state.prev_inv_hessian = Some(vec![vec![1.0, 2.0], vec![3.0, 4.0]]);
780 /// # assert_eq!(state.prev_inv_hessian.as_ref().unwrap()[0][0].to_ne_bytes(), 1.0f64.to_ne_bytes());
781 /// # assert_eq!(state.prev_inv_hessian.as_ref().unwrap()[0][1].to_ne_bytes(), 2.0f64.to_ne_bytes());
782 /// # assert_eq!(state.prev_inv_hessian.as_ref().unwrap()[1][0].to_ne_bytes(), 3.0f64.to_ne_bytes());
783 /// # assert_eq!(state.prev_inv_hessian.as_ref().unwrap()[1][1].to_ne_bytes(), 4.0f64.to_ne_bytes());
784 /// let prev_inv_hessian = state.take_prev_inv_hessian(); // Option<H>
785 /// # assert!(state.take_prev_inv_hessian().is_none());
786 /// # assert!(state.prev_inv_hessian.is_none());
787 /// # assert_eq!(prev_inv_hessian.as_ref().unwrap()[0][0].to_ne_bytes(), 1.0f64.to_ne_bytes());
788 /// # assert_eq!(prev_inv_hessian.as_ref().unwrap()[0][1].to_ne_bytes(), 2.0f64.to_ne_bytes());
789 /// # assert_eq!(prev_inv_hessian.as_ref().unwrap()[1][0].to_ne_bytes(), 3.0f64.to_ne_bytes());
790 /// # assert_eq!(prev_inv_hessian.as_ref().unwrap()[1][1].to_ne_bytes(), 4.0f64.to_ne_bytes());
791 /// ```
792 pub fn take_prev_inv_hessian(&mut self) -> Option<H> {
793 self.prev_inv_hessian.take()
794 }
795
796 /// Returns a reference to the current Jacobian
797 ///
798 /// # Example
799 ///
800 /// ```
801 /// # use argmin::core::{IterState, State, ArgminFloat};
802 /// # let mut state: IterState<(), (), Vec<Vec<f64>>, (), (), f64> = IterState::new();
803 /// # assert!(state.jacobian.is_none());
804 /// # assert!(state.get_jacobian().is_none());
805 /// # state.jacobian = Some(vec![vec![1.0, 2.0], vec![3.0, 4.0]]);
806 /// # assert_eq!(state.jacobian.as_ref().unwrap()[0][0].to_ne_bytes(), 1.0f64.to_ne_bytes());
807 /// # assert_eq!(state.jacobian.as_ref().unwrap()[0][1].to_ne_bytes(), 2.0f64.to_ne_bytes());
808 /// # assert_eq!(state.jacobian.as_ref().unwrap()[1][0].to_ne_bytes(), 3.0f64.to_ne_bytes());
809 /// # assert_eq!(state.jacobian.as_ref().unwrap()[1][1].to_ne_bytes(), 4.0f64.to_ne_bytes());
810 /// let jacobian = state.get_jacobian(); // Option<&J>
811 /// # assert_eq!(jacobian.as_ref().unwrap()[0][0].to_ne_bytes(), 1.0f64.to_ne_bytes());
812 /// # assert_eq!(jacobian.as_ref().unwrap()[0][1].to_ne_bytes(), 2.0f64.to_ne_bytes());
813 /// # assert_eq!(jacobian.as_ref().unwrap()[1][0].to_ne_bytes(), 3.0f64.to_ne_bytes());
814 /// # assert_eq!(jacobian.as_ref().unwrap()[1][1].to_ne_bytes(), 4.0f64.to_ne_bytes());
815 /// ```
816 pub fn get_jacobian(&self) -> Option<&J> {
817 self.jacobian.as_ref()
818 }
819
820 /// Moves the Jacobian out and replaces it internally with `None`
821 ///
822 /// # Example
823 ///
824 /// ```
825 /// # use argmin::core::{IterState, State, ArgminFloat};
826 /// # let mut state: IterState<(), (), Vec<Vec<f64>>, (), (), f64> = IterState::new();
827 /// # assert!(state.jacobian.is_none());
828 /// # assert!(state.take_jacobian().is_none());
829 /// # state.jacobian = Some(vec![vec![1.0, 2.0], vec![3.0, 4.0]]);
830 /// # assert_eq!(state.jacobian.as_ref().unwrap()[0][0].to_ne_bytes(), 1.0f64.to_ne_bytes());
831 /// # assert_eq!(state.jacobian.as_ref().unwrap()[0][1].to_ne_bytes(), 2.0f64.to_ne_bytes());
832 /// # assert_eq!(state.jacobian.as_ref().unwrap()[1][0].to_ne_bytes(), 3.0f64.to_ne_bytes());
833 /// # assert_eq!(state.jacobian.as_ref().unwrap()[1][1].to_ne_bytes(), 4.0f64.to_ne_bytes());
834 /// let jacobian = state.take_jacobian(); // Option<J>
835 /// # assert!(state.take_jacobian().is_none());
836 /// # assert!(state.jacobian.is_none());
837 /// # assert_eq!(jacobian.as_ref().unwrap()[0][0].to_ne_bytes(), 1.0f64.to_ne_bytes());
838 /// # assert_eq!(jacobian.as_ref().unwrap()[0][1].to_ne_bytes(), 2.0f64.to_ne_bytes());
839 /// # assert_eq!(jacobian.as_ref().unwrap()[1][0].to_ne_bytes(), 3.0f64.to_ne_bytes());
840 /// # assert_eq!(jacobian.as_ref().unwrap()[1][1].to_ne_bytes(), 4.0f64.to_ne_bytes());
841 /// ```
842 pub fn take_jacobian(&mut self) -> Option<J> {
843 self.jacobian.take()
844 }
845
846 /// Returns a reference to the previous Jacobian
847 ///
848 /// # Example
849 ///
850 /// ```
851 /// # use argmin::core::{IterState, State, ArgminFloat};
852 /// # let mut state: IterState<(), (), Vec<Vec<f64>>, (), (), f64> = IterState::new();
853 /// # assert!(state.prev_jacobian.is_none());
854 /// # assert!(state.get_prev_jacobian().is_none());
855 /// # state.prev_jacobian = Some(vec![vec![1.0, 2.0], vec![3.0, 4.0]]);
856 /// # assert_eq!(state.prev_jacobian.as_ref().unwrap()[0][0].to_ne_bytes(), 1.0f64.to_ne_bytes());
857 /// # assert_eq!(state.prev_jacobian.as_ref().unwrap()[0][1].to_ne_bytes(), 2.0f64.to_ne_bytes());
858 /// # assert_eq!(state.prev_jacobian.as_ref().unwrap()[1][0].to_ne_bytes(), 3.0f64.to_ne_bytes());
859 /// # assert_eq!(state.prev_jacobian.as_ref().unwrap()[1][1].to_ne_bytes(), 4.0f64.to_ne_bytes());
860 /// let prev_jacobian = state.get_prev_jacobian(); // Option<&J>
861 /// # assert_eq!(prev_jacobian.as_ref().unwrap()[0][0].to_ne_bytes(), 1.0f64.to_ne_bytes());
862 /// # assert_eq!(prev_jacobian.as_ref().unwrap()[0][1].to_ne_bytes(), 2.0f64.to_ne_bytes());
863 /// # assert_eq!(prev_jacobian.as_ref().unwrap()[1][0].to_ne_bytes(), 3.0f64.to_ne_bytes());
864 /// # assert_eq!(prev_jacobian.as_ref().unwrap()[1][1].to_ne_bytes(), 4.0f64.to_ne_bytes());
865 /// ```
866 pub fn get_prev_jacobian(&self) -> Option<&J> {
867 self.prev_jacobian.as_ref()
868 }
869
870 /// Moves the previous Jacobian out and replaces it internally with `None`
871 ///
872 /// # Example
873 ///
874 /// ```
875 /// # use argmin::core::{IterState, State, ArgminFloat};
876 /// # let mut state: IterState<(), (), Vec<Vec<f64>>, (), (), f64> = IterState::new();
877 /// # assert!(state.prev_jacobian.is_none());
878 /// # assert!(state.take_prev_jacobian().is_none());
879 /// # state.prev_jacobian = Some(vec![vec![1.0, 2.0], vec![3.0, 4.0]]);
880 /// # assert_eq!(state.prev_jacobian.as_ref().unwrap()[0][0].to_ne_bytes(), 1.0f64.to_ne_bytes());
881 /// # assert_eq!(state.prev_jacobian.as_ref().unwrap()[0][1].to_ne_bytes(), 2.0f64.to_ne_bytes());
882 /// # assert_eq!(state.prev_jacobian.as_ref().unwrap()[1][0].to_ne_bytes(), 3.0f64.to_ne_bytes());
883 /// # assert_eq!(state.prev_jacobian.as_ref().unwrap()[1][1].to_ne_bytes(), 4.0f64.to_ne_bytes());
884 /// let prev_jacobian = state.take_prev_jacobian(); // Option<J>
885 /// # assert!(state.take_prev_jacobian().is_none());
886 /// # assert!(state.prev_jacobian.is_none());
887 /// # assert_eq!(prev_jacobian.as_ref().unwrap()[0][0].to_ne_bytes(), 1.0f64.to_ne_bytes());
888 /// # assert_eq!(prev_jacobian.as_ref().unwrap()[0][1].to_ne_bytes(), 2.0f64.to_ne_bytes());
889 /// # assert_eq!(prev_jacobian.as_ref().unwrap()[1][0].to_ne_bytes(), 3.0f64.to_ne_bytes());
890 /// # assert_eq!(prev_jacobian.as_ref().unwrap()[1][1].to_ne_bytes(), 4.0f64.to_ne_bytes());
891 /// ```
892 pub fn take_prev_jacobian(&mut self) -> Option<J> {
893 self.prev_jacobian.take()
894 }
895
896 /// Returns a reference to the residuals
897 ///
898 /// # Example
899 ///
900 /// ```
901 /// # use argmin::core::{IterState, State, ArgminFloat};
902 /// # let mut state: IterState<(), (), (), (), Vec<f64>, f64> = IterState::new();
903 /// # assert!(state.residuals.is_none());
904 /// # state.residuals = Some(vec![1.0, 2.0]);
905 /// # assert_eq!(state.residuals.as_ref().unwrap()[0].to_ne_bytes(), 1.0f64.to_ne_bytes());
906 /// # assert_eq!(state.residuals.as_ref().unwrap()[1].to_ne_bytes(), 2.0f64.to_ne_bytes());
907 /// let residuals = state.get_residuals(); // Option<&R>
908 /// # assert_eq!(residuals.as_ref().unwrap()[0].to_ne_bytes(), 1.0f64.to_ne_bytes());
909 /// # assert_eq!(residuals.as_ref().unwrap()[1].to_ne_bytes(), 2.0f64.to_ne_bytes());
910 /// ```
911 pub fn get_residuals(&self) -> Option<&R> {
912 self.residuals.as_ref()
913 }
914
915 /// Moves the residuals out and replaces it internally with `None`
916 ///
917 /// # Example
918 ///
919 /// ```
920 /// # use argmin::core::{IterState, State, ArgminFloat};
921 /// # let mut state: IterState<(), (), (), (), Vec<f64>, f64> = IterState::new();
922 /// # assert!(state.take_residuals().is_none());
923 /// # state.residuals = Some(vec![1.0, 2.0]);
924 /// # assert_eq!(state.residuals.as_ref().unwrap()[0].to_ne_bytes(), 1.0f64.to_ne_bytes());
925 /// # assert_eq!(state.residuals.as_ref().unwrap()[1].to_ne_bytes(), 2.0f64.to_ne_bytes());
926 /// let residuals = state.take_residuals(); // Option<R>
927 /// # assert!(state.take_residuals().is_none());
928 /// # assert!(state.residuals.is_none());
929 /// # assert_eq!(residuals.as_ref().unwrap()[0].to_ne_bytes(), 1.0f64.to_ne_bytes());
930 /// # assert_eq!(residuals.as_ref().unwrap()[1].to_ne_bytes(), 2.0f64.to_ne_bytes());
931 /// ```
932 pub fn take_residuals(&mut self) -> Option<R> {
933 self.residuals.take()
934 }
935
936 /// Returns a reference to the previous residuals
937 ///
938 /// # Example
939 ///
940 /// ```
941 /// # use argmin::core::{IterState, State, ArgminFloat};
942 /// # let mut state: IterState<(), (), (), (), Vec<f64>, f64> = IterState::new();
943 /// # assert!(state.residuals.is_none());
944 /// # state.residuals = Some(vec![1.0, 2.0]);
945 /// # assert_eq!(state.residuals.as_ref().unwrap()[0].to_ne_bytes(), 1.0f64.to_ne_bytes());
946 /// # assert_eq!(state.residuals.as_ref().unwrap()[1].to_ne_bytes(), 2.0f64.to_ne_bytes());
947 /// let residuals = state.get_residuals(); // Option<&R>
948 /// # assert_eq!(residuals.as_ref().unwrap()[0].to_ne_bytes(), 1.0f64.to_ne_bytes());
949 /// # assert_eq!(residuals.as_ref().unwrap()[1].to_ne_bytes(), 2.0f64.to_ne_bytes());
950 /// ```
951 pub fn get_prev_residuals(&self) -> Option<&R> {
952 self.prev_residuals.as_ref()
953 }
954
955 /// Moves the previous residuals out and replaces it internally with `None`
956 ///
957 /// # Example
958 ///
959 /// ```
960 /// # use argmin::core::{IterState, State, ArgminFloat};
961 /// # let mut state: IterState<(), (), (), (), Vec<f64>, f64> = IterState::new();
962 /// # assert!(state.take_residuals().is_none());
963 /// # state.residuals = Some(vec![1.0, 2.0]);
964 /// # assert_eq!(state.residuals.as_ref().unwrap()[0].to_ne_bytes(), 1.0f64.to_ne_bytes());
965 /// # assert_eq!(state.residuals.as_ref().unwrap()[1].to_ne_bytes(), 2.0f64.to_ne_bytes());
966 /// let residuals = state.take_residuals(); // Option<R>
967 /// # assert!(state.take_residuals().is_none());
968 /// # assert!(state.residuals.is_none());
969 /// # assert_eq!(residuals.as_ref().unwrap()[0].to_ne_bytes(), 1.0f64.to_ne_bytes());
970 /// # assert_eq!(residuals.as_ref().unwrap()[1].to_ne_bytes(), 2.0f64.to_ne_bytes());
971 /// ```
972 pub fn take_prev_residuals(&mut self) -> Option<R> {
973 self.prev_residuals.take()
974 }
975
976 /// Overrides state of counting function executions (default: false)
977 /// ```
978 /// # use argmin::core::{IterState, State};
979 /// # let mut state: IterState<(), (), (), (), Vec<f64>, f64> = IterState::new();
980 /// # assert!(!state.counting_enabled);
981 /// let state = state.counting(true);
982 /// # assert!(state.counting_enabled);
983 /// ```
984 #[must_use]
985 pub fn counting(mut self, mode: bool) -> Self {
986 self.counting_enabled = mode;
987 self
988 }
989}
990
991impl<P, G, J, H, R, F> State for IterState<P, G, J, H, R, F>
992where
993 P: Clone,
994 F: ArgminFloat,
995{
996 /// Type of parameter vector
997 type Param = P;
998 /// Floating point precision
999 type Float = F;
1000
1001 /// Create a new IterState instance
1002 ///
1003 /// # Example
1004 ///
1005 /// ```
1006 /// # extern crate web_time;
1007 /// # use web_time::Duration;
1008 /// # use argmin::core::{IterState, State, ArgminFloat, TerminationStatus};
1009 /// let state: IterState<Vec<f64>, Vec<f64>, Vec<Vec<f64>>, Vec<Vec<f64>>, Vec<f64>, f64> = IterState::new();
1010 /// # assert!(state.param.is_none());
1011 /// # assert!(state.prev_param.is_none());
1012 /// # assert!(state.best_param.is_none());
1013 /// # assert!(state.prev_best_param.is_none());
1014 /// # assert_eq!(state.cost.to_ne_bytes(), f64::INFINITY.to_ne_bytes());
1015 /// # assert_eq!(state.prev_cost.to_ne_bytes(), f64::INFINITY.to_ne_bytes());
1016 /// # assert_eq!(state.best_cost.to_ne_bytes(), f64::INFINITY.to_ne_bytes());
1017 /// # assert_eq!(state.prev_best_cost.to_ne_bytes(), f64::INFINITY.to_ne_bytes());
1018 /// # assert_eq!(state.target_cost.to_ne_bytes(), f64::NEG_INFINITY.to_ne_bytes());
1019 /// # assert!(state.grad.is_none());
1020 /// # assert!(state.prev_grad.is_none());
1021 /// # assert!(state.hessian.is_none());
1022 /// # assert!(state.prev_hessian.is_none());
1023 /// # assert!(state.inv_hessian.is_none());
1024 /// # assert!(state.prev_inv_hessian.is_none());
1025 /// # assert!(state.jacobian.is_none());
1026 /// # assert!(state.prev_jacobian.is_none());
1027 /// # assert_eq!(state.iter, 0);
1028 /// # assert_eq!(state.last_best_iter, 0);
1029 /// # assert_eq!(state.max_iters, u64::MAX);
1030 /// # assert_eq!(state.counts.len(), 0);
1031 /// # assert_eq!(state.time.unwrap(), Duration::ZERO);
1032 /// # assert_eq!(state.termination_status, TerminationStatus::NotTerminated);
1033 /// ```
1034 fn new() -> Self {
1035 IterState {
1036 param: None,
1037 prev_param: None,
1038 best_param: None,
1039 prev_best_param: None,
1040 cost: F::infinity(),
1041 prev_cost: F::infinity(),
1042 best_cost: F::infinity(),
1043 prev_best_cost: F::infinity(),
1044 target_cost: F::neg_infinity(),
1045 grad: None,
1046 prev_grad: None,
1047 hessian: None,
1048 prev_hessian: None,
1049 inv_hessian: None,
1050 prev_inv_hessian: None,
1051 jacobian: None,
1052 prev_jacobian: None,
1053 residuals: None,
1054 prev_residuals: None,
1055 iter: 0,
1056 last_best_iter: 0,
1057 max_iters: u64::MAX,
1058 counts: HashMap::new(),
1059 counting_enabled: false,
1060 time: Some(Duration::ZERO),
1061 termination_status: TerminationStatus::NotTerminated,
1062 }
1063 }
1064
1065 /// Checks if the current parameter vector is better than the previous best parameter value. If
1066 /// a new best parameter vector was found, the state is updated accordingly.
1067 ///
1068 /// # Example
1069 ///
1070 /// ```
1071 /// # use argmin::core::{IterState, State, ArgminFloat};
1072 /// let mut state: IterState<Vec<f64>, (), (), (), (), f64> = IterState::new();
1073 ///
1074 /// // Simulating a new, better parameter vector
1075 /// state.best_param = Some(vec![1.0f64]);
1076 /// state.best_cost = 10.0;
1077 /// state.param = Some(vec![2.0f64]);
1078 /// state.cost = 5.0;
1079 ///
1080 /// // Calling update
1081 /// state.update();
1082 ///
1083 /// // Check if update was successful
1084 /// assert_eq!(state.best_param.as_ref().unwrap()[0], 2.0f64);
1085 /// assert_eq!(state.best_cost.to_ne_bytes(), state.best_cost.to_ne_bytes());
1086 /// assert!(state.is_best());
1087 /// ```
1088 ///
1089 /// For algorithms which do not compute the cost function, every new parameter vector will be
1090 /// the new best:
1091 ///
1092 /// ```
1093 /// # use argmin::core::{IterState, State, ArgminFloat};
1094 /// let mut state: IterState<Vec<f64>, (), (), (), (), f64> = IterState::new();
1095 ///
1096 /// // Simulating a new, better parameter vector
1097 /// state.best_param = Some(vec![1.0f64]);
1098 /// state.param = Some(vec![2.0f64]);
1099 ///
1100 /// // Calling update
1101 /// state.update();
1102 ///
1103 /// // Check if update was successful
1104 /// assert_eq!(state.best_param.as_ref().unwrap()[0], 2.0f64);
1105 /// assert_eq!(state.best_cost.to_ne_bytes(), state.best_cost.to_ne_bytes());
1106 /// assert!(state.is_best());
1107 /// ```
1108 fn update(&mut self) {
1109 // check if parameters are the best so far
1110 // Comparison is done using `<` to avoid new solutions with the same cost function value as
1111 // the current best to be accepted. However, some solvers to not compute the cost function
1112 // value (such as the Newton method). Those will always have `Inf` cost. Therefore if both
1113 // the new value and the previous best value are `Inf`, the solution is also accepted. Care
1114 // is taken that both `Inf` also have the same sign.
1115 if self.cost < self.best_cost
1116 || (self.cost.is_infinite()
1117 && self.best_cost.is_infinite()
1118 && self.cost.is_sign_positive() == self.best_cost.is_sign_positive())
1119 {
1120 // If there is no parameter vector, then also don't set the best param.
1121 if let Some(param) = self.param.as_ref().cloned() {
1122 std::mem::swap(&mut self.prev_best_param, &mut self.best_param);
1123 self.best_param = Some(param);
1124 }
1125 std::mem::swap(&mut self.prev_best_cost, &mut self.best_cost);
1126 self.best_cost = self.cost;
1127 self.last_best_iter = self.iter;
1128 }
1129 }
1130
1131 /// Returns a reference to the current parameter vector
1132 ///
1133 /// # Example
1134 ///
1135 /// ```
1136 /// # use argmin::core::{IterState, State, ArgminFloat};
1137 /// # let mut state: IterState<Vec<f64>, (), (), (), (), f64> = IterState::new();
1138 /// # assert!(state.param.is_none());
1139 /// # state.param = Some(vec![1.0, 2.0]);
1140 /// # assert_eq!(state.param.as_ref().unwrap()[0].to_ne_bytes(), 1.0f64.to_ne_bytes());
1141 /// # assert_eq!(state.param.as_ref().unwrap()[1].to_ne_bytes(), 2.0f64.to_ne_bytes());
1142 /// let param = state.get_param(); // Option<&P>
1143 /// # assert_eq!(param.as_ref().unwrap()[0].to_ne_bytes(), 1.0f64.to_ne_bytes());
1144 /// # assert_eq!(param.as_ref().unwrap()[1].to_ne_bytes(), 2.0f64.to_ne_bytes());
1145 /// ```
1146 fn get_param(&self) -> Option<&P> {
1147 self.param.as_ref()
1148 }
1149
1150 /// Returns a reference to the current best parameter vector
1151 ///
1152 /// # Example
1153 ///
1154 /// ```
1155 /// # use argmin::core::{IterState, State, ArgminFloat};
1156 /// # let mut state: IterState<Vec<f64>, (), (), (), (), f64> = IterState::new();
1157 /// # assert!(state.best_param.is_none());
1158 /// # state.best_param = Some(vec![1.0, 2.0]);
1159 /// # assert_eq!(state.best_param.as_ref().unwrap()[0].to_ne_bytes(), 1.0f64.to_ne_bytes());
1160 /// # assert_eq!(state.best_param.as_ref().unwrap()[1].to_ne_bytes(), 2.0f64.to_ne_bytes());
1161 /// let best_param = state.get_best_param(); // Option<&P>
1162 /// # assert_eq!(best_param.as_ref().unwrap()[0].to_ne_bytes(), 1.0f64.to_ne_bytes());
1163 /// # assert_eq!(best_param.as_ref().unwrap()[1].to_ne_bytes(), 2.0f64.to_ne_bytes());
1164 /// ```
1165 fn get_best_param(&self) -> Option<&P> {
1166 self.best_param.as_ref()
1167 }
1168
1169 /// Sets the termination status to [`Terminated`](`TerminationStatus::Terminated`) with the given reason
1170 ///
1171 /// # Example
1172 ///
1173 /// ```
1174 /// # use argmin::core::{IterState, State, ArgminFloat, TerminationReason, TerminationStatus};
1175 /// # let mut state: IterState<Vec<f64>, (), (), (), (), f64> = IterState::new();
1176 /// # assert_eq!(state.termination_status, TerminationStatus::NotTerminated);
1177 /// let state = state.terminate_with(TerminationReason::MaxItersReached);
1178 /// # assert_eq!(state.termination_status, TerminationStatus::Terminated(TerminationReason::MaxItersReached));
1179 /// ```
1180 fn terminate_with(mut self, reason: TerminationReason) -> Self {
1181 self.termination_status = TerminationStatus::Terminated(reason);
1182 self
1183 }
1184
1185 /// Sets the time required so far.
1186 ///
1187 /// # Example
1188 ///
1189 /// ```
1190 /// # extern crate web_time;
1191 /// # use web_time::Duration;
1192 /// # use argmin::core::{IterState, State, ArgminFloat, TerminationReason};
1193 /// # let mut state: IterState<Vec<f64>, (), (), (), (), f64> = IterState::new();
1194 /// let state = state.time(Some(Duration::from_nanos(12)));
1195 /// # assert_eq!(state.time.unwrap(), Duration::from_nanos(12));
1196 /// ```
1197 fn time(&mut self, time: Option<Duration>) -> &mut Self {
1198 self.time = time;
1199 self
1200 }
1201
1202 /// Returns current cost function value.
1203 ///
1204 /// # Example
1205 ///
1206 /// ```
1207 /// # use argmin::core::{IterState, State, ArgminFloat};
1208 /// # let mut state: IterState<Vec<f64>, (), (), (), (), f64> = IterState::new();
1209 /// # state.cost = 12.0;
1210 /// let cost = state.get_cost();
1211 /// # assert_eq!(cost.to_ne_bytes(), 12.0f64.to_ne_bytes());
1212 /// ```
1213 fn get_cost(&self) -> Self::Float {
1214 self.cost
1215 }
1216
1217 /// Returns current best cost function value.
1218 ///
1219 /// # Example
1220 ///
1221 /// ```
1222 /// # use argmin::core::{IterState, State, ArgminFloat};
1223 /// # let mut state: IterState<Vec<f64>, (), (), (), (), f64> = IterState::new();
1224 /// # state.best_cost = 12.0;
1225 /// let best_cost = state.get_best_cost();
1226 /// # assert_eq!(best_cost.to_ne_bytes(), 12.0f64.to_ne_bytes());
1227 /// ```
1228 fn get_best_cost(&self) -> Self::Float {
1229 self.best_cost
1230 }
1231
1232 /// Returns target cost function value.
1233 ///
1234 /// # Example
1235 ///
1236 /// ```
1237 /// # use argmin::core::{IterState, State, ArgminFloat};
1238 /// # let mut state: IterState<Vec<f64>, (), (), (), (), f64> = IterState::new();
1239 /// # state.target_cost = 12.0;
1240 /// let target_cost = state.get_target_cost();
1241 /// # assert_eq!(target_cost.to_ne_bytes(), 12.0f64.to_ne_bytes());
1242 /// ```
1243 fn get_target_cost(&self) -> Self::Float {
1244 self.target_cost
1245 }
1246
1247 /// Returns current number of iterations.
1248 ///
1249 /// # Example
1250 ///
1251 /// ```
1252 /// # use argmin::core::{IterState, State, ArgminFloat};
1253 /// # let mut state: IterState<Vec<f64>, (), (), (), (), f64> = IterState::new();
1254 /// # state.iter = 12;
1255 /// let iter = state.get_iter();
1256 /// # assert_eq!(iter, 12);
1257 /// ```
1258 fn get_iter(&self) -> u64 {
1259 self.iter
1260 }
1261
1262 /// Returns iteration number of last best parameter vector.
1263 ///
1264 /// # Example
1265 ///
1266 /// ```
1267 /// # use argmin::core::{IterState, State, ArgminFloat};
1268 /// # let mut state: IterState<Vec<f64>, (), (), (), (), f64> = IterState::new();
1269 /// # state.last_best_iter = 12;
1270 /// let last_best_iter = state.get_last_best_iter();
1271 /// # assert_eq!(last_best_iter, 12);
1272 /// ```
1273 fn get_last_best_iter(&self) -> u64 {
1274 self.last_best_iter
1275 }
1276
1277 /// Returns the maximum number of iterations.
1278 ///
1279 /// # Example
1280 ///
1281 /// ```
1282 /// # use argmin::core::{IterState, State, ArgminFloat};
1283 /// # let mut state: IterState<Vec<f64>, (), (), (), (), f64> = IterState::new();
1284 /// # state.max_iters = 12;
1285 /// let max_iters = state.get_max_iters();
1286 /// # assert_eq!(max_iters, 12);
1287 /// ```
1288 fn get_max_iters(&self) -> u64 {
1289 self.max_iters
1290 }
1291
1292 /// Returns the termination status.
1293 ///
1294 /// # Example
1295 ///
1296 /// ```
1297 /// # use argmin::core::{IterState, State, ArgminFloat, TerminationStatus};
1298 /// # let mut state: IterState<Vec<f64>, (), (), (), (), f64> = IterState::new();
1299 /// let termination_status = state.get_termination_status();
1300 /// # assert_eq!(*termination_status, TerminationStatus::NotTerminated);
1301 /// ```
1302 fn get_termination_status(&self) -> &TerminationStatus {
1303 &self.termination_status
1304 }
1305
1306 /// Returns the termination reason if terminated, otherwise None.
1307 ///
1308 /// # Example
1309 ///
1310 /// ```
1311 /// # use argmin::core::{IterState, State, ArgminFloat, TerminationReason};
1312 /// # let mut state: IterState<Vec<f64>, (), (), (), (), f64> = IterState::new();
1313 /// let termination_reason = state.get_termination_reason();
1314 /// # assert_eq!(termination_reason, None);
1315 /// ```
1316 fn get_termination_reason(&self) -> Option<&TerminationReason> {
1317 match &self.termination_status {
1318 TerminationStatus::Terminated(reason) => Some(reason),
1319 TerminationStatus::NotTerminated => None,
1320 }
1321 }
1322
1323 /// Returns the time elapsed since the start of the optimization.
1324 ///
1325 /// # Example
1326 ///
1327 /// ```
1328 /// # extern crate web_time;
1329 /// # use web_time::Duration;
1330 /// # use argmin::core::{IterState, State, ArgminFloat};
1331 /// # let mut state: IterState<Vec<f64>, (), (), (), (), f64> = IterState::new();
1332 /// let time = state.get_time();
1333 /// # assert_eq!(time.unwrap(), Duration::ZERO);
1334 /// ```
1335 fn get_time(&self) -> Option<Duration> {
1336 self.time
1337 }
1338
1339 /// Increments the number of iterations by one
1340 ///
1341 /// # Example
1342 ///
1343 /// ```
1344 /// # use argmin::core::{IterState, State, ArgminFloat};
1345 /// # let mut state: IterState<Vec<f64>, (), (), (), (), f64> = IterState::new();
1346 /// # assert_eq!(state.iter, 0);
1347 /// state.increment_iter();
1348 /// # assert_eq!(state.iter, 1);
1349 /// ```
1350 fn increment_iter(&mut self) {
1351 self.iter += 1;
1352 }
1353
1354 /// Set all function evaluation counts to the evaluation counts of another `Problem`.
1355 ///
1356 /// ```
1357 /// # use std::collections::HashMap;
1358 /// # use argmin::core::{Problem, IterState, State, ArgminFloat};
1359 /// # let mut state: IterState<Vec<f64>, (), (), (), (), f64> = IterState::new().counting(true);
1360 /// # assert_eq!(state.counts, HashMap::new());
1361 /// # state.counts.insert("test2".to_string(), 10u64);
1362 /// #
1363 /// # #[derive(Eq, PartialEq, Debug)]
1364 /// # struct UserDefinedProblem {};
1365 /// #
1366 /// # let mut problem = Problem::new(UserDefinedProblem {});
1367 /// # problem.counts.insert("test1", 10u64);
1368 /// # problem.counts.insert("test2", 2);
1369 /// state.func_counts(&problem);
1370 /// # let mut hm = HashMap::new();
1371 /// # hm.insert("test1".to_string(), 10u64);
1372 /// # hm.insert("test2".to_string(), 2u64);
1373 /// # assert_eq!(state.counts, hm);
1374 /// ```
1375 fn func_counts<O>(&mut self, problem: &Problem<O>) {
1376 if self.counting_enabled {
1377 for (k, &v) in problem.counts.iter() {
1378 let count = self.counts.entry(k.to_string()).or_insert(0);
1379 *count = v
1380 }
1381 }
1382 }
1383
1384 /// Returns function evaluation counts
1385 ///
1386 /// # Example
1387 ///
1388 /// ```
1389 /// # use std::collections::HashMap;
1390 /// # use argmin::core::{IterState, State, ArgminFloat};
1391 /// # let mut state: IterState<Vec<f64>, (), (), (), (), f64> = IterState::new();
1392 /// # assert_eq!(state.counts, HashMap::new());
1393 /// # state.counts.insert("test2".to_string(), 10u64);
1394 /// let counts = state.get_func_counts();
1395 /// # let mut hm = HashMap::new();
1396 /// # hm.insert("test2".to_string(), 10u64);
1397 /// # assert_eq!(*counts, hm);
1398 /// ```
1399 fn get_func_counts(&self) -> &HashMap<String, u64> {
1400 &self.counts
1401 }
1402
1403 /// Returns whether the current parameter vector is also the best parameter vector found so
1404 /// far.
1405 ///
1406 /// # Example
1407 ///
1408 /// ```
1409 /// # use argmin::core::{IterState, State, ArgminFloat};
1410 /// # let mut state: IterState<Vec<f64>, (), (), (), (), f64> = IterState::new();
1411 /// # state.last_best_iter = 12;
1412 /// # state.iter = 12;
1413 /// let is_best = state.is_best();
1414 /// # assert!(is_best);
1415 /// # state.last_best_iter = 12;
1416 /// # state.iter = 21;
1417 /// # let is_best = state.is_best();
1418 /// # assert!(!is_best);
1419 /// ```
1420 fn is_best(&self) -> bool {
1421 self.last_best_iter == self.iter
1422 }
1423}
1424
1425#[cfg(test)]
1426mod tests {
1427 use super::*;
1428
1429 #[test]
1430 #[allow(clippy::type_complexity)]
1431 fn test_iterstate() {
1432 let param = vec![1.0f64, 2.0];
1433 let residuals = vec![1.0f64, 2.0];
1434 let cost: f64 = 42.0;
1435
1436 let mut state: IterState<Vec<f64>, Vec<f64>, Vec<f64>, Vec<Vec<f64>>, Vec<f64>, f64> =
1437 IterState::new();
1438
1439 assert!(state.get_param().is_none());
1440 assert!(state.get_prev_param().is_none());
1441 assert!(state.get_best_param().is_none());
1442 assert!(state.get_prev_best_param().is_none());
1443
1444 state = state.param(param.clone());
1445
1446 assert_eq!(*state.get_param().unwrap(), param);
1447 assert!(state.get_prev_param().is_none());
1448 assert!(state.get_best_param().is_none());
1449 assert!(state.get_prev_best_param().is_none());
1450
1451 assert!(state.get_cost().is_infinite());
1452 assert!(state.get_cost().is_sign_positive());
1453
1454 assert!(state.get_prev_cost().is_infinite());
1455 assert!(state.get_prev_cost().is_sign_positive());
1456
1457 assert!(state.get_best_cost().is_infinite());
1458 assert!(state.get_best_cost().is_sign_positive());
1459
1460 assert!(state.get_prev_best_cost().is_infinite());
1461 assert!(state.get_prev_best_cost().is_sign_positive());
1462
1463 assert!(state.get_target_cost().is_infinite());
1464 assert!(state.get_target_cost().is_sign_negative());
1465
1466 assert!(state.get_gradient().is_none());
1467 assert!(state.get_prev_gradient().is_none());
1468 assert!(state.get_hessian().is_none());
1469 assert!(state.get_prev_hessian().is_none());
1470 assert!(state.get_inv_hessian().is_none());
1471 assert!(state.get_prev_inv_hessian().is_none());
1472 assert!(state.get_jacobian().is_none());
1473 assert!(state.get_prev_jacobian().is_none());
1474 assert!(state.get_residuals().is_none());
1475 assert!(state.get_prev_residuals().is_none());
1476 assert_eq!(state.get_iter(), 0);
1477
1478 assert!(state.is_best());
1479
1480 state = state.residuals(param.clone());
1481
1482 assert_eq!(state.get_max_iters(), u64::MAX);
1483 let func_counts = state.get_func_counts().clone();
1484 assert!(!func_counts.contains_key("cost_count"));
1485 assert!(!func_counts.contains_key("operator_count"));
1486 assert!(!func_counts.contains_key("gradient_count"));
1487 assert!(!func_counts.contains_key("hessian_count"));
1488 assert!(!func_counts.contains_key("jacobian_count"));
1489 assert!(!func_counts.contains_key("modify_count"));
1490
1491 state = state.max_iters(42);
1492
1493 assert_eq!(state.get_max_iters(), 42);
1494
1495 let mut state = state.cost(cost);
1496
1497 assert_eq!(state.get_cost().to_ne_bytes(), cost.to_ne_bytes());
1498 assert!(state.get_prev_cost().is_infinite());
1499 assert!(state.get_prev_cost().is_sign_positive());
1500
1501 let new_param = vec![2.0, 1.0];
1502
1503 state = state.param(new_param.clone());
1504
1505 assert_eq!(*state.get_param().unwrap(), new_param);
1506 assert_eq!(*state.get_prev_param().unwrap(), param);
1507
1508 let new_residuals = vec![2.0, 1.0];
1509
1510 state = state.residuals(new_residuals.clone());
1511
1512 assert_eq!(*state.get_residuals().unwrap(), new_residuals);
1513 assert_eq!(*state.get_prev_residuals().unwrap(), residuals);
1514
1515 let new_cost: f64 = 21.0;
1516
1517 let mut state = state.cost(new_cost);
1518
1519 assert_eq!(state.get_cost().to_ne_bytes(), new_cost.to_ne_bytes());
1520 assert_eq!(state.get_prev_cost().to_ne_bytes(), cost.to_ne_bytes());
1521
1522 state.increment_iter();
1523
1524 assert_eq!(state.get_iter(), 1);
1525
1526 assert!(!state.is_best());
1527
1528 state.last_best_iter = state.iter;
1529
1530 assert!(state.is_best());
1531
1532 let grad = vec![1.0, 2.0];
1533
1534 let state = state.gradient(grad.clone());
1535 assert_eq!(*state.get_gradient().unwrap(), grad);
1536 assert!(state.get_prev_gradient().is_none());
1537
1538 let new_grad = vec![2.0, 1.0];
1539
1540 let state = state.gradient(new_grad.clone());
1541
1542 assert_eq!(*state.get_gradient().unwrap(), new_grad);
1543 assert_eq!(*state.get_prev_gradient().unwrap(), grad);
1544
1545 let hessian = vec![vec![1.0, 2.0], vec![2.0, 1.0]];
1546
1547 let state = state.hessian(hessian.clone());
1548 assert_eq!(*state.get_hessian().unwrap(), hessian);
1549 assert!(state.get_prev_hessian().is_none());
1550
1551 let new_hessian = vec![vec![2.0, 1.0], vec![1.0, 2.0]];
1552
1553 let state = state.hessian(new_hessian.clone());
1554
1555 assert_eq!(*state.get_hessian().unwrap(), new_hessian);
1556 assert_eq!(*state.get_prev_hessian().unwrap(), hessian);
1557
1558 let inv_hessian = vec![vec![2.0, 1.0], vec![1.0, 2.0]];
1559
1560 let state = state.inv_hessian(inv_hessian.clone());
1561 assert_eq!(*state.get_inv_hessian().unwrap(), inv_hessian);
1562 assert!(state.get_prev_inv_hessian().is_none());
1563
1564 let new_inv_hessian = vec![vec![3.0, 4.0], vec![4.0, 3.0]];
1565
1566 let state = state.inv_hessian(new_inv_hessian.clone());
1567
1568 assert_eq!(*state.get_inv_hessian().unwrap(), new_inv_hessian);
1569 assert_eq!(*state.get_prev_inv_hessian().unwrap(), inv_hessian);
1570
1571 let jacobian = vec![1.0f64, 2.0];
1572
1573 let state = state.jacobian(jacobian.clone());
1574 assert!(state.get_prev_jacobian().is_none());
1575
1576 let new_jacobian = vec![2.0f64, 1.0];
1577
1578 let mut state = state.jacobian(new_jacobian.clone());
1579
1580 assert_eq!(*state.get_jacobian().unwrap(), new_jacobian);
1581 assert_eq!(*state.get_prev_jacobian().unwrap(), jacobian);
1582
1583 state.increment_iter();
1584
1585 assert_eq!(state.get_iter(), 2);
1586 assert_eq!(state.get_last_best_iter(), 1);
1587 assert!(!state.is_best());
1588
1589 // check again!
1590 assert_eq!(state.get_iter(), 2);
1591 assert_eq!(state.get_last_best_iter(), 1);
1592 assert_eq!(state.get_max_iters(), 42);
1593
1594 assert!(!state.is_best());
1595
1596 assert_eq!(state.get_cost().to_ne_bytes(), new_cost.to_ne_bytes());
1597 assert_eq!(state.get_prev_cost().to_ne_bytes(), cost.to_ne_bytes());
1598 assert_eq!(state.get_prev_cost().to_ne_bytes(), cost.to_ne_bytes());
1599
1600 assert_eq!(*state.get_param().unwrap(), new_param);
1601 assert_eq!(*state.get_prev_param().unwrap(), param);
1602
1603 assert_eq!(*state.get_gradient().unwrap(), new_grad);
1604 assert_eq!(*state.get_prev_gradient().unwrap(), grad);
1605 assert_eq!(*state.get_hessian().unwrap(), new_hessian);
1606 assert_eq!(*state.get_prev_hessian().unwrap(), hessian);
1607 assert_eq!(*state.get_inv_hessian().unwrap(), new_inv_hessian);
1608 assert_eq!(*state.get_prev_inv_hessian().unwrap(), inv_hessian);
1609 assert_eq!(*state.get_jacobian().unwrap(), new_jacobian);
1610 assert_eq!(*state.get_prev_jacobian().unwrap(), jacobian);
1611 assert_eq!(state.take_gradient().unwrap(), new_grad);
1612 assert_eq!(state.take_prev_gradient().unwrap(), grad);
1613 assert_eq!(state.take_hessian().unwrap(), new_hessian);
1614 assert_eq!(state.take_prev_hessian().unwrap(), hessian);
1615 assert_eq!(state.take_inv_hessian().unwrap(), new_inv_hessian);
1616 assert_eq!(state.take_prev_inv_hessian().unwrap(), inv_hessian);
1617 assert_eq!(state.take_jacobian().unwrap(), new_jacobian);
1618 assert_eq!(state.take_prev_jacobian().unwrap(), jacobian);
1619 assert_eq!(*state.get_residuals().unwrap(), new_residuals);
1620 assert_eq!(*state.get_prev_residuals().unwrap(), residuals);
1621 let func_counts = state.get_func_counts().clone();
1622 assert!(!func_counts.contains_key("cost_count"));
1623 assert!(!func_counts.contains_key("operator_count"));
1624 assert!(!func_counts.contains_key("gradient_count"));
1625 assert!(!func_counts.contains_key("hessian_count"));
1626 assert!(!func_counts.contains_key("jacobian_count"));
1627 assert!(!func_counts.contains_key("modify_count"));
1628 }
1629}