liblbfgs 0.1.0

Fast and safe Rust implementation of LBFGS and OWL-QN algorithms ported from Naoaki Okazaki's C library libLBFGS.
Documentation
// sample.rs
// :PROPERTIES:
// :header-args: :tangle examples/sample.rs
// :END:
// Adopted from sample.c in original source.

// [[file:~/Workspace/Programming/gosh-rs/lbfgs/lbfgs.note::*sample.rs][sample.rs:1]]
use liblbfgs::{lbfgs, Progress};

fn main() {
    const N: usize = 100;

    // Initialize the variables
    let mut x = [0.0 as f64; N];
    for i in (0..N).step_by(2) {
        x[i] = -1.2;
        x[i + 1] = 1.0;
    }

    // Default evaluator adopted from liblbfgs sample.c
    //
    // # Parameters
    // - x: The current values of variables.
    // - gx   : The gradient vector. The callback function must compute the gradient values for the current variables.
    // # Return
    // - fx: evaluated value
    let evaluate = |x: &[f64], gx: &mut [f64]| {
        let n = x.len();

        let mut fx = 0.0;
        for i in (0..n).step_by(2) {
            let t1 = 1.0 - x[i];
            let t2 = 10.0 * (x[i + 1] - x[i] * x[i]);
            gx[i + 1] = 20.0 * t2;
            gx[i] = -2.0 * (x[i] * gx[i + 1] + t1);
            fx += t1 * t1 + t2 * t2;
        }

        Ok(fx)
    };

    // Default progress monitor adopted from liblbfgs sample.c
    //
    // # Parameters
    // - prgr: holding all progressive data
    // # Return
    // - false to continue the optimization process. Returning true will cancel the optimization process.
    let progress = |prgr: &Progress| {
        let x = &prgr.x;

        println!("Iteration {}:", &prgr.niter);
        println!("  fx = {}, x[0] = {}, x[1] = {}", &prgr.fx, x[0], x[1]);
        println!(
            "  xnorm = {}, gnorm = {}, step = {}",
            &prgr.xnorm, &prgr.gnorm, &prgr.step
        );
        println!("");

        false
    };

    let prb = lbfgs()
        .minimize(&mut x, evaluate, progress)
        .expect("lbfgs minimize");

    println!("  fx = {:}, x[0] = {}, x[1] = {}\n", prb.fx, x[0], x[1]);
}
// sample.rs:1 ends here