Adds LBFGS optimization method

This commit is contained in:
Volodymyr Orlov
2019-11-15 08:56:09 -08:00
parent 4488cc110e
commit b5e677e615
6 changed files with 525 additions and 33 deletions
+42 -1
View File
@@ -14,6 +14,7 @@ pub struct LineSearchResult {
pub struct Backtracking {
pub c1: f64,
pub max_iterations: usize,
pub max_infinity_iterations: usize,
pub phi: f64,
pub plo: f64,
pub order: FunctionOrder
@@ -24,6 +25,7 @@ impl Default for Backtracking {
Backtracking {
c1: 1e-4,
max_iterations: 1000,
max_infinity_iterations: -EPSILON.log2() as usize,
phi: 0.5,
plo: 0.1,
order: FunctionOrder::SECOND
@@ -38,6 +40,15 @@ impl LineSearchMethod for Backtracking {
let (mut a1, mut a2) = (alpha, alpha);
let (mut fx0, mut fx1) = (f0, f(a1));
let mut iterfinite = 0;
while !fx1.is_finite() && iterfinite < self.max_infinity_iterations {
iterfinite += 1;
a1 = a2;
a2 = a1 / 2.;
fx1 = f(a2);
}
let mut iteration = 0;
while fx1 > f0 + self.c1 * a2 * df0 {
@@ -49,7 +60,7 @@ impl LineSearchMethod for Backtracking {
match self.order {
FunctionOrder::FIRST | FunctionOrder::SECOND => {
FunctionOrder::FIRST | FunctionOrder::SECOND => {
a_tmp = - (df0 * a2.powf(2.)) / (2. * (fx1 - f0 - df0*a2))
},
@@ -85,4 +96,34 @@ impl LineSearchMethod for Backtracking {
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn backtracking() {
let f = |x: f64| -> f64 {
x.powf(2.) + x
};
let df = |x: f64| -> f64 {
2. * x + 1.
};
let ls: Backtracking = Default::default();
let mut x = -3.;
let mut alpha = 1.;
for _ in 0..10 {
let result = ls.search(&f, &df, alpha, f(x), df(x));
alpha = result.alpha;
x += alpha;
}
assert!(f(x).abs() < 0.01);
}
}