conspire/math/optimize/globalization/line_search/residual/
mod.rs1use super::{LineSearchError, ResidualMerit, exhausted};
2use crate::math::Scalar;
3use std::fmt::{self, Display, Formatter};
4
5#[derive(Clone, Debug)]
7pub struct Residual {
8 pub control: Scalar,
9 pub cut_back: Scalar,
10 pub max_steps: usize,
11}
12
13impl Default for Residual {
14 fn default() -> Self {
15 Self {
16 control: 1e-3,
17 cut_back: 9e-1,
18 max_steps: 100,
19 }
20 }
21}
22
23impl Display for Residual {
24 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
25 write!(f, "Residual")
26 }
27}
28
29impl ResidualMerit for Residual {
30 fn search_residual(
31 &self,
32 mut merit: impl FnMut(Scalar) -> Result<Scalar, String>,
33 value: Scalar,
34 fraction: Scalar,
35 ) -> Result<Scalar, LineSearchError> {
36 let t = self.control * 2.0 * fraction * value;
37 let mut n = 1.0;
38 for _ in 0..self.max_steps {
39 if let Ok(trial) = merit(n)
40 && value - trial >= n * t
41 {
42 return Ok(n);
43 } else {
44 n *= self.cut_back
45 }
46 }
47 Err(exhausted(self, self.max_steps))
48 }
49}