auxiliary_noop/
auxiliary_noop.rs1#![allow(clippy::expect_used, clippy::unwrap_used)]
16
17use std::cell::RefCell;
18use std::rc::Rc;
19
20use pounce_nlp::tnlp::{
21 BoundsInfo, IndexStyle, IpoptCq, IpoptData, NlpInfo, Solution, SparsityRequest, StartingPoint,
22 TNLP,
23};
24use pounce_presolve::{wrap_with_presolve, AuxiliaryCouplingPolicy, PresolveOptions, PresolveTnlp};
25
26struct Mini;
28
29impl TNLP for Mini {
30 fn get_nlp_info(&mut self) -> Option<NlpInfo> {
31 Some(NlpInfo {
32 n: 2,
33 m: 1,
34 nnz_jac_g: 2,
35 nnz_h_lag: 2,
36 index_style: IndexStyle::C,
37 })
38 }
39 fn get_bounds_info(&mut self, b: BoundsInfo<'_>) -> bool {
40 b.x_l.iter_mut().for_each(|v| *v = -1e19);
41 b.x_u.iter_mut().for_each(|v| *v = 1e19);
42 b.g_l[0] = 1.0;
43 b.g_u[0] = 1.0;
44 true
45 }
46 fn get_starting_point(&mut self, sp: StartingPoint<'_>) -> bool {
47 sp.x[0] = 0.5;
48 sp.x[1] = 0.5;
49 true
50 }
51 fn eval_f(&mut self, x: &[f64], _new_x: bool) -> Option<f64> {
52 Some(x[0] * x[0] + x[1] * x[1])
53 }
54 fn eval_grad_f(&mut self, x: &[f64], _new_x: bool, g: &mut [f64]) -> bool {
55 g[0] = 2.0 * x[0];
56 g[1] = 2.0 * x[1];
57 true
58 }
59 fn eval_g(&mut self, x: &[f64], _new_x: bool, g: &mut [f64]) -> bool {
60 g[0] = x[0] + x[1];
61 true
62 }
63 fn eval_jac_g(&mut self, _x: Option<&[f64]>, _new_x: bool, mode: SparsityRequest<'_>) -> bool {
64 match mode {
65 SparsityRequest::Structure { irow, jcol } => {
66 irow.copy_from_slice(&[0, 0]);
67 jcol.copy_from_slice(&[0, 1]);
68 }
69 SparsityRequest::Values { values } => {
70 values.copy_from_slice(&[1.0, 1.0]);
71 }
72 }
73 true
74 }
75 fn finalize_solution(&mut self, _sol: Solution<'_>, _d: &IpoptData, _q: &IpoptCq) {}
76}
77
78fn main() {
79 let opts = PresolveOptions {
80 enabled: true,
81 auxiliary: true,
82 auxiliary_coupling: AuxiliaryCouplingPolicy::Safe,
83 auxiliary_diagnostics: true,
84 ..PresolveOptions::defaults()
85 };
86 let inner: Rc<RefCell<dyn TNLP>> = Rc::new(RefCell::new(Mini));
87 let wrapped = wrap_with_presolve(inner, opts).expect("wrap ok");
88
89 let info = wrapped.borrow_mut().get_nlp_info().expect("get_nlp_info");
91
92 let mut values = vec![0.0; info.nnz_jac_g as usize];
95 let ok = wrapped.borrow_mut().eval_jac_g(
96 Some(&[0.5, 0.5]),
97 true,
98 SparsityRequest::Values {
99 values: &mut values,
100 },
101 );
102 assert!(ok, "eval_jac_g(Values) must succeed");
103
104 let inner2: Rc<RefCell<dyn TNLP>> = Rc::new(RefCell::new(Mini));
108 let mut typed = PresolveTnlp::new(inner2, opts);
109 let _ = typed.get_nlp_info();
110 let d = typed.auxiliary_diagnostics();
111
112 println!("auxiliary_noop example — PR 1 of pounce#53");
113 println!(
114 "inner shape: n={}, m={}, nnz_jac_g={}",
115 info.n, info.m, info.nnz_jac_g
116 );
117 println!("jac values at (0.5, 0.5): {:?}", values);
118 println!(
119 "diagnostics: blocks_eliminated={}, vars_eliminated={}, rows_eliminated={}, total_time_ms={}",
120 d.blocks_eliminated, d.vars_eliminated, d.rows_eliminated, d.total_time_ms,
121 );
122 println!("rejection_reasons: {:?}", d.rejection_reasons);
123}