conspire/math/optimize/globalization/line_search/armijo/
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 Armijo {
11 pub control: Scalar,
12 pub cut_back: Scalar,
13 pub max_steps: usize,
14}
15
16impl Default for Armijo {
17 fn default() -> Self {
18 Self {
19 control: 1e-3,
20 cut_back: 9e-1,
21 max_steps: 100,
22 }
23 }
24}
25
26impl Display for Armijo {
27 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
28 write!(f, "Armijo")
29 }
30}
31
32impl ObjectiveMerit for Armijo {
33 fn search<X, J, D, W, E>(
34 &self,
35 function: impl FnMut(&X, Scalar) -> Result<Scalar, String>,
36 _jacobian: impl FnMut(&X) -> Result<J, String>,
37 argument: &X,
38 jacobian0: &J,
39 decrement: &D,
40 step_size: Scalar,
41 ) -> Result<Scalar, LineSearchError>
42 where
43 J: Erase<Erased = E> + Jacobian,
44 D: Erase<Erased = E>,
45 E: Tensor,
46 X: Solution,
47 for<'a> &'a D: Mul<Quantity<W>, Output = X>,
48 {
49 backtrack(
50 self,
51 self.cut_back,
52 self.max_steps,
53 function,
54 argument,
55 jacobian0,
56 decrement,
57 step_size,
58 |decrease, n, slope| decrease >= n * self.control * slope,
59 )
60 }
61 fn search_merit(
62 &self,
63 merit: impl FnMut(Scalar) -> Result<Scalar, String>,
64 value: Scalar,
65 slope: Scalar,
66 step_size: Scalar,
67 ) -> Result<Scalar, LineSearchError> {
68 backtrack_merit(
69 self,
70 self.cut_back,
71 self.max_steps,
72 merit,
73 value,
74 slope,
75 step_size,
76 |decrease, n, slope| decrease >= n * self.control * slope,
77 )
78 }
79}