optimization_engine 0.12.0

A pure Rust framework for embedded nonconvex optimization. Ideal for robotics!
Documentation
//! # PANOC Example 2
//!
//! This example shows how to minimize the [Rosenbrock function] subject to constraints,
//! in a loop using a common cache object.
//!
//! [Rosenbrock function]: https://en.wikipedia.org/wiki/Rosenbrock_function
//!
use optimization_engine::{panoc::*, *};

fn rosenbrock_cost(a: f64, b: f64, u: &[f64]) -> f64 {
    (a - u[0]).powi(2) + b * (u[1] - u[0].powi(2)).powi(2)
}

fn rosenbrock_grad(a: f64, b: f64, u: &[f64], grad: &mut [f64]) {
    grad[0] = 2.0 * u[0] - 2.0 * a - 4.0 * b * u[0] * (-u[0].powi(2) + u[1]);
    grad[1] = b * (-2.0 * u[0].powi(2) + 2.0 * u[1]);
}

fn main() {
    let tolerance = 1e-6;
    let mut a_param = 1.0;
    let mut b_param = 100.0;
    let n_dim_u = 2;
    let lbfgs_memory = 10;
    let max_iters = 100;
    let mut u = [-1.5, 0.9];
    let mut radius = 1.0;

    // the cache is created only ONCE
    let mut panoc_cache = PANOCCache::new(n_dim_u, tolerance, lbfgs_memory);

    let mut idx = 0;
    while idx < 100 {
        // update the values of `a`, `b` and `radius`
        b_param *= 1.01;
        a_param -= 1e-3;
        radius += 0.001;

        // update the function definitions (`f` and `df`)
        let df = |u: &[f64], grad: &mut [f64]| -> Result<(), SolverError> {
            rosenbrock_grad(a_param, b_param, u, grad);
            Ok(())
        };
        let f = |u: &[f64], c: &mut f64| -> Result<(), SolverError> {
            *c = rosenbrock_cost(a_param, b_param, u);
            Ok(())
        };

        // define the bounds at every iteration
        let bounds = constraints::Ball2::new(None, radius);

        // the problem definition is updated at every iteration
        let problem = Problem::new(&bounds, df, f);

        // updated instance of the solver
        let mut panoc = PANOCOptimizer::new(problem, &mut panoc_cache).with_max_iter(max_iters);

        let status = panoc.solve(&mut u).unwrap();

        idx += 1;

        // print useful information
        println!(
            "parameters: (a={:.4}, b={:.4}, r={:.4}), iters = {}",
            a_param,
            b_param,
            radius,
            status.iterations()
        );
        println!("u = {:#.6?}", u);
    }
}