argmin/solver/trustregion/mod.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
8//! # Trust region method
9//!
10//! The trust region method approximates the cost function within a certain region around the
11//! current point in parameter space. Depending on the quality of this approximation, the region is
12//! either expanded or contracted.
13//!
14//! For more details see [`TrustRegion`].
15//!
16//! ## Reference
17//!
18//! Jorge Nocedal and Stephen J. Wright (2006). Numerical Optimization.
19//! Springer. ISBN 0-387-30303-0.
20
21/// Cauchy Point
22mod cauchypoint;
23/// Dogleg method
24mod dogleg;
25/// Steihaug method
26mod steihaug;
27/// Trust region solver
28mod trustregion_method;
29
30pub use self::cauchypoint::*;
31pub use self::dogleg::*;
32pub use self::steihaug::*;
33pub use self::trustregion_method::*;
34
35/// An interface methods which calculate approximate steps for trust region methods must implement.
36///
37/// # Example
38///
39/// ```
40/// use argmin::solver::trustregion::TrustRegionRadius;
41///
42/// struct MySubProblem<F> {
43/// radius: F
44/// }
45///
46/// impl<F> TrustRegionRadius<F> for MySubProblem<F> {
47/// fn set_radius(&mut self, radius: F) {
48/// self.radius = radius
49/// }
50/// }
51/// ```
52pub trait TrustRegionRadius<F> {
53 /// Set the initial radius
54 ///
55 /// # Example
56 ///
57 /// ```
58 /// use argmin::solver::trustregion::TrustRegionRadius;
59 /// # use argmin::core::ArgminFloat;
60 ///
61 /// # struct MySubProblem<F> {
62 /// # radius: F
63 /// # }
64 /// #
65 /// # impl<F: ArgminFloat> MySubProblem<F> {
66 /// # pub fn new() -> Self {
67 /// # MySubProblem { radius: F::from_f64(1.0f64).unwrap() }
68 /// # }
69 /// # }
70 /// #
71 /// # impl<F> TrustRegionRadius<F> for MySubProblem<F> {
72 /// # fn set_radius(&mut self, radius: F) {
73 /// # self.radius = radius
74 /// # }
75 /// # }
76 /// let mut subproblem = MySubProblem::new();
77 ///
78 /// subproblem.set_radius(0.8);
79 /// ```
80 fn set_radius(&mut self, radius: F);
81}
82
83/// Computes reduction ratio
84pub fn reduction_ratio<F: crate::core::ArgminFloat>(fxk: F, fxkpk: F, mk0: F, mkpk: F) -> F {
85 (fxk - fxkpk) / (mk0 - mkpk)
86}
87
88#[cfg(test)]
89mod tests {
90 use super::*;
91 use approx::assert_relative_eq;
92
93 #[test]
94 fn test_reduction_ration() {
95 let fxk = 10.0f64;
96 let fxkpk = 6.0;
97 let mk0 = 12.0;
98 let mkpk = 10.0;
99
100 assert_relative_eq!(
101 reduction_ratio(fxk, fxkpk, mk0, mkpk),
102 2.0f64,
103 epsilon = f64::EPSILON
104 );
105 }
106}