sleqp_interface.cpp
1 /*
2  * This file is part of CasADi.
3  *
4  * CasADi -- A symbolic framework for dynamic optimization.
5  * Copyright (C) 2010-2023 Joel Andersson, Joris Gillis, Moritz Diehl,
6  * KU Leuven. All rights reserved.
7  * Copyright (C) 2011-2014 Greg Horn
8  *
9  * CasADi is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 3 of the License, or (at your option) any later version.
13  *
14  * CasADi is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with CasADi; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  *
23  */
24 
25 
26 #include "sleqp_interface.hpp"
27 #include "sleqp_func.hpp"
28 
29 // TODO: Pass options
30 // TODO: Add consistent error handling
31 // TODO: Take care of exact / quasi Newton
32 // TODO: Turn Hessian into products?
33 
34 // TODO: Do we ever need the parameters??
35 
36 
37 namespace casadi {
38 
39  std::string log_level_name(SLEQP_LOG_LEVEL level)
40  {
41  switch (level) {
42  case SLEQP_LOG_DEBUG:
43  return " debug";
44  case SLEQP_LOG_INFO:
45  return " info";
46  default:
47  return "unknown";
48  }
49  }
50 
51  static void casadi_log_output(SLEQP_LOG_LEVEL level,
52  time_t time,
53  const char* message)
54  {
55  switch(level)
56  {
57  case SLEQP_LOG_WARN:
58  casadi_warning(message);
59  break;
60  case SLEQP_LOG_ERROR:
61  casadi_error(message);
62  break;
63  default:
64  uout() << "[" << log_level_name(level) << "] " << message << std::endl;
65  }
66  }
67 
68  extern "C"
69  int CASADI_NLPSOL_SLEQP_EXPORT
70  casadi_register_nlpsol_sleqp(Nlpsol::Plugin* plugin) {
71  plugin->creator = SLEQPInterface::creator;
72  plugin->name = "sleqp";
73  plugin->doc = SLEQPInterface::meta_doc.c_str();
74  plugin->version = CASADI_VERSION;
75  plugin->options = &SLEQPInterface::options_;
76  plugin->deserialize = &SLEQPInterface::deserialize;
77 
78  sleqp_log_set_handler(casadi_log_output);
79 
80  return 0;
81  }
82 
83  extern "C"
84  void CASADI_NLPSOL_SLEQP_EXPORT casadi_load_nlpsol_sleqp() {
86  }
87 
88  SLEQPInterface::SLEQPInterface(const std::string& name, const Function& nlp)
89  : Nlpsol(name, nlp) {
90  settings_ = nullptr;
91  }
92 
94  clear_mem();
95 
96  try {
97  if (settings_) SLEQP_CALL_EXC(sleqp_settings_release(&settings_));
98  settings_ = nullptr;
99  } catch(std::exception e) {
100  casadi_message(std::string("SLEQP error ") + e.what());
101  }
102  }
103 
105  = {{&Nlpsol::options_},
106  {{"sleqp",
107  {OT_DICT,
108  "Options to be passed to SLEQP"}},
109  {"print_level",
110  {OT_INT,
111  "Print level of SLEQP (default: 2/SLEQP_LOG_WARN)"}},
112  {"max_iter",
113  {OT_INT,
114  "Maximum number of iterations"}},
115  {"max_wall_time",
116  {OT_DOUBLE,
117  "maximum wall time allowed"}}
118  }
119  };
120 
121  const std::string SLEQPInterface::meta_doc = "";
122 
123  bool SLEQPInterface::exact_hess() const
124  {
125  SLEQP_HESS_EVAL hess_eval = (SLEQP_HESS_EVAL) sleqp_settings_enum_value(settings_,
126  SLEQP_SETTINGS_ENUM_HESS_EVAL);
127 
128  return hess_eval == SLEQP_HESS_EVAL_EXACT;
129  }
130 
131  void SLEQPInterface::init(const Dict& opts) {
132  Nlpsol::init(opts);
133 
134  max_iter_ = SLEQP_NONE;
135  max_wall_time_ = SLEQP_NONE;
136  print_level_ = static_cast<int>(SLEQP_LOG_WARN);
137 
138  // Read user options
139  for (auto&& op : opts) {
140  if (op.first=="sleqp") {
141  opts_ = op.second;
142  } if (op.first=="print_level") {
143  print_level_ = op.second;
144  } if (op.first=="max_iter") {
145  max_iter_ = op.second;
146  casadi_assert(max_iter_>=0, "Invalid iteration limit " + str(max_iter_));
147  } if (op.first=="time_limit") {
148  max_wall_time_ = op.second;
149  casadi_assert(max_wall_time_>=0, "Invalid time limit " + str(max_wall_time_));
150  }
151  }
152 
153  SLEQP_CALL_EXC(sleqp_settings_create(&settings_));
154 
155  // Set Exact Hessian default (per CasADi conventions)
156  SLEQP_CALL_EXC(sleqp_settings_set_enum_value(settings_,
157  SLEQP_SETTINGS_ENUM_HESS_EVAL,
158  SLEQP_HESS_EVAL_EXACT));
159  update_settings(opts_);
160 
161  // Setup NLP functions
162  create_function("nlp_f", {"x", "p"}, {"f"});
163  create_function("nlp_g", {"x", "p"}, {"g"});
164  if (!has_function("nlp_grad_f")) {
165  create_function("nlp_grad_f", {"x", "p"}, {"f", "grad:f:x"});
166  }
167  if (!has_function("nlp_jac_g")) {
168  create_function("nlp_jac_g", {"x", "p"}, {"g", "jac:g:x"});
169  }
170 
171  jacg_sp_ = get_function("nlp_jac_g").sparsity_out(1);
172 
173  // Allocate work vectors
174  alloc_w(nx_, true); // xk_
175  alloc_w(ng_, true); // gk_
176  alloc_w(nx_, true); // grad_fk_
177  alloc_w(jacg_sp_.nnz(), true); // jac_gk_
178 
179  if(!fcallback_.is_null())
180  {
181  // callback xk
182  alloc_w(nx_, true);
183 
184  // callback lam_xk
185  alloc_w(nx_, true);
186 
187  // callback lam_gk
188  alloc_w(ng_, true);
189  }
190 
191  if(exact_hess())
192  {
193  // Hessian direction
194  alloc_w(nx_, true);
195 
196  // Hessian product
197  alloc_w(nx_, true);
198 
199  // Multipliers
200  alloc_w(ng_, true);
201 
202  // Tweaking options for increased efficiency
203  Dict final_options;
204  final_options["is_diff_in"] = std::vector<bool>{true, false, false, false};
205  final_options["is_diff_out"] = std::vector<bool>{true};
206  Dict opts;
207  opts["final_options"] = final_options;
208 
209  // Setup NLP Hessian product
210  Function func = create_function("nlp_grad_l", {"x", "p", "lam:f", "lam:g"},
211  {"grad:gamma:x"}, {{"gamma", {"f", "g"}}}, opts);
212 
213  // only differentiate wrt first argument, i.e., x
214  // inputs:
215  // "x", "p", "lam_f", "lam_g", "out_grad_gamma_x",
216  // "fwd_x", "fwd_p", "fwd_lam_f", "fwd_lam_g"
217  // outputs:
218  // "fwd_grad_gamma_x"
219  Function ret = create_forward("nlp_grad_l", 1);
220  }
221  }
222 
224  int SLEQPInterface::init_mem(void* mem) const {
225  if (Nlpsol::init_mem(mem)) return 1;
226 
227  SLEQPMemory* m = static_cast<SLEQPMemory*>(mem);
228 
229  m->interface = this;
230 
231  return 0;
232  }
233 
234  void SLEQPInterface::clear_mem_at(SLEQPMemory* m) const {
235  SLEQP_CALL_EXC(sleqp_solver_release(&m->internal.solver));
236  SLEQP_CALL_EXC(sleqp_problem_release(&m->internal.problem));
237  SLEQP_CALL_EXC(sleqp_vec_free(&m->internal.primal));
238  }
239 
240  void SLEQPInterface::free_mem(void *mem) const {
241  SLEQPMemory* m = static_cast<SLEQPMemory*>(mem);
242 
243  clear_mem_at(m);
244 
245  delete m;
246  }
247 
248  static std::string status_string(SLEQP_STATUS status)
249  {
250  switch (status) {
251  case SLEQP_STATUS_RUNNING:
252  return "running";
253  case SLEQP_STATUS_OPTIMAL:
254  return "optimal";
255  case SLEQP_STATUS_INFEASIBLE:
256  return "infeasible";
257  case SLEQP_STATUS_UNBOUNDED:
258  return "unbounded";
259  case SLEQP_STATUS_ABORT_DEADPOINT:
260  return "deadpoint";
261  case SLEQP_STATUS_ABORT_ITER:
262  return "iteration limit";
263  case SLEQP_STATUS_ABORT_MANUAL:
264  return "manual abort";
265  case SLEQP_STATUS_ABORT_TIME:
266  return "time limit";
267  default:
268  return "unknown";
269  }
270  }
271 
273  Dict SLEQPInterface::get_stats(void* mem) const {
274  Dict stats = Nlpsol::get_stats(mem);
275 
276  SLEQPMemory* m = static_cast<SLEQPMemory*>(mem);
277 
278  SLEQP_STATUS status = sleqp_solver_status(m->internal.solver);
279 
280  stats["return_status"] = status_string(status);
281  stats["iter_count"] = sleqp_solver_iterations(m->internal.solver);
282 
283  return stats;
284  }
285 
286  void SLEQPInterface::update_settings(const Dict& opts)
287  {
288 
289  // Read options
290  for (auto&& op : opts_) {
291  bool found = false;
292  for (int i = 0; i < SLEQP_NUM_INT_SETTINGS; ++i) {
293  SLEQP_SETTINGS_INT ii = static_cast<SLEQP_SETTINGS_INT>(i);
294  if (op.first==sleqp_settings_int_name(ii)) {
295  found = true;
296  SLEQP_CALL_EXC(sleqp_settings_set_int_value(settings_,
297  ii,
298  op.second.to_int()));
299  }
300  }
301  for (int i = 0; i < SLEQP_NUM_REAL_SETTINGS; ++i) {
302  SLEQP_SETTINGS_REAL ii = static_cast<SLEQP_SETTINGS_REAL>(i);
303  if (op.first==sleqp_settings_real_name(ii)) {
304  found = true;
305  SLEQP_CALL_EXC(sleqp_settings_set_real_value(settings_,
306  ii,
307  op.second.to_double()));
308  }
309  }
310  for (int i = 0; i < SLEQP_NUM_BOOL_SETTINGS; ++i) {
311  SLEQP_SETTINGS_BOOL ii = static_cast<SLEQP_SETTINGS_BOOL>(i);
312  if (op.first==sleqp_settings_bool_name(ii)) {
313  found = true;
314  SLEQP_CALL_EXC(sleqp_settings_set_bool_value(settings_,
315  ii,
316  op.second.to_bool()));
317  }
318  }
319  for (int i = 0; i < SLEQP_NUM_ENUM_SETTINGS; ++i) {
320  SLEQP_SETTINGS_ENUM ii = static_cast<SLEQP_SETTINGS_ENUM>(i);
321  if (op.first==sleqp_settings_enum_name(ii)) {
322  found = true;
323  std::string value = op.second.to_string();
324 
325  SLEQP_CALL_EXC(sleqp_settings_set_enum_value_from_string(settings_,
326  ii,
327  value.c_str()));
328  }
329  }
330  casadi_assert(found, "Could not find option '" + op.first + "'.");
331  }
332  }
333 
335  void SLEQPInterface::set_work(void* mem, const double**& arg, double**& res,
336  casadi_int*& iw, double*& w) const {
337 
338  // Set work in base classes
339  Nlpsol::set_work(mem, arg, res, iw, w);
340 
341  SLEQPMemory* m = static_cast<SLEQPMemory*>(mem);
342 
343  check_inputs(m);
344 
345  // clear_mem(m);
346 
347  casadi_nlpsol_data<double>& d_nlp = m->d_nlp;
348 
349  const int num_vars = nx_;
350  const int num_cons = ng_;
351 
352  SleqpVec* var_lb;
353  SleqpVec* var_ub;
354 
355  sleqp_log_set_level(static_cast<SLEQP_LOG_LEVEL>(print_level_));
356 
357  SLEQP_CALL_EXC(sleqp_vec_create_full(&var_lb, num_vars));
358  SLEQP_CALL_EXC(sleqp_vec_create_full(&var_ub, num_vars));
359 
360  SLEQP_CALL_EXC(sleqp_vec_set_from_raw(var_lb,
361  const_cast<double*>(d_nlp.lbx),
362  num_vars,
363  0.));
364 
365  SLEQP_CALL_EXC(sleqp_vec_set_from_raw(var_ub,
366  const_cast<double*>(d_nlp.ubx),
367  num_vars,
368  0.));
369 
370  SLEQP_CALL_EXC(sleqp_vec_create_full(&m->internal.primal, num_vars));
371 
372  SLEQP_CALL_EXC(sleqp_vec_set_from_raw(m->internal.primal,
373  const_cast<double*>(d_nlp.x0),
374  num_vars,
375  0.));
376 
377 
378  SleqpVec* cons_lb;
379  SleqpVec* cons_ub;
380 
381  SLEQP_CALL_EXC(sleqp_vec_create_full(&cons_lb, num_cons));
382  SLEQP_CALL_EXC(sleqp_vec_create_full(&cons_ub, num_cons));
383 
384  SLEQP_CALL_EXC(sleqp_vec_set_from_raw(cons_lb,
385  const_cast<double*>(d_nlp.lbg),
386  num_cons,
387  0.));
388 
389  SLEQP_CALL_EXC(sleqp_vec_set_from_raw(cons_ub,
390  const_cast<double*>(d_nlp.ubg),
391  num_cons,
392  0.));
393 
394  SleqpFunc* func = nullptr;
395 
397  num_vars,
398  num_cons,
399  m);
400 
401  /*
402  SLEQP_CALL_EXC(sleqp_settings_set_enum_value(m->internal.settings,
403  SLEQP_SETTINGS_ENUM_HESS_EVAL,
404  SLEQP_HESS_EVAL_DAMPED_BFGS));
405  */
406 
407 
408  /*
409  SLEQP_CALL_EXC(sleqp_settings_set_enum_value(m->internal.settings,
410  SLEQP_SETTINGS_ENUM_DERIV_CHECK,
411  SLEQP_DERIV_CHECK_FIRST));
412  */
413 
414  SLEQP_CALL_EXC(sleqp_problem_create_simple(&m->internal.problem,
415  func,
416  var_lb,
417  var_ub,
418  cons_lb,
419  cons_ub,
420  settings_));
421 
422  SLEQP_CALL_EXC(sleqp_func_release(&func));
423 
424  SLEQP_CALL_EXC(sleqp_vec_free(&cons_ub));
425  SLEQP_CALL_EXC(sleqp_vec_free(&cons_lb));
426 
427  SLEQP_CALL_EXC(sleqp_vec_free(&var_ub));
428  SLEQP_CALL_EXC(sleqp_vec_free(&var_lb));
429 
430 
431  // No scaling
432  SLEQP_CALL_EXC(sleqp_solver_create(&m->internal.solver,
433  m->internal.problem,
434  m->internal.primal,
435  nullptr));
436 
437  m->xk = w;
438  w += nx_;
439 
440  m->gk = w;
441  w += ng_;
442 
443  m->grad_fk = w;
444  w += nx_;
445 
446  m->jac_gk = w;
447  w += jacg_sp_.nnz();
448 
449  if(!fcallback_.is_null())
450  {
451  m->cb_xk = w;
452  w += nx_;
453 
454  m->cb_lam_xk = w;
455  w += nx_;
456 
457  m->cb_lam_gk = w;
458  w += ng_;
459  }
460 
461  if (exact_hess()) {
462  m->h_dk = w;
463  w += nx_;
464 
465  m->h_pk = w;
466  w += nx_;
467 
468  m->h_mk = w;
469  w += ng_;
470  }
471 
472  return;
473  }
474 
475  UnifiedReturnStatus map_status(SLEQP_STATUS status)
476  {
477  switch (status) {
478  case SLEQP_STATUS_OPTIMAL:
479  return SOLVER_RET_SUCCESS;
480  case SLEQP_STATUS_INFEASIBLE:
481  return SOLVER_RET_INFEASIBLE;
482 
483  case SLEQP_STATUS_ABORT_ITER:
484  case SLEQP_STATUS_ABORT_MANUAL:
485  case SLEQP_STATUS_ABORT_TIME:
486  return SOLVER_RET_LIMITED;
487  default:
488  // case SLEQP_STATUS_UNKNOWN:
489  // case SLEQP_STATUS_RUNNING:
490  // case SLEQP_STATUS_UNBOUNDED:
491  // case SLEQP_STATUS_ABORT_DEADPOINT:
492  return SOLVER_RET_UNKNOWN;
493  }
494  }
495 
496  static SLEQP_RETCODE
497  accepted_iterate(SleqpSolver* solver, SleqpIterate* iterate, void* data)
498  {
499  SLEQPMemory* m = static_cast<SLEQPMemory*>(data);
500 
501  const SLEQPInterface* interface = m->interface;
502  const Function& fcallback_ = interface->fcallback_;
503 
504  std::fill_n(m->arg, fcallback_.n_in(), nullptr);
505 
506  double ret_double;
507  m->res[0] = &ret_double;
508 
509  casadi_nlpsol_data<double>& d_nlp = m->d_nlp;
510 
511  double obj_val = sleqp_iterate_obj_val(iterate);
512 
513  m->arg[NLPSOL_F] = &obj_val;
514 
515  SleqpVec* primal = sleqp_iterate_primal(iterate);
516  SLEQP_CALL(sleqp_vec_to_raw(primal, m->cb_xk));
517  m->arg[NLPSOL_X] = m->cb_xk;
518 
519  SleqpVec* cons_val = sleqp_iterate_cons_val(iterate);
520  SLEQP_CALL(sleqp_vec_to_raw(cons_val, m->gk));
521  m->arg[NLPSOL_G] = m->gk;
522 
523  SleqpVec* vars_dual = sleqp_iterate_vars_dual(iterate);
524  SLEQP_CALL(sleqp_vec_to_raw(vars_dual, m->cb_lam_xk));
525  m->arg[NLPSOL_LAM_X] = m->cb_lam_xk;
526 
527  SleqpVec* cons_dual = sleqp_iterate_cons_dual(iterate);
528  SLEQP_CALL(sleqp_vec_to_raw(cons_dual, m->cb_lam_gk));
529  m->arg[NLPSOL_LAM_G] = m->cb_lam_gk;
530 
531  try {
532  fcallback_(m->arg, m->res, m->iw, m->w, 0);
533  } catch(KeyboardInterruptException& ex) {
534  sleqp_raise(SLEQP_CALLBACK_ERROR, "Interrupt caught in callback...");
535  } catch(std::exception& ex) {
536  casadi_warning("intermediate_callback: " + std::string(ex.what()));
537  if (m->iteration_callback_ignore_errors) return SLEQP_OKAY;
538  sleqp_raise(SLEQP_CALLBACK_ERROR, "Exception caught in callback...");
539  }
540 
541  casadi_int ret = static_cast<casadi_int>(ret_double);
542 
543  if(ret != 0 && !m->iteration_callback_ignore_errors)
544  {
545  sleqp_raise(SLEQP_CALLBACK_ERROR, "Error in callback...");
546  }
547 
548  return SLEQP_OKAY;
549  }
550 
551  // Solve the NLP
552  int SLEQPInterface::solve(void* mem) const {
553 
554  SLEQPMemory* m = static_cast<SLEQPMemory*>(mem);
555 
557  if (!fcallback_.is_null()) {
558  SLEQP_CALL_EXC(sleqp_solver_add_callback(m->internal.solver,
559  SLEQP_SOLVER_EVENT_ACCEPTED_ITERATE,
560  (void*)accepted_iterate,
561  mem));
562  }
563 
564  SLEQP_CALL_EXC(sleqp_solver_solve(m->internal.solver,
565  max_iter_,
566  max_wall_time_));
567 
568  SleqpIterate* iterate;
569 
570  SLEQP_CALL(sleqp_solver_solution(m->internal.solver, &iterate));
571 
572  casadi_nlpsol_data<double>& d_nlp = m->d_nlp;
573 
574  m->success = true;
575  m->unified_return_status = map_status(sleqp_solver_status(m->internal.solver));
576 
577  SleqpVec* primal = sleqp_iterate_primal(iterate);
578  SLEQP_CALL_EXC(sleqp_vec_to_raw(primal, d_nlp.z));
579 
580  d_nlp.objective = sleqp_iterate_obj_val(iterate);
581 
582  SleqpVec* cons_val = sleqp_iterate_cons_val(iterate);
583  SLEQP_CALL_EXC(sleqp_vec_to_raw(cons_val, d_nlp.z + nx_));
584 
585  SleqpVec* var_dual = sleqp_iterate_vars_dual(iterate);
586  SLEQP_CALL_EXC(sleqp_vec_to_raw(var_dual, d_nlp.lam));
587 
588  SleqpVec* cons_dual = sleqp_iterate_cons_dual(iterate);
589  SLEQP_CALL_EXC(sleqp_vec_to_raw(cons_dual, d_nlp.lam + nx_));
590 
591  if (!fcallback_.is_null()) {
592  SLEQP_CALL_EXC(sleqp_solver_remove_callback(m->internal.solver,
593  SLEQP_SOLVER_EVENT_ACCEPTED_ITERATE,
594  (void*)accepted_iterate,
595  mem));
596  }
597 
598  return 0;
599  }
600 
601 
603  s.version("SLEQPInterface", 1);
604  s.unpack("SLEQPInterface::jacg_sp", jacg_sp_);
605  s.unpack("SLEQPInterface::max_iter", max_iter_);
606  s.unpack("SLEQPInterface::max_wall_time", max_wall_time_);
607  s.unpack("SLEQPInterface::print_level", print_level_);
608  s.unpack("SLEQPInterface::opts", opts_);
609 
610  SLEQP_CALL_EXC(sleqp_settings_create(&settings_));
611  update_settings(opts_);
612  }
613 
616  s.version("SLEQPInterface", 1);
617  s.pack("SLEQPInterface::jacg_sp", jacg_sp_);
618  s.pack("SLEQPInterface::max_iter", max_iter_);
619  s.pack("SLEQPInterface::max_wall_time", max_wall_time_);
620  s.pack("SLEQPInterface::print_level", print_level_);
621  s.pack("SLEQPInterface::opts", opts_);
622  }
623 
624 } // namespace casadi
const char * what() const override
Display error.
Definition: exception.hpp:90
Helper class for Serialization.
void unpack(Sparsity &e)
Reconstruct an object from the input stream.
void version(const std::string &name, int v)
void alloc_w(size_t sz_w, bool persistent=false)
Ensure required length of w field.
Function object.
Definition: function.hpp:60
bool is_null() const
Is a null pointer?
NLP solver storage class.
Definition: nlpsol_impl.hpp:59
bool iteration_callback_ignore_errors_
Options.
Definition: nlpsol_impl.hpp:95
Dict get_stats(void *mem) const override
Get all statistics.
Definition: nlpsol.cpp:1162
static const Options options_
Options.
void init(const Dict &opts) override
Initialize.
Definition: nlpsol.cpp:420
casadi_int ng_
Number of constraints.
Definition: nlpsol_impl.hpp:69
virtual void check_inputs(void *mem) const
Check if the inputs correspond to a well-posed problem.
Definition: nlpsol.cpp:613
int init_mem(void *mem) const override
Initalize memory block.
Definition: nlpsol.cpp:603
void serialize_body(SerializingStream &s) const override
Serialize an object without type information.
Definition: nlpsol.cpp:1306
casadi_int nx_
Number of variables.
Definition: nlpsol_impl.hpp:66
void set_work(void *mem, const double **&arg, double **&res, casadi_int *&iw, double *&w) const override
Set the (persistent) work vectors.
Definition: nlpsol.cpp:795
Function fcallback_
callback function, executed at each iteration
Definition: nlpsol_impl.hpp:75
Function create_function(const Function &oracle, const std::string &fname, const std::vector< std::string > &s_in, const std::vector< std::string > &s_out, const Function::AuxOut &aux=Function::AuxOut(), const Dict &opts=Dict())
Function create_forward(const std::string &fname, casadi_int nfwd)
std::vector< std::string > get_function() const override
Get list of dependency functions.
bool has_function(const std::string &fname) const override
static void registerPlugin(const Plugin &plugin, bool needs_lock=true)
Register an integrator in the factory.
void clear_mem()
Clear all memory (called from destructor)
static const Options options_
int init_mem(void *mem) const override
Initalize memory block.
void serialize_body(SerializingStream &s) const override
Serialize an object without type information.
static ProtoFunction * deserialize(DeserializingStream &s)
Deserialize into MX.
int solve(void *mem) const override
SLEQPInterface(const std::string &name, const Function &nlp)
static const std::string meta_doc
void init(const Dict &opts) override
Initialize.
static Nlpsol * creator(const std::string &name, const Function &nlp)
Dict get_stats(void *mem) const override
Get all statistics.
void set_work(void *mem, const double **&arg, double **&res, casadi_int *&iw, double *&w) const override
Set the (persistent) work vectors.
void free_mem(void *mem) const override
Free memory block.
Helper class for Serialization.
void version(const std::string &name, int v)
void pack(const Sparsity &e)
Serializes an object to the output stream.
casadi_int nnz() const
Get the number of (structural) non-zeros.
Definition: sparsity.cpp:148
The casadi namespace.
Definition: archiver.cpp:28
@ NLPSOL_G
Constraints function at the optimal solution (ng x 1)
Definition: nlpsol.hpp:221
@ NLPSOL_X
Decision variables at the optimal solution (nx x 1)
Definition: nlpsol.hpp:217
@ NLPSOL_F
Cost function value at the optimal solution (1 x 1)
Definition: nlpsol.hpp:219
@ NLPSOL_LAM_G
Lagrange multipliers for bounds on G at the solution (ng x 1)
Definition: nlpsol.hpp:225
@ NLPSOL_LAM_X
Lagrange multipliers for bounds on X at the solution (nx x 1)
Definition: nlpsol.hpp:223
int CASADI_NLPSOL_SLEQP_EXPORT casadi_register_nlpsol_sleqp(Nlpsol::Plugin *plugin)
void casadi_sleqp_func_create(SleqpFunc **star, int num_vars, int num_cons, SLEQPMemory *m)
Definition: sleqp_func.cpp:237
std::string log_level_name(SLEQP_LOG_LEVEL level)
void CASADI_NLPSOL_SLEQP_EXPORT casadi_load_nlpsol_sleqp()
UnifiedReturnStatus map_status(SLEQP_STATUS status)
static std::string status_string(SLEQP_STATUS status)
std::string str(const T &v)
String representation, any type.
GenericType::Dict Dict
C++ equivalent of Python's dict or MATLAB's struct.
static void casadi_log_output(SLEQP_LOG_LEVEL level, time_t time, const char *message)
static SLEQP_RETCODE accepted_iterate(SleqpSolver *solver, SleqpIterate *iterate, void *data)
std::ostream & uout()
UnifiedReturnStatus
@ SOLVER_RET_INFEASIBLE
@ SOLVER_RET_LIMITED
@ SOLVER_RET_SUCCESS
@ SOLVER_RET_UNKNOWN
UnifiedReturnStatus unified_return_status
Definition: nlpsol_impl.hpp:48
casadi_nlpsol_data< double > d_nlp
Definition: nlpsol_impl.hpp:42
Options metadata for a class.
Definition: options.hpp:40
SleqpProblem * problem
const SLEQPInterface * interface
struct casadi::SLEQPMemory::@6 internal