osqp_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, Kobe Bergmans
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 "osqp_interface.hpp"
27 #include "casadi/core/casadi_misc.hpp"
28 
29 namespace casadi {
30 
31  extern "C"
32  int CASADI_CONIC_OSQP_EXPORT
33  casadi_register_conic_osqp(Conic::Plugin* plugin) {
34  plugin->creator = OsqpInterface::creator;
35  plugin->name = "osqp";
36  plugin->doc = OsqpInterface::meta_doc.c_str();
37  plugin->version = CASADI_VERSION;
38  plugin->options = &OsqpInterface::options_;
39  plugin->deserialize = &OsqpInterface::deserialize;
40  return 0;
41  }
42 
43  extern "C"
44  void CASADI_CONIC_OSQP_EXPORT casadi_load_conic_osqp() {
46  }
47 
48  OsqpInterface::OsqpInterface(const std::string& name,
49  const std::map<std::string, Sparsity>& st)
50  : Conic(name, st) {
51 
52  has_refcount_ = true;
53  }
54 
56  clear_mem();
57  }
58 
60  = {{&Conic::options_},
61  {{"osqp",
62  {OT_DICT,
63  "const Options to be passed to osqp."}},
64  {"warm_start_primal",
65  {OT_BOOL,
66  "Use x0 input to warmstart [Default: true]."}},
67  {"warm_start_dual",
68  {OT_BOOL,
69  "Use lam_a0 and lam_x0 input to warmstart [Default: truw]."}}
70  }
71  };
72 
73  void OsqpInterface::init(const Dict& opts) {
74  // Initialize the base classes
75  Conic::init(opts);
76 
77  osqp_set_default_settings(&settings_);
78  settings_.warm_start = false;
79 
80  warm_start_primal_ = true;
81  warm_start_dual_ = true;
82 
83  // Read options
84  for (auto&& op : opts) {
85  if (op.first=="warm_start_primal") {
86  warm_start_primal_ = op.second;
87  } else if (op.first=="warm_start_dual") {
88  warm_start_dual_ = op.second;
89  } else if (op.first=="osqp") {
90  const Dict& opts = op.second;
91  for (auto&& op : opts) {
92  if (op.first=="rho") {
93  settings_.rho = op.second;
94  } else if (op.first=="sigma") {
95  settings_.sigma = op.second;
96  } else if (op.first=="scaling") {
97  settings_.scaling = op.second;
98  } else if (op.first=="adaptive_rho") {
99  settings_.adaptive_rho = op.second;
100  } else if (op.first=="adaptive_rho_interval") {
101  settings_.adaptive_rho_interval = op.second;
102  } else if (op.first=="adaptive_rho_tolerance") {
103  settings_.adaptive_rho_tolerance = op.second;
104  //} else if (op.first=="adaptive_rho_fraction") {
105  // settings_.adaptive_rho_fraction = op.second;
106  } else if (op.first=="max_iter") {
107  settings_.max_iter = op.second;
108  } else if (op.first=="eps_abs") {
109  settings_.eps_abs = op.second;
110  } else if (op.first=="eps_rel") {
111  settings_.eps_rel = op.second;
112  } else if (op.first=="eps_prim_inf") {
113  settings_.eps_prim_inf = op.second;
114  } else if (op.first=="eps_dual_inf") {
115  settings_.eps_dual_inf = op.second;
116  } else if (op.first=="alpha") {
117  settings_.alpha = op.second;
118  } else if (op.first=="delta") {
119  settings_.delta = op.second;
120  } else if (op.first=="polish") {
121  settings_.polish = op.second;
122  } else if (op.first=="polish_refine_iter") {
123  settings_.polish_refine_iter = op.second;
124  } else if (op.first=="verbose") {
125  settings_.verbose = op.second;
126  } else if (op.first=="scaled_termination") {
127  settings_.scaled_termination = op.second;
128  } else if (op.first=="check_termination") {
129  settings_.check_termination = op.second;
130  } else if (op.first=="warm_start") {
131  casadi_error("OSQP's warm_start option is impure and therefore disabled. "
132  "Use CasADi options 'warm_start_primal' and 'warm_start_dual' instead.");
133  //} else if (op.first=="time_limit") {
134  // settings_.time_limit = op.second;
135  } else {
136  casadi_error("Not recognised");
137  }
138  }
139  }
140  }
141 
142  nnzHupp_ = H_.nnz_upper();
143  nnzA_ = A_.nnz()+nx_;
144 
145  alloc_w(nnzHupp_+nnzA_, false);
146  alloc_w(2*nx_+2*na_, false);
147  }
148 
149  int OsqpInterface::init_mem(void* mem) const {
150  if (Conic::init_mem(mem)) return 1;
151  auto m = static_cast<OsqpMemory*>(mem);
152 
153  // convert H in a upper triangular matrix. This is required by osqp v0.6.0
154  Sparsity H_triu = Sparsity::triu(H_);
155 
156  Sparsity Asp = vertcat(Sparsity::diag(nx_), A_);
157  std::vector<double> dummy(std::max(nx_+na_, std::max(Asp.nnz(), H_.nnz())));
158 
159  std::vector<c_int> A_row = vector_static_cast<c_int>(Asp.get_row());
160  std::vector<c_int> A_colind = vector_static_cast<c_int>(Asp.get_colind());
161  std::vector<c_int> H_row = vector_static_cast<c_int>(H_triu.get_row());
162  std::vector<c_int> H_colind = vector_static_cast<c_int>(H_triu.get_colind());
163 
164  csc A;
165  A.m = nx_ + na_;
166  A.n = nx_;
167  A.nz = nnzA_;
168  A.nzmax = A.nz;
169  A.x = get_ptr(dummy);
170  A.i = get_ptr(A_row);
171  A.p = get_ptr(A_colind);
172 
173  csc H;
174  H.m = nx_;
175  H.n = nx_;
176  H.nz = H_triu.nnz_upper();
177  H.nzmax = H_triu.nnz_upper();
178  H.x = get_ptr(dummy);
179  H.i = get_ptr(H_row);
180  H.p = get_ptr(H_colind);
181 
182  OSQPData data;
183  // Populate data
184  data.n = nx_;
185  data.m = nx_ + na_;
186  // csc_matrix in mem
187  data.P = &H;
188  data.q = get_ptr(dummy);
189  data.A = &A;
190  data.l = get_ptr(dummy);
191  data.u = get_ptr(dummy);
192 
193  // Setup workspace
194  if (osqp_setup(&m->work, &data, &settings_)) return 1;
195  // if(osqp_setup(&data, &settings_)) return 1;
196 
197  m->fstats["preprocessing"] = FStats();
198  m->fstats["solver"] = FStats();
199  m->fstats["postprocessing"] = FStats();
200  return 0;
201  }
202 
203  inline const char* return_status_string(casadi_int status) {
204  return "Unknown";
205  }
206 
208  solve(const double** arg, double** res, casadi_int* iw, double* w, void* mem) const {
209  auto m = static_cast<OsqpMemory*>(mem);
210 
211  // Inputs
212  const double *a=arg[CONIC_A],
213  *h=arg[CONIC_H];
214 
215  // Outputs
216  double *x=res[CONIC_X],
217  *cost=res[CONIC_COST],
218  *lam_a=res[CONIC_LAM_A],
219  *lam_x=res[CONIC_LAM_X];
220 
221  int ret;
222 
223  // Set objective
224  if (arg[CONIC_G]) {
225  ret = osqp_update_lin_cost(m->work, arg[CONIC_G]);
226  casadi_assert(ret==0, "Problem in osqp_update_lin_cost");
227  }
228 
229  // Set bounds
230  casadi_copy(arg[CONIC_LBX], nx_, w);
231  casadi_copy(arg[CONIC_LBA], na_, w+nx_);
232  casadi_copy(arg[CONIC_UBX], nx_, w+nx_+na_);
233  casadi_copy(arg[CONIC_UBA], na_, w+2*nx_+na_);
234 
235  ret = osqp_update_bounds(m->work, w, w+nx_+na_);
236  casadi_assert(ret==0, "Problem in osqp_update_bounds");
237 
238  // Project Hessian
239  casadi_tri_project(arg[CONIC_H], H_, w, false);
240 
241  // Get contraint matrix
242  const casadi_int* colind = A_.colind();
243  double* A = w + nnzHupp_;
244  // Get constraint matrix
245  casadi_int offset = 0;
246  // Loop over columns
247  for (casadi_int i=0; i<nx_; ++i) {
248  A[offset] = 1;
249  offset++;
250  casadi_int n = colind[i+1]-colind[i];
251  casadi_copy(a+colind[i], n, A+offset);
252  offset+= n;
253  }
254 
255  // Pass Hessian and constraint matrices
256  ret = osqp_update_P_A(m->work, w, nullptr, nnzHupp_, A, nullptr, nnzA_);
257  casadi_assert(ret==0, "Problem in osqp_update_P_A");
258 
259 
260  if (warm_start_primal_) {
261  ret = osqp_warm_start_x(m->work, arg[CONIC_X0]);
262  casadi_assert(ret==0, "Problem in osqp_warm_start_x");
263  }
264 
265  if (warm_start_dual_) {
266  casadi_copy(arg[CONIC_LAM_X0], nx_, w);
267  casadi_copy(arg[CONIC_LAM_A0], na_, w+nx_);
268  ret = osqp_warm_start_y(m->work, w);
269  casadi_assert(ret==0, "Problem in osqp_warm_start_y");
270  }
271 
272  // Solve Problem
273  ret = osqp_solve(m->work);
274  casadi_assert(ret==0, "Problem in osqp_solve");
275 
276  casadi_copy(m->work->solution->x, nx_, res[CONIC_X]);
277  casadi_copy(m->work->solution->y, nx_, res[CONIC_LAM_X]);
278  casadi_copy(m->work->solution->y+nx_, na_, res[CONIC_LAM_A]);
279  if (res[CONIC_COST]) *res[CONIC_COST] = m->work->info->obj_val;
280 
281  m->d_qp.success = m->work->info->status_val == OSQP_SOLVED;
282  if (m->d_qp.success) {
283  m->d_qp.unified_return_status = SOLVER_RET_SUCCESS;
284  } else if (m->work->info->status_val == OSQP_PRIMAL_INFEASIBLE ||
285  m->work->info->status_val == OSQP_MAX_ITER_REACHED ||
286  m->work->info->status_val == OSQP_DUAL_INFEASIBLE ||
287  m->work->info->status_val == OSQP_NON_CVX ||
288  m->work->info->status_val == OSQP_PRIMAL_INFEASIBLE_INACCURATE ||
289  m->work->info->status_val == OSQP_DUAL_INFEASIBLE_INACCURATE) {
290  m->d_qp.unified_return_status = SOLVER_RET_INFEASIBLE;
291  } else {
292  m->d_qp.unified_return_status = SOLVER_RET_UNKNOWN;
293  }
294 
295  return 0;
296  }
297 
299  g << "osqp_cleanup(" + codegen_mem(g) + ");\n";
300  }
301 
303  Sparsity Asp = vertcat(Sparsity::diag(nx_), A_);
304  casadi_int dummy_size = std::max(nx_+na_, std::max(Asp.nnz(), H_.nnz()));
305 
306  g.local("A", "csc");
307  g.local("dummy[" + str(dummy_size) + "]", "casadi_real");
308  g << g.clear("dummy", dummy_size) << "\n";
309 
310  g.constant_copy("A_row", Asp.get_row(), "c_int");
311  g.constant_copy("A_colind", Asp.get_colind(), "c_int");
312 
313  // convert H in a upper triangular matrix. This is required by osqp v0.6.0
314  Sparsity H_triu = Sparsity::triu(H_);
315 
316  g.constant_copy("H_row", H_triu.get_row(), "c_int");
317  g.constant_copy("H_colind", H_triu.get_colind(), "c_int");
318 
319  g.local("A", "csc");
320  g << "A.m = " << nx_ + na_ << ";\n";
321  g << "A.n = " << nx_ << ";\n";
322  g << "A.nz = " << nnzA_ << ";\n";
323  g << "A.nzmax = " << nnzA_ << ";\n";
324  g << "A.x = dummy;\n";
325  g << "A.i = A_row;\n";
326  g << "A.p = A_colind;\n";
327 
328  g.local("H", "csc");
329  g << "H.m = " << nx_ << ";\n";
330  g << "H.n = " << nx_ << ";\n";
331  g << "H.nz = " << H_.nnz_upper() << ";\n";
332  g << "H.nzmax = " << H_.nnz_upper() << ";\n";
333  g << "H.x = dummy;\n";
334  g << "H.i = H_row;\n";
335  g << "H.p = H_colind;\n";
336 
337  g.local("data", "OSQPData");
338  g << "data.n = " << nx_ << ";\n";
339  g << "data.m = " << nx_ + na_ << ";\n";
340  g << "data.P = &H;\n";
341  g << "data.q = dummy;\n";
342  g << "data.A = &A;\n";
343  g << "data.l = dummy;\n";
344  g << "data.u = dummy;\n";
345 
346  g.local("settings", "OSQPSettings");
347  g << "osqp_set_default_settings(&settings);\n";
348  g << "settings.rho = " << settings_.rho << ";\n";
349  g << "settings.sigma = " << settings_.sigma << ";\n";
350  g << "settings.scaling = " << settings_.scaling << ";\n";
351  g << "settings.adaptive_rho = " << settings_.adaptive_rho << ";\n";
352  g << "settings.adaptive_rho_interval = " << settings_.adaptive_rho_interval << ";\n";
353  g << "settings.adaptive_rho_tolerance = " << settings_.adaptive_rho_tolerance << ";\n";
354  //g << "settings.adaptive_rho_fraction = " << settings_.adaptive_rho_fraction << ";\n";
355  g << "settings.max_iter = " << settings_.max_iter << ";\n";
356  g << "settings.eps_abs = " << settings_.eps_abs << ";\n";
357  g << "settings.eps_rel = " << settings_.eps_rel << ";\n";
358  g << "settings.eps_prim_inf = " << settings_.eps_prim_inf << ";\n";
359  g << "settings.eps_dual_inf = " << settings_.eps_dual_inf << ";\n";
360  g << "settings.alpha = " << settings_.alpha << ";\n";
361  g << "settings.delta = " << settings_.delta << ";\n";
362  g << "settings.polish = " << settings_.polish << ";\n";
363  g << "settings.polish_refine_iter = " << settings_.polish_refine_iter << ";\n";
364  g << "settings.verbose = " << settings_.verbose << ";\n";
365  g << "settings.scaled_termination = " << settings_.scaled_termination << ";\n";
366  g << "settings.check_termination = " << settings_.check_termination << ";\n";
367  g << "settings.warm_start = " << settings_.warm_start << ";\n";
368  //g << "settings.time_limit = " << settings_.time_limit << ";\n";
369 
370  g << "return osqp_setup(&" + codegen_mem(g) + ", &data, &settings)!=0;\n";
371  }
372 
374  g.add_include("osqp/osqp.h");
376 
377  g.local("work", "OSQPWorkspace", "*");
378  g.init_local("work", codegen_mem(g));
379 
380  g.comment("Set objective");
381  g.copy_default(g.arg(CONIC_G), nx_, "w", "0", false);
382  g << "if (osqp_update_lin_cost(work, w)) return 1;\n";
383 
384  g.comment("Set bounds");
385  g.copy_default(g.arg(CONIC_LBX), nx_, "w", "-casadi_inf", false);
386  g.copy_default(g.arg(CONIC_LBA), na_, "w+"+str(nx_), "-casadi_inf", false);
387  g.copy_default(g.arg(CONIC_UBX), nx_, "w+"+str(nx_+na_), "casadi_inf", false);
388  g.copy_default(g.arg(CONIC_UBA), na_, "w+"+str(2*nx_+na_), "casadi_inf", false);
389  g << "if (osqp_update_bounds(work, w, w+" + str(nx_+na_)+ ")) return 1;\n";
390 
391  g.comment("Project Hessian");
392  g << g.tri_project(g.arg(CONIC_H), H_, "w", false);
393 
394  g.comment("Get constraint matrix");
395  std::string A_colind = g.constant(A_.get_colind());
396  g.local("offset", "casadi_int");
397  g.local("n", "casadi_int");
398  g.local("i", "casadi_int");
399  g << "offset = 0;\n";
400  g << "for (i=0; i< " << nx_ << "; ++i) {\n";
401  g << "w[" + str(nnzHupp_) + "+offset] = 1;\n";
402  g << "offset++;\n";
403  g << "n = " + A_colind + "[i+1]-" + A_colind + "[i];\n";
404  g << "casadi_copy(" << g.arg(CONIC_A) << "+" + A_colind + "[i], n, "
405  "w+offset+" + str(nnzHupp_) + ");\n";
406  g << "offset+= n;\n";
407  g << "}\n";
408 
409  g.comment("Pass Hessian and constraint matrices");
410  g << "if (osqp_update_P_A(work, w, 0, " + str(nnzHupp_) + ", w+" + str(nnzHupp_) +
411  ", 0, " + str(nnzA_) + ")) return 1;\n";
412 
413  g << "if (osqp_warm_start_x(work, " + g.arg(CONIC_X0) + ")) return 1;\n";
414  g.copy_default(g.arg(CONIC_LAM_X0), nx_, "w", "0", false);
415  g.copy_default(g.arg(CONIC_LAM_A0), na_, "w+"+str(nx_), "0", false);
416  g << "if (osqp_warm_start_y(work, w)) return 1;\n";
417 
418  g << "if (osqp_solve(work)) return 1;\n";
419 
420  g.copy_check("&work->info->obj_val", 1, g.res(CONIC_COST), false, true);
421  g.copy_check("work->solution->x", nx_, g.res(CONIC_X), false, true);
422  g.copy_check("work->solution->y", nx_, g.res(CONIC_LAM_X), false, true);
423  g.copy_check("work->solution->y+" + str(nx_), na_, g.res(CONIC_LAM_A), false, true);
424 
425  g << "if (work->info->status_val != OSQP_SOLVED) {\n";
426  if (error_on_fail_) {
427  g << "return -1000;\n";
428  } else {
429  g << "if (work->info->status_val == OSQP_PRIMAL_INFEASIBLE || ";
430  g << "work->info->status_val == OSQP_MAX_ITER_REACHED || ";
431  g << "work->info->status_val == OSQP_DUAL_INFEASIBLE || ";
432  g << "work->info->status_val == OSQP_PRIMAL_INFEASIBLE_INACCURATE || ";
433  g << "work->info->status_val == OSQP_DUAL_INFEASIBLE_INACCURATE || ";
434  g << "work->info->status_val == OSQP_NON_CVX) {\n";
435  g << "return " << SOLVER_RET_INFEASIBLE << ";\n";
436  g << "} else {\n";
437  g << "return " << SOLVER_RET_UNKNOWN << ";\n";
438  g << "}\n";
439  }
440  g << "}\n";
441 
442  g << "return 0;\n";
443  }
444 
445  Dict OsqpInterface::get_stats(void* mem) const {
446  Dict stats = Conic::get_stats(mem);
447  auto m = static_cast<OsqpMemory*>(mem);
448  stats["return_status"] = m->work->info->status;
449  return stats;
450  }
451 
453  }
454 
456  osqp_cleanup(work);
457  }
458 
460  s.version("OsqpInterface", 1);
461  s.unpack("OsqpInterface::nnzHupp", nnzHupp_);
462  s.unpack("OsqpInterface::nnzA", nnzA_);
463  s.unpack("OsqpInterface::warm_start_primal", warm_start_primal_);
464  s.unpack("OsqpInterface::warm_start_dual", warm_start_dual_);
465 
466  osqp_set_default_settings(&settings_);
467  s.unpack("OsqpInterface::settings::rho", settings_.rho);
468  s.unpack("OsqpInterface::settings::sigma", settings_.sigma);
469  s.unpack("OsqpInterface::settings::scaling", settings_.scaling);
470  s.unpack("OsqpInterface::settings::adaptive_rho", settings_.adaptive_rho);
471  s.unpack("OsqpInterface::settings::adaptive_rho_interval", settings_.adaptive_rho_interval);
472  s.unpack("OsqpInterface::settings::adaptive_rho_tolerance", settings_.adaptive_rho_tolerance);
473  //s.unpack("OsqpInterface::settings::adaptive_rho_fraction", settings_.adaptive_rho_fraction);
474  s.unpack("OsqpInterface::settings::max_iter", settings_.max_iter);
475  s.unpack("OsqpInterface::settings::eps_abs", settings_.eps_abs);
476  s.unpack("OsqpInterface::settings::eps_rel", settings_.eps_rel);
477  s.unpack("OsqpInterface::settings::eps_prim_inf", settings_.eps_prim_inf);
478  s.unpack("OsqpInterface::settings::eps_dual_inf", settings_.eps_dual_inf);
479  s.unpack("OsqpInterface::settings::alpha", settings_.alpha);
480  s.unpack("OsqpInterface::settings::delta", settings_.delta);
481  s.unpack("OsqpInterface::settings::polish", settings_.polish);
482  s.unpack("OsqpInterface::settings::polish_refine_iter", settings_.polish_refine_iter);
483  s.unpack("OsqpInterface::settings::verbose", settings_.verbose);
484  s.unpack("OsqpInterface::settings::scaled_termination", settings_.scaled_termination);
485  s.unpack("OsqpInterface::settings::check_termination", settings_.check_termination);
486  s.unpack("OsqpInterface::settings::warm_start", settings_.warm_start);
487  //s.unpack("OsqpInterface::settings::time_limit", settings_.time_limit);
488  }
489 
492  s.version("OsqpInterface", 1);
493  s.pack("OsqpInterface::nnzHupp", nnzHupp_);
494  s.pack("OsqpInterface::nnzA", nnzA_);
495  s.pack("OsqpInterface::warm_start_primal", warm_start_primal_);
496  s.pack("OsqpInterface::warm_start_dual", warm_start_dual_);
497  s.pack("OsqpInterface::settings::rho", settings_.rho);
498  s.pack("OsqpInterface::settings::sigma", settings_.sigma);
499  s.pack("OsqpInterface::settings::scaling", settings_.scaling);
500  s.pack("OsqpInterface::settings::adaptive_rho", settings_.adaptive_rho);
501  s.pack("OsqpInterface::settings::adaptive_rho_interval", settings_.adaptive_rho_interval);
502  s.pack("OsqpInterface::settings::adaptive_rho_tolerance", settings_.adaptive_rho_tolerance);
503  //s.pack("OsqpInterface::settings::adaptive_rho_fraction", settings_.adaptive_rho_fraction);
504  s.pack("OsqpInterface::settings::max_iter", settings_.max_iter);
505  s.pack("OsqpInterface::settings::eps_abs", settings_.eps_abs);
506  s.pack("OsqpInterface::settings::eps_rel", settings_.eps_rel);
507  s.pack("OsqpInterface::settings::eps_prim_inf", settings_.eps_prim_inf);
508  s.pack("OsqpInterface::settings::eps_dual_inf", settings_.eps_dual_inf);
509  s.pack("OsqpInterface::settings::alpha", settings_.alpha);
510  s.pack("OsqpInterface::settings::delta", settings_.delta);
511  s.pack("OsqpInterface::settings::polish", settings_.polish);
512  s.pack("OsqpInterface::settings::polish_refine_iter", settings_.polish_refine_iter);
513  s.pack("OsqpInterface::settings::verbose", settings_.verbose);
514  s.pack("OsqpInterface::settings::scaled_termination", settings_.scaled_termination);
515  s.pack("OsqpInterface::settings::check_termination", settings_.check_termination);
516  s.pack("OsqpInterface::settings::warm_start", settings_.warm_start);
517  //s.pack("OsqpInterface::settings::time_limit", settings_.time_limit);
518  }
519 
520 } // namespace casadi
Helper class for C code generation.
std::string arg(casadi_int i) const
Refer to argument.
void comment(const std::string &s)
Write a comment line (ignored if not verbose)
std::string constant(const std::vector< casadi_int > &v)
Represent an array constant; adding it when new.
void local(const std::string &name, const std::string &type, const std::string &ref="")
Declare a local variable.
std::string res(casadi_int i) const
Refer to resuly.
void init_local(const std::string &name, const std::string &def)
Specify the default value for a local variable.
void add_include(const std::string &new_include, bool relative_path=false, const std::string &use_ifdef=std::string())
Add an include file optionally using a relative path "..." instead of an absolute path <....
void constant_copy(const std::string &var_name, const std::vector< casadi_int > &v, const std::string &type="casadi_int")
Represent an array constant; adding it when new.
void copy_check(const std::string &arg, std::size_t n, const std::string &res, bool check_lhs=true, bool check_rhs=true)
std::string tri_project(const std::string &arg, const Sparsity &sp_arg, const std::string &res, bool lower)
Project triangular part.
void copy_default(const std::string &arg, std::size_t n, const std::string &res, const std::string &def, bool check_rhs=true)
std::string clear(const std::string &res, std::size_t n)
Create a fill operation.
void add_auxiliary(Auxiliary f, const std::vector< std::string > &inst={"casadi_real"})
Add a built-in auxiliary function.
Internal class.
Definition: conic_impl.hpp:44
static const Options options_
Options.
Definition: conic_impl.hpp:83
casadi_int nx_
Number of decision variables.
Definition: conic_impl.hpp:169
int init_mem(void *mem) const override
Initalize memory block.
Definition: conic.cpp:451
casadi_int na_
The number of constraints (counting both equality and inequality) == A.size1()
Definition: conic_impl.hpp:172
Sparsity H_
Problem structure.
Definition: conic_impl.hpp:166
void init(const Dict &opts) override
Initialize.
Definition: conic.cpp:412
void serialize_body(SerializingStream &s) const override
Serialize an object without type information.
Definition: conic.cpp:738
Dict get_stats(void *mem) const override
Get all statistics.
Definition: conic.cpp:711
Helper class for Serialization.
void unpack(Sparsity &e)
Reconstruct an object from the input stream.
void version(const std::string &name, int v)
bool has_refcount_
Reference counting in codegen?
std::string codegen_mem(CodeGenerator &g, const std::string &index="mem") const
Get thread-local memory object.
void alloc_w(size_t sz_w, bool persistent=false)
Ensure required length of w field.
void codegen_free_mem(CodeGenerator &g) const override
Codegen free_mem.
void codegen_init_mem(CodeGenerator &g) const override
Codegen alloc_mem.
void serialize_body(SerializingStream &s) const override
Serialize an object without type information.
Dict get_stats(void *mem) const override
Get all statistics.
void codegen_body(CodeGenerator &g) const override
Generate code for the function body.
~OsqpInterface() override
Destructor.
static ProtoFunction * deserialize(DeserializingStream &s)
Deserialize with type disambiguation.
int init_mem(void *mem) const override
Initalize memory block.
static Conic * creator(const std::string &name, const std::map< std::string, Sparsity > &st)
Create a new QP Solver.
OsqpInterface(const std::string &name, const std::map< std::string, Sparsity > &st)
Create a new Solver.
void init(const Dict &opts) override
Initialize.
int solve(const double **arg, double **res, casadi_int *iw, double *w, void *mem) const override
Solve the QP.
static const std::string meta_doc
A documentation string.
static const Options options_
const Options
static void registerPlugin(const Plugin &plugin, bool needs_lock=true)
Register an integrator in the factory.
bool error_on_fail_
Throw an exception on failure?
void clear_mem()
Clear all memory (called from destructor)
Helper class for Serialization.
void version(const std::string &name, int v)
void pack(const Sparsity &e)
Serializes an object to the output stream.
General sparsity class.
Definition: sparsity.hpp:106
static Sparsity diag(casadi_int nrow)
Create diagonal sparsity pattern *.
Definition: sparsity.hpp:190
static Sparsity triu(const Sparsity &x, bool includeDiagonal=true)
Enlarge matrix.
Definition: sparsity.cpp:983
casadi_int nnz_upper(bool strictly=false) const
Number of non-zeros in the upper triangular half,.
Definition: sparsity.cpp:356
casadi_int nnz() const
Get the number of (structural) non-zeros.
Definition: sparsity.cpp:148
std::vector< casadi_int > get_colind() const
Get the column index for each column.
Definition: sparsity.cpp:364
std::vector< casadi_int > get_row() const
Get the row for each non-zero entry.
Definition: sparsity.cpp:372
const casadi_int * colind() const
Get a reference to the colindex of all column element (see class description)
Definition: sparsity.cpp:168
The casadi namespace.
Definition: archiver.cpp:28
@ CONIC_UBA
dense, (nc x 1)
Definition: conic.hpp:181
@ CONIC_X0
dense, (n x 1)
Definition: conic.hpp:187
@ CONIC_A
The matrix A: sparse, (nc x n) - product with x must be dense.
Definition: conic.hpp:177
@ CONIC_G
The vector g: dense, (n x 1)
Definition: conic.hpp:175
@ CONIC_LBA
dense, (nc x 1)
Definition: conic.hpp:179
@ CONIC_UBX
dense, (n x 1)
Definition: conic.hpp:185
@ CONIC_H
Definition: conic.hpp:173
@ CONIC_LAM_A0
dense
Definition: conic.hpp:191
@ CONIC_LBX
dense, (n x 1)
Definition: conic.hpp:183
@ CONIC_LAM_X0
dense
Definition: conic.hpp:189
void casadi_copy(const T1 *x, casadi_int n, T1 *y)
COPY: y <-x.
const char * return_status_string(Bonmin::TMINLP::SolverReturn status)
int CASADI_CONIC_OSQP_EXPORT casadi_register_conic_osqp(Conic::Plugin *plugin)
std::string str(const T &v)
String representation, any type.
GenericType::Dict Dict
C++ equivalent of Python's dict or MATLAB's struct.
T * get_ptr(std::vector< T > &v)
Get a pointer to the data contained in the vector.
void CASADI_CONIC_OSQP_EXPORT casadi_load_conic_osqp()
@ SOLVER_RET_INFEASIBLE
@ SOLVER_RET_SUCCESS
@ SOLVER_RET_UNKNOWN
@ CONIC_X
The primal solution.
Definition: conic.hpp:201
@ CONIC_LAM_A
The dual solution corresponding to linear bounds.
Definition: conic.hpp:205
@ CONIC_COST
The optimal cost.
Definition: conic.hpp:203
@ CONIC_LAM_X
The dual solution corresponding to simple bounds.
Definition: conic.hpp:207
Options metadata for a class.
Definition: options.hpp:40
~OsqpMemory()
Destructor.
OSQPWorkspace * work
OsqpMemory()
Constructor.