nlpsol_impl.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_NLPSOL_IMPL_HPP
27 #define CASADI_NLPSOL_IMPL_HPP
28 
29 #include "nlpsol.hpp"
30 #include "oracle_function.hpp"
31 #include "plugin_interface.hpp"
32 
33 
35 namespace casadi {
36 
40  struct CASADI_EXPORT NlpsolMemory : public OracleMemory {
41  // Problem data structure
43  // number of iterations
44  casadi_int n_iter;
45  // Success?
46  bool success;
47  // Return status
49  };
50 
58  class CASADI_EXPORT
59  Nlpsol : public OracleFunction, public PluginInterface<Nlpsol> {
60  public:
61 
62  // Memory structure
64 
66  casadi_int nx_;
67 
69  casadi_int ng_;
70 
72  casadi_int np_;
73 
76 
78  casadi_int callback_step_;
79 
81  std::string sens_linsol_;
83 
86  std::vector<casadi_int> detect_simple_bounds_target_x_;
87  std::vector<casadi_int> detect_simple_bounds_target_g_;
88 
90 
97  bool calc_lam_x_, calc_lam_p_, calc_f_, calc_g_;
99  double min_lam_;
101  std::vector<bool> discrete_;
102  std::vector<bool> equality_;
104 
105  // Mixed integer problem?
106  bool mi_;
107 
109  mutable WeakRef kkt_;
110 
111 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
113  mutable std::mutex kkt_mtx_;
114 #endif // CASADI_WITH_THREADSAFE_SYMBOLICS
115 
119  void serialize_body(SerializingStream &s) const override;
123  void serialize_type(SerializingStream &s) const override;
124 
128  static ProtoFunction* deserialize(DeserializingStream& s);
129 
133  std::string serialize_base_function() const override { return "Nlpsol"; }
134 
136  Nlpsol(const std::string& name, const Function& oracle);
137 
139  ~Nlpsol() override = 0;
140 
142 
145  size_t get_n_in() override { return NLPSOL_NUM_IN;}
146  size_t get_n_out() override { return NLPSOL_NUM_OUT;}
148 
150 
153  Sparsity get_sparsity_in(casadi_int i) override;
154  Sparsity get_sparsity_out(casadi_int i) override;
156 
158 
161  std::string get_name_in(casadi_int i) override { return nlpsol_in(i);}
162  std::string get_name_out(casadi_int i) override { return nlpsol_out(i);}
164 
166 
169  static const Options options_;
170  const Options& get_options() const override { return options_;}
172 
176  void disp_more(std::ostream& stream) const override;
177 
179  void init(const Dict& opts) override;
180 
184  void* alloc_mem() const override { return new NlpsolMemory();}
185 
189  int init_mem(void* mem) const override;
190 
194  void free_mem(void *mem) const override { delete static_cast<NlpsolMemory*>(mem);}
195 
199  virtual void check_inputs(void* mem) const;
200 
204  double get_default_in(casadi_int ind) const override { return nlpsol_default_in(ind);}
205 
207  virtual bool integer_support() const { return false;}
208 
212  void set_work(void* mem, const double**& arg, double**& res,
213  casadi_int*& iw, double*& w) const override;
214 
215  // Evaluate numerically
216  int eval(const double** arg, double** res, casadi_int* iw, double* w, void* mem) const final;
217 
218  // Solve the NLP
219  virtual int solve(void* mem) const = 0;
220 
224  void codegen_declarations(CodeGenerator& g) const override;
225 
229  void codegen_body_enter(CodeGenerator& g) const override;
230 
234  void codegen_body_exit(CodeGenerator& g) const override;
235 
236  // Plugins that prefer to keep d_nlp/p_nlp/d_oracle storage on their own
237  // per-mem-block data struct (instead of letting codegen_body_enter emit
238  // them as per-call function-scope locals) skip codegen_body_enter and
239  // call these directly with their own lvalues. The default-prefix call
240  // chain through codegen_body_enter / codegen_body_exit is preserved
241  // byte-for-byte for plugins that don't opt in.
242  // codegen_setup_constants: emit p_nlp constants + d_nlp <-> p_nlp /
243  // d_oracle wiring. Runs once -- call from codegen_init_mem.
244  // codegen_setup_per_call: emit arg/res-dependent d_nlp wiring +
245  // casadi_nlpsol_init + copy_default's. Runs every call -- call
246  // from codegen_body.
247  // codegen_post_solve: emit nlp_grad post-solve + bound consistency +
248  // final NLPSOL_X/F/G/LAM_* fan-out. Per-call -- call from codegen_body.
249  void codegen_setup_constants(CodeGenerator& g,
250  const std::string& d_nlp, const std::string& p_nlp,
251  const std::string& d_oracle) const;
252  void codegen_setup_per_call(CodeGenerator& g, const std::string& d_nlp) const;
253  void codegen_post_solve(CodeGenerator& g, const std::string& d_nlp) const;
254 
258  bool uses_output() const override {return true;}
259 
261  Dict get_stats(void* mem) const override;
262 
264 
267  bool has_forward(casadi_int nfwd) const override { return true;}
268  Function get_forward(casadi_int nfwd, const std::string& name,
269  const std::vector<std::string>& inames,
270  const std::vector<std::string>& onames,
271  const Dict& opts) const override;
273 
275 
278  bool has_reverse(casadi_int nadj) const override { return true;}
279  Function get_reverse(casadi_int nadj, const std::string& name,
280  const std::vector<std::string>& inames,
281  const std::vector<std::string>& onames,
282  const Dict& opts) const override;
284 
285  // Call the callback function
286  int callback(NlpsolMemory* m) const;
287 
288  // Get KKT function
289  Function kkt() const;
290 
291  // Make sure primal-dual solution is consistent with bounds
292  static void bound_consistency(casadi_int n, double* z, double* lam,
293  const double* lbz, const double* ubz);
294 
295  // Creator function for internal class
296  typedef Nlpsol* (*Creator)(const std::string& name, const Function& oracle);
297 
298  // No static functions exposed
299  struct Exposed{ };
300 
302  static std::map<std::string, Plugin> solvers_;
303 
304 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
305  static std::mutex mutex_solvers_;
306 #endif // CASADI_WITH_THREADSAFE_SYMBOLICS
307 
309  static const std::string infix_;
310 
312  static std::string shortname() { return "nlpsol";}
313 
317  std::string class_name() const override {return "Nlpsol";}
318 
322  bool is_a(const std::string& type, bool recursive) const override;
323 
324  // Get reduced Hessian
325  virtual DM getReducedHessian();
326 
328  virtual void setOptionsFromFile(const std::string & file);
329 
331  template<typename Type> static void append_to_vec(GenericType& t, Type el) {
332  std::vector<Type> v = t;
333  v.push_back(el);
334  t = v;
335  }
336 
338  template<typename XType>
339  static Function create_oracle(const std::map<std::string, XType>& d,
340  const Dict& opts);
341 
342  protected:
346  explicit Nlpsol(DeserializingStream& s);
347  private:
348  void set_nlpsol_prob();
349  };
350 
351 } // namespace casadi
353 #endif // CASADI_NLPSOL_IMPL_HPP
Helper class for C code generation.
Helper class for Serialization.
Function object.
Definition: function.hpp:60
Generic data type, can hold different types such as bool, casadi_int, std::string etc.
NLP solver storage class.
Definition: nlpsol_impl.hpp:59
bool iteration_callback_ignore_errors_
Options.
Definition: nlpsol_impl.hpp:95
WeakRef kkt_
Cache for KKT function.
size_t get_n_in() override
Number of function inputs and outputs.
static std::string shortname()
Short name.
std::string get_name_out(casadi_int i) override
Names of function input and outputs.
static const Options options_
Options.
std::string serialize_base_function() const override
String used to identify the immediate FunctionInternal subclass.
casadi_int ng_
Number of constraints.
Definition: nlpsol_impl.hpp:69
bool uses_output() const override
Do the derivative functions need nondifferentiated outputs?
void * alloc_mem() const override
Create memory block.
bool eval_errors_fatal_
Options.
Definition: nlpsol_impl.hpp:93
Function detect_simple_bounds_parts_
Definition: nlpsol_impl.hpp:85
bool calc_multipliers_
Options.
Definition: nlpsol_impl.hpp:96
std::vector< bool > equality_
Options.
bool warn_initial_bounds_
Options.
Definition: nlpsol_impl.hpp:94
static const std::string infix_
Infix.
Dict sens_linsol_options_
Definition: nlpsol_impl.hpp:82
static void append_to_vec(GenericType &t, Type el)
WORKAROUND: Add an element to an std::vector stored in a GenericType:
casadi_nlpsol_prob< double > p_nlp_
Definition: nlpsol_impl.hpp:63
bool has_reverse(casadi_int nadj) const override
Generate a function that calculates reverse mode derivatives.
static std::map< std::string, Plugin > solvers_
Collection of solvers.
bool calc_f_
Options.
Definition: nlpsol_impl.hpp:97
const Options & get_options() const override
Options.
std::string class_name() const override
Get type name.
std::vector< char > detect_simple_bounds_is_simple_
Definition: nlpsol_impl.hpp:84
casadi_int np_
Number of parameters.
Definition: nlpsol_impl.hpp:72
double min_lam_
Options.
Definition: nlpsol_impl.hpp:99
std::vector< casadi_int > detect_simple_bounds_target_g_
Definition: nlpsol_impl.hpp:87
bool has_forward(casadi_int nfwd) const override
Generate a function that calculates forward mode derivatives.
std::string get_name_in(casadi_int i) override
Names of function input and outputs.
void free_mem(void *mem) const override
Free memory block.
casadi_int callback_step_
Execute the callback function only after this amount of iterations.
Definition: nlpsol_impl.hpp:78
std::vector< casadi_int > detect_simple_bounds_target_x_
Definition: nlpsol_impl.hpp:86
size_t get_n_out() override
Number of function inputs and outputs.
std::vector< bool > discrete_
Options.
casadi_int nx_
Number of variables.
Definition: nlpsol_impl.hpp:66
virtual bool integer_support() const
Can discrete variables be treated.
bool bound_consistency_
Options.
Definition: nlpsol_impl.hpp:98
bool no_nlp_grad_
Options.
std::string sens_linsol_
Linear solver and options.
Definition: nlpsol_impl.hpp:81
virtual int solve(void *mem) const =0
Function fcallback_
callback function, executed at each iteration
Definition: nlpsol_impl.hpp:75
double get_default_in(casadi_int ind) const override
Get default input value.
Base class for functions that perform calculation with an oracle.
Interface for accessing input and output data structures.
Base class for FunctionInternal and LinsolInternal.
Helper class for Serialization.
General sparsity class.
Definition: sparsity.hpp:106
Weak reference type.
std::vector< std::string > nlpsol_in()
Get input scheme of NLP solvers.
Definition: nlpsol.cpp:279
std::vector< std::string > nlpsol_out()
Get NLP solver output scheme of NLP solvers.
Definition: nlpsol.cpp:285
double nlpsol_default_in(casadi_int ind)
Default input for an NLP solver.
Definition: nlpsol.cpp:291
The casadi namespace.
Definition: archiver.cpp:28
@ NLPSOL_NUM_IN
Definition: nlpsol.hpp:211
@ NLPSOL_NUM_OUT
Definition: nlpsol.hpp:228
GenericType::Dict Dict
C++ equivalent of Python's dict or MATLAB's struct.
Type
Variable type (FMI 3)
UnifiedReturnStatus
Integrator memory.
Definition: nlpsol_impl.hpp:40
UnifiedReturnStatus unified_return_status
Definition: nlpsol_impl.hpp:48
casadi_nlpsol_data< double > d_nlp
Definition: nlpsol_impl.hpp:42
Options metadata for a class.
Definition: options.hpp:40
Function memory.