use ripopt::{NlpProblem, SolveStatus, SolverOptions};
struct Rosenbrock;
impl NlpProblem for Rosenbrock {
fn num_variables(&self) -> usize {
2
}
fn num_constraints(&self) -> usize {
0
}
fn bounds(&self, x_l: &mut [f64], x_u: &mut [f64]) {
x_l[0] = f64::NEG_INFINITY;
x_l[1] = f64::NEG_INFINITY;
x_u[0] = f64::INFINITY;
x_u[1] = f64::INFINITY;
}
fn constraint_bounds(&self, _g_l: &mut [f64], _g_u: &mut [f64]) {
}
fn initial_point(&self, x0: &mut [f64]) {
x0[0] = -1.2;
x0[1] = 1.0;
}
fn objective(&self, x: &[f64]) -> f64 {
let (x1, x2) = (x[0], x[1]);
(1.0 - x1).powi(2) + 100.0 * (x2 - x1 * x1).powi(2)
}
fn gradient(&self, x: &[f64], grad: &mut [f64]) {
let (x1, x2) = (x[0], x[1]);
grad[0] = -2.0 * (1.0 - x1) - 400.0 * x1 * (x2 - x1 * x1);
grad[1] = 200.0 * (x2 - x1 * x1);
}
fn constraints(&self, _x: &[f64], _g: &mut [f64]) {
}
fn jacobian_structure(&self) -> (Vec<usize>, Vec<usize>) {
(vec![], vec![])
}
fn jacobian_values(&self, _x: &[f64], _vals: &mut [f64]) {
}
fn hessian_structure(&self) -> (Vec<usize>, Vec<usize>) {
(vec![0, 1, 1], vec![0, 0, 1])
}
fn hessian_values(&self, x: &[f64], obj_factor: f64, _lambda: &[f64], vals: &mut [f64]) {
let (x1, x2) = (x[0], x[1]);
vals[0] = obj_factor * (2.0 - 400.0 * x2 + 1200.0 * x1 * x1);
vals[1] = obj_factor * (-400.0 * x1);
vals[2] = obj_factor * 200.0;
}
}
fn main() {
env_logger::init();
let problem = Rosenbrock;
let options = SolverOptions::default();
println!("Solving Rosenbrock function...");
println!(" Start: (-1.2, 1.0)");
println!();
let result = ripopt::solve(&problem, &options);
println!("Status: {:?}", result.status);
println!("Iterations: {}", result.iterations);
println!("Objective: {:.10e}", result.objective);
println!("Solution: x1 = {:.10}, x2 = {:.10}", result.x[0], result.x[1]);
assert_eq!(result.status, SolveStatus::Optimal);
}