Skip to main content

conspire/math/optimize/globalization/line_search/wolfe/
mod.rs

1use super::{LineSearchError, ObjectiveMerit, exhausted, start};
2use crate::{
3    math::{Quantity, Scalar},
4    units::UnitMul,
5};
6use std::fmt::{self, Display, Formatter};
7
8/// The Wolfe conditions on the objective.
9#[derive(Clone, Debug)]
10pub struct Wolfe {
11    pub control_1: Scalar,
12    pub control_2: Scalar,
13    pub cut_back: Scalar,
14    pub max_steps: usize,
15    pub strong: bool,
16}
17
18impl Display for Wolfe {
19    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
20        write!(f, "Wolfe")
21    }
22}
23
24impl ObjectiveMerit for Wolfe {
25    fn search<W, U, V>(
26        &self,
27        mut value: impl FnMut(Quantity<W>) -> Result<Quantity<V>, String>,
28        mut slope: impl FnMut(Quantity<W>) -> Result<Quantity<U>, String>,
29        step_size: Quantity<W>,
30    ) -> Result<Quantity<W>, LineSearchError<W>>
31    where
32        W: UnitMul<U, Output = V>,
33    {
34        let (initial, gradient) = start(self, &mut value, &mut slope, step_size)?;
35        let t_1 = gradient * self.control_1;
36        let t_2 = gradient * self.control_2;
37        let mut n = step_size;
38        for _ in 0..self.max_steps {
39            if let Ok(trial) = value(n)
40                && let Ok(curvature) = slope(n)
41                && initial - trial >= n * t_1
42                && if self.strong {
43                    curvature.abs() < t_2.abs()
44                } else {
45                    curvature < t_2
46                }
47            {
48                return Ok(n);
49            } else {
50                n *= self.cut_back
51            }
52        }
53        Err(exhausted(self, self.max_steps))
54    }
55    fn search_merit(
56        &self,
57        _merit: impl FnMut(Scalar) -> Result<Scalar, String>,
58        _value: Scalar,
59        _slope: Scalar,
60        _step_size: Scalar,
61    ) -> Result<Scalar, LineSearchError> {
62        panic!(
63            "The Wolfe conditions need the gradient of the merit function, which the exact penalty function does not have."
64        )
65    }
66}