Adds LBFGS optimization method
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user