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_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 34 /// \cond INTERNAL 35 namespace casadi { 36 37 /** \brief Integrator memory */ 38 struct CASADI_EXPORT NlpsolMemory : public OracleMemory { 39 // Problem data structure 40 casadi_nlpsol_data<double> d_nlp; 41 // number of iterations 42 casadi_int n_iter; 43 // Success? 44 bool success; 45 // Return status 46 FunctionInternal::UnifiedReturnStatus unified_return_status; 47 }; 48 49 /** \brief NLP solver storage class 50 51 @copydoc Nlpsol_doc 52 \author Joel Andersson 53 \date 2010-2013 54 */ 55 class CASADI_EXPORT 56 Nlpsol : public OracleFunction, public PluginInterface<Nlpsol> { 57 public: 58 59 // Memory structure 60 casadi_nlpsol_prob<double> p_nlp_; 61 62 /// Number of variables 63 casadi_int nx_; 64 65 /// Number of constraints 66 casadi_int ng_; 67 68 /// Number of parameters 69 casadi_int np_; 70 71 /// callback function, executed at each iteration 72 Function fcallback_; 73 74 /// Execute the callback function only after this amount of iterations 75 casadi_int callback_step_; 76 77 /// Throw an exception on failure? 78 bool error_on_fail_; 79 80 /// Linear solver and options 81 std::string sens_linsol_; 82 Dict sens_linsol_options_; 83 84 ///@{ 85 /** \brief Options */ 86 bool eval_errors_fatal_; 87 bool warn_initial_bounds_; 88 bool iteration_callback_ignore_errors_; 89 bool calc_multipliers_; 90 bool calc_lam_x_, calc_lam_p_, calc_f_, calc_g_; 91 bool bound_consistency_; 92 double min_lam_; 93 bool no_nlp_grad_; 94 std::vector<bool> discrete_; 95 ///@} 96 97 // Mixed integer problem? 98 bool mi_; 99 100 /// Cache for KKT function 101 mutable WeakRef kkt_; 102 103 /** \brief Serialize an object without type information */ 104 void serialize_body(SerializingStream &s) const override; 105 /** \brief Serialize type information */ 106 void serialize_type(SerializingStream &s) const override; 107 108 /** \brief Deserialize into MX */ 109 static ProtoFunction* deserialize(DeserializingStream& s); 110 111 /** \brief String used to identify the immediate FunctionInternal subclass */ serialize_base_function() const112 std::string serialize_base_function() const override { return "Nlpsol"; } 113 114 /// Constructor 115 Nlpsol(const std::string& name, const Function& oracle); 116 117 /// Destructor 118 ~Nlpsol() override = 0; 119 120 ///@{ 121 /** \brief Number of function inputs and outputs */ get_n_in()122 size_t get_n_in() override { return NLPSOL_NUM_IN;} get_n_out()123 size_t get_n_out() override { return NLPSOL_NUM_OUT;} 124 ///@} 125 126 /// @{ 127 /** \brief Sparsities of function inputs and outputs */ 128 Sparsity get_sparsity_in(casadi_int i) override; 129 Sparsity get_sparsity_out(casadi_int i) override; 130 /// @} 131 132 ///@{ 133 /** \brief Names of function input and outputs */ get_name_in(casadi_int i)134 std::string get_name_in(casadi_int i) override { return nlpsol_in(i);} get_name_out(casadi_int i)135 std::string get_name_out(casadi_int i) override { return nlpsol_out(i);} 136 /// @} 137 138 ///@{ 139 /** \brief Options */ 140 static const Options options_; get_options() const141 const Options& get_options() const override { return options_;} 142 ///@} 143 144 /** \brief Print description */ 145 void disp_more(std::ostream& stream) const override; 146 147 /// Initialize 148 void init(const Dict& opts) override; 149 150 /** \brief Create memory block */ alloc_mem() const151 void* alloc_mem() const override { return new NlpsolMemory();} 152 153 /** \brief Initalize memory block */ 154 int init_mem(void* mem) const override; 155 156 /** \brief Free memory block */ free_mem(void * mem) const157 void free_mem(void *mem) const override { delete static_cast<NlpsolMemory*>(mem);} 158 159 /** \brief Check if the inputs correspond to a well-posed problem */ 160 virtual void check_inputs(void* mem) const; 161 162 /** \brief Get default input value */ get_default_in(casadi_int ind) const163 double get_default_in(casadi_int ind) const override { return nlpsol_default_in(ind);} 164 165 /// Can discrete variables be treated integer_support() const166 virtual bool integer_support() const { return false;} 167 168 /** \brief Set the (persistent) work vectors */ 169 void set_work(void* mem, const double**& arg, double**& res, 170 casadi_int*& iw, double*& w) const override; 171 172 // Evaluate numerically 173 int eval(const double** arg, double** res, casadi_int* iw, double* w, void* mem) const final; 174 175 // Solve the NLP 176 virtual int solve(void* mem) const = 0; 177 178 /** \brief Generate code for the function body */ 179 void nlpsol_codegen_body(CodeGenerator& g) const; 180 181 /** \brief Do the derivative functions need nondifferentiated outputs? */ uses_output() const182 bool uses_output() const override {return true;} 183 184 /// Get all statistics 185 Dict get_stats(void* mem) const override; 186 187 ///@{ 188 /** \brief Generate a function that calculates forward mode derivatives */ has_forward(casadi_int nfwd) const189 bool has_forward(casadi_int nfwd) const override { return true;} 190 Function get_forward(casadi_int nfwd, const std::string& name, 191 const std::vector<std::string>& inames, 192 const std::vector<std::string>& onames, 193 const Dict& opts) const override; 194 ///@} 195 196 ///@{ 197 /** \brief Generate a function that calculates reverse mode derivatives */ has_reverse(casadi_int nadj) const198 bool has_reverse(casadi_int nadj) const override { return true;} 199 Function get_reverse(casadi_int nadj, const std::string& name, 200 const std::vector<std::string>& inames, 201 const std::vector<std::string>& onames, 202 const Dict& opts) const override; 203 ///@} 204 205 // Call the callback function 206 int callback(NlpsolMemory* m) const; 207 208 // Get KKT function 209 Function kkt() const; 210 211 // Make sure primal-dual solution is consistent with bounds 212 static void bound_consistency(casadi_int n, double* z, double* lam, 213 const double* lbz, const double* ubz); 214 215 // Creator function for internal class 216 typedef Nlpsol* (*Creator)(const std::string& name, const Function& oracle); 217 218 // No static functions exposed 219 struct Exposed{ }; 220 221 /// Collection of solvers 222 static std::map<std::string, Plugin> solvers_; 223 224 /// Infix 225 static const std::string infix_; 226 227 /// Short name shortname()228 static std::string shortname() { return "nlpsol";} 229 230 /** \brief Get type name */ class_name() const231 std::string class_name() const override {return "Nlpsol";} 232 233 /** \brief Check if the function is of a particular type */ 234 bool is_a(const std::string& type, bool recursive) const override; 235 236 // Get reduced Hessian 237 virtual DM getReducedHessian(); 238 239 /// Read options from parameter xml 240 virtual void setOptionsFromFile(const std::string & file); 241 242 /// WORKAROUND: Add an element to an std::vector stored in a GenericType: append_to_vec(GenericType & t,Type el)243 template<typename Type> static void append_to_vec(GenericType& t, Type el) { 244 std::vector<Type> v = t; 245 v.push_back(el); 246 t = v; 247 } 248 249 /// Convert dictionary to Problem 250 template<typename XType> 251 static Function create_oracle(const std::map<std::string, XType>& d, 252 const Dict& opts); 253 254 protected: 255 /** \brief Deserializing constructor */ 256 explicit Nlpsol(DeserializingStream& s); 257 private: 258 void set_nlpsol_prob(); 259 }; 260 261 } // namespace casadi 262 /// \endcond 263 #endif // CASADI_NLPSOL_IMPL_HPP 264