newton_example/
newton_example.rs1use nalgebra::{DMatrix, DVector};
2use optimization_solvers::{FuncEvalMultivariate, LineSearchSolver, MoreThuente, Newton, Tracer};
3
4fn main() {
5 std::env::set_var("RUST_LOG", "info");
7 let _ = Tracer::default().with_normal_stdout_layer().build();
8
9 let f_and_g = |x: &DVector<f64>| -> FuncEvalMultivariate {
12 let x1 = x[0];
13 let x2 = x[1];
14
15 let f = x1.powi(2) + x2.powi(2) + (x1.powi(2) + x2.powi(2)).exp();
17
18 let exp_term = (x1.powi(2) + x2.powi(2)).exp();
20 let g1 = 2.0 * x1 * (1.0 + exp_term);
21 let g2 = 2.0 * x2 * (1.0 + exp_term);
22 let g = DVector::from_vec(vec![g1, g2]);
23
24 let h11 = 2.0 * (1.0 + exp_term) + 4.0 * x1.powi(2) * exp_term;
26 let h12 = 4.0 * x1 * x2 * exp_term;
27 let h21 = h12;
28 let h22 = 2.0 * (1.0 + exp_term) + 4.0 * x2.powi(2) * exp_term;
29 let hessian = DMatrix::from_vec(2, 2, vec![h11, h21, h12, h22]);
30
31 FuncEvalMultivariate::new(f, g).with_hessian(hessian)
32 };
33
34 let mut ls = MoreThuente::default();
36
37 let tol = 1e-6;
39 let x0 = DVector::from_vec(vec![1.0, 1.0]); let mut solver = Newton::new(tol, x0.clone());
41
42 let max_iter_solver = 20;
44 let max_iter_line_search = 20;
45
46 println!("=== Newton's Method Example ===");
47 println!("Objective: f(x,y) = x^2 + y^2 + exp(x^2 + y^2) (convex)");
48 println!("Global minimum: (0, 0) with f(0,0) = 1");
49 println!("Starting point: {:?}", x0);
50 println!("Tolerance: {}", tol);
51 println!();
52
53 match solver.minimize(
54 &mut ls,
55 f_and_g,
56 max_iter_solver,
57 max_iter_line_search,
58 None,
59 ) {
60 Ok(()) => {
61 let x = solver.x();
62 let eval = f_and_g(x);
63 println!("✅ Optimization completed successfully!");
64 println!("Final iterate: {:?}", x);
65 println!("Function value: {:.6}", eval.f());
66 println!("Gradient norm: {:.6}", eval.g().norm());
67 println!("Iterations: {}", solver.k());
68
69 if let Some(decrement_squared) = solver.decrement_squared() {
71 println!("Newton decrement squared: {:.6}", decrement_squared);
72 println!("Newton decrement: {:.6}", decrement_squared.sqrt());
73 }
74
75 let true_min = DVector::from_vec(vec![0.0, 0.0]);
77 let distance_to_min = (x - true_min).norm();
78 println!("Distance to true minimum: {:.6}", distance_to_min);
79 println!("Expected function value: 1.0");
80 }
81 Err(e) => {
82 println!("❌ Optimization failed: {:?}", e);
83 }
84 }
85}