madnlp_runtime.hpp
1 //
2 // MIT No Attribution
3 //
4 // Copyright (C) 2010-2023 Joel Andersson, Joris Gillis, Moritz Diehl, KU Leuven.
5 //
6 // Permission is hereby granted, free of charge, to any person obtaining a copy of this
7 // software and associated documentation files (the "Software"), to deal in the Software
8 // without restriction, including without limitation the rights to use, copy, modify,
9 // merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
10 // permit persons to whom the Software is furnished to do so.
11 //
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
13 // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
14 // PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
15 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
16 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
17 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
18 //
19 
20 // C-REPLACE "SOLVER_RET_SUCCESS" "0"
21 // C-REPLACE "SOLVER_RET_UNKNOWN" "1"
22 // C-REPLACE "SOLVER_RET_LIMITED" "2"
23 
24 // C-REPLACE "casadi_nlpsol_prob<T1>" "struct casadi_nlpsol_prob"
25 // C-REPLACE "casadi_nlpsol_data<T1>" "struct casadi_nlpsol_data"
26 
27 // C-REPLACE "reinterpret_cast<int**>" "(int**) "
28 // C-REPLACE "reinterpret_cast<int*>" "(int*) "
29 // C-REPLACE "const_cast<int*>" "(int*) "
30 
31 // SYMBOL "madnlp_prob"
32 template<typename T1>
35 
36  // 1-index cco format
37  madnlp_int *nzj_i, *nzj_j;
38  madnlp_int *nzh_i, *nzh_j;
39 
40  casadi_int nnz_hess_l, nnz_jac_g;
41 
42  OracleCallback nlp_hess_l;
43  OracleCallback nlp_jac_g;
44  OracleCallback nlp_grad_f;
45  OracleCallback nlp_f;
46  OracleCallback nlp_g;
47 };
48 // C-REPLACE "casadi_madnlp_prob<T1>" "struct casadi_madnlp_prob"
49 
50 // SYMBOL "madnlp_data"
51 template<typename T1>
53  // Problem structure
55  // Problem structure
57 
58  const T1** arg;
59  T1** res;
60  casadi_int* iw;
61  T1 *w;
62 
63  // temporary data
64  T1 *x, *lam_g, *g, *f, *jac_g, *grad_f, *hess_l, *grad_l;
65 
67  int success;
68 
69  //struct blasfeo_dvec v, r;
70  //struct blasfeo_dmat R;
71 
72  struct MadnlpCInterface c_interface;
73  struct MadnlpCStats stats;
74  struct MadnlpCSolver *solver;
75 };
76 // C-REPLACE "casadi_madnlp_data<T1>" "struct casadi_madnlp_data"
77 
78 // SYMBOL "madnlp_setup"
79 template<typename T1>
80 void casadi_madnlp_setup(casadi_madnlp_prob<T1>* p) {
81 
82 }
83 
84 // SYMBOL "madnlp_init_mem"
85 template<typename T1>
86 int madnlp_init_mem(casadi_madnlp_data<T1>* d) {
87  return 0;
88 }
89 
90 // SYMBOL "madnlp_free_mem"
91 template<typename T1>
92 void madnlp_free_mem(casadi_madnlp_data<T1>* d) {
93  //Highs_destroy(d->madnlp);
94 }
95 // C-REPLACE "static_cast< casadi_madnlp_data<T1>* >" "(struct casadi_madnlp_data*)"
96 // C-REPLACE "casadi_oracle_data<T1>" "struct casadi_oracle_data"
97 // C-REPLACE "calc_function" "casadi_oracle_call"
98 // C-REPLACE "casadi_error" "//casadi_error"
99 
100 // SYMBOL "madnlp_eval_constr_jac"
101 template<typename T1>
102 int casadi_madnlp_eval_constr_jac(const T1* w, T1* res, void* user_data) {
103  casadi_int i;
104  casadi_madnlp_data<T1>* d = static_cast< casadi_madnlp_data<T1>* >(user_data);
105  const casadi_madnlp_prob<T1>* p = d->prob;
106  casadi_nlpsol_data<T1>* d_nlp = d->nlp;
107  casadi_oracle_data<T1>* d_oracle = d_nlp->oracle;
108 
109  d_oracle->arg[0] = w;
110  d_oracle->arg[1] = d_nlp->p;
111  d_oracle->res[0] = res;
112 
113  return calc_function(&d->prob->nlp_jac_g, d_oracle);
114 }
115 
116 // SYMBOL "madnlp_eval_constr"
117 template<typename T1>
118 int casadi_madnlp_eval_constr(const T1* w, T1* res, void* user_data) {
119  casadi_int i,k,column;
120  casadi_madnlp_data<T1>* d = static_cast< casadi_madnlp_data<T1>* >(user_data);
121  const casadi_madnlp_prob<T1>* p = d->prob;
122  casadi_nlpsol_data<T1>* d_nlp = d->nlp;
123  casadi_oracle_data<T1>* d_oracle = d_nlp->oracle;
124 
125  d_oracle->arg[0] = w;
126  d_oracle->arg[1] = d_nlp->p;
127  d_oracle->res[0] = res;
128 
129  return calc_function(&d->prob->nlp_g, d_oracle);
130 }
131 
132 // SYMBOL "madnlp_eval_obj_grad"
133 template<typename T1>
134 int casadi_madnlp_eval_obj_grad(const T1* w, T1* res, void* user_data) {
135  casadi_madnlp_data<T1>* d = static_cast< casadi_madnlp_data<T1>* >(user_data);
136  const casadi_madnlp_prob<T1>* p = d->prob;
137  casadi_nlpsol_data<T1>* d_nlp = d->nlp;
138  casadi_oracle_data<T1>* d_oracle = d_nlp->oracle;
139 
140  // TODO add argument
141  T1 objective_scale = 1.0;
142 
143  d_oracle->arg[0] = w;
144  d_oracle->arg[1] = d_nlp->p;
145  d_oracle->res[0] = res;
146  return calc_function(&d->prob->nlp_grad_f, d_oracle);
147 
148  //d->x = (double*)w;
149  //d->grad_f = res;
150  //casadi_scal(p->nlp->nx, objective_scale, res);
151 }
152 
153 // SYMBOL "madnlp_eval_obj"
154 template<typename T1>
155 int casadi_madnlp_eval_obj(const T1* w, T1* res, void* user_data) {
156  casadi_madnlp_data<T1>* d = static_cast< casadi_madnlp_data<T1>* >(user_data);
157  casadi_nlpsol_data<T1>* d_nlp = d->nlp;
158  casadi_oracle_data<T1>* d_oracle = d_nlp->oracle;
159 
160  // TODO add argument
161  T1 objective_scale = 1.0;
162 
163  d_oracle->arg[0] = w;
164  d_oracle->arg[1] = d_nlp->p;
165  d_oracle->res[0] = res;
166  return calc_function(&d->prob->nlp_f, d_oracle);
167 
168  //d->x = (double*)w;
169  //d->f = res;
170 }
171 
172 // SYMBOL "madnlp_eval_obj"
173 template<typename T1>
174 int casadi_madnlp_eval_lag_hess(T1 objective_scale, const T1* w, const T1* lam,
175  T1* res, void* user_data){
176  casadi_int k, column, i;
177  casadi_madnlp_data<T1>* d = static_cast< casadi_madnlp_data<T1>* >(user_data);
178  const casadi_madnlp_prob<T1>* p = d->prob;
179  casadi_nlpsol_data<T1>* d_nlp = d->nlp;
180  casadi_oracle_data<T1>* d_oracle = d_nlp->oracle;
181 
182  // evaluate hessian with given parameters / inputs
183  d_oracle->arg[0] = w;
184  d_oracle->arg[1] = d_nlp->p;
185  d_oracle->arg[2] = &objective_scale;
186  d_oracle->arg[3] = lam;
187  d_oracle->res[0] = res;
188 
189  return calc_function(&d->prob->nlp_hess_l, d_oracle);
190 }
191 
192 // C-REPLACE "const_cast<T1*>" "(T1*)"
193 
194 // C-REPLACE "casadi_madnlp_eval_constr_jac<T1>" "casadi_madnlp_eval_constr_jac"
195 // C-REPLACE "casadi_madnlp_eval_obj_grad<T1>" "casadi_madnlp_eval_obj_grad"
196 // C-REPLACE "casadi_madnlp_eval_obj<T1>" "casadi_madnlp_eval_obj"
197 // C-REPLACE "casadi_madnlp_eval_constr<T1>" "casadi_madnlp_eval_constr"
198 // C-REPLACE "casadi_madnlp_eval_lag_hess<T1>" "casadi_madnlp_eval_lag_hess"
199 // C-REPLACE "std::numeric_limits<T1>::infinity()" "casadi_inf"
200 
201 // SYMBOL "madnlp_work"
202 template<typename T1>
203 void casadi_madnlp_work(const casadi_madnlp_prob<T1>* p, casadi_int* sz_arg, casadi_int* sz_res, casadi_int* sz_iw, casadi_int* sz_w) {
204  casadi_nlpsol_work(p->nlp, sz_arg, sz_res, sz_iw, sz_w);
205 
206  // Temporary work vectors
207  *sz_w = casadi_max(*sz_w, 2*(p->nlp->nx+p->nlp->ng)); // pv
208 
209 }
210 
211 // SYMBOL "madnlp_init"
212 template<typename T1>
213 void casadi_madnlp_init(casadi_madnlp_data<T1>* d, const T1*** arg, T1*** res, casadi_int** iw, T1** w) {
214  // Problem structure
215  const casadi_madnlp_prob<T1>* p = d->prob;
216  //casadi_oracle_data<T1>* d_oracle = d->nlp->oracle;
217  const casadi_nlpsol_prob<T1>* p_nlp = p->nlp;
218 
219  d->arg = *arg;
220  d->res = *res;
221  d->iw = *iw;
222  d->w = *w;
223 }
224 
225 // SYMBOL "madnlp_presolve"
226 template<typename T1>
227 void casadi_madnlp_presolve(casadi_madnlp_data<T1>* d) {
228  casadi_int k, i, start, stop, nx;
229  // Problem structure
230  const casadi_madnlp_prob<T1>* p = d->prob;
231  const casadi_nlpsol_prob<T1>* p_nlp = p->nlp;
232  casadi_nlpsol_data<T1>* d_nlp = d->nlp;
233  struct MadnlpCInterface* c_interface = &d->c_interface;
234 
235  c_interface->eval_constr_jac = casadi_madnlp_eval_constr_jac<T1>;
236  c_interface->eval_obj_grad = casadi_madnlp_eval_obj_grad<T1>;
237  c_interface->eval_obj = casadi_madnlp_eval_obj<T1>;
238  c_interface->eval_constr = casadi_madnlp_eval_constr<T1>;
239  c_interface->eval_lag_hess = casadi_madnlp_eval_lag_hess<T1>;
240  c_interface->nw = p_nlp->nx;
241  c_interface->nc = p_nlp->ng;
242  c_interface->nnzo = p_nlp->nx;
243  c_interface->nnzj = d->prob->nnz_jac_g;
244  c_interface->nnzh = d->prob->nnz_hess_l;
245  c_interface->user_data = d;
246 
247  c_interface->nzj_i = d->prob->nzj_i;
248  c_interface->nzj_j = d->prob->nzj_j;
249  c_interface->nzh_i = d->prob->nzh_i;
250  c_interface->nzh_j = d->prob->nzh_j;
251 
252  d->solver = madnlp_c_create(&d->c_interface);
253 
254 }
255 
256 // SYMBOL "madnlp_c_solve"
257 template<typename T1>
258 int casadi_madnlp_solve(casadi_madnlp_data<T1>* d) {
259  // Problem structure
260  casadi_int k, i, column;
261  const casadi_madnlp_prob<T1>* p = d->prob;
262  const casadi_nlpsol_prob<T1>* p_nlp = p->nlp;
263  casadi_nlpsol_data<T1>* d_nlp = d->nlp;
264 
266  d->success = 0;
267 
268  const struct MadnlpCNumericIn* in = madnlp_c_input(d->solver);
269  // set initial guess
270  casadi_copy(d_nlp->z, p_nlp->nx, in->x0);
271  casadi_copy(d_nlp->lam + p_nlp->nx, p_nlp->ng, in->l0);
272  casadi_copy(d_nlp->lbx, p_nlp->nx, in->lbx);
273  casadi_copy(d_nlp->ubx, p_nlp->nx, in->ubx);
274  casadi_copy(d_nlp->lbg, p_nlp->ng, in->lbg);
275  casadi_copy(d_nlp->ubg, p_nlp->ng, in->ubg);
276 
277  madnlp_int ret = madnlp_c_solve(d->solver);
278 
279  if (ret!=0) {
280  madnlp_c_destroy(d->solver);
281  return ret;
282  }
283 
284  const struct MadnlpCNumericOut* out = madnlp_c_output(d->solver);
285 
286  d_nlp->objective = out->obj[0];
287 
288  for (casadi_int i=0; i<p_nlp->nx; ++i) {
289  // get primal solution
290  d_nlp->z[i] = out->sol[i];
291  // get dual solution x
292  d_nlp->lam[i] = out->mul_U[i]-out->mul_L[i];
293  }
294  // Unpack dual solution
295  for (casadi_int i=0; i<p_nlp->ng; ++i) {
296  d_nlp->z[p_nlp->nx+i] = out->con[i];
297  d_nlp->lam[p_nlp->nx+i] = out->mul[i];
298  }
299 
300  const struct MadnlpCStats* stats = madnlp_c_get_stats(d->solver);
301 
302  printf("iter %d\n", stats->iter);
303 
304  d->stats.iter = stats->iter;
305  d->stats.status = stats->status;
306  d->stats.dual_feas = stats->dual_feas;
307  d->stats.primal_feas = stats->primal_feas;
308 
309  if (d->stats.status==MADNLP_SOLVE_SUCCEEDED ||
310  d->stats.status==MADNLP_SOLVED_TO_ACCEPTABLE_LEVEL) {
312  } else if (d->stats.status==MADNLP_MAXIMUM_ITERATIONS_EXCEEDED ||
313  d->stats.status==MADNLP_MAXIMUM_WALLTIME_EXCEEDED) {
315  }
316 
318 
319  madnlp_c_destroy(d->solver);
320  return 0;
321 }
@ SOLVER_RET_LIMITED
@ SOLVER_RET_SUCCESS
@ SOLVER_RET_UNKNOWN
struct MadnlpCSolver * solver
struct MadnlpCInterface c_interface
struct MadnlpCStats stats
casadi_nlpsol_data< T1 > * nlp
const casadi_madnlp_prob< T1 > * prob
OracleCallback nlp_f
OracleCallback nlp_g
OracleCallback nlp_jac_g
OracleCallback nlp_hess_l
const casadi_nlpsol_prob< T1 > * nlp
OracleCallback nlp_grad_f
casadi_oracle_data< T1 > * oracle
Definition: casadi_nlp.hpp:76