Crates.io | liblbfgs |
lib.rs | liblbfgs |
version | 0.1.0 |
source | src |
created_at | 2020-02-10 10:24:12.27547 |
updated_at | 2022-08-08 02:19:41.470758 |
description | Fast and safe Rust implementation of LBFGS and OWL-QN algorithms ported from Naoaki Okazaki's C library libLBFGS. |
homepage | https://github.com/ybyygu/rust-lbfgs |
repository | https://github.com/ybyygu/rust-lbfgs |
max_upload_size | |
id | 206970 |
size | 107,547 |
Fast and safe Rust implementation of LBFGS and OWL-QN algorithms ported from Naoaki Okazaki's C library libLBFGS.
Check rust-liblbfgs for a working wrapper around the original C codes.
Bring native LBFGS implementation to Rust community.
Learn how a great optimization algorithm is implemented in real world.
Learn how to "replace the jet engine while still flying" URL
Make it more maintainable with Rust high level abstraction.
Improve it to meet my needs for computational chemistry.
Parallel with rayon
SIMD support
add option to disable line search for gradient only optimization
Fix issues inherited from liblbfgs URL
Clean and safe Rust implementation.
OWL-QN algorithm.
Closure based callback interfaces.
Damped L-BFGS algorithm.
// 0. Import the lib
use liblbfgs::lbfgs;
const N: usize = 100;
// 1. Initialize data
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;
}
// 2. Defining how to evaluate function and gradient
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)
};
let prb = lbfgs()
.with_max_iterations(5)
.with_orthantwise(1.0, 0, 99) // enable OWL-QN
.minimize(
&mut x, // input variables
evaluate, // define how to evaluate function
|prgr| { // define progress monitor
println!("iter: {:}", prgr.niter);
false // returning true will cancel optimization
}
)
.expect("lbfgs owlqn minimize");
println!("fx = {:}", prb.fx);
The callback functions are native Rust FnMut closures, possible to capture/change variables in the environment.
Full codes with comments are available in examples/sample.rs.
Run the example:
cargo run --example sample