extern crate argmin;
extern crate argmin_testfunctions;
extern crate finitediff;
extern crate ndarray;
use argmin::prelude::*;
use argmin::solver::linesearch::MoreThuenteLineSearch;
use argmin::solver::quasinewton::BFGS;
use argmin_testfunctions::rosenbrock;
use finitediff::*;
use ndarray::{array, Array1, Array2};
struct Rosenbrock {
a: f64,
b: f64,
}
impl ArgminOp for Rosenbrock {
type Param = Array1<f64>;
type Output = f64;
type Hessian = Array2<f64>;
type Jacobian = ();
type Float = f64;
fn apply(&self, p: &Self::Param) -> Result<Self::Output, Error> {
Ok(rosenbrock(&p.to_vec(), self.a, self.b))
}
fn gradient(&self, p: &Self::Param) -> Result<Self::Param, Error> {
Ok((*p).forward_diff(&|x| rosenbrock(&x.to_vec(), self.a, self.b)))
}
}
fn run() -> Result<(), Error> {
let cost = Rosenbrock { a: 1.0, b: 100.0 };
let init_param: Array1<f64> = array![-1.2, 1.0, -10.0, 2.0, 3.0, 2.0, 4.0, 10.0];
let init_hessian: Array2<f64> = Array2::eye(8);
let linesearch = MoreThuenteLineSearch::new();
let solver = BFGS::new(init_hessian, linesearch);
let writer = WriteToFile::new("params", "param")
.serializer(WriteToFileSerializer::JSON);
let writer2 = WriteToFile::new("params", "best")
.serializer(WriteToFileSerializer::JSON);
let res = Executor::new(cost, solver, init_param)
.max_iters(10)
.add_observer(ArgminSlogLogger::term(), ObserverMode::Always)
.add_observer(writer, ObserverMode::Every(3))
.add_observer(writer2, ObserverMode::NewBest)
.run()?;
std::thread::sleep(std::time::Duration::from_secs(1));
println!("{}", res);
Ok(())
}
fn main() {
if let Err(ref e) = run() {
println!("{}", e);
std::process::exit(1);
}
}