function_internal.hpp
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  * 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_FUNCTION_INTERNAL_HPP
27 #define CASADI_FUNCTION_INTERNAL_HPP
28 
29 #include "function.hpp"
30 #include <set>
31 #include <stack>
32 #include "code_generator.hpp"
33 #include "importer.hpp"
34 #include "options.hpp"
35 #include "shared_object.hpp"
36 #include "timing.hpp"
37 #ifdef CASADI_WITH_THREAD
38 #ifdef CASADI_WITH_THREAD_MINGW
39 #include <mingw.mutex.h>
40 #else // CASADI_WITH_THREAD_MINGW
41 #include <mutex>
42 #endif // CASADI_WITH_THREAD_MINGW
43 #endif //CASADI_WITH_THREAD
44 
45 // This macro is for documentation purposes
46 #define INPUTSCHEME(name)
47 
48 // This macro is for documentation purposes
49 #define OUTPUTSCHEME(name)
50 
52 
53 namespace casadi {
54  template<typename T>
55  std::vector<std::pair<std::string, T>> zip(const std::vector<std::string>& id,
56  const std::vector<T>& mat) {
57  casadi_assert_dev(id.size()==mat.size());
58  std::vector<std::pair<std::string, T>> r(id.size());
59  for (casadi_uint i=0; i<r.size(); ++i) r[i] = std::make_pair(id[i], mat[i]);
60  return r;
61  }
62 
66  struct CASADI_EXPORT ProtoFunctionMemory {
67  // Function specific statistics
68  std::map<std::string, FStats> fstats;
69 
70  // Short-hand for "total" fstats
72 
73  // Add a statistic
74  void add_stat(const std::string& s) {
75  bool added = fstats.insert(std::make_pair(s, FStats())).second;
76  casadi_assert(added, "Duplicate stat: '" + s + "'");
77  }
78  };
79 
83  struct CASADI_EXPORT FunctionMemory : public ProtoFunctionMemory {
85  // Shared sequence number for input, output and instruction dumps.
86  casadi_int dump_id;
87  FunctionMemory() : stats_available(false), dump_id(-1) {}
88  };
89 
96  class CASADI_EXPORT ProtoFunction : public SharedObjectInternal {
97  public:
101  ProtoFunction(const std::string& name);
102 
106  ~ProtoFunction() override = 0;
107 
113  void construct(const Dict& opts);
114 
116 
119  static const Options options_;
120  virtual const Options& get_options() const { return options_;}
122 
124  virtual Dict generate_options(const std::string& target) const;
125 
129  void print_options(std::ostream &stream) const;
130 
134  void print_option(const std::string &name, std::ostream &stream) const;
135 
139  bool has_option(const std::string &option_name) const;
140 
144  virtual void change_option(const std::string& option_name, const GenericType& option_value);
145 
154  virtual void init(const Dict& opts);
155 
162  virtual void finalize();
163 
165  int checkout() const;
166 
168  void release(int mem) const;
169 
171  void* memory(int ind) const;
172 
174  bool has_memory(int ind) const;
175 
181  virtual void check_mem_count(casadi_int n) const { }
182 
186  virtual void* alloc_mem() const { return new ProtoFunctionMemory(); }
187 
191  virtual int init_mem(void* mem) const;
192 
196  virtual void free_mem(void *mem) const { delete static_cast<ProtoFunctionMemory*>(mem); }
197 
199  virtual Dict get_stats(void* mem) const;
200 
204  void clear_mem();
205 
209  void print(const char* fmt, ...) const;
210 
214  void sprint(char* buf, size_t buf_sz, const char* fmt, ...) const;
215 
219  void format_time(char* buffer, double time) const;
220 
224  void print_time(const std::map<std::string, FStats>& fstats) const;
225 
229  void serialize(SerializingStream &s) const;
230 
234  virtual void serialize_body(SerializingStream &s) const;
238  virtual void serialize_type(SerializingStream &s) const {}
239 
243  virtual std::string serialize_base_function() const {
244  return class_name();
245  }
246 
248  std::string name_;
249 
251  bool verbose_;
252 
253  // Print timing statistics
255 
256  // Print timing statistics
258 
261 
264 
265  protected:
269  explicit ProtoFunction(DeserializingStream& s);
270 
271 #ifdef CASADI_WITH_THREAD
273  mutable std::mutex mtx_;
274 #endif // CASADI_WITH_THREAD
275 
276  private:
278  mutable std::vector<void*> mem_;
279 
281  mutable std::stack<int> unused_;
282  };
283 
290  class CASADI_EXPORT FunctionInternal : public ProtoFunction {
291  friend class Function;
292  public:
296  FunctionInternal(const std::string& name);
297 
301  ~FunctionInternal() override = 0;
302 
306  virtual std::string getAdaptorSolverName() const { return ""; }
307 
309 
312  static const Options options_;
313  const Options& get_options() const override { return options_;}
315 
317  Dict generate_options(const std::string& target) const override;
318 
322  void change_option(const std::string& option_name, const GenericType& option_value) override;
323 
327  void reset_dump_count();
328 
332  void init(const Dict& opts) override;
333 
337  void finalize() override;
338 
342  void* alloc_mem() const override { return new FunctionMemory(); }
343 
347  void free_mem(void *mem) const override { delete static_cast<FunctionMemory*>(mem); }
348 
350  Dict get_stats(void* mem) const override;
351 
355  Function self() const { return shared_from_this<Function>();}
356 
357  // Factory
358  virtual Function factory(const std::string& name,
359  const std::vector<std::string>& s_in,
360  const std::vector<std::string>& s_out,
361  const Function::AuxOut& aux,
362  const Dict& opts) const;
363 
364  // Get list of dependency functions
365  virtual std::vector<std::string> get_function() const;
366 
367  // Get a dependency function
368  virtual const Function& get_function(const std::string &name) const;
369 
370  // Check if a particular dependency exists
371  virtual bool has_function(const std::string& fname) const;
372 
373  // Add embedded function to map, helper function
374  void add_embedded(std::map<FunctionInternal*, std::pair<Function, size_t> >& all_fun,
375  const Function& dep, casadi_int max_depth) const;
376 
377  // Get all embedded functions, recursively
378  virtual void find(std::map<FunctionInternal*, std::pair<Function, size_t> >& all_fun,
379  casadi_int max_depth) const;
380 
389  virtual std::vector<bool> which_depends(const std::string& s_in,
390  const std::vector<std::string>& s_out,
391  casadi_int order, bool tr=false) const;
392 
399  virtual Function simplify_passes(
400  const std::vector<std::pair<std::string, casadi_int> >& tasks) const;
401 
403 
406  virtual bool has_spfwd() const { return false;}
407  virtual bool has_sprev() const { return false;}
409 
411 
414  int eval_gen(const double** arg, double** res, casadi_int* iw, double* w, void* mem,
415  bool always_inline, bool never_inline) const;
416  virtual int eval(const double** arg, double** res, casadi_int* iw, double* w, void* mem) const;
417 
419 
423  virtual int eval_sx(const SXElem** arg, SXElem** res,
424  casadi_int* iw, SXElem* w, void* mem, bool always_inline, bool never_inline) const;
425 
429  virtual void eval_mx(const MXVector& arg, MXVector& res,
430  bool always_inline, bool never_inline) const;
431 
433 
436  virtual std::vector<DM> eval_dm(const std::vector<DM>& arg) const;
437  virtual bool has_eval_dm() const { return false;}
439 
441 
444  int eval_gen(const SXElem** arg, SXElem** res, casadi_int* iw, SXElem* w, void* mem,
445  bool always_inline, bool never_inline) const {
446  return eval_sx(arg, res, iw, w, mem, always_inline, never_inline);
447  }
448  int eval_gen(const bvec_t** arg, bvec_t** res, casadi_int* iw, bvec_t* w, void* mem,
449  bool always_inline, bool never_inline) const {
450  return sp_forward(arg, res, iw, w, mem);
451  }
453 
455 
458  void call_gen(const MXVector& arg, MXVector& res, casadi_int npar,
459  bool always_inline, bool never_inline) const;
460 
461  template<typename D>
462  void call_gen(const std::vector<Matrix<D> >& arg, std::vector<Matrix<D> >& res,
463  casadi_int npar, bool always_inline, bool never_inline) const;
465 
469  template<typename M>
470  void call(const std::vector<M>& arg, std::vector<M>& res,
471  bool always_inline, bool never_inline) const;
472 
474 
479  static bool check_mat(const Sparsity& arg, const Sparsity& inp, casadi_int& npar);
481 
483 
491  template<typename M>
492  void check_arg(const std::vector<M>& arg, casadi_int& npar) const;
494 
496 
504  template<typename M>
505  void check_res(const std::vector<M>& res, casadi_int& npar) const;
507 
516  template<typename M> bool
517  matching_arg(const std::vector<M>& arg, casadi_int& npar) const;
518 
527  template<typename M> bool
528  matching_res(const std::vector<M>& arg, casadi_int& npar) const;
529 
533  template<typename M> std::vector<M>
534  replace_arg(const std::vector<M>& arg, casadi_int npar) const;
535 
539  template<typename M> std::vector<M>
540  project_arg(const std::vector<M>& arg, casadi_int npar) const;
541 
545  template<typename M> std::vector<M>
546  project_res(const std::vector<M>& arg, casadi_int npar) const;
547 
551  template<typename M> std::vector<M>
552  replace_res(const std::vector<M>& res, casadi_int npar) const;
553 
557  template<typename M> std::vector<std::vector<M>>
558  replace_fseed(const std::vector<std::vector<M>>& fseed, casadi_int npar) const;
559 
563  template<typename M> std::vector<std::vector<M>>
564  replace_aseed(const std::vector<std::vector<M>>& aseed, casadi_int npar) const;
565 
570  template<typename M>
571  std::map<std::string, M> convert_arg(const std::vector<M>& arg) const;
572  template<typename M>
573  std::vector<M> convert_arg(const std::map<std::string, M>& arg) const;
574  template<typename M>
575  std::map<std::string, M> convert_res(const std::vector<M>& res) const;
576  template<typename M>
577  std::vector<M> convert_res(const std::map<std::string, M>& res) const;
579 
584  std::vector<double> nz_in(const std::vector<DM>& arg) const;
585  std::vector<double> nz_out(const std::vector<DM>& res) const;
586  std::vector<DM> nz_in(const std::vector<double>& arg) const;
587  std::vector<DM> nz_out(const std::vector<double>& res) const;
589 
591 
594  virtual void call_forward(const std::vector<MX>& arg, const std::vector<MX>& res,
595  const std::vector<std::vector<MX> >& fseed,
596  std::vector<std::vector<MX> >& fsens,
597  bool always_inline, bool never_inline) const;
598  virtual void call_forward(const std::vector<SX>& arg, const std::vector<SX>& res,
599  const std::vector<std::vector<SX> >& fseed,
600  std::vector<std::vector<SX> >& fsens,
601  bool always_inline, bool never_inline) const;
603 
605 
608  virtual void call_reverse(const std::vector<MX>& arg, const std::vector<MX>& res,
609  const std::vector<std::vector<MX> >& aseed,
610  std::vector<std::vector<MX> >& asens,
611  bool always_inline, bool never_inline) const;
612  virtual void call_reverse(const std::vector<SX>& arg, const std::vector<SX>& res,
613  const std::vector<std::vector<SX> >& aseed,
614  std::vector<std::vector<SX> >& asens,
615  bool always_inline, bool never_inline) const;
617 
621  std::vector<MX> mapsum_mx(const std::vector<MX > &arg, const std::string& parallelization);
622 
626  virtual bool uses_output() const {return false;}
627 
629 
632  Function jacobian() const;
633  virtual bool has_jacobian() const { return false;}
634  virtual Function get_jacobian(const std::string& name,
635  const std::vector<std::string>& inames,
636  const std::vector<std::string>& onames,
637  const Dict& opts) const;
639 
641 
645  Sparsity& jac_sparsity(casadi_int oind, casadi_int iind, bool compact, bool symmetric) const;
646  virtual bool has_jac_sparsity(casadi_int oind, casadi_int iind) const { return false;}
647  virtual Sparsity get_jac_sparsity(casadi_int oind, casadi_int iind, bool symmetric) const;
649 
651  static std::string forward_name(const std::string& fcn, casadi_int nfwd) {
652  return "fwd" + str(nfwd) + "_" + fcn;
653  }
654 
656  std::string diff_prefix(const std::string& prefix) const;
657 
659 
666  Function forward(casadi_int nfwd) const;
667  virtual bool has_forward(casadi_int nfwd) const { return false;}
668  virtual Function get_forward(casadi_int nfwd, const std::string& name,
669  const std::vector<std::string>& inames,
670  const std::vector<std::string>& onames,
671  const Dict& opts) const;
673 
675  static std::string reverse_name(const std::string& fcn, casadi_int nadj) {
676  return "adj" + str(nadj) + "_" + fcn;
677  }
678 
680 
687  Function reverse(casadi_int nadj) const;
688  virtual bool has_reverse(casadi_int nadj) const { return false;}
689  virtual Function get_reverse(casadi_int nadj, const std::string& name,
690  const std::vector<std::string>& inames,
691  const std::vector<std::string>& onames,
692  const Dict& opts) const;
694 
698  template<typename MatType>
699  static MatType ensure_stacked(const MatType& v, const Sparsity& sp, casadi_int n);
700 
704  virtual Function slice(const std::string& name, const std::vector<casadi_int>& order_in,
705  const std::vector<casadi_int>& order_out, const Dict& opts) const;
706 
710  virtual const Function& oracle() const;
711 
715  bool has_derivative() const;
716 
720  virtual double ad_weight() const;
721 
727  virtual double sp_weight() const;
728 
730 
733  virtual const SX sx_in(casadi_int ind) const;
734  virtual const SX sx_out(casadi_int ind) const;
735  virtual const std::vector<SX> sx_in() const;
736  virtual const std::vector<SX> sx_out() const;
737  virtual const MX mx_in(casadi_int ind) const;
738  virtual const MX mx_out(casadi_int ind) const;
739  virtual const std::vector<MX> mx_in() const;
740  virtual const std::vector<MX> mx_out() const;
741  const DM dm_in(casadi_int ind) const;
742  const DM dm_out(casadi_int ind) const;
743  const std::vector<DM> dm_in() const;
744  const std::vector<DM> dm_out() const;
746 
748  virtual std::vector<MX> free_mx() const;
749 
751  virtual std::vector<SX> free_sx() const;
752 
756  virtual bool has_free() const { return false;}
757 
761  virtual void generate_lifted(Function& vdef_fcn, Function& vinit_fcn) const;
762 
766  virtual casadi_int n_instructions() const;
767 
771  virtual casadi_int instruction_id(casadi_int k) const;
772 
776  virtual std::vector<casadi_int> instruction_input(casadi_int k) const;
777 
781  virtual double instruction_constant(casadi_int k) const;
782 
786  virtual std::vector<casadi_int> instruction_output(casadi_int k) const;
787 
791  virtual casadi_int n_nodes() const;
792 
796  virtual MX instruction_MX(casadi_int k) const;
797 
801  virtual SX instructions_sx() const;
802 
807  Function wrap(const std::string& name) const;
808  Function wrap() const;
810 
815  Function wrap_as_needed(const std::string& name, const Dict& opts) const;
816  Function wrap_as_needed(const Dict& opts) const;
818 
822  Dict cache() const;
823 
827  bool incache(const std::string& fname, Function& f, const std::string& suffix="") const;
828 
832  void tocache(const Function& f, const std::string& suffix="") const;
833 
834 
838  void tocache_if_missing(Function& f, const std::string& suffix="") const;
839 
843  void codegen(CodeGenerator& g, const std::string& fname) const;
844 
848  void codegen_meta(CodeGenerator& g) const;
849 
853  void codegen_sparsities(CodeGenerator& g) const;
854 
858  virtual std::string codegen_name(const CodeGenerator& g, bool ns=true) const;
859 
863  std::string codegen_mem(CodeGenerator& g, const std::string& index="mem") const;
864 
868  virtual void codegen_incref(CodeGenerator& g) const;
869 
873  virtual void codegen_decref(CodeGenerator& g) const;
874 
878  virtual void codegen_alloc_mem(CodeGenerator& g) const;
879 
883  virtual void codegen_init_mem(CodeGenerator& g) const;
884 
888  virtual void codegen_free_mem(CodeGenerator& g) const {}
889 
893  virtual void codegen_checkout(CodeGenerator& g) const;
894 
898  virtual void codegen_release(CodeGenerator& g) const;
899 
903  std::string signature(const std::string& fname) const;
904 
908  std::string signature_unrolled(const std::string& fname) const;
909 
913  virtual void codegen_declarations(CodeGenerator& g) const;
914 
918  virtual void codegen_body(CodeGenerator& g) const;
919 
923  virtual std::string codegen_mem_type() const { return ""; }
924 
928  virtual bool codegen_needs_mem() const { return false; }
929 
935  virtual bool codegen_mem_is_opaque() const { return false; }
936 
940  virtual std::string generate_dependencies(const std::string& fname, const Dict& opts) const;
941 
945  virtual bool has_codegen() const { return false;}
946 
950  virtual void jit_dependencies(const std::string& fname) {}
951 
955  static std::string get_jit_directory(const Dict& jit_options);
956 
960  virtual void export_code(const std::string& lang,
961  std::ostream &stream, const Dict& options) const;
962 
966  void serialize_type(SerializingStream &s) const override;
967 
971  void serialize_body(SerializingStream &s) const override;
972 
976  void disp(std::ostream& stream, bool more) const override;
977 
981  virtual void disp_more(std::ostream& stream) const {}
982 
986  std::string definition() const;
987 
991  void print_dimensions(std::ostream &stream) const;
992 
996  virtual std::vector<std::string> get_free() const;
997 
1001  void get_partition(casadi_int iind, casadi_int oind, Sparsity& D1, Sparsity& D2,
1002  bool compact, bool symmetric,
1003  bool allow_forward, bool allow_reverse) const;
1004 
1006 
1009  casadi_int nnz_in() const;
1010  casadi_int nnz_in(casadi_int ind) const { return sparsity_in(ind).nnz(); }
1011  casadi_int nnz_out() const;
1012  casadi_int nnz_out(casadi_int ind) const { return sparsity_out(ind).nnz(); }
1014 
1016 
1019  casadi_int numel_in() const;
1020  casadi_int numel_in(casadi_int ind) const { return sparsity_in(ind).numel(); }
1021  casadi_int numel_out(casadi_int ind) const { return sparsity_out(ind).numel(); }
1022  casadi_int numel_out() const;
1024 
1026 
1029  casadi_int size1_in(casadi_int ind) const { return sparsity_in(ind).size1(); }
1030  casadi_int size2_in(casadi_int ind) const { return sparsity_in(ind).size2(); }
1031  casadi_int size1_out(casadi_int ind) const { return sparsity_out(ind).size1(); }
1032  casadi_int size2_out(casadi_int ind) const { return sparsity_out(ind).size2(); }
1033  std::pair<casadi_int, casadi_int> size_in(casadi_int ind) const {
1034  return sparsity_in(ind).size();
1035  }
1036  std::pair<casadi_int, casadi_int> size_out(casadi_int ind) const {
1037  return sparsity_out(ind).size();
1038  }
1040 
1042 
1045  const Sparsity& sparsity_in(casadi_int ind) const { return sparsity_in_.at(ind); }
1046  const Sparsity& sparsity_out(casadi_int ind) const { return sparsity_out_.at(ind); }
1048 
1050 
1053  bool all_scalar() const;
1054 
1056  virtual bool jac_is_symm(casadi_int oind, casadi_int iind) const;
1057 
1059  Sparsity to_compact(casadi_int oind, casadi_int iind, const Sparsity& sp) const;
1060 
1062  Sparsity from_compact(casadi_int oind, casadi_int iind, const Sparsity& sp) const;
1063 
1065  template<bool fwd>
1066  Sparsity get_jac_sparsity_gen(casadi_int oind, casadi_int iind) const;
1067 
1069  Sparsity get_jac_sparsity_hierarchical(casadi_int oind, casadi_int iind) const;
1070 
1074  Sparsity get_jac_sparsity_hierarchical_symm(casadi_int oind, casadi_int iind) const;
1075 
1077  virtual std::vector<MX> symbolic_output(const std::vector<MX>& arg) const;
1078 
1080 
1083  virtual size_t get_n_in();
1084  virtual size_t get_n_out();
1086 
1087 
1089 
1092  virtual std::string get_name_in(casadi_int i);
1093  virtual std::string get_name_out(casadi_int i);
1095 
1099  virtual double get_default_in(casadi_int ind) const {
1100  return 0;
1101  }
1102 
1106  virtual double get_max_in(casadi_int ind) const {
1107  return inf;
1108  }
1109 
1113  virtual double get_min_in(casadi_int ind) const {
1114  return -inf;
1115  }
1116 
1117  virtual std::vector<double> get_nominal_in(casadi_int ind) const {
1118  return std::vector<double>(nnz_in(ind), 1.);
1119  }
1120 
1121  virtual std::vector<double> get_nominal_out(casadi_int ind) const {
1122  return std::vector<double>(nnz_out(ind), 1.);
1123  }
1124 
1128  virtual double get_reltol() const {
1129  return eps;
1130  }
1131 
1135  virtual double get_abstol() const {
1136  return eps;
1137  }
1138 
1142  virtual Sparsity get_sparsity_in(casadi_int i);
1143 
1147  virtual Sparsity get_sparsity_out(casadi_int i);
1148 
1152  virtual bool get_diff_in(casadi_int i) { return true; }
1153 
1157  virtual bool get_diff_out(casadi_int i) { return true; }
1158 
1162  casadi_int index_in(const std::string &name) const {
1163  for (casadi_int i=0; i<name_in_.size(); ++i) {
1164  if (name_in_[i]==name) return i;
1165  }
1166  casadi_error("FunctionInternal::index_in: could not find entry \""
1167  + name + "\". Available names are: " + str(name_in_) + ".");
1168  return -1;
1169  }
1170 
1174  casadi_int index_out(const std::string &name) const {
1175  for (casadi_int i=0; i<name_out_.size(); ++i) {
1176  if (name_out_[i]==name) return i;
1177  }
1178  casadi_error("FunctionInternal::index_out: could not find entry \""
1179  + name + "\". Available names are: " + str(name_out_) + ".");
1180  return -1;
1181  }
1182 
1186  virtual int sp_forward(const bvec_t** arg, bvec_t** res,
1187  casadi_int* iw, bvec_t* w, void* mem) const;
1188 
1196  virtual int eval_activity(const bvec_t** arg, bvec_t** res,
1197  casadi_int* iw, bvec_t* w, void* mem) const;
1198 
1202  virtual int sp_forward_block(const bvec_t** arg, bvec_t** res,
1203  casadi_int* iw, bvec_t* w, void* mem, casadi_int oind, casadi_int iind) const;
1204 
1208  virtual int sp_reverse(bvec_t** arg, bvec_t** res, casadi_int* iw, bvec_t* w, void* mem) const;
1209 
1213  void sz_work(size_t& sz_arg, size_t& sz_res, size_t& sz_iw, size_t& sz_w) const;
1214 
1218  size_t sz_arg() const { return sz_arg_per_ + sz_arg_tmp_;}
1219 
1223  size_t sz_res() const { return sz_res_per_ + sz_res_tmp_;}
1224 
1228  size_t sz_iw() const { return sz_iw_per_ + sz_iw_tmp_;}
1229 
1233  size_t sz_w() const { return sz_w_per_ + sz_w_tmp_;}
1234 
1239  virtual size_t codegen_sz_arg(const CodeGenerator& g) const;
1240  virtual size_t codegen_sz_res(const CodeGenerator& g) const;
1241  virtual size_t codegen_sz_iw(const CodeGenerator& g) const;
1242  virtual size_t codegen_sz_w(const CodeGenerator& g) const;
1244 
1248  void alloc_arg(size_t sz_arg, bool persistent=false);
1249 
1253  void alloc_res(size_t sz_res, bool persistent=false);
1254 
1258  void alloc_iw(size_t sz_iw, bool persistent=false);
1259 
1263  void alloc_w(size_t sz_w, bool persistent=false);
1264 
1268  void alloc(const Function& f, bool persistent=false, int num_threads=1);
1269 
1273  virtual void set_work(void* mem, const double**& arg, double**& res,
1274  casadi_int*& iw, double*& w) const {}
1275 
1279  virtual void set_temp(void* mem, const double** arg, double** res,
1280  casadi_int* iw, double* w) const {}
1281 
1285  void setup(void* mem, const double** arg, double** res, casadi_int* iw, double* w) const;
1286 
1288 
1291  virtual bool fwdViaJac(casadi_int nfwd) const;
1292  virtual bool adjViaJac(casadi_int nadj) const;
1294 
1296  virtual Dict info() const;
1297 
1301  Function map(casadi_int n, const std::string& parallelization) const;
1302 
1306  void generate_in(const std::string& fname, const double** arg) const;
1307  void generate_out(const std::string& fname, double** res) const;
1308 
1309  bool always_inline_, never_inline_;
1310 
1312  size_t n_in_, n_out_;
1313 
1315  std::vector<bool> is_diff_in_, is_diff_out_;
1316 
1318  std::vector<Sparsity> sparsity_in_, sparsity_out_;
1319 
1321  std::vector<std::string> name_in_, name_out_;
1322 
1326  bool jit_;
1327 
1332 
1336  std::string jit_serialize_;
1337 
1341  std::string jit_name_;
1342  std::string jit_directory_;
1343  std::string jit_base_name_;
1344 
1349 
1354 
1359 
1364 
1368  signal_t incref_, decref_;
1369 
1374 
1379 
1384 
1389 
1392 
1394  mutable std::vector<Sparsity> jac_sparsity_[2];
1395 
1396 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
1398  mutable std::mutex jac_sparsity_mtx_;
1399 #endif // CASADI_WITH_THREADSAFE_SYMBOLICS
1400 
1403 
1405  void* user_data_;
1406 
1408  std::string compiler_plugin_;
1411 
1414 
1417 
1418  // Types of derivative calculation permitted
1419  bool enable_forward_, enable_reverse_, enable_jacobian_, enable_fd_;
1420  bool enable_forward_op_, enable_reverse_op_, enable_jacobian_op_, enable_fd_op_;
1421 
1423  double ad_weight_, ad_weight_sp_;
1424 
1426  casadi_int max_num_dir_;
1427 
1430 
1431  // Finite difference step
1433 
1434  // Finite difference step size
1435  double fd_step_;
1436 
1437  // Finite difference method
1438  std::string fd_method_;
1439 
1440  // Print input/output
1443 
1444  // Print canonical form
1446 
1447  // Warn when number of inputs or outputs exceed this value
1448  casadi_int max_io_;
1449 
1450  // Dump input/output
1451  bool dump_in_, dump_out_, dump_;
1452 
1453  // Directory to dump to
1454  std::string dump_dir_;
1455 
1456  // Format to dump with
1457  std::string dump_format_;
1458 
1459  // Forward/reverse/Jacobian options
1460  Dict forward_options_, reverse_options_, jacobian_options_, der_options_;
1461 
1462  // Store a reference to a custom Jacobian
1464 
1465  // Registered functions
1466  std::vector<Function> registered_functions_;
1467 
1468  // Counter for unique names for dumping inputs and output
1469 #ifdef CASADI_WITH_THREAD
1470  mutable std::atomic<casadi_int> dump_count_;
1471 #else
1472  mutable casadi_int dump_count_;
1473 #endif // CASADI_WITH_THREAD
1474 
1478  virtual bool is_a(const std::string& type, bool recursive) const;
1479 
1483  virtual void merge(const std::vector<MX>& arg,
1484  std::vector<MX>& subs_from, std::vector<MX>& subs_to) const;
1485 
1489  template<typename MatType>
1490  static bool purgable(const std::vector<MatType>& seed);
1491 
1495  template<typename MatType>
1496  std::vector<std::vector<MatType> >
1497  fwd_seed(casadi_int nfwd) const;
1498 
1502  template<typename MatType>
1503  std::vector<std::vector<MatType> >
1504  symbolicAdjSeed(casadi_int nadj, const std::vector<MatType>& v) const;
1505 
1506  static std::string string_from_UnifiedReturnStatus(UnifiedReturnStatus status);
1507 
1512 
1516  static Function deserialize(DeserializingStream& s);
1517  static std::map<std::string, ProtoFunction* (*)(DeserializingStream&)> deserialize_map;
1518 
1522  void print_in(std::ostream &stream, const double** arg, bool truncate) const;
1523 
1527  void print_out(std::ostream &stream, double** res, bool truncate) const;
1528 
1532  static void print_canonical(std::ostream &stream, const Sparsity& sp, const double* nz);
1533 
1537  static void print_canonical(std::ostream &stream, casadi_int sz, const double* nz);
1538 
1542  static void print_canonical(std::ostream &stream, double a);
1543 
1544  protected:
1548  void set_jac_sparsity(casadi_int oind, casadi_int iind, const Sparsity& sp);
1549 
1550  std::unique_ptr<std::ostream> open_trace(const double** arg, casadi_int dump_id) const;
1551  void finish_trace(std::ostream& trace, double** res, int ret) const;
1552  static void trace_values(std::ostream& trace, const double* values, casadi_int nnz);
1553 
1554  private:
1555  // @{
1557  casadi_int get_dump_id() const;
1558  void dump_in(casadi_int id, const double** arg) const;
1559  void dump_out(casadi_int id, double** res) const;
1560  void dump() const;
1561  // @}
1562 
1566  size_t sz_arg_per_, sz_res_per_, sz_iw_per_, sz_w_per_;
1567 
1571  size_t sz_arg_tmp_, sz_res_tmp_, sz_iw_tmp_, sz_w_tmp_;
1572  };
1573 
1574  // Template implementations
1575  template<typename MatType>
1576  bool FunctionInternal::purgable(const std::vector<MatType>& v) {
1577  for (auto i=v.begin(); i!=v.end(); ++i) {
1578  if (!i->is_zero()) return false;
1579  }
1580  return true;
1581  }
1582 
1583  template<typename MatType>
1584  std::vector<std::vector<MatType> >
1586  fwd_seed(casadi_int nfwd) const {
1587  std::vector<std::vector<MatType>> fseed(nfwd);
1588  for (casadi_int dir=0; dir<nfwd; ++dir) {
1589  fseed[dir].resize(n_in_);
1590  for (casadi_int iind=0; iind<n_in_; ++iind) {
1591  std::string n = "f" + str(dir) + "_" + name_in_[iind];
1592  Sparsity sp = is_diff_in_[iind] ? sparsity_in(iind) : Sparsity(size_in(iind));
1593  fseed[dir][iind] = MatType::sym(n, sp);
1594  }
1595  }
1596  return fseed;
1597  }
1598 
1599  template<typename MatType>
1600  std::vector<std::vector<MatType> >
1602  symbolicAdjSeed(casadi_int nadj, const std::vector<MatType>& v) const {
1603  std::vector<std::vector<MatType> > aseed(nadj, v);
1604  for (casadi_int dir=0; dir<nadj; ++dir) {
1605  // Replace symbolic inputs
1606  casadi_int oind=0;
1607  for (typename std::vector<MatType>::iterator i=aseed[dir].begin();
1608  i!=aseed[dir].end();
1609  ++i, ++oind) {
1610  // Name of the adjoint seed
1611  std::stringstream ss;
1612  ss << "a";
1613  if (nadj>1) ss << dir << "_";
1614  ss << oind;
1615 
1616  // Save to matrix
1617  *i = MatType::sym(ss.str(), is_diff_out_[oind] ? i->sparsity() : Sparsity(i->size()));
1618 
1619  }
1620  }
1621  return aseed;
1622  }
1623 
1624  template<typename M>
1625  void FunctionInternal::call(const std::vector<M>& arg, std::vector<M>& res,
1626  bool always_inline, bool never_inline) const {
1627  // If all inputs are scalar ...
1628  if (all_scalar()) {
1629  // ... and some arguments are matrix-valued with matching dimensions ...
1630  bool matrix_call = false;
1631  std::pair<casadi_int, casadi_int> sz;
1632  for (auto&& a : arg) {
1633  if (!a.is_scalar() && !a.is_empty()) {
1634  if (!matrix_call) {
1635  // Matrix call
1636  matrix_call = true;
1637  sz = a.size();
1638  } else if (a.size()!=sz) {
1639  // Not same dimensions
1640  matrix_call = false;
1641  break;
1642  }
1643  }
1644  }
1645 
1646  // ... then, call multiple times
1647  if (matrix_call) {
1648  // Start with zeros
1649  res.resize(n_out_);
1650  M z = M::zeros(sz);
1651  for (auto&& a : res) a = z;
1652  // Call multiple times
1653  std::vector<M> arg1 = arg, res1;
1654  for (casadi_int c=0; c<sz.second; ++c) {
1655  for (casadi_int r=0; r<sz.first; ++r) {
1656  // Get scalar arguments
1657  for (casadi_int i=0; i<arg.size(); ++i) {
1658  if (arg[i].size()==sz) arg1[i] = arg[i](r, c);
1659  }
1660  // Call recursively with scalar arguments
1661  call(arg1, res1, always_inline, never_inline);
1662  // Get results
1663  casadi_assert_dev(res.size() == res1.size());
1664  for (casadi_int i=0; i<res.size(); ++i) res[i](r, c) = res1[i];
1665  }
1666  }
1667  // All elements assigned
1668  return;
1669  }
1670  }
1671 
1672  // Check if inputs need to be replaced
1673  casadi_int npar = 1;
1674  if (!matching_arg(arg, npar)) {
1675  return call(replace_arg(arg, npar), res, always_inline, never_inline);
1676  }
1677 
1678  // Call the type-specific method
1679  call_gen(arg, res, npar, always_inline, never_inline);
1680  }
1681 
1682  template<typename M>
1683  std::vector<M> FunctionInternal::
1684  project_arg(const std::vector<M>& arg, casadi_int npar) const {
1685  casadi_assert_dev(arg.size()==n_in_);
1686 
1687  // Which arguments require mapped evaluation
1688  std::vector<bool> mapped(n_in_);
1689  for (casadi_int i=0; i<n_in_; ++i) {
1690  mapped[i] = arg[i].size2()!=size2_in(i);
1691  }
1692 
1693  // Check if matching input sparsity
1694  std::vector<bool> matching(n_in_);
1695  bool any_mismatch = false;
1696  for (casadi_int i=0; i<n_in_; ++i) {
1697  if (mapped[i]) {
1698  matching[i] = arg[i].sparsity().is_stacked(sparsity_in(i), npar);
1699  } else {
1700  matching[i] = arg[i].sparsity()==sparsity_in(i);
1701  }
1702  any_mismatch = any_mismatch || !matching[i];
1703  }
1704 
1705  // Correct input sparsity
1706  if (any_mismatch) {
1707  std::vector<M> arg2(arg);
1708  for (casadi_int i=0; i<n_in_; ++i) {
1709  if (!matching[i]) {
1710  if (mapped[i]) {
1711  arg2[i] = project(arg2[i], repmat(sparsity_in(i), 1, npar));
1712  } else {
1713  arg2[i] = project(arg2[i], sparsity_in(i));
1714  }
1715  }
1716  }
1717  return arg2;
1718  }
1719  return arg;
1720  }
1721 
1722  template<typename M>
1723  std::vector<M> FunctionInternal::
1724  project_res(const std::vector<M>& arg, casadi_int npar) const {
1725  return arg;
1726  }
1727 
1728  template<typename D>
1730  call_gen(const std::vector<Matrix<D> >& arg, std::vector<Matrix<D> >& res,
1731  casadi_int npar, bool always_inline, bool never_inline) const {
1732  std::vector< Matrix<D> > arg2 = project_arg(arg, npar);
1733 
1734  // Which arguments require mapped evaluation
1735  std::vector<bool> mapped(n_in_);
1736  for (casadi_int i=0; i<n_in_; ++i) {
1737  mapped[i] = arg[i].size2()!=size2_in(i);
1738  }
1739 
1740  // Allocate results
1741  res.resize(n_out_);
1742  for (casadi_int i=0; i<n_out_; ++i) {
1743  if (!res[i].sparsity().is_stacked(sparsity_out(i), npar)) {
1744  res[i] = Matrix<D>::zeros(repmat(sparsity_out(i), 1, npar));
1745  }
1746  }
1747 
1748  // Allocate temporary memory if needed
1749  std::vector<casadi_int> iw_tmp(sz_iw());
1750  std::vector<D> w_tmp(sz_w());
1751 
1752  // Get pointers to input arguments
1753  std::vector<const D*> argp(sz_arg());
1754  for (casadi_int i=0; i<n_in_; ++i) argp[i]=get_ptr(arg2[i]);
1755 
1756  // Get pointers to output arguments
1757  std::vector<D*> resp(sz_res());
1758  for (casadi_int i=0; i<n_out_; ++i) resp[i]=get_ptr(res[i]);
1759 
1760  // For all parallel calls
1761  for (casadi_int p=0; p<npar; ++p) {
1762  // Call memory-less
1763  if (eval_gen(get_ptr(argp), get_ptr(resp),
1764  get_ptr(iw_tmp), get_ptr(w_tmp), memory(0),
1765  always_inline, never_inline)) {
1766  if (error_on_fail_) casadi_error("Evaluation failed");
1767  }
1768  // Update offsets
1769  if (p==npar-1) break;
1770  for (casadi_int i=0; i<n_in_; ++i) if (mapped[i]) argp[i] += nnz_in(i);
1771  for (casadi_int i=0; i<n_out_; ++i) resp[i] += nnz_out(i);
1772  }
1773  }
1774 
1775  template<typename M>
1776  void FunctionInternal::check_arg(const std::vector<M>& arg, casadi_int& npar) const {
1777  casadi_assert(arg.size()==n_in_, "Incorrect number of inputs: Expected "
1778  + str(n_in_) + ", got " + str(arg.size()));
1779  for (casadi_int i=0; i<n_in_; ++i) {
1780  if (!check_mat(arg[i].sparsity(), sparsity_in(i), npar)) {
1781  // Dimensions
1782  std::string d_arg = str(arg[i].size1()) + "-by-" + str(arg[i].size2());
1783  std::string d_in = str(size1_in(i)) + "-by-" + str(size2_in(i));
1784  std::string e = "Input " + str(i) + " (" + name_in_[i] + ") has mismatching shape. "
1785  "Got " + d_arg + ". Allowed dimensions, in general, are:\n"
1786  " - The input dimension N-by-M (here " + d_in + ")\n"
1787  " - A scalar, i.e. 1-by-1\n"
1788  " - M-by-N if N=1 or M=1 (i.e. a transposed vector)\n"
1789  " - N-by-M1 if K*M1=M for some K (argument repeated horizontally)\n";
1790  if (npar!=-1) {
1791  e += " - N-by-P*M, indicating evaluation with multiple arguments (P must be a "
1792  "multiple of " + str(npar) + " for consistency with previous inputs)";
1793  }
1794  casadi_error(e);
1795  }
1796  }
1797  }
1798 
1799  template<typename M>
1800  void FunctionInternal::check_res(const std::vector<M>& res, casadi_int& npar) const {
1801  casadi_assert(res.size()==n_out_, "Incorrect number of outputs: Expected "
1802  + str(n_out_) + ", got " + str(res.size()));
1803  for (casadi_int i=0; i<n_out_; ++i) {
1804  casadi_assert(check_mat(res[i].sparsity(), sparsity_out(i), npar),
1805  "Output " + str(i) + " (" + name_out_[i] + ") has mismatching shape. "
1806  "Expected " + str(size_out(i)) + ", got " + str(res[i].size()));
1807  }
1808  }
1809 
1810  template<typename M>
1811  bool FunctionInternal::matching_arg(const std::vector<M>& arg, casadi_int& npar) const {
1812  check_arg(arg, npar);
1813  for (casadi_int i=0; i<n_in_; ++i) {
1814  if (arg.at(i).size1()!=size1_in(i)) return false;
1815  if (arg.at(i).size2()!=size2_in(i) && arg.at(i).size2()!=npar*size2_in(i)) return false;
1816  }
1817  return true;
1818  }
1819 
1820  template<typename M>
1821  bool FunctionInternal::matching_res(const std::vector<M>& res, casadi_int& npar) const {
1822  check_res(res, npar);
1823  for (casadi_int i=0; i<n_out_; ++i) {
1824  if (res.at(i).size1()!=size1_out(i)) return false;
1825  if (res.at(i).size2()!=size2_out(i) && res.at(i).size2()!=npar*size2_out(i)) return false;
1826  }
1827  return true;
1828  }
1829 
1830  template<typename M>
1831  M replace_mat(const M& arg, const Sparsity& inp, casadi_int npar) {
1832  if (arg.size()==inp.size()) {
1833  // Matching dimensions already
1834  return arg;
1835  } else if (arg.is_scalar()) {
1836  // Scalar assign means set all
1837  return M(inp, arg);
1838  } else if (arg.is_vector() && inp.size()==std::make_pair(arg.size2(), arg.size1())) {
1839  // Transpose vector
1840  return arg.T();
1841  } else if (arg.size1()==inp.size1() && arg.size2()>0 && inp.size2()>0
1842  && inp.size2()%arg.size2()==0) {
1843  // Horizontal repmat
1844  return repmat(arg, 1, inp.size2()/arg.size2());
1845  } else if (npar!=-1 && arg.size1()==inp.size1() && arg.size2()>0 && inp.size2()>0
1846  && (npar*inp.size2())%arg.size2()==0) {
1847  // Multiple evaluation: grow argument horizontally to npar*inp columns
1848  return repmat(arg, 1, (npar*inp.size2())/arg.size2());
1849  } else {
1850  // Empty matrix means set zero (kept last so a 0-by-N argument is first given the
1851  // chance to be recognised as a parallel/repmat call above)
1852  casadi_assert_dev(arg.is_empty());
1853  return M(inp.size());
1854  }
1855  }
1856 
1857  template<typename M>
1858  std::vector<M> FunctionInternal::
1859  replace_arg(const std::vector<M>& arg, casadi_int npar) const {
1860  std::vector<M> r(arg.size());
1861  for (casadi_int i=0; i<r.size(); ++i) r[i] = replace_mat(arg[i], sparsity_in(i), npar);
1862  return r;
1863  }
1864 
1865  template<typename M>
1866  std::vector<M> FunctionInternal::
1867  replace_res(const std::vector<M>& res, casadi_int npar) const {
1868  std::vector<M> r(res.size());
1869  for (casadi_int i=0; i<r.size(); ++i) r[i] = replace_mat(res[i], sparsity_out(i), npar);
1870  return r;
1871  }
1872 
1873  template<typename M>
1874  std::vector<std::vector<M> > FunctionInternal::
1875  replace_fseed(const std::vector<std::vector<M> >& fseed, casadi_int npar) const {
1876  std::vector<std::vector<M> > r(fseed.size());
1877  for (casadi_int d=0; d<r.size(); ++d) r[d] = replace_arg(fseed[d], npar);
1878  return r;
1879  }
1880 
1881  template<typename M>
1882  std::vector<std::vector<M> > FunctionInternal::
1883  replace_aseed(const std::vector<std::vector<M> >& aseed, casadi_int npar) const {
1884  std::vector<std::vector<M> > r(aseed.size());
1885  for (casadi_int d=0; d<r.size(); ++d) r[d] = replace_res(aseed[d], npar);
1886  return r;
1887  }
1888 
1889  template<typename M>
1890  std::map<std::string, M> FunctionInternal::
1891  convert_arg(const std::vector<M>& arg) const {
1892  casadi_assert(arg.size()==n_in_, "Incorrect number of inputs: Expected "
1893  + str(n_in_) + ", got " + str(arg.size()));
1894  std::map<std::string, M> ret;
1895  for (casadi_int i=0;i<n_in_;++i) {
1896  ret[name_in_[i]] = arg[i];
1897  }
1898  return ret;
1899  }
1900 
1901  template<typename M>
1902  std::vector<M> FunctionInternal::
1903  convert_arg(const std::map<std::string, M>& arg) const {
1904  // Get default inputs
1905  std::vector<M> arg_v(n_in_);
1906  for (casadi_int i=0; i<arg_v.size(); ++i) {
1907  arg_v[i] = get_default_in(i);
1908  }
1909 
1910  // Assign provided inputs
1911  for (auto&& e : arg) {
1912  arg_v.at(index_in(e.first)) = e.second;
1913  }
1914 
1915  return arg_v;
1916  }
1917 
1918  template<typename M>
1919  std::map<std::string, M> FunctionInternal::
1920  convert_res(const std::vector<M>& res) const {
1921  casadi_assert(res.size()==n_out_, "Incorrect number of outputs: Expected "
1922  + str(n_out_) + ", got " + str(res.size()));
1923  std::map<std::string, M> ret;
1924  for (casadi_int i=0;i<n_out_;++i) {
1925  ret[name_out_[i]] = res[i];
1926  }
1927  return ret;
1928  }
1929 
1930  template<typename M>
1931  std::vector<M> FunctionInternal::
1932  convert_res(const std::map<std::string, M>& res) const {
1933  // Get default inputs
1934  std::vector<M> res_v(n_out_);
1935  for (casadi_int i=0; i<res_v.size(); ++i) {
1936  res_v[i] = std::numeric_limits<double>::quiet_NaN();
1937  }
1938 
1939  // Assign provided inputs
1940  for (auto&& e : res) {
1941  M a = e.second;
1942  res_v.at(index_out(e.first)) = a;
1943  }
1944  return res_v;
1945  }
1946 
1947  template<typename MatType>
1948  MatType FunctionInternal::ensure_stacked(const MatType& v, const Sparsity& sp, casadi_int n) {
1949  // Check dimensions
1950  if (v.size1() == sp.size1() && v.size2() == n * sp.size2()) {
1951  // Ensure that sparsity is a horizontal multiple of original input, or has no entries
1952  if (v.nnz() != 0 && !v.sparsity().is_stacked(sp, n)) {
1953  return project(v, repmat(sp, 1, n));
1954  }
1955  } else {
1956  // Correct empty sparsity
1957  casadi_assert_dev(v.is_empty());
1958  return MatType(sp.size1(), sp.size2() * n);
1959  }
1960  // No correction needed
1961  return v;
1962  }
1963 
1964 } // namespace casadi
1965 
1967 
1968 #endif // CASADI_FUNCTION_INTERNAL_HPP
Helper class for C code generation.
Helper class for Serialization.
Internal class for Function.
bool has_refcount_
Reference counting in codegen?
casadi_int size1_in(casadi_int ind) const
Input/output dimensions.
virtual std::string codegen_mem_type() const
Thread-local memory object type.
std::string jit_serialize_
Serialize behaviour.
std::vector< M > project_arg(const std::vector< M > &arg, casadi_int npar) const
Project sparsities.
virtual bool has_sprev() const
Is the class able to propagate seeds through the algorithm?
casadi_int nnz_out(casadi_int ind) const
Number of input/output nonzeros.
double jac_penalty_
Penalty factor for using a complete Jacobian to calculate directional derivatives.
void call_gen(const MXVector &arg, MXVector &res, casadi_int npar, bool always_inline, bool never_inline) const
Call a function, overloaded.
std::vector< Sparsity > sparsity_in_
Input and output sparsity.
virtual bool has_forward(casadi_int nfwd) const
Return function that calculates forward derivatives.
static std::string forward_name(const std::string &fcn, casadi_int nfwd)
Helper function: Get name of forward derivative function.
virtual void jit_dependencies(const std::string &fname)
Jit dependencies.
void check_arg(const std::vector< M > &arg, casadi_int &npar) const
Check if input arguments have correct length and dimensions.
std::vector< std::vector< M > > replace_fseed(const std::vector< std::vector< M >> &fseed, casadi_int npar) const
Replace 0-by-0 forward seeds.
std::vector< bool > is_diff_out_
std::vector< std::vector< MatType > > fwd_seed(casadi_int nfwd) const
Symbolic expressions for the forward seeds.
virtual bool codegen_mem_is_opaque() const
Is thread-local memory object managed by checkout/release.
std::string jit_name_
Name if jit source file.
int eval_gen(const SXElem **arg, SXElem **res, casadi_int *iw, SXElem *w, void *mem, bool always_inline, bool never_inline) const
Evaluate a function, overloaded.
virtual void codegen_free_mem(CodeGenerator &g) const
Codegen for free_mem.
std::string compiler_plugin_
Just-in-time compiler.
casadi_release_t release_
Release redirected to a C function.
std::pair< casadi_int, casadi_int > size_in(casadi_int ind) const
Input/output dimensions.
virtual bool has_eval_dm() const
Evaluate with DM matrices.
virtual std::vector< double > get_nominal_out(casadi_int ind) const
const Options & get_options() const override
Options.
const Sparsity & sparsity_in(casadi_int ind) const
Input/output sparsity.
void * user_data_
User-set field.
std::vector< M > replace_arg(const std::vector< M > &arg, casadi_int npar) const
Replace 0-by-0 inputs.
virtual bool has_jac_sparsity(casadi_int oind, casadi_int iind) const
Get Jacobian sparsity.
int eval_gen(const bvec_t **arg, bvec_t **res, casadi_int *iw, bvec_t *w, void *mem, bool always_inline, bool never_inline) const
Evaluate a function, overloaded.
virtual void set_work(void *mem, const double **&arg, double **&res, casadi_int *&iw, double *&w) const
Set the (persistent) work vectors.
Dict codegen_options_
Options of the code generator of jit.
static std::map< std::string, ProtoFunction *(*)(DeserializingStream &)> deserialize_map
std::vector< std::vector< MatType > > symbolicAdjSeed(casadi_int nadj, const std::vector< MatType > &v) const
Symbolic expressions for the adjoint seeds.
double ad_weight_
Weighting factor for derivative calculation and sparsity pattern calculation.
virtual bool has_jacobian() const
Return Jacobian of all input elements with respect to all output elements.
std::vector< Function > registered_functions_
bool inputs_check_
Errors are thrown if numerical values of inputs look bad.
casadi_int nnz_in(casadi_int ind) const
Number of input/output nonzeros.
bool jit_
Use just-in-time compiler.
casadi_int index_out(const std::string &name) const
Get output scheme index by name.
virtual double get_min_in(casadi_int ind) const
Get smallest input value.
eval_t eval_
Numerical evaluation redirected to a C function.
bool has_refcount_in_deps_
Reference counting in dependent functions.
casadi_int numel_out(casadi_int ind) const
Number of input/output elements.
virtual std::string getAdaptorSolverName() const
Obtain solver name from Adaptor.
void * alloc_mem() const override
Create memory block.
virtual bool uses_output() const
Do the derivative functions need nondifferentiated outputs?
size_t n_in_
Number of inputs and outputs.
std::map< std::string, M > convert_res(const std::vector< M > &res) const
Convert from/to input/output lists/map.
size_t sz_res() const
Get required length of res field.
casadi_int size2_out(casadi_int ind) const
Input/output dimensions.
virtual void set_temp(void *mem, const double **arg, double **res, casadi_int *iw, double *w) const
Set the (temporary) work vectors.
bool matching_arg(const std::vector< M > &arg, casadi_int &npar) const
Check if input arguments that needs to be replaced.
std::vector< M > project_res(const std::vector< M > &arg, casadi_int npar) const
Project sparsities.
casadi_int size1_out(casadi_int ind) const
Input/output dimensions.
std::pair< casadi_int, casadi_int > size_out(casadi_int ind) const
Input/output dimensions.
WeakCache< std::string, Function > cache_
Function cache.
casadi_checkout_t checkout_
Checkout redirected to a C function.
casadi_int nnz_in() const
Number of input/output nonzeros.
virtual void disp_more(std::ostream &stream) const
Print more.
static const Options options_
Options.
casadi_int numel_in(casadi_int ind) const
Number of input/output elements.
std::vector< M > replace_res(const std::vector< M > &res, casadi_int npar) const
Replace 0-by-0 outputs.
virtual bool get_diff_in(casadi_int i)
Which inputs are differentiable.
bool jit_temp_suffix_
Use a temporary name.
casadi_int max_num_dir_
Maximum number of sensitivity directions.
virtual std::vector< double > get_nominal_in(casadi_int ind) const
void call(const std::vector< M > &arg, std::vector< M > &res, bool always_inline, bool never_inline) const
Call a function, templated.
const Sparsity & sparsity_out(casadi_int ind) const
Input/output sparsity.
bool matching_res(const std::vector< M > &arg, casadi_int &npar) const
Check if output arguments that needs to be replaced.
casadi_int index_in(const std::string &name) const
Get input scheme index by name.
size_t sz_w() const
Get required length of w field.
bool jit_cleanup_
Cleanup jit source file.
virtual bool codegen_needs_mem() const
Is thread-local memory object needed?
static MatType ensure_stacked(const MatType &v, const Sparsity &sp, casadi_int n)
Ensure that a matrix's sparsity is a horizontal multiple of another, or empty.
Dict stats_
Dict of statistics (resulting from evaluate)
int eval_gen(const double **arg, double **res, casadi_int *iw, double *w, void *mem, bool always_inline, bool never_inline) const
Evaluate numerically.
bool all_scalar() const
Are all inputs and outputs scalar.
casadi_int nnz_out() const
Number of input/output nonzeros.
size_t sz_arg() const
Get required length of arg field.
virtual double get_abstol() const
Get absolute tolerance.
virtual bool has_codegen() const
Is codegen supported?
static bool check_mat(const Sparsity &arg, const Sparsity &inp, casadi_int &npar)
void check_res(const std::vector< M > &res, casadi_int &npar) const
Check if output arguments have correct length and dimensions.
virtual bool has_free() const
Does the function have free variables.
virtual bool has_reverse(casadi_int nadj) const
Return function that calculates adjoint derivatives.
std::map< std::string, M > convert_arg(const std::vector< M > &arg) const
Convert from/to input/output lists/map.
virtual double get_reltol() const
Get relative tolerance.
std::vector< bool > is_diff_in_
Are inputs and outputs differentiable?
size_t sz_iw() const
Get required length of iw field.
static bool purgable(const std::vector< MatType > &seed)
Can a derivative direction be skipped.
Dict cache_init_
Values to prepopulate the function cache with.
void free_mem(void *mem) const override
Free memory block.
std::vector< std::string > name_out_
virtual bool get_diff_out(casadi_int i)
Which outputs are differentiable.
Function derivative_of_
If the function is the derivative of another function.
virtual bool has_spfwd() const
Is the class able to propagate seeds through the algorithm?
static std::string reverse_name(const std::string &fcn, casadi_int nadj)
Helper function: Get name of adjoint derivative function.
std::vector< std::vector< M > > replace_aseed(const std::vector< std::vector< M >> &aseed, casadi_int npar) const
Replace 0-by-0 reverse seeds.
casadi_int size2_in(casadi_int ind) const
Input/output dimensions.
virtual double get_default_in(casadi_int ind) const
Get default input value.
std::vector< std::string > name_in_
Input and output scheme.
virtual double get_max_in(casadi_int ind) const
Get largest input value.
Function object.
Definition: function.hpp:126
std::map< std::string, std::vector< std::string > > AuxOut
Definition: function.hpp:1546
static Matrix< Scalar > zeros(casadi_int nrow=1, casadi_int ncol=1)
Create a dense matrix or a matrix with specified sparsity with all entries zero.
Generic data type, can hold different types such as bool, casadi_int, std::string etc.
Importer.
Definition: importer.hpp:86
MX - Matrix expression.
Definition: mx.hpp:145
Sparse matrix class. SX and DM are specializations.
Base class for FunctionInternal and LinsolInternal.
bool error_on_fail_
Throw an exception on failure?
virtual void serialize_type(SerializingStream &s) const
Serialize type information.
virtual void * alloc_mem() const
Create memory block.
virtual const Options & get_options() const
Options.
bool regularity_check_
Errors are thrown when NaN is produced.
virtual void free_mem(void *mem) const
Free memory block.
void * memory(int ind) const
Memory objects.
bool verbose_
Verbose printout.
virtual std::string serialize_base_function() const
String used to identify the immediate FunctionInternal subclass.
virtual void check_mem_count(casadi_int n) const
Check for validatity of memory object count.
static const Options options_
Options.
The basic scalar symbolic class of CasADi.
Definition: sx_elem.hpp:75
Helper class for Serialization.
General sparsity class.
Definition: sparsity.hpp:200
casadi_int size1() const
Number of rows.
Definition: sparsity.cpp:124
casadi_int size2() const
Number of columns.
Definition: sparsity.cpp:128
std::pair< casadi_int, casadi_int > size() const
Shape as a pair (number of rows, number of columns)
Definition: sparsity.cpp:154
The casadi namespace.
Definition: archiver.cpp:28
const double eps
Machine epsilon.
Definition: calculus.hpp:56
unsigned long long bvec_t
int(* casadi_checkout_t)(void)
Function pointer types for the C API.
std::vector< std::pair< std::string, T > > zip(const std::vector< std::string > &id, const std::vector< T > &mat)
M replace_mat(const M &arg, const Sparsity &inp, casadi_int npar)
std::vector< casadi_int > find(const std::vector< T > &v)
find nonzeros
int(* eval_t)(const double **arg, double **res, casadi_int *iw, double *w, int)
Function pointer types for the C API.
std::vector< MX > MXVector
Definition: mx.hpp:5148
std::string str(const T &v)
String representation, any type.
GenericType::Dict Dict
C++ equivalent of Python's dict or MATLAB's struct.
const double inf
infinity
Definition: calculus.hpp:50
void(* casadi_release_t)(int)
Function pointer types for the C API.
void(* signal_t)(void)
Function pointer types for the C API.
T * get_ptr(std::vector< T > &v)
Get a pointer to the data contained in the vector.
std::vector< T > reverse(const std::vector< T > &v)
Reverse a list.
UnifiedReturnStatus
Function memory with temporary work vectors.
Options metadata for a class.
Definition: options.hpp:40
Function memory with temporary work vectors.
std::map< std::string, FStats > fstats
void add_stat(const std::string &s)