fatrop_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 // C-REPLACE "SOLVER_RET_EXCEPTION" "5"
24 
25 // C-REPLACE "casadi_nlpsol_prob<T1>" "struct casadi_nlpsol_prob"
26 // C-REPLACE "casadi_nlpsol_data<T1>" "struct casadi_nlpsol_data"
27 
28 // C-REPLACE "reinterpret_cast<int**>" "(int**) "
29 // C-REPLACE "reinterpret_cast<int*>" "(int*) "
30 // C-REPLACE "const_cast<int*>" "(int*) "
31 
32 // SYMBOL "fatrop_mproject"
33 template<typename T1>
34 void casadi_fatrop_mproject(T1 factor, const T1* x, const casadi_int* sp_x,
35  T1* y, const casadi_int* sp_y, T1* w) {
36  casadi_int ncol_y;
37  const casadi_int* colind_y;
38  ncol_y = sp_y[1];
39  colind_y = sp_y+2;
40  casadi_project(x, sp_x, y, sp_y, w);
41  casadi_scal(colind_y[ncol_y], factor, y);
42 }
43 
44 // SYMBOL "fatrop_dense_transfer"
45 template<typename T1>
46 void casadi_fatrop_dense_transfer(double factor, const T1* x,
47  const casadi_int* sp_x, T1* y,
48  const casadi_int* sp_y, T1* w) {
49  casadi_sparsify(x, w, sp_x, 0);
50  casadi_int nrow_y = sp_y[0];
51  casadi_int ncol_y = sp_y[1];
52  const casadi_int *colind_y = sp_y+2, *row_y = sp_y + 2 + ncol_y+1;
53  /* Loop over columns of y */
54  casadi_int i, el;
55  for (i=0; i<ncol_y; ++i) {
56  for (el=colind_y[i]; el<colind_y[i+1]; ++el) y[nrow_y*i + row_y[el]] += factor*(*w++);
57  }
58 }
59 
60 // SYMBOL "fatrop_read_primal_data"
61 template<typename T1>
62 void casadi_fatrop_read_primal_data(const double* primal_data, T1* x, const struct FatropOcpCDims *s) {
63  int k;
64  for (k=0;k<s->K;++k) {
65  casadi_copy(primal_data+s->ux_offs[k], s->nu[k], x+s->nx[k]+s->ux_offs[k]);
66  casadi_copy(primal_data+s->ux_offs[k]+s->nu[k], s->nx[k], x+s->ux_offs[k]);
67  }
68 }
69 
70 // SYMBOL "fatrop_write_primal_data"
71 template<typename T1>
72 void casadi_fatrop_write_primal_data(const double* x, T1* primal_data, const struct FatropOcpCDims *s) {
73  int k;
74  for (k=0;k<s->K;++k) {
75  casadi_copy(x+s->nx[k]+s->ux_offs[k], s->nu[k], primal_data+s->ux_offs[k]);
76  casadi_copy(x+s->ux_offs[k], s->nx[k], primal_data+s->ux_offs[k]+s->nu[k]);
77  }
78 }
79 
80 // C-REPLACE "casadi_ocp_block" "struct casadi_ocp_block"
81 
82 // C-REPLACE "OracleCallback" "struct casadi_oracle_callback"
83 template<typename T1>
86  const casadi_int *nx, *nu, *ng;
87  casadi_int nx_max, nu_max, nxu_max;
88  // Sparsity patterns
89  const casadi_int *sp_h, *sp_a;
90 
91  casadi_int nnz_h, nnz_a;
92 
93  // Sparsities
94  const casadi_int *ABsp;
95  const casadi_int *AB_offsets;
96  const casadi_int *CDsp;
97  const casadi_int *CD_offsets;
98  const casadi_int *RSQsp;
99  const casadi_int *RSQ_offsets;
100  const casadi_int *Isp;
101  const casadi_int *I_offsets;
102 
103  casadi_int N;
105 
106  OracleCallback nlp_hess_l;
107  OracleCallback nlp_jac_g;
108  OracleCallback nlp_grad_f;
109  OracleCallback nlp_f;
110  OracleCallback nlp_g;
111 
112  FatropOcpCWrite write;
113  FatropOcpCFlush flush;
114 };
115 // C-REPLACE "casadi_fatrop_prob<T1>" "struct casadi_fatrop_prob"
116 
117 
118 // SYMBOL "fatrop_setup"
119 template<typename T1>
120 void casadi_fatrop_setup(casadi_fatrop_prob<T1>* p) {
121  casadi_int k;
122  if (p->sp_h) {
123  p->nnz_h = p->sp_h[2+p->sp_h[1]];
124  } else {
125  p->nnz_h = 0;
126  }
127  p->nnz_a = p->sp_a[2+p->sp_a[1]];
128 
129  p->nx_max = 0;
130  for (k=0;k<p->N+1;++k) {
131  if (p->nx[k]>p->nx_max) p->nx_max = p->nx[k];
132  }
133  p->nu_max = 0;
134  p->nxu_max = 0;
135  for (k=0;k<p->N;++k) {
136  if (p->nu[k]>p->nu_max) p->nu_max = p->nu[k];
137  if (p->nu[k]+p->nx[k]>p->nxu_max) p->nxu_max = p->nu[k]+p->nx[k];
138  }
139 }
140 
141 
142 
143 // SYMBOL "fatrop_data"
144 template<typename T1>
146  // Problem structure
148  // Problem structure
150 
151  T1 *AB, *CD, *RSQ, *I;
152 
153  casadi_int *a_eq, *a_ineq, *a_eq_idx, *a_ineq_idx;
154  casadi_int *x_eq, *x_ineq, *x_eq_idx, *x_ineq_idx;
155 
156  const T1** arg;
157  T1** res;
158  casadi_int* iw;
159  T1* w;
160 
162  int success;
164 
165  T1 *pv, *x, *a, *g, *h, *lam;
166 
167  struct blasfeo_dvec v, r;
168  struct blasfeo_dmat R;
169 
170  struct FatropOcpCInterface ocp_interface;
171 
172  struct FatropOcpCStats stats;
173 
174  struct FatropOcpCSolver *solver;
175 };
176 // C-REPLACE "casadi_fatrop_data<T1>" "struct casadi_fatrop_data"
177 
178 // SYMBOL "fatrop_init_mem"
179 template<typename T1>
180 int casadi_fatrop_init_mem(casadi_fatrop_data<T1>* d) {
181  d->solver = 0;
182  return 0;
183 }
184 
185 // SYMBOL "fatrop_free_mem"
186 template<typename T1>
187 void casadi_fatrop_free_mem(casadi_fatrop_data<T1>* d) {
188  if (d->solver) {
189  fatrop_ocp_c_destroy(d->solver);
190  d->solver = 0;
191  }
192 }
193 // C-REPLACE "static_cast< casadi_fatrop_data<T1>* >" "(struct casadi_fatrop_data*)"
194 // C-REPLACE "casadi_oracle_data<T1>" "struct casadi_oracle_data"
195 // C-REPLACE "calc_function" "casadi_oracle_call"
196 // C-REPLACE "casadi_error" "//casadi_error"
197 
198 // SYMBOL "fatrop_full_eval_contr_viol"
199 template<typename T1>
200 fatrop_int casadi_fatrop_full_eval_contr_viol(const double* primal_data, const double* stageparams_p, const double* globalparams_p,
201  double* res, const struct FatropOcpCDims* s, void* user_data) {
202  casadi_int i,k,column;
203  casadi_fatrop_data<T1>* d = static_cast< casadi_fatrop_data<T1>* >(user_data);
204  const casadi_fatrop_prob<T1>* p = d->prob;
205  casadi_nlpsol_data<T1>* d_nlp = d->nlp;
206  casadi_oracle_data<T1>* d_oracle = d_nlp->oracle;
207 
208  casadi_fatrop_read_primal_data(primal_data, d->x, s);
209  d_oracle->arg[0] = d->x;
210  d_oracle->arg[1] = d_nlp->p;
211  d_oracle->res[0] = d->g;
212  calc_function(&d->prob->nlp_g, d_oracle);
213 
214  for (k=0;k<s->K;++k) {
215  column = 0;
216  for (i=d->a_ineq_idx[k];i<d->a_ineq_idx[k+1];++i) {
217  res[s->g_ineq_offs[k]+column] = d->g[d->a_ineq[i]];
218  column++;
219  }
220  for (i=d->x_ineq_idx[k];i<d->x_ineq_idx[k+1];++i) {
221  res[s->g_ineq_offs[k]+column] = d->x[d->x_ineq[i]];
222  column++;
223  }
224  column = 0;
225  for (i=d->a_eq_idx[k];i<d->a_eq_idx[k+1];++i) {
226  res[s->g_offs[k]+column] = d->g[d->a_eq[i]]-d->nlp->lbz[p->nlp->nx+d->a_eq[i]];
227  column++;
228  }
229  for (i=d->x_eq_idx[k];i<d->x_eq_idx[k+1];++i) {
230  res[s->g_offs[k]+column] = d->x[d->x_eq[i]]-d->nlp->lbz[d->x_eq[i]];
231  column++;
232  }
233  }
234  for (k=0;k<s->K-1;++k) {
235  const T1* lbg_k = d_nlp->lbz+p->nlp->nx+p->AB[k].offset_r;
236  const T1* g_k = d->g+p->AB[k].offset_r;
237  casadi_copy(lbg_k, p->nx[k+1], res+s->dyn_eq_offs[k]);
238  casadi_axpy(p->nx[k+1], -1.0, g_k, res+s->dyn_eq_offs[k]);
239  }
240  return 1; //skip
241 }
242 
243 // SYMBOL "fatrop_full_eval_obj_grad"
244 template<typename T1>
245 fatrop_int casadi_fatrop_full_eval_obj_grad(
246  double objective_scale,
247  const double *primal_data,
248  const double *stage_params_k,
249  const double *global_params,
250  double *res, const struct FatropOcpCDims* s, void* user_data) {
251  casadi_fatrop_data<T1>* d = static_cast< casadi_fatrop_data<T1>* >(user_data);
252  const casadi_fatrop_prob<T1>* p = d->prob;
253  casadi_nlpsol_data<T1>* d_nlp = d->nlp;
254  casadi_oracle_data<T1>* d_oracle = d_nlp->oracle;
255 
256  casadi_fatrop_read_primal_data(primal_data, d->x, s);
257  d_oracle->arg[0] = d->x;
258  d_oracle->arg[1] = d_nlp->p;
259  d_oracle->res[0] = d->g;
260  calc_function(&d->prob->nlp_grad_f, d_oracle);
261 
262  casadi_fatrop_write_primal_data(d->g, res, s);
263  casadi_scal(p->nlp->nx, objective_scale, res);
264  return 1; // skip
265 }
266 
267 // SYMBOL "fatrop_full_eval_obj"
268 template<typename T1>
269 fatrop_int casadi_fatrop_full_eval_obj(
270  double objective_scale,
271  const double *primal_data,
272  const double *stage_params_k,
273  const double *global_params,
274  double *res, const struct FatropOcpCDims* s, void* user_data) {
275  casadi_fatrop_data<T1>* d = static_cast< casadi_fatrop_data<T1>* >(user_data);
276  casadi_nlpsol_data<T1>* d_nlp = d->nlp;
277  casadi_oracle_data<T1>* d_oracle = d_nlp->oracle;
278 
279  casadi_fatrop_read_primal_data(primal_data, d->x, s);
280  d_oracle->arg[0] = d->x;
281  d_oracle->arg[1] = d_nlp->p;
282  d_oracle->res[0] = res;
283  calc_function(&d->prob->nlp_f, d_oracle);
284 
285  *res *= objective_scale;
286  return 1; // skip
287 }
288 
289 // C-REPLACE "const_cast<T1*>" "(T1*)"
290 
291 // SYMBOL "fatrop_eval_BAbt"
292 template<typename T1>
293 fatrop_int casadi_fatrop_eval_BAbt(const double *states_kp1, const double *inputs_k,
294  const double *states_k, const double *stage_params_k,
295  const double *global_params, struct blasfeo_dmat *res, const fatrop_int k, void* user_data) {
296  casadi_fatrop_data<T1>* d = static_cast< casadi_fatrop_data<T1>* >(user_data);
297  const casadi_fatrop_prob<T1>* p = d->prob;
298  casadi_nlpsol_data<T1>* d_nlp = d->nlp;
299  const T1* lbg_k = d_nlp->lbz+p->nlp->nx+p->AB[k].offset_r;
300  const T1* g_k = d->g+p->AB[k].offset_r;
301  casadi_int i;
302  blasfeo_pack_tran_dmat(p->nx[k+1], p->nx[k], d->AB+p->AB_offsets[k], p->nx[k+1], res, p->nu[k], 0);
303  blasfeo_pack_tran_dmat(p->nx[k+1], p->nu[k], d->AB+p->AB_offsets[k]+p->nx[k]*p->nx[k+1], p->nx[k+1], res, 0, 0);
304 
305  for (i=0; i<p->nx[k+1]; ++i) {
306  BLASFEO_DMATEL(res, p->nx[k]+p->nu[k], i) = lbg_k[i]-g_k[i];
307  }
308 
309  return 0;
310 
311 }
312 
313 // C-REPLACE "casadi_fatrop_eval_BAbt<T1>" "casadi_fatrop_eval_BAbt"
314 
315 // SYMBOL "fatrop_eval_RSQrqt"
316 template<typename T1>
317 fatrop_int casadi_fatrop_eval_RSQrqt(
318  const double *objective_scale,
319  const double *inputs_k,
320  const double *states_k,
321  const double *lam_dyn_k,
322  const double *lam_eq_k,
323  const double *lam_eq_ineq_k,
324  const double *stage_params_k,
325  const double *global_params,
326  struct blasfeo_dmat *res,
327  const fatrop_int k, void* user_data) {
328  casadi_fatrop_data<T1>* d = static_cast< casadi_fatrop_data<T1>* >(user_data);
329  const casadi_fatrop_prob<T1>* p = d->prob;
330 
331  int n = p->nx[k]+p->nu[k];
332  blasfeo_pack_dmat(p->nx[k], p->nx[k],
333  d->RSQ+p->RSQ_offsets[k], n, res, p->nu[k], p->nu[k]);
334  blasfeo_pack_dmat(p->nu[k], p->nu[k],
335  d->RSQ+p->RSQ_offsets[k]+p->nx[k]*n+p->nx[k], n, res, 0, 0);
336  blasfeo_pack_dmat(p->nu[k], p->nx[k],
337  d->RSQ+p->RSQ_offsets[k]+p->nx[k], n, res, 0, p->nu[k]);
338  blasfeo_pack_dmat(p->nx[k], p->nu[k],
339  d->RSQ+p->RSQ_offsets[k]+p->nx[k]*n, n, res, p->nu[k], 0);
340 
341 
342  blasfeo_pack_dmat(1, p->nx[k], d->g+p->CD[k].offset_c, 1, res, p->nx[k]+p->nu[k], p->nu[k]);
343  blasfeo_pack_dmat(1, p->nu[k], d->g+p->CD[k].offset_c+p->nx[k], 1, res, p->nx[k]+p->nu[k], 0);
344 
345  return 0;
346 }
347 
348 // C-REPLACE "casadi_fatrop_eval_RSQrqt<T1>" "casadi_fatrop_eval_RSQrqt"
349 
350 // SYMBOL "fatrop_full_eval_lag_hess"
351 template<typename T1>
352 fatrop_int casadi_fatrop_full_eval_lag_hess(
353  double objective_scale,
354  const double *primal_data,
355  const double *lam_data,
356  const double *stage_params_k,
357  const double *global_params,
358  struct blasfeo_dmat *res, const struct FatropOcpCDims* s, void* user_data) {
359  casadi_int k, column, i;
360  casadi_fatrop_data<T1>* d = static_cast< casadi_fatrop_data<T1>* >(user_data);
361  const casadi_fatrop_prob<T1>* p = d->prob;
362  casadi_nlpsol_data<T1>* d_nlp = d->nlp;
363  casadi_oracle_data<T1>* d_oracle = d_nlp->oracle;
364 
365  casadi_fatrop_read_primal_data(primal_data, d->x, s);
366  for (k=0;k<s->K;++k) {
367  column = 0;
368  for (i=d->a_ineq_idx[k];i<d->a_ineq_idx[k+1];++i) {
369  d->lam[d->a_ineq[i]] = lam_data[s->g_ineq_offs[k]+column];
370  column++;
371  }
372  column = 0;
373  for (i=d->a_eq_idx[k];i<d->a_eq_idx[k+1];++i) {
374  d->lam[d->a_eq[i]] = lam_data[s->g_offs[k]+column];
375  column++;
376  }
377  }
378  for (k=0;k<s->K-1;++k) {
379  casadi_scaled_copy(-1.0, lam_data+s->dyn_eq_offs[k], p->nx[k+1], d->lam+p->AB[k].offset_r);
380  }
381 
382  d_oracle->arg[0] = d->x;
383  d_oracle->arg[1] = d_nlp->p;
384  d_oracle->arg[2] = &objective_scale;
385  d_oracle->arg[3] = d->lam;
386  d_oracle->res[0] = d->g;
387  d_oracle->res[1] = d->h;
388  calc_function(&d->prob->nlp_hess_l, d_oracle);
389 
390  casadi_project(d->h, p->sp_h, d->RSQ, p->RSQsp, d->pv);
391 
392  // Note: Lagrangian is defined with lambda_dyn*(F(x_k,u_k)) with x_k+1 notably absent
393  for (k=0;k<s->K-1;++k) {
394  casadi_axpy(p->nx[k+1], 1.0, lam_data+s->dyn_eq_offs[k], d->g+p->CD[k+1].offset_c);
395  }
396  // Note: we still need to handle simple bounds
397  for (k=0;k<s->K;++k) {
398  column = d->a_ineq_idx[k+1]-d->a_ineq_idx[k];
399  for (i=d->x_ineq_idx[k];i<d->x_ineq_idx[k+1];++i) {
400  d->g[d->x_ineq[i]] += lam_data[s->g_ineq_offs[k]+column];
401  column++;
402  }
403  column = d->a_eq_idx[k+1]-d->a_eq_idx[k];
404  for (i=d->x_eq_idx[k];i<d->x_eq_idx[k+1];++i) {
405  d->g[d->x_eq[i]] += lam_data[s->g_offs[k]+column];
406  column++;
407  }
408  }
409 
410  for (k = 0; k < s->K; k++) {
411  fatrop_int nu = p->nu[k];
412  fatrop_int offs_ux = s->ux_offs[k];
413 
414  fatrop_int offs_g = s->g_offs[k];
415  fatrop_int offs_g_ineq = s->g_ineq_offs[k];
416  fatrop_int offs_dyn_eq = s->dyn_eq_offs[k];
417 
418  casadi_fatrop_eval_RSQrqt<T1>(&objective_scale,
419  primal_data + offs_ux,
420  primal_data + offs_ux + nu,
421  lam_data + offs_dyn_eq,
422  lam_data + offs_g,
423  lam_data + offs_g_ineq,
424  NULL, NULL,
425  res + k,
426  k,
427  user_data);
428  }
429  return 1; //skip
430 }
431 
432 // SYMBOL "fatrop_eval_Ggt"
433 template<typename T1>
434 fatrop_int casadi_fatrop_eval_Ggt(
435  const double *inputs_k,
436  const double *states_k,
437  const double *stage_params_k,
438  const double *global_params,
439  struct blasfeo_dmat *res,
440  const fatrop_int k, void* user_data) {
441  casadi_fatrop_data<T1>* d = static_cast< casadi_fatrop_data<T1>* >(user_data);
442  const casadi_fatrop_prob<T1>* p = d->prob;
443  casadi_int i, column;
444 
445  int n_a_eq = d->a_eq_idx[k+1]-d->a_eq_idx[k];
446  int n_x_eq = d->x_eq_idx[k+1]-d->x_eq_idx[k];
447  int ng_eq = n_a_eq+n_x_eq;
448 
449  blasfeo_dgese(p->nx[k]+p->nu[k]+1, ng_eq, 0.0, res, 0, 0);
450 
451  column = 0;
452  for (i=d->a_eq_idx[k];i<d->a_eq_idx[k+1];++i) {
453  blasfeo_pack_tran_dmat(1, p->nx[k],
454  d->CD+p->CD_offsets[k]+(d->a_eq[i]-p->CD[k].offset_r),
455  p->CD[k].rows, res, p->nu[k], column);
456  blasfeo_pack_tran_dmat(1, p->nu[k],
457  d->CD+p->CD_offsets[k]+(d->a_eq[i]-p->CD[k].offset_r)+p->nx[k]*p->CD[k].rows,
458  p->CD[k].rows, res, 0, column);
459  BLASFEO_DMATEL(res, p->nx[k]+p->nu[k], column) = d->g[d->a_eq[i]]-d->nlp->lbz[p->nlp->nx+d->a_eq[i]];
460  column++;
461  }
462  for (i=d->x_eq_idx[k];i<d->x_eq_idx[k+1];++i) {
463  int j = d->x_eq[i]-p->CD[k].offset_c;
464  if (j>=p->nx[k]) {
465  j -= p->nx[k];
466  } else {
467  j += p->nu[k];
468  }
469  BLASFEO_DMATEL(res, j, column) = 1;
470  BLASFEO_DMATEL(res, p->nx[k]+p->nu[k], column) = d->x[d->x_eq[i]]-d->nlp->lbz[d->x_eq[i]];
471  column++;
472  }
473 
474  return 0;
475 }
476 
477 // C-REPLACE "casadi_fatrop_eval_Ggt<T1>" "casadi_fatrop_eval_Ggt"
478 
479 // SYMBOL "fatrop_eval_Ggt_ineq"
480 template<typename T1>
481 fatrop_int casadi_fatrop_eval_Ggt_ineq(
482  const double *inputs_k,
483  const double *states_k,
484  const double *stage_params_k,
485  const double *global_params,
486  struct blasfeo_dmat *res,
487  const fatrop_int k, void* user_data) {
488  casadi_fatrop_data<T1>* d = static_cast< casadi_fatrop_data<T1>* >(user_data);
489  const casadi_fatrop_prob<T1>* p = d->prob;
490  casadi_int i, column;
491 
492  int n_a_ineq = d->a_ineq_idx[k+1]-d->a_ineq_idx[k];
493  int n_x_ineq = d->x_ineq_idx[k+1]-d->x_ineq_idx[k];
494  int ng_ineq = n_a_ineq+n_x_ineq;
495 
496  // Ggt_ineq: [G_ineq;g_ineq]
497  // G_ineq: (nu+nx by ng_ineq)
498  // g_ineq: (nu+nx by 1)
499 
500  // Clear Ggt_ineq
501  blasfeo_dgese(p->nx[k]+p->nu[k]+1, ng_ineq, 0.0, res, 0, 0);
502 
503  column = 0;
504  for (i=d->a_ineq_idx[k];i<d->a_ineq_idx[k+1];++i) {
505  blasfeo_pack_tran_dmat(1, p->nx[k],
506  d->CD+p->CD_offsets[k]+(d->a_ineq[i]-p->CD[k].offset_r),
507  p->CD[k].rows, res, p->nu[k], column);
508  blasfeo_pack_tran_dmat(1, p->nu[k],
509  d->CD+p->CD_offsets[k]+(d->a_ineq[i]-p->CD[k].offset_r)+p->nx[k]*p->CD[k].rows,
510  p->CD[k].rows, res, 0, column);
511  BLASFEO_DMATEL(res, p->nx[k]+p->nu[k], column) = d->g[d->a_ineq[i]];
512  column++;
513  }
514  for (i=d->x_ineq_idx[k];i<d->x_ineq_idx[k+1];++i) {
515  int j = d->x_ineq[i]-p->CD[k].offset_c;
516  if (j>=p->nx[k]) {
517  j -= p->nx[k];
518  } else {
519  j += p->nu[k];
520  }
521  BLASFEO_DMATEL(res, j, column) = 1;
522  BLASFEO_DMATEL(res, p->nx[k]+p->nu[k], column) = d->x[d->x_ineq[i]];
523  column++;
524  }
525 
526  return 0;
527 }
528 
529 // C-REPLACE "casadi_fatrop_eval_Ggt_ineq<T1>" "casadi_fatrop_eval_Ggt_ineq"
530 
531 // SYMBOL "fatrop_full_eval_constr_jac"
532 template<typename T1>
533 fatrop_int casadi_fatrop_full_eval_constr_jac(const double* primal_data, const double* stageparams_p, const double* globalparams_p,
534  struct blasfeo_dmat* BAbt_p, struct blasfeo_dmat* Ggt_p, struct blasfeo_dmat* Ggt_ineq_p, const struct FatropOcpCDims* s, void* user_data) {
535  casadi_int i, k;
536  casadi_fatrop_data<T1>* d = static_cast< casadi_fatrop_data<T1>* >(user_data);
537  const casadi_fatrop_prob<T1>* p = d->prob;
538  casadi_nlpsol_data<T1>* d_nlp = d->nlp;
539  casadi_oracle_data<T1>* d_oracle = d_nlp->oracle;
540 
541  casadi_fatrop_read_primal_data(primal_data, d->x, s);
542  d_oracle->arg[0] = d->x;
543  d_oracle->arg[1] = d_nlp->p;
544  d_oracle->res[0] = d->g;
545  d_oracle->res[1] = d->a;
546  calc_function(&d->prob->nlp_jac_g, d_oracle);
547 
548  casadi_fatrop_mproject(-1.0, d->a, p->sp_a, d->AB, p->ABsp, d->pv);
549  casadi_project(d->a, p->sp_a, d->CD, p->CDsp, d->pv);
550  casadi_project(d->a, p->sp_a, d->I, p->Isp, d->pv);
551 
552  for (i=0;i<p->Isp[2+p->Isp[1]];++i) {
553  if (d->I[i]!=1.0) {
554  casadi_error("Structure mismatch: gap-closing constraints must be like this: x_{k+1}-F(xk,uk).");
555  }
556  }
557 
558  for (k = 0; k < s->K-1; k++) {
559  fatrop_int nu_k = p->nu[k];
560  fatrop_int nu_kp1 = p->nu[k+1];
561  fatrop_int offs_ux_k = s->ux_offs[k];
562  fatrop_int offs_ux_kp1 = s->ux_offs[k+1];
563  casadi_fatrop_eval_BAbt<T1>(primal_data + offs_ux_kp1 + nu_kp1, primal_data + offs_ux_k, primal_data + offs_ux_k + nu_k, NULL, NULL, BAbt_p + k, k, user_data);
564  }
565 
566  for (k = 0; k < s->K; k++) {
567  fatrop_int nu = p->nu[k];
568  fatrop_int ng = s->ng[k];
569  fatrop_int offs_ux = s->ux_offs[k];
570  if (ng>0) {
571  casadi_fatrop_eval_Ggt<T1>(
572  primal_data + offs_ux,
573  primal_data + offs_ux + nu,
574  NULL, NULL,
575  Ggt_p + k,
576  k, user_data);
577  }
578  }
579 
580  for (k = 0; k < s->K; k++) {
581  fatrop_int nu = p->nu[k];
582  fatrop_int ng_ineq = s->ng_ineq[k];
583  fatrop_int offs_ux = s->ux_offs[k];
584 
585  if (ng_ineq>0) {
586  casadi_fatrop_eval_Ggt_ineq<T1>(
587  primal_data + offs_ux,
588  primal_data + offs_ux + nu,
589  NULL, NULL,
590  Ggt_ineq_p + k,
591  k, user_data);
592  }
593  }
594  return 1; // skip
595 }
596 
597 // SYMBOL "fatrop_get_nx"
598 template<typename T1>
599 fatrop_int casadi_fatrop_get_nx(const fatrop_int k, void* user_data) {
600  casadi_fatrop_data<T1>* d = static_cast< casadi_fatrop_data<T1>* >(user_data);
601  const casadi_fatrop_prob<T1>* p = d->prob;
602 
603  //printf("nx %lld\n", p->nx[k]);
604 
605  if (k==p->N+1) return p->nx[k-1];
606  return p->nx[k];
607 }
608 
609 // SYMBOL "fatrop_get_nu"
610 template<typename T1>
611 fatrop_int casadi_fatrop_get_nu(const fatrop_int k, void* user_data) {
612  casadi_fatrop_data<T1>* d = static_cast< casadi_fatrop_data<T1>* >(user_data);
613  const casadi_fatrop_prob<T1>* p = d->prob;
614  return p->nu[k];
615 }
616 
617 // SYMBOL "fatrop_get_ng"
618 template<typename T1>
619 fatrop_int casadi_fatrop_get_ng(const fatrop_int k, void* user_data) {
620  casadi_fatrop_data<T1>* d = static_cast< casadi_fatrop_data<T1>* >(user_data);
621  int ret;
622  fatrop_int n_a_eq = d->a_eq_idx[k+1]-d->a_eq_idx[k];
623  fatrop_int n_x_eq = d->x_eq_idx[k+1]-d->x_eq_idx[k];
624 
625  ret = n_a_eq+n_x_eq;
626 
627  /* printf("d->a_eq_idx[k] %lld\n", d->a_eq_idx[k]);
628  printf("d->a_eq_idx[k+1] %lld\n", d->a_eq_idx[k+1]);
629  printf("d->x_eq_idx[k] %lld\n", d->x_eq_idx[k]);
630  printf("d->x_eq_idx[k+1] %lld\n", d->x_eq_idx[k+1]);
631 
632 
633  printf("get_ng %d\n", ret);*/
634  return ret;
635 }
636 
637 
638 // SYMBOL "fatrop_get_horizon_length"
639 template<typename T1>
640 fatrop_int casadi_fatrop_get_horizon_length(void* user_data) {
641  casadi_fatrop_data<T1>* d = static_cast< casadi_fatrop_data<T1>* >(user_data);
642 
643  //printf("horizon_length %lld\n", d->prob->N+1);
644  return d->prob->N+1;
645 }
646 
647 // SYMBOL "fatrop_get_ng_ineq"
648 template<typename T1>
649 fatrop_int casadi_fatrop_get_ng_ineq(const fatrop_int k, void* user_data) {
650  casadi_fatrop_data<T1>* d = static_cast< casadi_fatrop_data<T1>* >(user_data);
651  fatrop_int n_a_ineq = d->a_ineq_idx[k+1]-d->a_ineq_idx[k];
652  fatrop_int n_x_ineq = d->x_ineq_idx[k+1]-d->x_ineq_idx[k];
653  //printf("get_ng_ineq %d\n", n_a_ineq+n_x_ineq);
654  return n_a_ineq+n_x_ineq;
655 }
656 
657 // SYMBOL "fatrop_get_bounds"
658 template<typename T1>
659 fatrop_int casadi_fatrop_get_bounds(double *lower, double *upper, const fatrop_int k, void* user_data) {
660  casadi_fatrop_data<T1>* d = static_cast< casadi_fatrop_data<T1>* >(user_data);
661  const casadi_fatrop_prob<T1>* p = d->prob;
662  casadi_nlpsol_data<T1>* d_nlp = d->nlp;
663 
664  casadi_int nx = p->nlp->nx;
665 
666  int i=0;
667  int column = 0;
668  for (i=d->a_ineq_idx[k];i<d->a_ineq_idx[k+1];++i) {
669  lower[column] = d_nlp->lbz[nx+d->a_ineq[i]];
670  upper[column] = d_nlp->ubz[nx+d->a_ineq[i]];
671  column++;
672  }
673 
674  for (i=d->x_ineq_idx[k];i<d->x_ineq_idx[k+1];++i) {
675  lower[column] = d_nlp->lbz[d->x_ineq[i]];
676  upper[column] = d_nlp->ubz[d->x_ineq[i]];
677  column++;
678  }
679 
680  return 0;
681 }
682 
683 // SYMBOL "fatrop_get_initial_xk"
684 template<typename T1>
685 fatrop_int casadi_fatrop_get_initial_xk(double *xk, const fatrop_int k, void* user_data) {
686  casadi_fatrop_data<T1>* d = static_cast< casadi_fatrop_data<T1>* >(user_data);
687  const casadi_fatrop_prob<T1>* p = d->prob;
688  casadi_nlpsol_data<T1>* d_nlp = d->nlp;
689  //printf("casadi_fatrop_get_initial_xk offset %lld %e\n",p->CD[k].offset_c,d_nlp->z[p->CD[k].offset_c]);
690  casadi_copy(d_nlp->z+p->CD[k].offset_c, p->nx[k], xk);
691 
692  return 0;
693 }
694 
695 // SYMBOL "fatrop_get_initial_uk"
696 template<typename T1>
697 fatrop_int casadi_fatrop_get_initial_uk(double *uk, const fatrop_int k, void* user_data) {
698  casadi_fatrop_data<T1>* d = static_cast< casadi_fatrop_data<T1>* >(user_data);
699  const casadi_fatrop_prob<T1>* p = d->prob;
700  casadi_nlpsol_data<T1>* d_nlp = d->nlp;
701  casadi_copy(d_nlp->z+p->CD[k].offset_c+p->nx[k], p->nu[k], uk);
702  return 0;
703 }
704 
705 
706 // SYMBOL "fatrop_work"
707 template<typename T1>
708 void casadi_fatrop_work(const casadi_fatrop_prob<T1>* p, casadi_int* sz_arg, casadi_int* sz_res, casadi_int* sz_iw, casadi_int* sz_w) {
709  casadi_nlpsol_work(p->nlp, sz_arg, sz_res, sz_iw, sz_w);
710 
711  // Temporary work vectors
712  *sz_w = casadi_max(*sz_w, 2*(p->nlp->nx+p->nlp->ng)); // pv
713 
714  // Persistent work vectors
715  *sz_w += casadi_sp_nnz(p->ABsp); // AB
716  *sz_w += casadi_sp_nnz(p->CDsp); // CD
717  *sz_w += casadi_sp_nnz(p->RSQsp); // RSQ
718  *sz_w += casadi_sp_nnz(p->Isp); // I
719  *sz_w += p->nlp->nx; // x
720  *sz_w += p->nlp->nx+p->nlp->ng; // lam
721  *sz_w += casadi_sp_nnz(p->sp_a); // a
722  *sz_w += casadi_sp_nnz(p->sp_h); // h
723  *sz_w += casadi_max(p->nlp->nx,p->nlp->ng); // g
724  *sz_w += blasfeo_memsize_dvec(p->nxu_max+1)+64; // v p->nx[k]+p->nu[k]+1
725  *sz_w += blasfeo_memsize_dvec(p->nx_max+p->nlp->ng)+64; // r p->nx[k+1]
726  *sz_w += blasfeo_memsize_dmat(p->nxu_max, p->nxu_max)+64; // r p->nx[k]+p->nx[u]
727 
728  *sz_iw += p->N+2; // a_eq_idx
729  *sz_iw += p->N+2; // a_ineq_idx
730  *sz_iw += p->N+2; // x_eq_idx
731  *sz_iw += p->N+2; // x_ineq_idx
732  *sz_iw += p->nlp->ng; // a_eq
733  *sz_iw += p->nlp->ng; // a_ineq
734  *sz_iw += p->nlp->nx; // x_eq
735  *sz_iw += p->nlp->nx; // x_ineq
736 
737 }
738 
739 // SYMBOL "fatrop_set_work"
740 template<typename T1>
741 void casadi_fatrop_set_work(casadi_fatrop_data<T1>* d, const T1*** arg, T1*** res, casadi_int** iw, T1** w) {
742  // Problem structure
743  const casadi_fatrop_prob<T1>* p = d->prob;
744  //casadi_oracle_data<T1>* d_oracle = d->nlp->oracle;
745  //const casadi_nlpsol_prob<T1>* p_nlp = p->nlp;
746 
747  //d->z_L = *w; *w += p_nlp->nx;
748  //d->z_U = *w; *w += p_nlp->nx;
749 
750  d->AB = *w; *w += casadi_sp_nnz(p->ABsp);
751  d->CD = *w; *w += casadi_sp_nnz(p->CDsp);
752  d->RSQ = *w; *w += casadi_sp_nnz(p->RSQsp);
753  d->I = *w; *w += casadi_sp_nnz(p->Isp);
754  d->x = *w; *w += p->nlp->nx;
755  d->lam = *w; *w += p->nlp->nx+p->nlp->ng;
756  d->a = *w; *w += casadi_sp_nnz(p->sp_a);
757  d->h = *w; *w += casadi_sp_nnz(p->sp_h);
758  d->g = *w; *w += casadi_max(p->nlp->nx,p->nlp->ng);
759  blasfeo_create_dvec(p->nxu_max+1, &d->v, (void*) (((unsigned long long) (*w)+63)/64*64));
760  *w += blasfeo_memsize_dvec(p->nxu_max+1)+64;
761  blasfeo_create_dvec(p->nx_max+p->nlp->ng, &d->r, (void*) (((unsigned long long) (*w)+63)/64*64));
762  *w += blasfeo_memsize_dvec(p->nx_max+p->nlp->ng)+64;
763  blasfeo_create_dmat(p->nxu_max, p->nxu_max, &d->R, (void*) (((unsigned long long) (*w)+63)/64*64));
764  *w += blasfeo_memsize_dmat(p->nxu_max, p->nxu_max)+64;
765 
766  d->a_eq_idx = *iw; *iw += p->N+2;
767  d->a_ineq_idx = *iw; *iw += p->N+2;
768  d->x_eq_idx = *iw; *iw += p->N+2;
769  d->x_ineq_idx = *iw; *iw += p->N+2;
770 
771  d->a_eq = *iw; *iw += p->nlp->ng;
772  d->a_ineq = *iw; *iw += p->nlp->ng;
773  d->x_eq = *iw; *iw += p->nlp->nx;
774  d->x_ineq = *iw; *iw += p->nlp->nx;
775 
776  d->pv = *w;
777 
778  d->arg = *arg;
779  d->res = *res;
780  d->iw = *iw;
781  d->w = *w;
782 }
783 
784 // C-REPLACE "casadi_fatrop_get_nx<T1>" "casadi_fatrop_get_nx"
785 // C-REPLACE "casadi_fatrop_get_nu<T1>" "casadi_fatrop_get_nu"
786 // C-REPLACE "casadi_fatrop_get_ng<T1>" "casadi_fatrop_get_ng"
787 // C-REPLACE "casadi_fatrop_get_ng_ineq<T1>" "casadi_fatrop_get_ng_ineq"
788 // C-REPLACE "casadi_fatrop_get_horizon_length<T1>" "casadi_fatrop_get_horizon_length"
789 // C-REPLACE "casadi_fatrop_get_bounds<T1>" "casadi_fatrop_get_bounds"
790 // C-REPLACE "casadi_fatrop_get_initial_xk<T1>" "casadi_fatrop_get_initial_xk"
791 // C-REPLACE "casadi_fatrop_get_initial_uk<T1>" "casadi_fatrop_get_initial_uk"
792 // C-REPLACE "casadi_fatrop_full_eval_constr_jac<T1>" "casadi_fatrop_full_eval_constr_jac"
793 // C-REPLACE "casadi_fatrop_full_eval_obj_grad<T1>" "casadi_fatrop_full_eval_obj_grad"
794 // C-REPLACE "casadi_fatrop_full_eval_obj<T1>" "casadi_fatrop_full_eval_obj"
795 // C-REPLACE "casadi_fatrop_full_eval_contr_viol<T1>" "casadi_fatrop_full_eval_contr_viol"
796 // C-REPLACE "casadi_fatrop_full_eval_lag_hess<T1>" "casadi_fatrop_full_eval_lag_hess"
797 
798 
799 // C-REPLACE "std::numeric_limits<T1>::infinity()" "casadi_inf"
800 
801 // SYMBOL "fatrop_presolve"
802 template<typename T1>
803 void casadi_fatrop_presolve(casadi_fatrop_data<T1>* d) {
804  casadi_int k, i, start, stop, nx;
805  // Problem structure
806  const casadi_fatrop_prob<T1>* p = d->prob;
807  const casadi_nlpsol_prob<T1>* p_nlp = p->nlp;
808  casadi_nlpsol_data<T1>* d_nlp = d->nlp;
809  struct FatropOcpCInterface* ocp_interface = &d->ocp_interface;
810 
811  ocp_interface->get_nx = casadi_fatrop_get_nx<T1>;
812  ocp_interface->get_nu = casadi_fatrop_get_nu<T1>;
813  ocp_interface->get_ng = casadi_fatrop_get_ng<T1>;
814  ocp_interface->get_n_stage_params = 0;
815  ocp_interface->get_n_global_params = 0;
816  ocp_interface->get_default_stage_params = 0;
817  ocp_interface->get_default_global_params = 0;
818  ocp_interface->get_ng_ineq = casadi_fatrop_get_ng_ineq<T1>;
819  ocp_interface->get_horizon_length = casadi_fatrop_get_horizon_length<T1>;
820 
821  ocp_interface->get_bounds = casadi_fatrop_get_bounds<T1>;
822  ocp_interface->get_initial_xk = casadi_fatrop_get_initial_xk<T1>;
823  ocp_interface->get_initial_uk = casadi_fatrop_get_initial_uk<T1>;
824 
825  ocp_interface->full_eval_constr_jac = casadi_fatrop_full_eval_constr_jac<T1>;
826  ocp_interface->full_eval_obj_grad = casadi_fatrop_full_eval_obj_grad<T1>;
827  ocp_interface->full_eval_obj = casadi_fatrop_full_eval_obj<T1>;
828  ocp_interface->full_eval_contr_viol = casadi_fatrop_full_eval_contr_viol<T1>;
829  ocp_interface->full_eval_lag_hess = casadi_fatrop_full_eval_lag_hess<T1>;
830 
831  ocp_interface->eval_BAbt = casadi_fatrop_eval_BAbt<T1>;
832  ocp_interface->eval_RSQrqt = casadi_fatrop_eval_RSQrqt<T1>;
833  ocp_interface->eval_Ggt = casadi_fatrop_eval_Ggt<T1>;
834  ocp_interface->eval_Ggt_ineq = casadi_fatrop_eval_Ggt_ineq<T1>;
835  ocp_interface->eval_rq = 0; // Computed in full_eval_obj_grad
836  ocp_interface->eval_L = 0; // Computed in full_eval_obj
837 
838  nx = p_nlp->nx;
839 
840  d->a_eq_idx[0] = 0;
841  d->a_ineq_idx[0] = 0;
842  d->x_eq_idx[0] = 0;
843  d->x_ineq_idx[0] = 0;
844 
845  // Loop over CD blocks
846  for (k=0;k<p->N+1;++k) {
847  d->a_eq_idx[k+1] = d->a_eq_idx[k];
848  d->a_ineq_idx[k+1] = d->a_ineq_idx[k];
849  start = p->CD[k].offset_r;
850  stop = p->CD[k].offset_r+p->CD[k].rows;
851  for (i=start;i<stop;++i) {
852  if (d_nlp->lbz[nx+i]==d_nlp->ubz[nx+i]) {
853  d->a_eq[d->a_eq_idx[k+1]++] = i;
854  } else {
855  if (d_nlp->lbz[nx+i]==-std::numeric_limits<T1>::infinity() && d_nlp->ubz[nx+i]==std::numeric_limits<T1>::infinity()) continue;
856  d->a_ineq[d->a_ineq_idx[k+1]++] = i;
857  }
858  }
859  d->x_eq_idx[k+1] = d->x_eq_idx[k];
860  d->x_ineq_idx[k+1] = d->x_ineq_idx[k];
861  start = p->CD[k].offset_c;
862  stop = p->CD[k].offset_c+p->CD[k].cols;
863 
864  for (i=start;i<stop;++i) {
865  if (d_nlp->lbz[i]==d_nlp->ubz[i]) {
866  d->x_eq[d->x_eq_idx[k+1]++] = i;
867  } else {
868  if (d_nlp->lbz[i]==-std::numeric_limits<T1>::infinity() && d_nlp->ubz[i]==std::numeric_limits<T1>::infinity()) continue;
869  d->x_ineq[d->x_ineq_idx[k+1]++] = i;
870  }
871  }
872  }
873 
874  d->ocp_interface.user_data = d;
875 
876  // Detect structure change: if eq/ineq counts differ from cached solver, rebuild
877  if (d->solver) {
878  const struct FatropOcpCDims* dims = fatrop_ocp_c_get_dims(d->solver);
879  int structure_changed = 0;
880  for (k=0;k<p->N+1;++k) {
881  casadi_int ng_eq_k = d->a_eq_idx[k+1] - d->a_eq_idx[k]
882  + d->x_eq_idx[k+1] - d->x_eq_idx[k];
883  casadi_int ng_ineq_k = d->a_ineq_idx[k+1] - d->a_ineq_idx[k]
884  + d->x_ineq_idx[k+1] - d->x_ineq_idx[k];
885  if (ng_eq_k != dims->ng[k] || ng_ineq_k != dims->ng_ineq[k]) {
886  structure_changed = 1;
887  break;
888  }
889  }
890  if (structure_changed) {
891  fatrop_ocp_c_destroy(d->solver);
892  d->solver = 0;
893  }
894  }
895  if (!d->solver) {
896  d->solver = fatrop_ocp_c_create(&d->ocp_interface, p->write, p->flush);
897  }
898 }
899 
900 // SYMBOL "fatrop_solve"
901 template<typename T1>
902 void casadi_fatrop_solve(casadi_fatrop_data<T1>* d) {
903  // Problem structure
904  casadi_int k, i, column;
905  const casadi_fatrop_prob<T1>* p = d->prob;
906  const casadi_nlpsol_prob<T1>* p_nlp = p->nlp;
907  casadi_nlpsol_data<T1>* d_nlp = d->nlp;
908 
910  d->success = 0;
911 
912  fatrop_int ret = fatrop_ocp_c_solve(d->solver);
913 
914  d->return_status = ret;
915  if (ret==0) {
917  d->success = 1;
918  }
919 
920  if (ret==-1) {
922  }
923 
924  const struct blasfeo_dvec* primal = fatrop_ocp_c_get_primal(d->solver);
925  const struct blasfeo_dvec* dual = fatrop_ocp_c_get_dual(d->solver);
926  const struct FatropOcpCDims* str = fatrop_ocp_c_get_dims(d->solver);
927  const struct FatropOcpCStats* stats = fatrop_ocp_c_get_stats(d->solver);
928 
929  d->stats.compute_sd_time = stats->compute_sd_time;
930  d->stats.duinf_time = stats->duinf_time;
931  d->stats.eval_hess_time = stats->eval_hess_time;
932  d->stats.eval_jac_time = stats->eval_jac_time;
933  d->stats.eval_cv_time = stats->eval_cv_time;
934  d->stats.eval_grad_time = stats->eval_grad_time;
935  d->stats.eval_obj_time = stats->eval_obj_time;
936  d->stats.initialization_time = stats->initialization_time;
937  d->stats.time_total = stats->time_total;
938  d->stats.eval_hess_count = stats->eval_hess_count;
939  d->stats.eval_jac_count = stats->eval_jac_count;
940  d->stats.eval_cv_count = stats->eval_cv_count;
941  d->stats.eval_grad_count = stats->eval_grad_count;
942  d->stats.eval_obj_count = stats->eval_obj_count;
943  d->stats.iterations_count = stats->iterations_count;
944  d->stats.return_flag = stats->return_flag;
945 
946  const double* primal_data = primal->pa;
947  const double* dual_data = dual->pa;
948 
949  casadi_fatrop_read_primal_data(primal_data, d_nlp->z, str);
950  // Unpack dual solution
951  // Inequalities
952  for (k=0;k<str->K;++k) {
953  column = 0;
954  for (i=d->a_ineq_idx[k];i<d->a_ineq_idx[k+1];++i) {
955  d_nlp->lam[p_nlp->nx+d->a_ineq[i]] = dual_data[str->g_ineq_offs[k]+column];
956  column++;
957  }
958  for (i=d->x_ineq_idx[k];i<d->x_ineq_idx[k+1];++i) {
959  d_nlp->lam[d->x_ineq[i]] = dual_data[str->g_ineq_offs[k]+column];
960  column++;
961  }
962  }
963  // Equalities
964  for (k=0;k<str->K;++k) {
965  column = 0;
966  for (i=d->a_eq_idx[k];i<d->a_eq_idx[k+1];++i) {
967  d_nlp->lam[p_nlp->nx+d->a_eq[i]] = dual_data[str->g_offs[k]+column];
968  column++;
969  }
970  for (i=d->x_eq_idx[k];i<d->x_eq_idx[k+1];++i) {
971  d_nlp->lam[d->x_eq[i]] = dual_data[str->g_offs[k]+column];
972  column++;
973  }
974  }
975  // Dynamics
976  for (k=0;k<str->K-1;++k) {
977  casadi_scaled_copy(-1.0, dual_data+str->dyn_eq_offs[k], p->nx[k+1], d_nlp->lam+p_nlp->nx+p->AB[k].offset_r);
978  }
979 
980 
981 }
@ SOLVER_RET_SUCCESS
@ SOLVER_RET_UNKNOWN
@ SOLVER_RET_EXCEPTION
const casadi_fatrop_prob< T1 > * prob
struct blasfeo_dmat R
casadi_int * a_ineq_idx
struct FatropOcpCStats stats
struct FatropOcpCInterface ocp_interface
casadi_nlpsol_data< T1 > * nlp
struct blasfeo_dvec v r
casadi_int * x_ineq_idx
struct FatropOcpCSolver * solver
OracleCallback nlp_grad_f
const casadi_int * I_offsets
const casadi_int * sp_h
const casadi_int * ng
const casadi_int * nx
const casadi_int * RSQsp
OracleCallback nlp_hess_l
FatropOcpCWrite write
const casadi_int * nu
casadi_ocp_block * I
const casadi_int * sp_a
FatropOcpCFlush flush
casadi_ocp_block * AB
const casadi_int * CDsp
OracleCallback nlp_g
casadi_ocp_block * RSQ
const casadi_int * RSQ_offsets
casadi_ocp_block * CD
const casadi_int * CD_offsets
const casadi_int * Isp
const casadi_nlpsol_prob< T1 > * nlp
OracleCallback nlp_f
OracleCallback nlp_jac_g
const casadi_int * ABsp
const casadi_int * AB_offsets
casadi_oracle_data< T1 > * oracle
Definition: casadi_nlp.hpp:76