1 /* 2 * This file is part of CasADi. 3 * 4 * CasADi -- A symbolic framework for dynamic optimization. 5 * Copyright (C) 2010-2014 Joel Andersson, Joris Gillis, Moritz Diehl, 6 * K.U. 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 32 /** \defgroup plugin_Nlpsol_scpgen 33 A structure-exploiting sequential quadratic programming 34 (to be come sequential convex programming) method for nonlinear programming. 35 */ 36 37 /** \pluginsection{Nlpsol,scpgen} */ 38 39 /// \cond INTERNAL 40 41 namespace casadi { 42 43 struct CASADI_NLPSOL_SCPGEN_EXPORT ScpgenMemory : public NlpsolMemory { 44 // Work vectors, nonlifted problem 45 double *dxk, *dlam, *gfk, *gL, *b_gn; 46 // Memory for lifted variables 47 struct VarMem { 48 casadi_int n; 49 double *dx, *x0, *x, *lam, *dlam; 50 double *res, *resL; 51 }; 52 std::vector<VarMem> lifted_mem; 53 // Penalty parameter of merit function 54 double sigma; 55 // 1-norm of last primal step 56 double pr_step; 57 // 1-norm of last dual step 58 double du_step; 59 // Regularization 60 double reg; 61 // Message applying to a particular iteration 62 const char* iteration_note; 63 // QP 64 double *qpH, *qpA, *qpB, *qpL, *qpG, *qpH_times_du; 65 // QP solver 66 double *lbdz, *ubdz; 67 // Linesearch parameters 68 double* merit_mem; 69 casadi_int merit_ind; 70 // Timers 71 double t_eval_mat, t_eval_res, t_eval_vec, t_eval_exp, t_solve_qp, t_mainloop; 72 // Current iteration 73 casadi_int iter_count; 74 }; 75 76 /** \brief \pluginbrief{Nlpsol,scpgen} 77 78 @copydoc NLPSolver_doc 79 @copydoc plugin_Nlpsol_scpgen 80 81 \author Joel Andersson, Attila Kozma and Joris Gillis 82 \date 2013 83 */ 84 class CASADI_NLPSOL_SCPGEN_EXPORT Scpgen : public Nlpsol { 85 public: 86 explicit Scpgen(const std::string& name, const Function& nlp); 87 ~Scpgen() override; 88 89 // Get name of the plugin plugin_name() const90 const char* plugin_name() const override { return "scpgen";} 91 92 // Name of the class class_name() const93 std::string class_name() const override { return "Scpgen";} 94 95 /** \brief Create a new NLP Solver */ creator(const std::string & name,const Function & nlp)96 static Nlpsol* creator(const std::string& name, const Function& nlp) { 97 return new Scpgen(name, nlp); 98 } 99 100 ///@{ 101 /** \brief Options */ 102 static const Options options_; get_options() const103 const Options& get_options() const override { return options_;} 104 ///@} 105 106 // Initialize the solver 107 void init(const Dict& opts) override; 108 109 /** \brief Create memory block */ alloc_mem() const110 void* alloc_mem() const override { return new ScpgenMemory();} 111 112 /** \brief Initalize memory block */ 113 int init_mem(void* mem) const override; 114 115 /** \brief Free memory block */ free_mem(void * mem) const116 void free_mem(void *mem) const override { delete static_cast<ScpgenMemory*>(mem);} 117 118 /// Get all statistics 119 Dict get_stats(void* mem) const override; 120 121 /** \brief Set the (persistent) work vectors */ 122 void set_work(void* mem, const double**& arg, double**& res, 123 casadi_int*& iw, double*& w) const override; 124 125 // Solve the NLP 126 int solve(void* mem) const override; 127 128 // Calculate the L1-norm of the primal infeasibility 129 double primalInfeasibility(ScpgenMemory* m) const; 130 131 // Calculate the L1-norm of the dual infeasibility 132 double dualInfeasibility(ScpgenMemory* m) const; 133 134 // Print iteration header 135 void printIteration(ScpgenMemory* m, std::ostream &stream) const; 136 137 // Print iteration 138 void printIteration(ScpgenMemory* m, std::ostream &stream, casadi_int iter, double obj, 139 double pr_inf, double du_inf, 140 double rg, casadi_int ls_trials, bool ls_success) const; 141 142 // Evaluate the matrices in the condensed QP 143 void eval_mat(ScpgenMemory* m) const; 144 145 // Evaluate the vectors in the condensed QP 146 void eval_vec(ScpgenMemory* m) const; 147 148 // Evaluate the residual function 149 void eval_res(ScpgenMemory* m) const; 150 151 // Regularize the condensed QP 152 void regularize(ScpgenMemory* m) const; 153 154 // Solve the QP to get the (full) step 155 void solve_qp(ScpgenMemory* m) const; 156 157 // Perform the line-search to take the step 158 void line_search(ScpgenMemory* m, casadi_int& ls_iter, bool& ls_success) const; 159 160 // Evaluate the step expansion 161 void eval_exp(ScpgenMemory* m) const; 162 163 /// QP solver for the subproblems 164 Function qpsol_; 165 166 /// use Gauss-Newton Hessian 167 bool gauss_newton_; 168 169 /// maximum number of sqp iterations 170 casadi_int max_iter_; 171 172 /// Memory size of L-BFGS method 173 casadi_int lbfgs_memory_; 174 175 /// Tolerance on primal infeasibility 176 double tol_pr_; 177 178 /// Tolerance on dual infeasibility 179 double tol_du_; 180 181 /// Tolerance on regularization 182 double tol_reg_; 183 184 /// stopping criterion for the stepsize 185 double tol_pr_step_; 186 187 /// stopping criterion for the Lagrangian gradient 188 double tol_gl_; 189 190 /// Linesearch parameters 191 ///@{ 192 double c1_; 193 double beta_; 194 casadi_int max_iter_ls_; 195 casadi_int merit_memsize_; 196 double merit_start_; 197 ///@} 198 199 /// Enable Code generation 200 bool codegen_; 201 202 /// Access qpsol getConic() const203 const Function getConic() const { return qpsol_;} 204 205 /// Regularization 206 bool regularize_; 207 208 // Number of gauss_newton equations 209 casadi_int ngn_; 210 211 // Options 212 double reg_threshold_; 213 214 /// Print timers 215 bool print_time_; 216 217 /// Generate initial guess for lifted variables 218 Function vinit_fcn_; 219 220 /// Residual function 221 Function res_fcn_; 222 223 // Function to calculate the matrices in the reduced QP 224 Function mat_fcn_; 225 casadi_int mat_jac_, mat_hes_; 226 227 /// Quadratic approximation 228 Function vec_fcn_; 229 casadi_int vec_gf_, vec_g_; 230 231 /// Step expansion 232 Function exp_fcn_; 233 234 // Residual function io indices 235 casadi_int res_x_, res_p_, res_g_lam_, res_p_lam_, res_p_d_; 236 casadi_int res_f_, res_gl_, res_g_; 237 238 // Modifier function io indices 239 casadi_int mod_x_, mod_p_, mod_g_lam_; 240 casadi_int mod_f_, mod_gl_, mod_g_; 241 casadi_int mod_du_, mod_dlam_g_; 242 243 struct Var { 244 casadi_int n; 245 MX v, v_def, v_lam, v_defL; 246 MX d, d_def, d_lam, d_defL; 247 248 // Indices of function inputs and outputs 249 casadi_int res_var, res_lam, res_d, res_lam_d; 250 casadi_int mod_var, mod_lam, mod_def, mod_defL; 251 casadi_int exp_def, exp_defL; 252 }; 253 254 std::vector<Var> v_; 255 256 // Names of the components 257 std::vector<std::string> name_x_; 258 259 // Components to print 260 std::vector<casadi_int> print_x_; 261 262 // QP sparsity 263 Sparsity spH_, spA_, spL_; 264 265 // Print options 266 bool print_header_; 267 268 /// A documentation string 269 static const std::string meta_doc; 270 }; 271 272 } // namespace casadi 273 274 /// \endcond 275 276 #endif // CASADI_SCPGEN_HPP 277