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_;
102  std::vector<bool> discrete_;
103  std::vector<bool> equality_;
105 
106  // Mixed integer problem?
107  bool mi_;
108 
110  mutable WeakRef kkt_;
111 
112 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
114  mutable std::mutex kkt_mtx_;
115 #endif // CASADI_WITH_THREADSAFE_SYMBOLICS
116 
120  void serialize_body(SerializingStream &s) const override;
124  void serialize_type(SerializingStream &s) const override;
125 
129  static ProtoFunction* deserialize(DeserializingStream& s);
130 
134  std::string serialize_base_function() const override { return "Nlpsol"; }
135 
137  Nlpsol(const std::string& name, const Function& oracle);
138 
140  ~Nlpsol() override = 0;
141 
143 
146  size_t get_n_in() override { return NLPSOL_NUM_IN;}
147  size_t get_n_out() override { return NLPSOL_NUM_OUT;}
149 
151 
154  Sparsity get_sparsity_in(casadi_int i) override;
155  Sparsity get_sparsity_out(casadi_int i) override;
157 
159 
162  std::string get_name_in(casadi_int i) override { return nlpsol_in(i);}
163  std::string get_name_out(casadi_int i) override { return nlpsol_out(i);}
165 
167 
170  static const Options options_;
171  const Options& get_options() const override { return options_;}
173 
177  void disp_more(std::ostream& stream) const override;
178 
180  void init(const Dict& opts) override;
181 
185  void* alloc_mem() const override { return new NlpsolMemory();}
186 
190  int init_mem(void* mem) const override;
191 
195  void free_mem(void *mem) const override { delete static_cast<NlpsolMemory*>(mem);}
196 
200  virtual void check_inputs(void* mem) const;
201 
205  double get_default_in(casadi_int ind) const override { return nlpsol_default_in(ind);}
206 
208  virtual bool integer_support() const { return false;}
209 
213  void set_work(void* mem, const double**& arg, double**& res,
214  casadi_int*& iw, double*& w) const override;
215 
216  // Evaluate numerically
217  int eval(const double** arg, double** res, casadi_int* iw, double* w, void* mem) const final;
218 
219  // Solve the NLP
220  virtual int solve(void* mem) const = 0;
221 
225  void codegen_declarations(CodeGenerator& g) const override;
226 
230  void codegen_body_enter(CodeGenerator& g) const override;
231 
235  void codegen_body_exit(CodeGenerator& g) const override;
236 
237  // Plugins that prefer to keep d_nlp/p_nlp/d_oracle storage on their own
238  // per-mem-block data struct (instead of letting codegen_body_enter emit
239  // them as per-call function-scope locals) skip codegen_body_enter and
240  // call these directly with their own lvalues. The default-prefix call
241  // chain through codegen_body_enter / codegen_body_exit is preserved
242  // byte-for-byte for plugins that don't opt in.
243  // codegen_setup_constants: emit p_nlp constants + d_nlp <-> p_nlp /
244  // d_oracle wiring. Runs once -- call from codegen_init_mem.
245  // codegen_setup_per_call: emit arg/res-dependent d_nlp wiring +
246  // casadi_nlpsol_init + copy_default's. Runs every call -- call
247  // from codegen_body.
248  // codegen_post_solve: emit nlp_grad post-solve + bound consistency +
249  // final NLPSOL_X/F/G/LAM_* fan-out. Per-call -- call from codegen_body.
250  void codegen_setup_constants(CodeGenerator& g,
251  const std::string& d_nlp, const std::string& p_nlp,
252  const std::string& d_oracle) const;
253  void codegen_setup_per_call(CodeGenerator& g, const std::string& d_nlp) const;
254  void codegen_post_solve(CodeGenerator& g, const std::string& d_nlp) const;
255 
259  bool uses_output() const override {return true;}
260 
262  Dict get_stats(void* mem) const override;
263 
265 
268  bool has_forward(casadi_int nfwd) const override { return true;}
269  Function get_forward(casadi_int nfwd, const std::string& name,
270  const std::vector<std::string>& inames,
271  const std::vector<std::string>& onames,
272  const Dict& opts) const override;
274 
276 
279  bool has_reverse(casadi_int nadj) const override { return true;}
280  Function get_reverse(casadi_int nadj, const std::string& name,
281  const std::vector<std::string>& inames,
282  const std::vector<std::string>& onames,
283  const Dict& opts) const override;
285 
286  // Call the callback function
287  int callback(NlpsolMemory* m) const;
288 
289  // Get KKT function
290  Function kkt() const;
291 
292  // Make sure primal-dual solution is consistent with bounds
293  static void bound_consistency(casadi_int n, double* z, double* lam,
294  const double* lbz, const double* ubz);
295 
296  // Creator function for internal class
297  typedef Nlpsol* (*Creator)(const std::string& name, const Function& oracle);
298 
299  // No static functions exposed
300  struct Exposed{ };
301 
303  static std::map<std::string, Plugin> solvers_;
304 
305 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
306  static std::mutex mutex_solvers_;
307 #endif // CASADI_WITH_THREADSAFE_SYMBOLICS
308 
310  static const std::string infix_;
311 
313  static std::string shortname() { return "nlpsol";}
314 
318  std::string class_name() const override {return "Nlpsol";}
319 
323  bool is_a(const std::string& type, bool recursive) const override;
324 
325  // Get reduced Hessian
326  virtual DM getReducedHessian();
327 
329  virtual void setOptionsFromFile(const std::string & file);
330 
332  template<typename Type> static void append_to_vec(GenericType& t, Type el) {
333  std::vector<Type> v = t;
334  v.push_back(el);
335  t = v;
336  }
337 
339  template<typename XType>
340  static Function create_oracle(const std::map<std::string, XType>& d,
341  const Dict& opts);
342 
343  protected:
347  explicit Nlpsol(DeserializingStream& s);
348  private:
349  void set_nlpsol_prob();
350  };
351 
352 } // namespace casadi
354 #endif // CASADI_NLPSOL_IMPL_HPP
Helper class for C code generation.
Helper class for Serialization.
Function object.
Definition: function.hpp:126
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.
bool sens_force_equality_
Options.
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:200
Weak reference type.
std::vector< std::string > nlpsol_in()
Get the input scheme of NLP solvers.
Definition: nlpsol.cpp:284
std::vector< std::string > nlpsol_out()
Get the output scheme of NLP solvers.
Definition: nlpsol.cpp:290
double nlpsol_default_in(casadi_int ind)
Default value of an NLP solver input.
Definition: nlpsol.cpp:296
The casadi namespace.
Definition: archiver.cpp:28
@ NLPSOL_NUM_IN
Definition: nlpsol.hpp:848
@ NLPSOL_NUM_OUT
Definition: nlpsol.hpp:867
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.