-
Notifications
You must be signed in to change notification settings - Fork 68
Expand file tree
/
Copy pathpanoc_ex2.rs
More file actions
72 lines (60 loc) · 2.15 KB
/
panoc_ex2.rs
File metadata and controls
72 lines (60 loc) · 2.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
//! # 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);
}
}