qrsqp.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 "qrsqp.hpp"
27 
28 #include "casadi/core/casadi_misc.hpp"
29 #include "casadi/core/calculus.hpp"
30 #include "casadi/core/conic.hpp"
31 
32 #include <ctime>
33 #include <iomanip>
34 #include <fstream>
35 #include <cmath>
36 #include <cfloat>
37 
38 namespace casadi {
39 
40  extern "C"
41  int CASADI_NLPSOL_QRSQP_EXPORT
42  casadi_register_nlpsol_qrsqp(Nlpsol::Plugin* plugin) {
43  plugin->creator = Qrsqp::creator;
44  plugin->name = "qrsqp";
45  plugin->doc = Qrsqp::meta_doc.c_str();
46  plugin->version = CASADI_VERSION;
47  plugin->options = &Qrsqp::options_;
48  return 0;
49  }
50 
51  extern "C"
52  void CASADI_NLPSOL_QRSQP_EXPORT casadi_load_nlpsol_qrsqp() {
54  }
55 
56  Qrsqp::Qrsqp(const std::string& name, const Function& nlp)
57  : Nlpsol(name, nlp) {
58  }
59 
61  clear_mem();
62  }
63 
65  = {{&Nlpsol::options_},
66  {{"qpsol",
67  {OT_STRING,
68  "The QP solver to be used by the SQP method [qrqp]"}},
69  {"qpsol_options",
70  {OT_DICT,
71  "Options to be passed to the QP solver"}},
72  {"hessian_approximation",
73  {OT_STRING,
74  "limited-memory|exact"}},
75  {"max_iter",
76  {OT_INT,
77  "Maximum number of SQP iterations"}},
78  {"min_iter",
79  {OT_INT,
80  "Minimum number of SQP iterations"}},
81  {"max_iter_ls",
82  {OT_INT,
83  "Maximum number of linesearch iterations"}},
84  {"tol_pr",
85  {OT_DOUBLE,
86  "Stopping criterion for primal infeasibility"}},
87  {"tol_du",
88  {OT_DOUBLE,
89  "Stopping criterion for dual infeasability"}},
90  {"c1",
91  {OT_DOUBLE,
92  "Armijo condition, coefficient of decrease in merit"}},
93  {"beta",
94  {OT_DOUBLE,
95  "Line-search parameter, restoration factor of stepsize"}},
96  {"merit_memory",
97  {OT_INT,
98  "Size of memory to store history of merit function values"}},
99  {"lbfgs_memory",
100  {OT_INT,
101  "Size of L-BFGS memory."}},
102  {"regularize",
103  {OT_BOOL,
104  "Automatic regularization of Lagrange Hessian."}},
105  {"print_header",
106  {OT_BOOL,
107  "Print the header with problem statistics"}},
108  {"print_iteration",
109  {OT_BOOL,
110  "Print the iterations"}},
111  {"min_step_size",
112  {OT_DOUBLE,
113  "The size (inf-norm) of the step size should not become smaller than this."}},
114  }
115  };
116 
117  void Qrsqp::init(const Dict& opts) {
118  // Call the init method of the base class
119  Nlpsol::init(opts);
120 
121  // Default options
122  min_iter_ = 0;
123  max_iter_ = 50;
124  max_iter_ls_ = 3;
125  c1_ = 1e-4;
126  beta_ = 0.8;
127  merit_memsize_ = 4;
128  lbfgs_memory_ = 10;
129  tol_pr_ = 1e-6;
130  tol_du_ = 1e-6;
131  regularize_ = false;
132  std::string hessian_approximation = "exact";
133  min_step_size_ = 1e-10;
134  std::string qpsol_plugin = "qrqp";
135  Dict qpsol_options;
136  print_header_ = true;
137  print_iteration_ = true;
138 
139  // Read user options
140  for (auto&& op : opts) {
141  if (op.first=="max_iter") {
142  max_iter_ = op.second;
143  } else if (op.first=="min_iter") {
144  min_iter_ = op.second;
145  } else if (op.first=="max_iter_ls") {
146  max_iter_ls_ = op.second;
147  } else if (op.first=="c1") {
148  c1_ = op.second;
149  } else if (op.first=="beta") {
150  beta_ = op.second;
151  } else if (op.first=="merit_memory") {
152  merit_memsize_ = op.second;
153  } else if (op.first=="lbfgs_memory") {
154  lbfgs_memory_ = op.second;
155  } else if (op.first=="tol_pr") {
156  tol_pr_ = op.second;
157  } else if (op.first=="tol_du") {
158  tol_du_ = op.second;
159  } else if (op.first=="hessian_approximation") {
160  hessian_approximation = op.second.to_string();
161  } else if (op.first=="min_step_size") {
162  min_step_size_ = op.second;
163  } else if (op.first=="qpsol") {
164  qpsol_plugin = op.second.to_string();
165  } else if (op.first=="qpsol_options") {
166  qpsol_options = op.second;
167  } else if (op.first=="regularize") {
168  regularize_ = op.second;
169  } else if (op.first=="print_header") {
170  print_header_ = op.second;
171  } else if (op.first=="print_iteration") {
172  print_iteration_ = op.second;
173  }
174  }
175 
176  // Use exact Hessian?
177  exact_hessian_ = hessian_approximation =="exact";
178 
179  // Get/generate required functions
180  create_function("nlp_fg", {"x", "p"}, {"f", "g"});
181  // First order derivative information
182  Function jac_g_fcn = create_function("nlp_jac_fg", {"x", "p"},
183  {"f", "grad:f:x", "g", "jac:g:x"});
184  Asp_ = jac_g_fcn.sparsity_out(3);
185 
186  if (exact_hessian_) {
187  Function hess_l_fcn = create_function("nlp_hess_l", {"x", "p", "lam:f", "lam:g"},
188  {"hess:gamma:x:x"}, {{"gamma", {"f", "g"}}});
189  Hsp_ = hess_l_fcn.sparsity_out(0);
190  } else {
192  }
193 
194 
195  // Allocate a QP solver
196  casadi_assert(!qpsol_plugin.empty(), "'qpsol' option has not been set");
197  qpsol_ = conic("qpsol", qpsol_plugin, {{"h", Hsp_}, {"a", Asp_}},
198  qpsol_options);
199  alloc(qpsol_);
200 
201  // BFGS?
202  if (!exact_hessian_) {
203  alloc_w(2*nx_); // casadi_bfgs
204  }
205 
206  // Header
207  if (print_header_) {
208  print("-------------------------------------------\n");
209  print("This is casadi::Qrsqp.\n");
210  if (exact_hessian_) {
211  print("Using exact Hessian\n");
212  } else {
213  print("Using limited memory BFGS Hessian approximation\n");
214  }
215  print("Number of variables: %9d\n", nx_);
216  print("Number of constraints: %9d\n", ng_);
217  print("Number of nonzeros in constraint Jacobian: %9d\n", Asp_.nnz());
218  print("Number of nonzeros in Lagrangian Hessian: %9d\n", Hsp_.nnz());
219  print("\n");
220  }
221 
222  // Current linearization point
223  alloc_w(nx_+ng_, true); // z_cand
224 
225  // Lagrange gradient in the next iterate
226  alloc_w(nx_, true); // gLag_
227  alloc_w(nx_, true); // gLag_old_
228 
229  // Gradient of the objective
230  alloc_w(nx_, true); // gf_
231 
232  // Bounds of the QP
233  alloc_w(nx_+ng_, true); // lbdz
234  alloc_w(nx_+ng_, true); // ubdz
235 
236  // QP solution
237  alloc_w(nx_+ng_, true); // dz
238  alloc_w(nx_+ng_, true); // dlam
239 
240  // Hessian approximation
241  alloc_w(Hsp_.nnz(), true); // Bk_
242 
243  // Jacobian
244  alloc_w(Asp_.nnz(), true); // Jk_
245 
246  // Line-search memory
247  alloc_w(merit_memsize_, true);
248  }
249 
250  void Qrsqp::set_work(void* mem, const double**& arg, double**& res,
251  casadi_int*& iw, double*& w) const {
252  auto m = static_cast<QrsqpMemory*>(mem);
253 
254  // Set work in base classes
255  Nlpsol::set_work(mem, arg, res, iw, w);
256 
257  // Current linearization point
258  m->z_cand = w; w += nx_+ng_;
259 
260  // Lagrange gradient in the next iterate
261  m->gLag = w; w += nx_;
262  m->gLag_old = w; w += nx_;
263 
264  // Gradient of the objective
265  m->gf = w; w += nx_;
266 
267  // Bounds of the QP
268  m->lbdz = w; w += nx_ + ng_;
269  m->ubdz = w; w += nx_ + ng_;
270 
271  // QP solution
272  m->dz = w; w += nx_ + ng_;
273  m->dlam = w; w += nx_ + ng_;
274 
275  // Hessian approximation
276  m->Bk = w; w += Hsp_.nnz();
277 
278  // Jacobian
279  m->Jk = w; w += Asp_.nnz();
280 
281  // merit_mem
282  m->merit_mem = w; w += merit_memsize_;
283 
284  m->iter_count = -1;
285  }
286 
287  int Qrsqp::solve(void* mem) const {
288  auto m = static_cast<QrsqpMemory*>(mem);
289  auto d_nlp = &m->d_nlp;
290 
291  // Number of SQP iterations
292  m->iter_count = 0;
293 
294  // Number of line-search iterations
295  casadi_int ls_iter = 0;
296 
297  // Last linesearch successfull
298  bool ls_success = true;
299 
300  // Reset
301  m->merit_ind = 0;
302  m->sigma = 0.; // NOTE: Move this into the main optimization loop
303  m->reg = 0;
304 
305  // Default stepsize
306  double t = 0;
307 
308  // For seeds
309  const double one = 1.;
310 
311  // MAIN OPTIMIZATION LOOP
312  while (true) {
313  // Evaluate f, g and first order derivative information
314  m->arg[0] = d_nlp->z;
315  m->arg[1] = d_nlp->p;
316  m->res[0] = &d_nlp->objective;
317  m->res[1] = m->gf;
318  m->res[2] = d_nlp->z + nx_;
319  m->res[3] = m->Jk;
320  if (calc_function(m, "nlp_jac_fg")) return 1;
321 
322  // Evaluate the gradient of the Lagrangian
323  casadi_copy(m->gf, nx_, m->gLag);
324  casadi_mv(m->Jk, Asp_, d_nlp->lam + nx_, m->gLag, true);
325  casadi_axpy(nx_, 1., d_nlp->lam, m->gLag);
326 
327  // Primal infeasability
328  double pr_inf = casadi_max_viol(nx_+ng_, d_nlp->z, d_nlp->lbz, d_nlp->ubz);
329 
330  // inf-norm of Lagrange gradient
331  double du_inf = casadi_norm_inf(nx_, m->gLag);
332 
333  // inf-norm of step
334  double dx_norminf = casadi_norm_inf(nx_, m->dz);
335 
336  // Printing information about the actual iterate
337  if (print_iteration_) {
338  if (m->iter_count % 10 == 0) print_iteration();
339  print_iteration(m->iter_count, d_nlp->objective, pr_inf, du_inf, dx_norminf,
340  m->reg, ls_iter, ls_success);
341  }
342 
343  // Callback function
344  if (callback(m)) {
345  print("WARNING(qrsqp): Aborted by callback...\n");
346  m->return_status = "User_Requested_Stop";
347  break;
348  }
349 
350  // Checking convergence criteria
351  if (m->iter_count >= min_iter_ && pr_inf < tol_pr_ && du_inf < tol_du_) {
352  print("MESSAGE(qrsqp): Convergence achieved after %d iterations\n", m->iter_count);
353  m->return_status = "Solve_Succeeded";
354  m->success = true;
355  break;
356  }
357 
358  if (m->iter_count >= max_iter_) {
359  print("MESSAGE(qrsqp): Maximum number of iterations reached.\n");
360  m->return_status = "Maximum_Iterations_Exceeded";
361  m->unified_return_status = SOLVER_RET_LIMITED;
362  break;
363  }
364 
365  if (m->iter_count >= 1 && m->iter_count >= min_iter_ && dx_norminf <= min_step_size_) {
366  print("MESSAGE(qrsqp): Search direction becomes too small without "
367  "convergence criteria being met.\n");
368  m->return_status = "Search_Direction_Becomes_Too_Small";
369  break;
370  }
371 
372  if (exact_hessian_) {
373  // Update/reset exact Hessian
374  m->arg[0] = d_nlp->z;
375  m->arg[1] = d_nlp->p;
376  m->arg[2] = &one;
377  m->arg[3] = d_nlp->lam + nx_;
378  m->res[0] = m->Bk;
379  if (calc_function(m, "nlp_hess_l")) return 1;
380 
381  // Determing regularization parameter with Gershgorin theorem
382  if (regularize_) {
383  m->reg = std::fmin(0, -casadi_lb_eig(Hsp_, m->Bk));
384  if (m->reg > 0) casadi_regularize(Hsp_, m->Bk, m->reg);
385  }
386  } else if (m->iter_count==0) {
387  // Initialize BFGS
388  casadi_fill(m->Bk, Hsp_.nnz(), 1.);
389  casadi_bfgs_reset(Hsp_, m->Bk);
390  } else {
391  // Update BFGS
392  if (m->iter_count % lbfgs_memory_ == 0) casadi_bfgs_reset(Hsp_, m->Bk);
393  // Update the Hessian approximation
394  casadi_bfgs(Hsp_, m->Bk, m->dz, m->gLag, m->gLag_old, m->w);
395  }
396 
397  // Formulate the QP
398  casadi_copy(d_nlp->lbz, nx_+ng_, m->lbdz);
399  casadi_axpy(nx_+ng_, -1., d_nlp->z, m->lbdz);
400  casadi_copy(d_nlp->ubz, nx_+ng_, m->ubdz);
401  casadi_axpy(nx_+ng_, -1., d_nlp->z, m->ubdz);
402 
403  // Intitial guess
404  casadi_copy(d_nlp->lam, nx_ + ng_, m->dlam);
405  casadi_clear(m->dz, nx_);
406 
407  // Increase counter
408  m->iter_count++;
409 
410  // Solve the QP
411  solve_QP(m, m->Bk, m->gf, m->lbdz, m->ubdz, m->Jk, m->dz, m->dlam);
412  casadi_fill(m->dz+nx_, ng_, 1.);
413  casadi_mv(m->Jk, Asp_, m->dz, m->dz+nx_, 0);
414 
415  // Detecting indefiniteness
416  double gain = casadi_bilin(m->Bk, Hsp_, m->dz, m->dz);
417  if (gain < 0) {
418  print("WARNING(qrsqp): Indefinite Hessian detected\n");
419  }
420 
421  // Calculate penalty parameter of merit function
422  m->sigma = std::fmax(m->sigma, 1.01*casadi_norm_inf(nx_ + ng_, m->dlam));
423 
424  // Calculate L1-merit function in the actual iterate
425  double l1_infeas = casadi_max_viol(nx_+ng_, d_nlp->z, d_nlp->lbz, d_nlp->ubz);
426 
427  // Right-hand side of Armijo condition
428  double F_sens = casadi_dot(nx_, m->dz, m->gf);
429  double L1dir = F_sens - m->sigma * l1_infeas;
430  double L1merit = d_nlp->objective + m->sigma * l1_infeas;
431 
432  // Storing the actual merit function value in a list
433  m->merit_mem[m->merit_ind] = L1merit;
434  ++m->merit_ind %= merit_memsize_;
435 
436  // Calculating maximal merit function value so far
437  double meritmax = m->merit_mem[0];
438  for (size_t i=1; i<merit_memsize_ && i<m->iter_count; ++i) {
439  if (meritmax < m->merit_mem[i]) meritmax = m->merit_mem[i];
440  }
441 
442  // Stepsize
443  t = 1.0;
444  double fk_cand;
445  // Merit function value in candidate
446  double L1merit_cand = 0;
447 
448  // Reset line-search counter, success marker
449  ls_iter = 0;
450  ls_success = true;
451 
452  // Line-search
453  if (verbose_) print("Starting line-search\n");
454  if (max_iter_ls_>0) { // max_iter_ls_== 0 disables line-search
455 
456  // Line-search loop
457  while (true) {
458  // Increase counter
459  ls_iter++;
460 
461  // Candidate step
462  casadi_copy(d_nlp->z, nx_, m->z_cand);
463  casadi_axpy(nx_, t, m->dz, m->z_cand);
464 
465  // Evaluating objective and constraints
466  m->arg[0] = m->z_cand;
467  m->arg[1] = d_nlp->p;
468  m->res[0] = &fk_cand;
469  m->res[1] = m->z_cand + nx_;
470  if (calc_function(m, "nlp_fg")) {
471  // line-search failed, skip iteration
472  t = beta_ * t;
473  continue;
474  }
475 
476  // Calculating merit-function in candidate
477  l1_infeas = casadi_max_viol(nx_+ng_, m->z_cand, d_nlp->lbz, d_nlp->ubz);
478  L1merit_cand = fk_cand + m->sigma * l1_infeas;
479  if (L1merit_cand <= meritmax + t * c1_ * L1dir) {
480  break;
481  }
482 
483  // Line-search not successful, but we accept it.
484  if (ls_iter == max_iter_ls_) {
485  ls_success = false;
486  break;
487  }
488 
489  // Backtracking
490  t = beta_ * t;
491  }
492 
493  // Candidate accepted, update dual variables
494  casadi_scal(nx_ + ng_, 1-t, d_nlp->lam);
495  casadi_axpy(nx_ + ng_, t, m->dlam, d_nlp->lam);
496  casadi_scal(nx_, t, m->dz);
497 
498  } else {
499  // Full step
500  casadi_copy(m->dlam, nx_ + ng_, d_nlp->lam);
501  }
502 
503  // Take step
504  casadi_axpy(nx_, 1., m->dz, d_nlp->z);
505 
506  if (!exact_hessian_) {
507  // Evaluate the gradient of the Lagrangian with the old x but new lam_g (for BFGS)
508  casadi_copy(m->gf, nx_, m->gLag_old);
509  casadi_mv(m->Jk, Asp_, d_nlp->lam + nx_, m->gLag_old, true);
510  casadi_axpy(nx_, 1., d_nlp->lam, m->gLag_old);
511  }
512  }
513 
514  return 0;
515  }
516 
517  void Qrsqp::print_iteration() const {
518  print("%4s %14s %9s %9s %9s %7s %2s\n", "iter", "objective", "inf_pr",
519  "inf_du", "||d||", "lg(rg)", "ls");
520  }
521 
522  void Qrsqp::print_iteration(casadi_int iter, double obj,
523  double pr_inf, double du_inf,
524  double dx_norm, double rg,
525  casadi_int ls_trials, bool ls_success) const {
526  print("%4d %14.6e %9.2e %9.2e %9.2e ", iter, obj, pr_inf, du_inf, dx_norm);
527  if (rg>0) {
528  print("%7.2d ", log10(rg));
529  } else {
530  print("%7s ", "-");
531  }
532  print("%2d", ls_trials);
533  if (!ls_success) print("F");
534  print("\n");
535  }
536 
537  void Qrsqp::solve_QP(QrsqpMemory* m, const double* H, const double* g,
538  const double* lbdz, const double* ubdz,
539  const double* A, double* x_opt, double* dlam) const {
540  // Inputs
541  std::fill_n(m->arg, qpsol_.n_in(), nullptr);
542  m->arg[CONIC_H] = H;
543  m->arg[CONIC_G] = g;
544  m->arg[CONIC_X0] = x_opt;
545  m->arg[CONIC_LAM_X0] = dlam;
546  m->arg[CONIC_LAM_A0] = dlam + nx_;
547  m->arg[CONIC_LBX] = lbdz;
548  m->arg[CONIC_UBX] = ubdz;
549  m->arg[CONIC_A] = A;
550  m->arg[CONIC_LBA] = lbdz + nx_;
551  m->arg[CONIC_UBA] = ubdz + nx_;
552 
553  // Outputs
554  std::fill_n(m->res, qpsol_.n_out(), nullptr);
555  m->res[CONIC_X] = x_opt;
556  m->res[CONIC_LAM_X] = dlam;
557  m->res[CONIC_LAM_A] = dlam + nx_;
558 
559  // Solve the QP
560  qpsol_(m->arg, m->res, m->iw, m->w);
561  if (verbose_) print("QP solved\n");
562  }
563 
564  Dict Qrsqp::get_stats(void* mem) const {
565  Dict stats = Nlpsol::get_stats(mem);
566  auto m = static_cast<QrsqpMemory*>(mem);
567  stats["return_status"] = m->return_status;
568  stats["iter_count"] = m->iter_count;
569  return stats;
570  }
571 } // namespace casadi
void alloc_w(size_t sz_w, bool persistent=false)
Ensure required length of w field.
void alloc(const Function &f, bool persistent=false, int num_threads=1)
Ensure work vectors long enough to evaluate function.
Function object.
Definition: function.hpp:60
const Sparsity & sparsity_out(casadi_int ind) const
Get sparsity of a given output.
Definition: function.cpp:1031
casadi_int n_out() const
Get the number of function outputs.
Definition: function.cpp:823
casadi_int n_in() const
Get the number of function inputs.
Definition: function.cpp:819
NLP solver storage class.
Definition: nlpsol_impl.hpp:59
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
int callback(NlpsolMemory *m) const
Definition: nlpsol.cpp:1121
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 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())
int calc_function(OracleMemory *m, const std::string &fcn, const double *const *arg=nullptr, int thread_id=0) const
static void registerPlugin(const Plugin &plugin, bool needs_lock=true)
Register an integrator in the factory.
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)
bool print_header_
Definition: qrsqp.hpp:155
virtual void solve_QP(QrsqpMemory *m, const double *H, const double *g, const double *lbdz, const double *ubdz, const double *A, double *x_opt, double *dlam) const
Definition: qrsqp.cpp:537
double tol_pr_
Tolerance of primal and dual infeasibility.
Definition: qrsqp.hpp:141
double min_step_size_
Minimum step size allowed.
Definition: qrsqp.hpp:144
casadi_int max_iter_
Maximum, minimum number of SQP iterations.
Definition: qrsqp.hpp:135
void set_work(void *mem, const double **&arg, double **&res, casadi_int *&iw, double *&w) const override
Set the (persistent) work vectors.
Definition: qrsqp.cpp:250
~Qrsqp() override
Definition: qrsqp.cpp:60
Sparsity Asp_
Definition: qrsqp.hpp:161
Dict get_stats(void *mem) const override
Get all statistics.
Definition: qrsqp.cpp:564
static const Options options_
Options.
Definition: qrsqp.hpp:105
int solve(void *mem) const override
Definition: qrsqp.cpp:287
Qrsqp(const std::string &name, const Function &nlp)
Definition: qrsqp.cpp:56
casadi_int merit_memsize_
Definition: qrsqp.hpp:151
casadi_int min_iter_
Definition: qrsqp.hpp:135
static const std::string meta_doc
A documentation string.
Definition: qrsqp.hpp:182
bool exact_hessian_
Exact Hessian?
Definition: qrsqp.hpp:132
void init(const Dict &opts) override
Initialize.
Definition: qrsqp.cpp:117
void print_iteration() const
Print iteration header.
Definition: qrsqp.cpp:517
double beta_
Definition: qrsqp.hpp:149
bool print_iteration_
Definition: qrsqp.hpp:155
bool regularize_
Regularization.
Definition: qrsqp.hpp:164
casadi_int max_iter_ls_
Definition: qrsqp.hpp:150
Sparsity Hsp_
Definition: qrsqp.hpp:158
Function qpsol_
QP solver for the subproblems.
Definition: qrsqp.hpp:129
double tol_du_
Definition: qrsqp.hpp:141
double c1_
Definition: qrsqp.hpp:148
static Nlpsol * creator(const std::string &name, const Function &nlp)
Create a new NLP Solver.
Definition: qrsqp.hpp:99
casadi_int lbfgs_memory_
Memory size of L-BFGS method.
Definition: qrsqp.hpp:138
static Sparsity dense(casadi_int nrow, casadi_int ncol=1)
Create a dense rectangular sparsity pattern *.
Definition: sparsity.cpp:1012
casadi_int nnz() const
Get the number of (structural) non-zeros.
Definition: sparsity.cpp:148
Function conic(const std::string &name, const std::string &solver, const SpDict &qp, const Dict &opts)
Definition: conic.cpp:44
The casadi namespace.
Definition: archiver.cpp:28
T1 casadi_max_viol(casadi_int n, const T1 *x, const T1 *lb, const T1 *ub)
Largest bound violation.
@ 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
T1 casadi_bilin(const T1 *A, const casadi_int *sp_A, const T1 *x, const T1 *y)
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.
GenericType::Dict Dict
C++ equivalent of Python's dict or MATLAB's struct.
T1 casadi_dot(casadi_int n, const T1 *x, const T1 *y)
Inner product.
void CASADI_NLPSOL_QRSQP_EXPORT casadi_load_nlpsol_qrsqp()
Definition: qrsqp.cpp:52
void casadi_scal(casadi_int n, T1 alpha, T1 *x)
SCAL: x <- alpha*x.
void casadi_axpy(casadi_int n, T1 alpha, const T1 *x, T1 *y)
AXPY: y <- a*x + y.
int CASADI_NLPSOL_QRSQP_EXPORT casadi_register_nlpsol_qrsqp(Nlpsol::Plugin *plugin)
Definition: qrsqp.cpp:42
T1 casadi_norm_inf(casadi_int n, const T1 *x)
void casadi_clear(T1 *x, casadi_int n)
CLEAR: x <- 0.
void casadi_mv(const T1 *x, const casadi_int *sp_x, const T1 *y, T1 *z, casadi_int tr)
Sparse matrix-vector multiplication: z <- z + x*y.
@ 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_LAM_X
The dual solution corresponding to simple bounds.
Definition: conic.hpp:207
casadi_nlpsol_data< double > d_nlp
Definition: nlpsol_impl.hpp:42
Options metadata for a class.
Definition: options.hpp:40
const char * return_status
Last return status.
Definition: qrsqp.hpp:77