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_SQPMETHOD_HPP
27 #define CASADI_SQPMETHOD_HPP
28 
29 #include "casadi/core/nlpsol_impl.hpp"
30 #include <casadi/solvers/casadi_nlpsol_sqpmethod_export.h>
31 
32 /** \defgroup plugin_Nlpsol_sqpmethod
33  A textbook SQPMethod
34 */
35 
36 /** \pluginsection{Nlpsol,sqpmethod} */
37 
38 /// \cond INTERNAL
39 namespace casadi {
40 
41   struct CASADI_NLPSOL_SQPMETHOD_EXPORT SqpmethodMemory : public NlpsolMemory {
42     // Problem data structure
43     casadi_sqpmethod_data<double> d;
44     /// Hessian regularization
45     double reg;
46 
47     /// Linesearch parameters
48     double sigma;
49 
50     casadi_int merit_ind;
51     /// Last return status
52     const char* return_status;
53 
54     /// Iteration count
55     int iter_count;
56   };
57 
58   /** \brief  \pluginbrief{Nlpsol,sqpmethod}
59   *  @copydoc NLPSolver_doc
60   *  @copydoc plugin_Nlpsol_sqpmethod
61   */
62   class CASADI_NLPSOL_SQPMETHOD_EXPORT Sqpmethod : public Nlpsol {
63   public:
64     explicit Sqpmethod(const std::string& name, const Function& nlp);
65     ~Sqpmethod() override;
66 
67     // Get name of the plugin
plugin_name() const68     const char* plugin_name() const override { return "sqpmethod";}
69 
70     // Name of the class
class_name() const71     std::string class_name() const override { return "Sqpmethod";}
72 
73     /** \brief  Create a new NLP Solver */
creator(const std::string & name,const Function & nlp)74     static Nlpsol* creator(const std::string& name, const Function& nlp) {
75       return new Sqpmethod(name, nlp);
76     }
77 
78     ///@{
79     /** \brief Options */
80     static const Options options_;
get_options() const81     const Options& get_options() const override { return options_;}
82     ///@}
83 
84     /// Get all statistics
85     Dict get_stats(void* mem) const override;
86 
87     // Initialize the solver
88     void init(const Dict& opts) override;
89 
90     /** \brief Create memory block */
alloc_mem() const91     void* alloc_mem() const override { return new SqpmethodMemory();}
92 
93     /** \brief Initalize memory block */
94     int init_mem(void* mem) const override;
95 
96     /** \brief Free memory block */
free_mem(void * mem) const97     void free_mem(void *mem) const override { delete static_cast<SqpmethodMemory*>(mem);}
98 
99     /** \brief Set the (persistent) work vectors */
100     void set_work(void* mem, const double**& arg, double**& res,
101                           casadi_int*& iw, double*& w) const override;
102 
103     // Solve the NLP
104     int solve(void* mem) const override;
105 
106     // Memory structure
107     casadi_sqpmethod_prob<double> p_;
108 
109     /// QP solver for the subproblems
110     Function qpsol_;
111 
112     /// Exact Hessian?
113     bool exact_hessian_;
114 
115     /// Maximum block size of Hessian
116     casadi_int block_size_ = 0;
117 
118     /// Maximum, minimum number of SQP iterations
119     casadi_int max_iter_, min_iter_;
120 
121     /// Memory size of L-BFGS method
122     casadi_int lbfgs_memory_;
123 
124     /// Tolerance of primal and dual infeasibility
125     double tol_pr_, tol_du_;
126 
127     /// Minimum step size allowed
128     double min_step_size_;
129 
130     /// Linesearch parameters
131     ///@{
132     double c1_;
133     double beta_;
134     casadi_int max_iter_ls_;
135     casadi_int merit_memsize_;
136     ///@}
137 
138     // Print options
139     bool print_header_, print_iteration_, print_status_;
140 
141     // Hessian Sparsity
142     Sparsity Hsp_;
143 
144     // Jacobian sparsity
145     Sparsity Asp_;
146 
147     /// Data for convexification
148     ConvexifyData convexify_data_;
149 
150     /// convexify?
151     bool convexify_;
152 
153     /** \brief Generate code for the function body */
154     void codegen_body(CodeGenerator& g) const override;
155 
156     /** \brief Generate code for the declarations of the C function */
157     void codegen_declarations(CodeGenerator& g) const override;
158 
159     /// Access Conic
getConic() const160     const Function getConic() const { return qpsol_;}
161 
162     /// Print iteration header
163     void print_iteration() const;
164 
165     /// Print iteration
166     void print_iteration(casadi_int iter, double obj, double pr_inf, double du_inf,
167                          double dx_norm, double rg, casadi_int ls_trials, bool ls_success) const;
168 
169     // Solve the QP subproblem
170     virtual void solve_QP(SqpmethodMemory* m, const double* H, const double* g,
171                           const double* lbdz, const double* ubdz,
172                           const double* A,
173                           double* x_opt, double* dlam) const;
174 
175 
176     // Solve the QP subproblem
177     void codegen_qp_solve(CodeGenerator& cg, const std::string& H, const std::string& g,
178               const std::string& lbdz, const std::string& ubdz,
179               const std::string& A, const std::string& x_opt, const std::string& dlam) const;
180 
181     /// A documentation string
182     static const std::string meta_doc;
183 
184 
185     /** \brief Serialize an object without type information */
186     void serialize_body(SerializingStream &s) const override;
187 
188     /** \brief Deserialize into MX */
deserialize(DeserializingStream & s)189     static ProtoFunction* deserialize(DeserializingStream& s) { return new Sqpmethod(s); }
190 
191   protected:
192     /** \brief Deserializing constructor */
193     explicit Sqpmethod(DeserializingStream& s);
194 
195   private:
196     void set_sqpmethod_prob();
197   };
198 
199 } // namespace casadi
200 /// \endcond
201 #endif // CASADI_SQPMETHOD_HPP
202