pounce_cli/
counting_tnlp.rs1use pounce_common::types::{Index, Number};
16use pounce_nlp::tnlp::{
17 BoundsInfo, IpoptCq, IpoptData, IterStats, MetaData, NlpInfo, ScalingRequest, Solution,
18 SparsityRequest, StartingPoint, TNLP,
19};
20use std::cell::{Cell, RefCell};
21use std::rc::Rc;
22
23pub struct CountingTnlp {
24 inner: Rc<RefCell<dyn TNLP>>,
25 pub n_obj: Cell<i32>,
26 pub n_grad_f: Cell<i32>,
27 pub n_g: Cell<i32>,
28 pub n_jac_g: Cell<i32>,
29 pub n_h: Cell<i32>,
30 captured_solution: RefCell<Option<(Vec<Number>, Vec<Number>)>>,
36}
37
38impl CountingTnlp {
39 pub fn new(inner: Rc<RefCell<dyn TNLP>>) -> Self {
40 Self {
41 inner,
42 n_obj: Cell::new(0),
43 n_grad_f: Cell::new(0),
44 n_g: Cell::new(0),
45 n_jac_g: Cell::new(0),
46 n_h: Cell::new(0),
47 captured_solution: RefCell::new(None),
48 }
49 }
50
51 pub fn captured_solution(&self) -> Option<(Vec<Number>, Vec<Number>)> {
53 self.captured_solution.borrow().clone()
54 }
55}
56
57impl TNLP for CountingTnlp {
58 fn get_nlp_info(&mut self) -> Option<NlpInfo> {
59 self.inner.borrow_mut().get_nlp_info()
60 }
61
62 fn get_bounds_info(&mut self, b: BoundsInfo<'_>) -> bool {
63 self.inner.borrow_mut().get_bounds_info(b)
64 }
65
66 fn get_starting_point(&mut self, sp: StartingPoint<'_>) -> bool {
67 self.inner.borrow_mut().get_starting_point(sp)
68 }
69
70 fn eval_f(&mut self, x: &[Number], new_x: bool) -> Option<Number> {
71 self.n_obj.set(self.n_obj.get() + 1);
72 self.inner.borrow_mut().eval_f(x, new_x)
73 }
74
75 fn eval_grad_f(&mut self, x: &[Number], new_x: bool, grad_f: &mut [Number]) -> bool {
76 self.n_grad_f.set(self.n_grad_f.get() + 1);
77 self.inner.borrow_mut().eval_grad_f(x, new_x, grad_f)
78 }
79
80 fn eval_g(&mut self, x: &[Number], new_x: bool, g: &mut [Number]) -> bool {
81 self.n_g.set(self.n_g.get() + 1);
82 self.inner.borrow_mut().eval_g(x, new_x, g)
83 }
84
85 fn eval_jac_g(&mut self, x: Option<&[Number]>, new_x: bool, mode: SparsityRequest<'_>) -> bool {
86 if matches!(mode, SparsityRequest::Values { .. }) {
89 self.n_jac_g.set(self.n_jac_g.get() + 1);
90 }
91 self.inner.borrow_mut().eval_jac_g(x, new_x, mode)
92 }
93
94 fn eval_h(
95 &mut self,
96 x: Option<&[Number]>,
97 new_x: bool,
98 obj_factor: Number,
99 lambda: Option<&[Number]>,
100 new_lambda: bool,
101 mode: SparsityRequest<'_>,
102 ) -> bool {
103 if matches!(mode, SparsityRequest::Values { .. }) {
104 self.n_h.set(self.n_h.get() + 1);
105 }
106 self.inner
107 .borrow_mut()
108 .eval_h(x, new_x, obj_factor, lambda, new_lambda, mode)
109 }
110
111 fn finalize_solution(&mut self, sol: Solution<'_>, ip_data: &IpoptData, ip_cq: &IpoptCq) {
112 *self.captured_solution.borrow_mut() = Some((sol.x.to_vec(), sol.lambda.to_vec()));
113 self.inner
114 .borrow_mut()
115 .finalize_solution(sol, ip_data, ip_cq);
116 }
117
118 fn get_var_con_metadata(&mut self, var: &mut MetaData, con: &mut MetaData) -> bool {
119 self.inner.borrow_mut().get_var_con_metadata(var, con)
120 }
121
122 fn get_scaling_parameters(&mut self, req: ScalingRequest<'_>) -> bool {
123 self.inner.borrow_mut().get_scaling_parameters(req)
124 }
125
126 fn get_number_of_nonlinear_variables(&mut self) -> Index {
127 self.inner.borrow_mut().get_number_of_nonlinear_variables()
128 }
129
130 fn get_list_of_nonlinear_variables(&mut self, pos: &mut [Index]) -> bool {
131 self.inner.borrow_mut().get_list_of_nonlinear_variables(pos)
132 }
133
134 fn intermediate_callback(
135 &mut self,
136 stats: IterStats,
137 ip_data: &IpoptData,
138 ip_cq: &IpoptCq,
139 ) -> bool {
140 self.inner
141 .borrow_mut()
142 .intermediate_callback(stats, ip_data, ip_cq)
143 }
144
145 fn finalize_metadata(&mut self, var: &MetaData, con: &MetaData) {
146 self.inner.borrow_mut().finalize_metadata(var, con)
147 }
148}