conspire/math/optimize/globalization/line_search/goldstein/
mod.rs1use super::{LineSearchError, ObjectiveMerit, backtrack, backtrack_merit};
2use crate::math::{Erase, Jacobian, Quantity, Scalar, Solution, Tensor};
3use std::{
4 fmt::{self, Display, Formatter},
5 ops::Mul,
6};
7
8#[derive(Clone, Debug)]
10pub struct Goldstein {
11 pub control: Scalar,
12 pub cut_back: Scalar,
13 pub max_steps: usize,
14}
15
16impl Display for Goldstein {
17 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
18 write!(f, "Goldstein")
19 }
20}
21
22impl Goldstein {
23 fn accepts(&self, decrease: Scalar, n: Scalar, slope: Scalar) -> bool {
24 !(n * (1.0 - self.control) * slope < decrease || decrease < n * self.control * slope)
25 }
26}
27
28impl ObjectiveMerit for Goldstein {
29 fn search<X, J, D, W, E>(
30 &self,
31 function: impl FnMut(&X, Scalar) -> Result<Scalar, String>,
32 _jacobian: impl FnMut(&X) -> Result<J, String>,
33 argument: &X,
34 jacobian0: &J,
35 decrement: &D,
36 step_size: Scalar,
37 ) -> Result<Scalar, LineSearchError>
38 where
39 J: Erase<Erased = E> + Jacobian,
40 D: Erase<Erased = E>,
41 E: Tensor,
42 X: Solution,
43 for<'a> &'a D: Mul<Quantity<W>, Output = X>,
44 {
45 backtrack(
46 self,
47 self.cut_back,
48 self.max_steps,
49 function,
50 argument,
51 jacobian0,
52 decrement,
53 step_size,
54 |decrease, n, slope| self.accepts(decrease, n, slope),
55 )
56 }
57 fn search_merit(
58 &self,
59 merit: impl FnMut(Scalar) -> Result<Scalar, String>,
60 value: Scalar,
61 slope: Scalar,
62 step_size: Scalar,
63 ) -> Result<Scalar, LineSearchError> {
64 backtrack_merit(
65 self,
66 self.cut_back,
67 self.max_steps,
68 merit,
69 value,
70 slope,
71 step_size,
72 |decrease, n, slope| self.accepts(decrease, n, slope),
73 )
74 }
75}