scpgen.hpp
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 #ifndef CASADI_SCPGEN_HPP
27 #define CASADI_SCPGEN_HPP
28 
29 #include "casadi/core/nlpsol_impl.hpp"
30 #include <casadi/solvers/casadi_nlpsol_scpgen_export.h>
31 
43 
44 namespace casadi {
45 
46  struct ScpgenMemory : public NlpsolMemory {
47  // Work vectors, nonlifted problem
48  double *dxk, *dlam, *gfk, *gL, *b_gn;
49  // Memory for lifted variables
50  struct VarMem {
51  casadi_int n;
52  double *dx, *x0, *x, *lam, *dlam;
53  double *res, *resL;
54  };
55  std::vector<VarMem> lifted_mem;
56  // Penalty parameter of merit function
57  double sigma;
58  // 1-norm of last primal step
59  double pr_step;
60  // 1-norm of last dual step
61  double du_step;
62  // Regularization
63  double reg;
64  // Message applying to a particular iteration
65  const char* iteration_note;
66  // QP
67  double *qpH, *qpA, *qpB, *qpL, *qpG, *qpH_times_du;
68  // QP solver
69  double *lbdz, *ubdz;
70  // Linesearch parameters
71  double* merit_mem;
72  casadi_int merit_ind;
73  // Timers
74  double t_eval_mat, t_eval_res, t_eval_vec, t_eval_exp, t_solve_qp, t_mainloop;
75  // Current iteration
76  casadi_int iter_count;
77  };
78 
87  class Scpgen : public Nlpsol {
88  public:
89  explicit Scpgen(const std::string& name, const Function& nlp);
90  ~Scpgen() override;
91 
92  // Get name of the plugin
93  const char* plugin_name() const override { return "scpgen";}
94 
95  // Name of the class
96  std::string class_name() const override { return "Scpgen";}
97 
99  static Nlpsol* creator(const std::string& name, const Function& nlp) {
100  return new Scpgen(name, nlp);
101  }
102 
104 
105  static const Options options_;
106  const Options& get_options() const override { return options_;}
108 
109  // Initialize the solver
110  void init(const Dict& opts) override;
111 
113  void* alloc_mem() const override { return new ScpgenMemory();}
114 
116  int init_mem(void* mem) const override;
117 
119  void free_mem(void *mem) const override { delete static_cast<ScpgenMemory*>(mem);}
120 
122  Dict get_stats(void* mem) const override;
123 
125  void set_work(void* mem, const double**& arg, double**& res,
126  casadi_int*& iw, double*& w) const override;
127 
128  // Solve the NLP
129  int solve(void* mem) const override;
130 
131  // Calculate the L1-norm of the primal infeasibility
132  double primalInfeasibility(ScpgenMemory* m) const;
133 
134  // Calculate the L1-norm of the dual infeasibility
135  double dualInfeasibility(ScpgenMemory* m) const;
136 
137  // Print iteration header
138  void printIteration(ScpgenMemory* m, std::ostream &stream) const;
139 
140  // Print iteration
141  void printIteration(ScpgenMemory* m, std::ostream &stream, casadi_int iter, double obj,
142  double pr_inf, double du_inf,
143  double rg, casadi_int ls_trials, bool ls_success) const;
144 
145  // Evaluate the matrices in the condensed QP
146  void eval_mat(ScpgenMemory* m) const;
147 
148  // Evaluate the vectors in the condensed QP
149  void eval_vec(ScpgenMemory* m) const;
150 
151  // Evaluate the residual function
152  void eval_res(ScpgenMemory* m) const;
153 
154  // Regularize the condensed QP
155  void regularize(ScpgenMemory* m) const;
156 
157  // Solve the QP to get the (full) step
158  void solve_qp(ScpgenMemory* m) const;
159 
160  // Perform the line-search to take the step
161  void line_search(ScpgenMemory* m, casadi_int& ls_iter, bool& ls_success) const;
162 
163  // Evaluate the step expansion
164  void eval_exp(ScpgenMemory* m) const;
165 
167  Function qpsol_;
168 
170  bool gauss_newton_;
171 
173  casadi_int max_iter_;
174 
176  casadi_int lbfgs_memory_;
177 
179  double tol_pr_;
180 
182  double tol_du_;
183 
185  double tol_reg_;
186 
188  double tol_pr_step_;
189 
191  double tol_gl_;
192 
195  double c1_;
196  double beta_;
197  casadi_int max_iter_ls_;
198  casadi_int merit_memsize_;
199  double merit_start_;
201 
203  bool codegen_;
204 
206  const Function getConic() const { return qpsol_;}
207 
209  bool regularize_;
210 
211  // Number of gauss_newton equations
212  casadi_int ngn_;
213 
214  // Options
215  double reg_threshold_;
216 
218  bool print_time_;
219 
221  Function vinit_fcn_;
222 
224  Function res_fcn_;
225 
226  // Function to calculate the matrices in the reduced QP
227  Function mat_fcn_;
228  casadi_int mat_jac_, mat_hes_;
229 
231  Function vec_fcn_;
232  casadi_int vec_gf_, vec_g_;
233 
235  Function exp_fcn_;
236 
237  // Residual function io indices
238  casadi_int res_x_, res_p_, res_g_lam_, res_p_lam_, res_p_d_;
239  casadi_int res_f_, res_gl_, res_g_;
240 
241  // Modifier function io indices
242  casadi_int mod_x_, mod_p_, mod_g_lam_;
243  casadi_int mod_f_, mod_gl_, mod_g_;
244  casadi_int mod_du_, mod_dlam_g_;
245 
246  struct Var {
247  casadi_int n;
248  MX v, v_def, v_lam, v_defL;
249  MX d, d_def, d_lam, d_defL;
250 
251  // Indices of function inputs and outputs
252  casadi_int res_var, res_lam, res_d, res_lam_d;
253  casadi_int mod_var, mod_lam, mod_def, mod_defL;
254  casadi_int exp_def, exp_defL;
255  };
256 
257  std::vector<Var> v_;
258 
259  // Names of the components
260  std::vector<std::string> name_x_;
261 
262  // Components to print
263  std::vector<casadi_int> print_x_;
264 
265  // QP sparsity
266  Sparsity spH_, spA_, spL_;
267 
268  // Print options
269  bool print_header_;
270 
272  static const std::string meta_doc;
273  };
274 
275 } // namespace casadi
276 
278 
279 #endif // CASADI_SCPGEN_HPP
The casadi namespace.
GenericType::Dict Dict
C++ equivalent of Python's dict or MATLAB's struct.