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=="max_wall_time") {
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  // A failed (re)setup can leave the solver null while stats are flagged available
279  if (!m->internal.solver) return stats;
280 
281  SLEQP_STATUS status = sleqp_solver_status(m->internal.solver);
282 
283  stats["return_status"] = status_string(status);
284  stats["iter_count"] = sleqp_solver_iterations(m->internal.solver);
285 
286  return stats;
287  }
288 
289  void SLEQPInterface::update_settings(const Dict& opts)
290  {
291 
292  // Read options
293  for (auto&& op : opts) {
294  bool found = false;
295  for (int i = 0; i < SLEQP_NUM_INT_SETTINGS; ++i) {
296  SLEQP_SETTINGS_INT ii = static_cast<SLEQP_SETTINGS_INT>(i);
297  if (op.first==sleqp_settings_int_name(ii)) {
298  found = true;
299  SLEQP_CALL_EXC(sleqp_settings_set_int_value(settings_,
300  ii,
301  op.second.to_int()));
302  }
303  }
304  for (int i = 0; i < SLEQP_NUM_REAL_SETTINGS; ++i) {
305  SLEQP_SETTINGS_REAL ii = static_cast<SLEQP_SETTINGS_REAL>(i);
306  if (op.first==sleqp_settings_real_name(ii)) {
307  found = true;
308  SLEQP_CALL_EXC(sleqp_settings_set_real_value(settings_,
309  ii,
310  op.second.to_double()));
311  }
312  }
313  for (int i = 0; i < SLEQP_NUM_BOOL_SETTINGS; ++i) {
314  SLEQP_SETTINGS_BOOL ii = static_cast<SLEQP_SETTINGS_BOOL>(i);
315  if (op.first==sleqp_settings_bool_name(ii)) {
316  found = true;
317  SLEQP_CALL_EXC(sleqp_settings_set_bool_value(settings_,
318  ii,
319  op.second.to_bool()));
320  }
321  }
322  for (int i = 0; i < SLEQP_NUM_ENUM_SETTINGS; ++i) {
323  SLEQP_SETTINGS_ENUM ii = static_cast<SLEQP_SETTINGS_ENUM>(i);
324  if (op.first==sleqp_settings_enum_name(ii)) {
325  found = true;
326  std::string value = op.second.to_string();
327 
328  SLEQP_CALL_EXC(sleqp_settings_set_enum_value_from_string(settings_,
329  ii,
330  value.c_str()));
331  }
332  }
333  casadi_assert(found, "Could not find option '" + op.first + "'.");
334  }
335  }
336 
338  void SLEQPInterface::set_work(void* mem, const double**& arg, double**& res,
339  casadi_int*& iw, double*& w) const {
340 
341  // Set work in base classes
342  Nlpsol::set_work(mem, arg, res, iw, w);
343 
344  SLEQPMemory* m = static_cast<SLEQPMemory*>(mem);
345 
346  check_inputs(m);
347 
348  // Release any SLEQP objects from a previous solve (set_work runs each call)
349  clear_mem_at(m);
350 
351  casadi_nlpsol_data<double>& d_nlp = m->d_nlp;
352 
353  const int num_vars = nx_;
354  const int num_cons = ng_;
355 
356  SleqpVec* var_lb;
357  SleqpVec* var_ub;
358 
359  sleqp_log_set_level(static_cast<SLEQP_LOG_LEVEL>(print_level_));
360 
361  SLEQP_CALL_EXC(sleqp_vec_create_full(&var_lb, num_vars));
362  SLEQP_CALL_EXC(sleqp_vec_create_full(&var_ub, num_vars));
363 
364  SLEQP_CALL_EXC(sleqp_vec_set_from_raw(var_lb,
365  const_cast<double*>(d_nlp.lbx),
366  num_vars,
367  0.));
368 
369  SLEQP_CALL_EXC(sleqp_vec_set_from_raw(var_ub,
370  const_cast<double*>(d_nlp.ubx),
371  num_vars,
372  0.));
373 
374  SLEQP_CALL_EXC(sleqp_vec_create_full(&m->internal.primal, num_vars));
375 
376  SLEQP_CALL_EXC(sleqp_vec_set_from_raw(m->internal.primal,
377  const_cast<double*>(d_nlp.x0),
378  num_vars,
379  0.));
380 
381 
382  SleqpVec* cons_lb;
383  SleqpVec* cons_ub;
384 
385  SLEQP_CALL_EXC(sleqp_vec_create_full(&cons_lb, num_cons));
386  SLEQP_CALL_EXC(sleqp_vec_create_full(&cons_ub, num_cons));
387 
388  SLEQP_CALL_EXC(sleqp_vec_set_from_raw(cons_lb,
389  const_cast<double*>(d_nlp.lbg),
390  num_cons,
391  0.));
392 
393  SLEQP_CALL_EXC(sleqp_vec_set_from_raw(cons_ub,
394  const_cast<double*>(d_nlp.ubg),
395  num_cons,
396  0.));
397 
398  SleqpFunc* func = nullptr;
399 
401  num_vars,
402  num_cons,
403  m);
404 
405  /*
406  SLEQP_CALL_EXC(sleqp_settings_set_enum_value(m->internal.settings,
407  SLEQP_SETTINGS_ENUM_HESS_EVAL,
408  SLEQP_HESS_EVAL_DAMPED_BFGS));
409  */
410 
411 
412  /*
413  SLEQP_CALL_EXC(sleqp_settings_set_enum_value(m->internal.settings,
414  SLEQP_SETTINGS_ENUM_DERIV_CHECK,
415  SLEQP_DERIV_CHECK_FIRST));
416  */
417 
418  SLEQP_CALL_EXC(sleqp_problem_create_simple(&m->internal.problem,
419  func,
420  var_lb,
421  var_ub,
422  cons_lb,
423  cons_ub,
424  settings_));
425 
426  SLEQP_CALL_EXC(sleqp_func_release(&func));
427 
428  SLEQP_CALL_EXC(sleqp_vec_free(&cons_ub));
429  SLEQP_CALL_EXC(sleqp_vec_free(&cons_lb));
430 
431  SLEQP_CALL_EXC(sleqp_vec_free(&var_ub));
432  SLEQP_CALL_EXC(sleqp_vec_free(&var_lb));
433 
434 
435  // No scaling
436  SLEQP_CALL_EXC(sleqp_solver_create(&m->internal.solver,
437  m->internal.problem,
438  m->internal.primal,
439  nullptr));
440 
441  m->xk = w;
442  w += nx_;
443 
444  m->gk = w;
445  w += ng_;
446 
447  m->grad_fk = w;
448  w += nx_;
449 
450  m->jac_gk = w;
451  w += jacg_sp_.nnz();
452 
453  if(!fcallback_.is_null())
454  {
455  m->cb_xk = w;
456  w += nx_;
457 
458  m->cb_lam_xk = w;
459  w += nx_;
460 
461  m->cb_lam_gk = w;
462  w += ng_;
463  }
464 
465  if (exact_hess()) {
466  m->h_dk = w;
467  w += nx_;
468 
469  m->h_pk = w;
470  w += nx_;
471 
472  m->h_mk = w;
473  w += ng_;
474  }
475 
476  return;
477  }
478 
479  UnifiedReturnStatus map_status(SLEQP_STATUS status)
480  {
481  switch (status) {
482  case SLEQP_STATUS_OPTIMAL:
483  return SOLVER_RET_SUCCESS;
484  case SLEQP_STATUS_INFEASIBLE:
485  return SOLVER_RET_INFEASIBLE;
486 
487  case SLEQP_STATUS_ABORT_ITER:
488  case SLEQP_STATUS_ABORT_MANUAL:
489  case SLEQP_STATUS_ABORT_TIME:
490  return SOLVER_RET_LIMITED;
491  default:
492  // case SLEQP_STATUS_UNKNOWN:
493  // case SLEQP_STATUS_RUNNING:
494  // case SLEQP_STATUS_UNBOUNDED:
495  // case SLEQP_STATUS_ABORT_DEADPOINT:
496  return SOLVER_RET_UNKNOWN;
497  }
498  }
499 
500  static SLEQP_RETCODE
501  accepted_iterate(SleqpSolver* solver, SleqpIterate* iterate, void* data)
502  {
503  SLEQPMemory* m = static_cast<SLEQPMemory*>(data);
504 
505  const SLEQPInterface* interface = m->interface;
506  const Function& fcallback_ = interface->fcallback_;
507 
508  std::fill_n(m->arg, fcallback_.n_in(), nullptr);
509 
510  double ret_double;
511  m->res[0] = &ret_double;
512 
513  casadi_nlpsol_data<double>& d_nlp = m->d_nlp;
514 
515  double obj_val = sleqp_iterate_obj_val(iterate);
516 
517  m->arg[NLPSOL_F] = &obj_val;
518 
519  SleqpVec* primal = sleqp_iterate_primal(iterate);
520  SLEQP_CALL(sleqp_vec_to_raw(primal, m->cb_xk));
521  m->arg[NLPSOL_X] = m->cb_xk;
522 
523  SleqpVec* cons_val = sleqp_iterate_cons_val(iterate);
524  SLEQP_CALL(sleqp_vec_to_raw(cons_val, m->gk));
525  m->arg[NLPSOL_G] = m->gk;
526 
527  SleqpVec* vars_dual = sleqp_iterate_vars_dual(iterate);
528  SLEQP_CALL(sleqp_vec_to_raw(vars_dual, m->cb_lam_xk));
529  m->arg[NLPSOL_LAM_X] = m->cb_lam_xk;
530 
531  SleqpVec* cons_dual = sleqp_iterate_cons_dual(iterate);
532  SLEQP_CALL(sleqp_vec_to_raw(cons_dual, m->cb_lam_gk));
533  m->arg[NLPSOL_LAM_G] = m->cb_lam_gk;
534 
535  try {
536  fcallback_(m->arg, m->res, m->iw, m->w, 0);
537  } catch(KeyboardInterruptException& ex) {
538  sleqp_raise(SLEQP_CALLBACK_ERROR, "Interrupt caught in callback...");
539  } catch(std::exception& ex) {
540  casadi_warning("intermediate_callback: " + std::string(ex.what()));
541  if (m->iteration_callback_ignore_errors) return SLEQP_OKAY;
542  sleqp_raise(SLEQP_CALLBACK_ERROR, "Exception caught in callback...");
543  }
544 
545  casadi_int ret = static_cast<casadi_int>(ret_double);
546 
547  if(ret != 0 && !m->iteration_callback_ignore_errors)
548  {
549  sleqp_raise(SLEQP_CALLBACK_ERROR, "Error in callback...");
550  }
551 
552  return SLEQP_OKAY;
553  }
554 
555  // Solve the NLP
556  int SLEQPInterface::solve(void* mem) const {
557 
558  SLEQPMemory* m = static_cast<SLEQPMemory*>(mem);
559 
561  if (!fcallback_.is_null()) {
562  SLEQP_CALL_EXC(sleqp_solver_add_callback(m->internal.solver,
563  SLEQP_SOLVER_EVENT_ACCEPTED_ITERATE,
564  (void*)accepted_iterate,
565  mem));
566  }
567 
568  SLEQP_CALL_EXC(sleqp_solver_solve(m->internal.solver,
569  max_iter_,
570  max_wall_time_));
571 
572  SleqpIterate* iterate;
573 
574  SLEQP_CALL(sleqp_solver_solution(m->internal.solver, &iterate));
575 
576  casadi_nlpsol_data<double>& d_nlp = m->d_nlp;
577 
578  m->success = true;
579  m->unified_return_status = map_status(sleqp_solver_status(m->internal.solver));
580 
581  SleqpVec* primal = sleqp_iterate_primal(iterate);
582  SLEQP_CALL_EXC(sleqp_vec_to_raw(primal, d_nlp.z));
583 
584  d_nlp.objective = sleqp_iterate_obj_val(iterate);
585 
586  SleqpVec* cons_val = sleqp_iterate_cons_val(iterate);
587  SLEQP_CALL_EXC(sleqp_vec_to_raw(cons_val, d_nlp.z + nx_));
588 
589  SleqpVec* var_dual = sleqp_iterate_vars_dual(iterate);
590  SLEQP_CALL_EXC(sleqp_vec_to_raw(var_dual, d_nlp.lam));
591 
592  SleqpVec* cons_dual = sleqp_iterate_cons_dual(iterate);
593  SLEQP_CALL_EXC(sleqp_vec_to_raw(cons_dual, d_nlp.lam + nx_));
594 
595  if (!fcallback_.is_null()) {
596  SLEQP_CALL_EXC(sleqp_solver_remove_callback(m->internal.solver,
597  SLEQP_SOLVER_EVENT_ACCEPTED_ITERATE,
598  (void*)accepted_iterate,
599  mem));
600  }
601 
602  return 0;
603  }
604 
605 
607  s.version("SLEQPInterface", 1);
608  s.unpack("SLEQPInterface::jacg_sp", jacg_sp_);
609  s.unpack("SLEQPInterface::max_iter", max_iter_);
610  s.unpack("SLEQPInterface::max_wall_time", max_wall_time_);
611  s.unpack("SLEQPInterface::print_level", print_level_);
612  s.unpack("SLEQPInterface::opts", opts_);
613 
614  SLEQP_CALL_EXC(sleqp_settings_create(&settings_));
615  // Mirror init(): exact Hessian default before applying user options
616  SLEQP_CALL_EXC(sleqp_settings_set_enum_value(settings_,
617  SLEQP_SETTINGS_ENUM_HESS_EVAL,
618  SLEQP_HESS_EVAL_EXACT));
619  update_settings(opts_);
620  }
621 
624  s.version("SLEQPInterface", 1);
625  s.pack("SLEQPInterface::jacg_sp", jacg_sp_);
626  s.pack("SLEQPInterface::max_iter", max_iter_);
627  s.pack("SLEQPInterface::max_wall_time", max_wall_time_);
628  s.pack("SLEQPInterface::print_level", print_level_);
629  s.pack("SLEQPInterface::opts", opts_);
630  }
631 
632 } // 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:1251
static const Options options_
Options.
void init(const Dict &opts) override
Initialize.
Definition: nlpsol.cpp:499
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:702
int init_mem(void *mem) const override
Initalize memory block.
Definition: nlpsol.cpp:692
void serialize_body(SerializingStream &s) const override
Serialize an object without type information.
Definition: nlpsol.cpp:1409
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:884
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
struct casadi::SLEQPMemory::@7 internal
SleqpProblem * problem
const SLEQPInterface * interface