qrqp.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 "qrqp.hpp"
27 #include "casadi/core/nlpsol.hpp"
28 
29 namespace casadi {
30 
31  extern "C"
32  int CASADI_CONIC_QRQP_EXPORT
33  casadi_register_conic_qrqp(Conic::Plugin* plugin) {
34  plugin->creator = Qrqp::creator;
35  plugin->name = "qrqp";
36  plugin->doc = Qrqp::meta_doc.c_str();
37  plugin->version = CASADI_VERSION;
38  plugin->options = &Qrqp::options_;
39  plugin->deserialize = &Qrqp::deserialize;
40  return 0;
41  }
42 
43  extern "C"
44  void CASADI_CONIC_QRQP_EXPORT casadi_load_conic_qrqp() {
46  }
47 
48  Qrqp::Qrqp(const std::string& name, const std::map<std::string, Sparsity> &st)
49  : Conic(name, st) {
50  }
51 
53  clear_mem();
54  }
55 
57  = {{&Conic::options_},
58  {{"max_iter",
59  {OT_INT,
60  "Maximum number of iterations [1000]."}},
61  {"constr_viol_tol",
62  {OT_DOUBLE,
63  "Constraint violation tolerance [1e-8]."}},
64  {"dual_inf_tol",
65  {OT_DOUBLE,
66  "Dual feasibility violation tolerance [1e-8]"}},
67  {"print_header",
68  {OT_BOOL,
69  "Print header [true]."}},
70  {"print_iter",
71  {OT_BOOL,
72  "Print iterations [true]."}},
73  {"print_info",
74  {OT_BOOL,
75  "Print info [true]."}},
76  {"print_lincomb",
77  {OT_BOOL,
78  "Print dependant linear combinations of constraints [false]. "
79  "Printed numbers are 0-based indices into the vector of [simple bounds;linear bounds]"}},
80  {"min_lam",
81  {OT_DOUBLE,
82  "Smallest multiplier treated as inactive for the initial active set [0]."}}
83  }
84  };
85 
86  void Qrqp::init(const Dict& opts) {
87  // Initialize the base classes
88  Conic::init(opts);
89 
90  // Transpose of the Jacobian
91  AT_ = A_.T();
92 
93  // Assemble KKT system sparsity
94  kkt_ = Sparsity::kkt(H_, A_, true, true);
95 
96  // Symbolic QR factorization
98 
99  // Setup memory structure
100  set_qrqp_prob();
101 
102  // Default options
103  print_iter_ = true;
104  print_header_ = true;
105  print_info_ = true;
106  print_lincomb_ = false;
107 
108  // Read user options
109  for (auto&& op : opts) {
110  if (op.first=="max_iter") {
111  p_.max_iter = op.second;
112  } else if (op.first=="constr_viol_tol") {
113  p_.constr_viol_tol = op.second;
114  } else if (op.first=="dual_inf_tol") {
115  p_.dual_inf_tol = op.second;
116  } else if (op.first=="min_lam") {
117  p_.min_lam = op.second;
118  } else if (op.first=="print_iter") {
119  print_iter_ = op.second;
120  } else if (op.first=="print_header") {
121  print_header_ = op.second;
122  } else if (op.first=="print_info") {
123  print_info_ = op.second;
124  } else if (op.first=="print_lincomb") {
125  print_lincomb_ = op.second;
126  }
127  }
128 
129  // Allocate memory
130  casadi_int sz_arg, sz_res, sz_w, sz_iw;
131  casadi_qrqp_work(&p_, &sz_arg, &sz_res, &sz_iw, &sz_w);
132  alloc_arg(sz_arg, true);
133  alloc_res(sz_res, true);
134  alloc_iw(sz_iw, true);
135  alloc_w(sz_w, true);
136 
137  if (print_header_) {
138  // Print summary
139  print("-------------------------------------------\n");
140  print("This is casadi::QRQP\n");
141  print("Number of variables: %9d\n", nx_);
142  print("Number of constraints: %9d\n", na_);
143  print("Number of nonzeros in H: %9d\n", H_.nnz());
144  print("Number of nonzeros in A: %9d\n", A_.nnz());
145  print("Number of nonzeros in KKT: %9d\n", kkt_.nnz());
146  print("Number of nonzeros in QR(V): %9d\n", sp_v_.nnz());
147  print("Number of nonzeros in QR(R): %9d\n", sp_r_.nnz());
148  }
149  }
150 
151  void Qrqp::set_work(void* mem, const double**& arg, double**& res,
152  casadi_int*& iw, double*& w) const {
153  auto m = static_cast<QrqpMemory*>(mem);
154 
155  // Set work in base classes
156  Conic::set_work(mem, arg, res, iw, w);
157 
158  // Setup data structure
159  m->d.prob = &p_;
160  m->d.qp = &m->d_qp;
161 
162  casadi_qrqp_init(&m->d, &iw, &w);
163  }
164 
165  void Qrqp::set_qrqp_prob() {
166  p_.qp = &p_qp_;
167  p_.sp_at = AT_;
168  p_.sp_kkt = kkt_;
169  p_.sp_v = sp_v_;
170  p_.sp_r = sp_r_;
171  p_.prinv = get_ptr(prinv_);
172  p_.pc = get_ptr(pc_);
173  casadi_qrqp_setup(&p_);
174  }
175 
176  int Qrqp::init_mem(void* mem) const {
177  if (Conic::init_mem(mem)) return 1;
178  auto m = static_cast<QrqpMemory*>(mem);
179  m->return_status = "";
180  return 0;
181  }
182 
183  int Qrqp::
184  solve(const double** arg, double** res, casadi_int* iw, double* w, void* mem) const {
185  auto m = static_cast<QrqpMemory*>(mem);
186  // Message buffer
187  char buf[121];
188  // Setup data structure
189  casadi_qrqp_data<double>& d = m->d;
190  casadi_qp_data<double>& d_qp = m->d_qp;
191 
192  // Pass bounds on z
193  casadi_copy(d_qp.lbx, nx_, d.lbz);
194  casadi_copy(d_qp.lba, na_, d.lbz+nx_);
195  casadi_copy(d_qp.ubx, nx_, d.ubz);
196  casadi_copy(d_qp.uba, na_, d.ubz+nx_);
197  // Pass initial guess
198  casadi_copy(d_qp.x0, nx_, d.z);
199  casadi_fill(d.z+nx_, na_, nan);
200  casadi_copy(d_qp.lam_x0, nx_, d.lam);
201  casadi_copy(d_qp.lam_a0, na_, d.lam+nx_);
202 
203  // Reset solver
204  if (casadi_qrqp_reset(&d)) return 1;
205  while (true) {
206  // Prepare QP
207  int flag = casadi_qrqp_prepare(&d);
208  // Print iteration progress
209  if (print_iter_) {
210  if (d.iter % 10 == 0) {
211  // Print header
212  if (casadi_qrqp_print_header(&d, buf, sizeof(buf))) break;
213  uout() << buf << "\n";
214  }
215  // Print iteration
216  if (casadi_qrqp_print_iteration(&d, buf, sizeof(buf))) break;
217  uout() << buf << "\n";
218  }
219  // Make an iteration
220  flag = flag || casadi_qrqp_iterate(&d);
221  // Print debug info
222  if (print_lincomb_) {
223  for (casadi_int k=0;k<d.sing;++k) {
224  uout() << "lincomb: ";
225  casadi_qrqp_print_colcomb(&d, buf, sizeof(buf), k);
226  uout() << buf << "\n";
227  }
228  }
229  if (flag) break;
230 
231  // User interrupt
233  }
234  // Check return flag
235  switch (d.status) {
236  case QP_SUCCESS:
237  m->return_status = "success";
238  break;
239  case QP_MAX_ITER:
240  m->return_status = "Maximum number of iterations reached";
241  m->d_qp.unified_return_status = SOLVER_RET_LIMITED;
242  break;
243  case QP_NO_SEARCH_DIR:
244  m->return_status = "Failed to calculate search direction";
245  m->d_qp.unified_return_status = SOLVER_RET_INFEASIBLE;
246  break;
247  case QP_PRINTING_ERROR:
248  m->return_status = "Printing error";
249  break;
250  }
251  // Get solution
252  casadi_copy(&d.f, 1, d_qp.f);
253  casadi_copy(d.z, nx_, d_qp.x);
254  casadi_copy(d.lam, nx_, d_qp.lam_x);
255  casadi_copy(d.lam+nx_, na_, d_qp.lam_a);
256  // Return
257  if (verbose_) casadi_warning(m->return_status);
258  m->d_qp.success = d.status == QP_SUCCESS;
259  return 0;
260  }
261 
263  qp_codegen_body(g);
266  g.local("d", "struct casadi_qrqp_data");
267  g.local("p", "struct casadi_qrqp_prob");
268  g.local("flag", "int");
269  if (print_iter_ || print_lincomb_) g.local("buf[121]", "char");
270  if (print_lincomb_) g.local("k", "casadi_int");
271 
272  // Setup memory structure
273  g << "p.qp = &p_qp;\n";
274  g << "p.sp_at = " << g.sparsity(AT_) << ";\n";
275  g << "p.sp_kkt = " << g.sparsity(kkt_) << ";\n";
276  g << "p.sp_v = " << g.sparsity(sp_v_) << ";\n";
277  g << "p.sp_r = " << g.sparsity(sp_r_) << ";\n";
278  g << "p.prinv = " << g.constant(prinv_) << ";\n";
279  g << "p.pc = " << g.constant(pc_) << ";\n";
280  g << "casadi_qrqp_setup(&p);\n";
281 
282  // Copy options
283  g << "p.max_iter = " << p_.max_iter << ";\n";
284  g << "p.min_lam = " << p_.min_lam << ";\n";
285  g << "p.constr_viol_tol = " << p_.constr_viol_tol << ";\n";
286  g << "p.dual_inf_tol = " << p_.dual_inf_tol << ";\n";
287 
288  // Setup data structure
289  g << "d.prob = &p;\n";
290  g << "d.qp = &d_qp;\n";
291  g << "casadi_qrqp_init(&d, &iw, &w);\n";
292 
293  g.comment("Pass bounds on z");
294  g.copy_default(g.arg(CONIC_LBX), nx_, "d.lbz", "-casadi_inf", false);
295  g.copy_default(g.arg(CONIC_LBA), na_, "d.lbz+" + str(nx_), "-casadi_inf", false);
296  g.copy_default(g.arg(CONIC_UBX), nx_, "d.ubz", "casadi_inf", false);
297  g.copy_default(g.arg(CONIC_UBA), na_, "d.ubz+" + str(nx_), "casadi_inf", false);
298 
299  g.comment("Pass initial guess");
300  g.copy_default(g.arg(CONIC_X0), nx_, "d.z", "0", false);
301  g << g.fill("d.z+"+str(nx_), na_, g.constant(nan)) << "\n";
302  g.copy_default(g.arg(CONIC_LAM_X0), nx_, "d.lam", "0", false);
303  g.copy_default(g.arg(CONIC_LAM_A0), na_, "d.lam+" + str(nx_), "0", false);
304 
305  g.comment("Solve QP");
306  g << "if (casadi_qrqp_reset(&d)) return 1;\n";
307  g << "while (1) {\n";
308  g << "flag = casadi_qrqp_prepare(&d);\n";
309  if (print_iter_) {
310  // Print header
311  g << "if (d.iter % 10 == 0) {\n";
312  g << "if (casadi_qrqp_print_header(&d, buf, sizeof(buf))) break;\n";
313  g << g.printf("%s\\n", "buf") << "\n";
314  g << "}\n";
315  // Print iteration
316  g << "if (casadi_qrqp_print_iteration(&d, buf, sizeof(buf))) break;\n";
317  g << g.printf("%s\\n", "buf") << "\n";
318  }
319  g << "if (flag || casadi_qrqp_iterate(&d)) break;\n";
320  if (print_lincomb_) {
321  g << "for (k=0;k<d.sing;++k) {\n";
322  g << "casadi_qrqp_print_colcomb(&d, buf, sizeof(buf), k);\n";
323  g << g.printf("lincomb: %s\\n", "buf") << "\n";
324  g << "}\n";
325  }
326  g << "}\n";
327 
328  g.comment("Get solution");
329  g.copy_check("&d.f", 1, g.res(CONIC_COST), false, true);
330  g.copy_check("d.z", nx_, g.res(CONIC_X), false, true);
331  g.copy_check("d.lam", nx_, g.res(CONIC_LAM_X), false, true);
332  g.copy_check("d.lam+"+str(nx_), na_, g.res(CONIC_LAM_A), false, true);
333 
334  g << "if (d.status == QP_SUCCESS) {;\n";
335  g << "return 0;\n";
336  g << "} else if (d.status == QP_NO_SEARCH_DIR) {\n";
337  g << "return " << SOLVER_RET_INFEASIBLE <<";\n";
338  g << "} else {\n";
339  if (error_on_fail_) {
340  g << "return -1000;\n";
341  } else {
342  g << "return -1;\n";
343  }
344  g << "}\n";
345  }
346 
347  Dict Qrqp::get_stats(void* mem) const {
348  Dict stats = Conic::get_stats(mem);
349  auto m = static_cast<QrqpMemory*>(mem);
350  stats["return_status"] = m->return_status;
351  return stats;
352  }
353 
355  s.version("Qrqp", 1);
356  s.unpack("Qrqp::AT", AT_);
357  s.unpack("Qrqp::kkt", kkt_);
358  s.unpack("Qrqp::sp_v", sp_v_);
359  s.unpack("Qrqp::sp_r", sp_r_);
360  s.unpack("Qrqp::prinv", prinv_);
361  s.unpack("Qrqp::pc", pc_);
362  s.unpack("Qrqp::print_iter", print_iter_);
363  s.unpack("Qrqp::print_header", print_header_);
364  s.unpack("Qrqp::print_info", print_info_);
365  s.unpack("Qrqp::print_lincomb_", print_lincomb_);
366  set_qrqp_prob();
367  s.unpack("Qrqp::max_iter", p_.max_iter);
368  s.unpack("Qrqp::min_lam", p_.min_lam);
369  s.unpack("Qrqp::constr_viol_tol", p_.constr_viol_tol);
370  s.unpack("Qrqp::dual_inf_tol", p_.dual_inf_tol);
371  }
372 
375 
376  s.version("Qrqp", 1);
377  s.pack("Qrqp::AT", AT_);
378  s.pack("Qrqp::kkt", kkt_);
379  s.pack("Qrqp::sp_v", sp_v_);
380  s.pack("Qrqp::sp_r", sp_r_);
381  s.pack("Qrqp::prinv", prinv_);
382  s.pack("Qrqp::pc", pc_);
383  s.pack("Qrqp::print_iter", print_iter_);
384  s.pack("Qrqp::print_header", print_header_);
385  s.pack("Qrqp::print_info", print_info_);
386  s.pack("Qrqp::print_lincomb_", print_lincomb_);
387  s.pack("Qrqp::max_iter", p_.max_iter);
388  s.pack("Qrqp::min_lam", p_.min_lam);
389  s.pack("Qrqp::constr_viol_tol", p_.constr_viol_tol);
390  s.pack("Qrqp::dual_inf_tol", p_.dual_inf_tol);
391  }
392 
393 } // namespace casadi
Helper class for C code generation.
std::string fill(const std::string &res, std::size_t n, const std::string &v)
Create a fill operation.
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.
std::string printf(const std::string &str, const std::vector< std::string > &arg=std::vector< std::string >())
Printf.
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 copy_check(const std::string &arg, std::size_t n, const std::string &res, bool check_lhs=true, bool check_rhs=true)
std::string sparsity(const Sparsity &sp, bool canonical=true)
void copy_default(const std::string &arg, std::size_t n, const std::string &res, const std::string &def, bool check_rhs=true)
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
void set_work(void *mem, const double **&arg, double **&res, casadi_int *&iw, double *&w) const override
Set the (persistent) work vectors.
Definition: conic.cpp:458
Dict get_stats(void *mem) const override
Get all statistics.
Definition: conic.cpp:711
casadi_qp_prob< double > p_qp_
Definition: conic_impl.hpp:47
void qp_codegen_body(CodeGenerator &g) const
Generate code for the function body.
Definition: conic.cpp:789
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_iw(size_t sz_iw, bool persistent=false)
Ensure required length of iw field.
void alloc_res(size_t sz_res, bool persistent=false)
Ensure required length of res field.
void alloc_arg(size_t sz_arg, bool persistent=false)
Ensure required length of arg field.
size_t sz_res() const
Get required length of res field.
size_t sz_w() const
Get required length of w field.
void alloc_w(size_t sz_w, bool persistent=false)
Ensure required length of w field.
size_t sz_arg() const
Get required length of arg field.
size_t sz_iw() const
Get required length of iw field.
static void check()
Raises an error if an interrupt was captured.
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 print(const char *fmt,...) const
C-style formatted printing during evaluation.
bool verbose_
Verbose printout.
void clear_mem()
Clear all memory (called from destructor)
static const std::string meta_doc
A documentation string.
Definition: qrqp.hpp:112
Qrqp(const std::string &name, const std::map< std::string, Sparsity > &st)
Create a new Solver.
Definition: qrqp.cpp:48
std::vector< casadi_int > pc_
Definition: qrqp.hpp:118
static const Options options_
Options.
Definition: qrqp.hpp:94
Sparsity kkt_
Definition: qrqp.hpp:116
~Qrqp() override
Destructor.
Definition: qrqp.cpp:52
Sparsity sp_r_
Definition: qrqp.hpp:116
void init(const Dict &opts) override
Initialize.
Definition: qrqp.cpp:86
bool print_header_
Definition: qrqp.hpp:121
bool print_info_
Definition: qrqp.hpp:121
std::vector< casadi_int > prinv_
Definition: qrqp.hpp:118
int init_mem(void *mem) const override
Initalize memory block.
Definition: qrqp.cpp:176
Sparsity AT_
Definition: qrqp.hpp:116
static ProtoFunction * deserialize(DeserializingStream &s)
Deserialize with type disambiguation.
Definition: qrqp.hpp:127
bool print_lincomb_
Definition: qrqp.hpp:121
bool print_iter_
Definition: qrqp.hpp:121
void codegen_body(CodeGenerator &g) const override
Generate code for the function body.
Definition: qrqp.cpp:262
int solve(const double **arg, double **res, casadi_int *iw, double *w, void *mem) const override
Solve the QP.
Definition: qrqp.cpp:184
void serialize_body(SerializingStream &s) const override
Serialize an object without type information.
Definition: qrqp.cpp:373
void set_work(void *mem, const double **&arg, double **&res, casadi_int *&iw, double *&w) const override
Set the (persistent) work vectors.
Definition: qrqp.cpp:151
casadi_qrqp_prob< double > p_
Definition: qrqp.hpp:114
Dict get_stats(void *mem) const override
Get all statistics.
Definition: qrqp.cpp:347
static Conic * creator(const std::string &name, const std::map< std::string, Sparsity > &st)
Create a new QP Solver.
Definition: qrqp.hpp:65
Sparsity sp_v_
Definition: qrqp.hpp:116
Helper class for Serialization.
void version(const std::string &name, int v)
void pack(const Sparsity &e)
Serializes an object to the output stream.
Sparsity T() const
Transpose the matrix.
Definition: sparsity.cpp:394
casadi_int nnz() const
Get the number of (structural) non-zeros.
Definition: sparsity.cpp:148
static Sparsity kkt(const Sparsity &H, const Sparsity &J, bool with_x_diag=true, bool with_lam_g_diag=true)
Get KKT system sparsity.
Definition: sparsity.cpp:1961
void qr_sparse(Sparsity &V, Sparsity &R, std::vector< casadi_int > &prinv, std::vector< casadi_int > &pc, bool amd=true) const
Symbolic QR factorization.
Definition: sparsity.cpp:654
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_LBA
dense, (nc x 1)
Definition: conic.hpp:179
@ CONIC_UBX
dense, (n x 1)
Definition: conic.hpp:185
@ 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
int CASADI_CONIC_QRQP_EXPORT casadi_register_conic_qrqp(Conic::Plugin *plugin)
Definition: qrqp.cpp:33
void casadi_copy(const T1 *x, casadi_int n, T1 *y)
COPY: y <-x.
void casadi_fill(T1 *x, casadi_int n, T1 alpha)
FILL: x <- alpha.
std::string str(const T &v)
String representation, any type.
GenericType::Dict Dict
C++ equivalent of Python's dict or MATLAB's struct.
const double nan
Not a number.
Definition: calculus.hpp:53
T * get_ptr(std::vector< T > &v)
Get a pointer to the data contained in the vector.
void CASADI_CONIC_QRQP_EXPORT casadi_load_conic_qrqp()
Definition: qrqp.cpp:44
std::ostream & uout()
@ SOLVER_RET_INFEASIBLE
@ SOLVER_RET_LIMITED
@ 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
const char * return_status
Definition: qrqp.hpp:47
const T1 * lba
Definition: casadi_qp.hpp:64
const T1 * lbx
Definition: casadi_qp.hpp:64
const T1 * uba
Definition: casadi_qp.hpp:64
const T1 * ubx
Definition: casadi_qp.hpp:64
const T1 * lam_x0
Definition: casadi_qp.hpp:64
const T1 * x0
Definition: casadi_qp.hpp:64
const T1 * lam_a0
Definition: casadi_qp.hpp:64
casadi_int sing
Definition: casadi_qrqp.hpp:93
casadi_qrqp_flag_t status
Definition: casadi_qrqp.hpp:80
const casadi_qp_prob< T1 > * qp
Definition: casadi_qrqp.hpp:33
casadi_int max_iter
Definition: casadi_qrqp.hpp:45
const casadi_int * sp_at
Definition: casadi_qrqp.hpp:35
const casadi_int * sp_r
Definition: casadi_qrqp.hpp:37
const casadi_int * prinv
Definition: casadi_qrqp.hpp:37
const casadi_int * sp_v
Definition: casadi_qrqp.hpp:37
const casadi_int * sp_kkt
Definition: casadi_qrqp.hpp:35
const casadi_int * pc
Definition: casadi_qrqp.hpp:37