sx_function.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_SX_FUNCTION_HPP
27 #define CASADI_SX_FUNCTION_HPP
28 
29 #include "x_function.hpp"
30 
32 
33 namespace casadi {
37  struct ScalarAtomic {
38  int op;
39  int i0;
40  union {
41  double d;
42  struct { int i1, i2; };
43  };
44  };
45 
53 class CASADI_EXPORT SXFunction :
54  public XFunction<SXFunction, Matrix<SXElem>, SXNode>{
55  public:
59  SXFunction(const std::string& name,
60  const std::vector<Matrix<SXElem> >& inputv,
61  const std::vector<Matrix<SXElem> >& outputv,
62  const std::vector<std::string>& name_in,
63  const std::vector<std::string>& name_out);
64 
68  ~SXFunction() override;
69 
73  int eval(const double** arg, double** res, casadi_int* iw, double* w, void* mem) const override;
74 
78  int eval_sx(const SXElem** arg, SXElem** res,
79  casadi_int* iw, SXElem* w, void* mem) const override;
80 
82  bool should_inline(bool always_inline, bool never_inline) const override {
83  return true;
84  }
85 
89  void ad_forward(const std::vector<std::vector<SX> >& fseed,
90  std::vector<std::vector<SX> >& fsens) const;
91 
95  void ad_reverse(const std::vector<std::vector<SX> >& aseed,
96  std::vector<std::vector<SX> >& asens) const;
97 
101  bool is_smooth() const;
102 
106  void disp_more(std::ostream& stream) const override;
107 
111  std::string class_name() const override {return "SXFunction";}
112 
116  bool is_a(const std::string& type, bool recursive) const override;
117 
119 
122  const SX sx_in(casadi_int ind) const override;
123  const std::vector<SX> sx_in() const override;
125 
127  std::vector<SX> free_sx() const override {
128  std::vector<SX> ret(free_vars_.size());
129  std::copy(free_vars_.begin(), free_vars_.end(), ret.begin());
130  return ret;
131  }
132 
136  bool has_free() const override { return !free_vars_.empty();}
137 
141  std::vector<std::string> get_free() const override {
142  std::vector<std::string> ret;
143  for (auto&& e : free_vars_) ret.push_back(e.name());
144  return ret;
145  }
146 
150  SX hess(casadi_int iind=0, casadi_int oind=0);
151 
155  casadi_int n_instructions() const override { return algorithm_.size();}
156 
160  casadi_int instruction_id(casadi_int k) const override { return algorithm_.at(k).op;}
161 
165  std::vector<casadi_int> instruction_input(casadi_int k) const override {
166  auto e = algorithm_.at(k);
167  if (casadi_math<double>::ndeps(e.op)==2 || e.op==OP_INPUT) {
168  return {e.i1, e.i2};
169  } else if (casadi_math<double>::ndeps(e.op)==1) {
170  return {e.i1};
171  } else {
172  return {};
173  }
174  }
175 
179  double instruction_constant(casadi_int k) const override {
180  return algorithm_.at(k).d;
181  }
182 
186  std::vector<casadi_int> instruction_output(casadi_int k) const override {
187  auto e = algorithm_.at(k);
188  if (e.op==OP_OUTPUT) {
189  return {e.i0, e.i2};
190  } else {
191  return {e.i0};
192  }
193  }
194 
198  casadi_int n_nodes() const override { return algorithm_.size() - nnz_out();}
199 
207  typedef ScalarAtomic AlgEl;
208 
212  template<typename T>
213  struct TapeEl {
214  T d[2];
215  };
216 
220  std::vector<AlgEl> algorithm_;
221 
222  // Work vector size
223  size_t worksize_;
224 
226  std::vector<SXElem> free_vars_;
227 
229  std::vector<SXElem> operations_;
230 
232  std::vector<SXElem> constants_;
233 
235  std::vector<double> default_in_;
236 
240  void serialize_body(SerializingStream &s) const override;
241 
245  static ProtoFunction* deserialize(DeserializingStream& s);
246 
248 
251  static const Options options_;
252  const Options& get_options() const override { return options_;}
254 
256  Dict generate_options(const std::string& target="clone") const override;
257 
261  void init(const Dict& opts) override;
262 
266  void codegen_declarations(CodeGenerator& g) const override;
267 
271  void codegen_body(CodeGenerator& g) const override;
272 
276  int sp_forward(const bvec_t** arg, bvec_t** res,
277  casadi_int* iw, bvec_t* w, void* mem) const override;
278 
282  int sp_reverse(bvec_t** arg, bvec_t** res, casadi_int* iw, bvec_t* w, void* mem) const override;
283 
287  SX instructions_sx() const override;
288 
292  double get_default_in(casadi_int ind) const override { return default_in_.at(ind);}
293 
297  void export_code_body(const std::string& lang,
298  std::ostream &stream, const Dict& options) const override;
299 
301  bool just_in_time_opencl_;
302 
304  bool just_in_time_sparsity_;
305 
307  bool live_variables_;
308 
309 protected:
313  explicit SXFunction(DeserializingStream& s);
314 };
315 
316 
317 } // namespace casadi
318 
320 #endif // CASADI_SX_FUNCTION_HPP
The casadi namespace.
Matrix< SXElem > SX
Definition: sx_fwd.hpp:32
GenericType::Dict Dict
C++ equivalent of Python's dict or MATLAB's struct.