26 #ifndef CASADI_FUNCTION_INTERNAL_HPP
27 #define CASADI_FUNCTION_INTERNAL_HPP
29 #include "function.hpp"
32 #include "code_generator.hpp"
33 #include "importer.hpp"
34 #include "options.hpp"
35 #include "shared_object.hpp"
37 #ifdef CASADI_WITH_THREAD
38 #ifdef CASADI_WITH_THREAD_MINGW
39 #include <mingw.mutex.h>
46 #define INPUTSCHEME(name)
49 #define OUTPUTSCHEME(name)
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]);
68 std::map<std::string, FStats>
fstats;
75 bool added = fstats.insert(std::make_pair(s,
FStats())).second;
76 casadi_assert(added,
"Duplicate stat: '" + s +
"'");
113 void construct(
const Dict& opts);
124 virtual Dict generate_options(
const std::string& target)
const;
129 void print_options(std::ostream &stream)
const;
134 void print_option(
const std::string &name, std::ostream &stream)
const;
139 bool has_option(
const std::string &option_name)
const;
144 virtual void change_option(
const std::string& option_name,
const GenericType& option_value);
154 virtual void init(
const Dict& opts);
162 virtual void finalize();
165 int checkout()
const;
168 void release(
int mem)
const;
171 void* memory(
int ind)
const;
174 bool has_memory(
int ind)
const;
191 virtual int init_mem(
void* mem)
const;
199 virtual Dict get_stats(
void* mem)
const;
209 void print(
const char* fmt, ...)
const;
214 void sprint(
char* buf,
size_t buf_sz,
const char* fmt, ...)
const;
219 void format_time(
char* buffer,
double time)
const;
224 void print_time(
const std::map<std::string, FStats>& fstats)
const;
271 #ifdef CASADI_WITH_THREAD
273 mutable std::mutex mtx_;
278 mutable std::vector<void*> mem_;
281 mutable std::stack<int> unused_;
317 Dict generate_options(
const std::string& target)
const override;
322 void change_option(
const std::string& option_name,
const GenericType& option_value)
override;
327 void reset_dump_count();
332 void init(
const Dict& opts)
override;
337 void finalize()
override;
350 Dict get_stats(
void* mem)
const override;
355 Function self()
const {
return shared_from_this<Function>();}
358 virtual Function factory(
const std::string& name,
359 const std::vector<std::string>& s_in,
360 const std::vector<std::string>& s_out,
362 const Dict& opts)
const;
365 virtual std::vector<std::string> get_function()
const;
368 virtual const Function& get_function(
const std::string &name)
const;
371 virtual bool has_function(
const std::string& fname)
const {
return false;}
374 void add_embedded(std::map<
FunctionInternal*, std::pair<Function, size_t> >& all_fun,
375 const Function& dep, casadi_int max_depth)
const;
379 casadi_int max_depth)
const;
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;
400 const std::vector<std::pair<std::string, casadi_int> >& tasks)
const;
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;
424 casadi_int* iw,
SXElem* w,
void* mem,
bool always_inline,
bool never_inline)
const;
430 bool always_inline,
bool never_inline)
const;
436 virtual std::vector<DM> eval_dm(
const std::vector<DM>& arg)
const;
445 bool always_inline,
bool never_inline)
const {
446 return eval_sx(arg, res, iw, w, mem, always_inline, never_inline);
449 bool always_inline,
bool never_inline)
const {
450 return sp_forward(arg, res, iw, w, mem);
459 bool always_inline,
bool never_inline)
const;
463 casadi_int npar,
bool always_inline,
bool never_inline)
const;
470 void call(
const std::vector<M>& arg, std::vector<M>& res,
471 bool always_inline,
bool never_inline)
const;
479 static bool check_mat(
const Sparsity& arg,
const Sparsity& inp, casadi_int& npar);
492 void check_arg(
const std::vector<M>& arg, casadi_int& npar)
const;
505 void check_res(
const std::vector<M>& res, casadi_int& npar)
const;
516 template<
typename M>
bool
517 matching_arg(
const std::vector<M>& arg, casadi_int& npar)
const;
527 template<
typename M>
bool
528 matching_res(
const std::vector<M>& arg, casadi_int& npar)
const;
533 template<
typename M> std::vector<M>
534 replace_arg(
const std::vector<M>& arg, casadi_int npar)
const;
539 template<
typename M> std::vector<M>
540 project_arg(
const std::vector<M>& arg, casadi_int npar)
const;
545 template<
typename M> std::vector<M>
546 project_res(
const std::vector<M>& arg, casadi_int npar)
const;
551 template<
typename M> std::vector<M>
552 replace_res(
const std::vector<M>& res, casadi_int npar)
const;
557 template<
typename M> std::vector<std::vector<M>>
558 replace_fseed(
const std::vector<std::vector<M>>& fseed, casadi_int npar)
const;
563 template<
typename M> std::vector<std::vector<M>>
564 replace_aseed(
const std::vector<std::vector<M>>& aseed, casadi_int npar)
const;
571 std::map<std::string, M> convert_arg(
const std::vector<M>& arg)
const;
573 std::vector<M> convert_arg(
const std::map<std::string, M>& arg)
const;
575 std::map<std::string, M> convert_res(
const std::vector<M>& res)
const;
577 std::vector<M> convert_res(
const std::map<std::string, M>& res)
const;
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;
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;
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;
621 std::vector<MX> mapsum_mx(
const std::vector<MX > &arg,
const std::string& parallelization);
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;
645 Sparsity& jac_sparsity(casadi_int oind, casadi_int iind,
bool compact,
bool symmetric)
const;
647 virtual Sparsity get_jac_sparsity(casadi_int oind, casadi_int iind,
bool symmetric)
const;
651 static std::string
forward_name(
const std::string& fcn, casadi_int nfwd) {
652 return "fwd" +
str(nfwd) +
"_" + fcn;
656 std::string diff_prefix(
const std::string& prefix)
const;
666 Function forward(casadi_int nfwd)
const;
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;
675 static std::string
reverse_name(
const std::string& fcn, casadi_int nadj) {
676 return "adj" +
str(nadj) +
"_" + fcn;
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;
698 template<
typename MatType>
699 static MatType ensure_stacked(
const MatType& v,
const Sparsity& sp, casadi_int n);
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;
710 virtual const Function& oracle()
const;
715 bool has_derivative()
const;
720 virtual double ad_weight()
const;
727 virtual double sp_weight()
const;
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;
748 virtual std::vector<MX> free_mx()
const;
751 virtual std::vector<SX> free_sx()
const;
761 virtual void generate_lifted(
Function& vdef_fcn,
Function& vinit_fcn)
const;
766 virtual casadi_int n_instructions()
const;
771 virtual casadi_int instruction_id(casadi_int k)
const;
776 virtual std::vector<casadi_int> instruction_input(casadi_int k)
const;
781 virtual double instruction_constant(casadi_int k)
const;
786 virtual std::vector<casadi_int> instruction_output(casadi_int k)
const;
791 virtual casadi_int n_nodes()
const;
796 virtual MX instruction_MX(casadi_int k)
const;
801 virtual SX instructions_sx()
const;
807 Function wrap(
const std::string& name)
const;
815 Function wrap_as_needed(
const std::string& name,
const Dict& opts)
const;
827 bool incache(
const std::string& fname,
Function& f,
const std::string& suffix=
"")
const;
832 void tocache(
const Function& f,
const std::string& suffix=
"")
const;
838 void tocache_if_missing(
Function& f,
const std::string& suffix=
"")
const;
843 void codegen(
CodeGenerator& g,
const std::string& fname)
const;
858 virtual std::string codegen_name(
const CodeGenerator& g,
bool ns=
true)
const;
863 std::string codegen_mem(
CodeGenerator& g,
const std::string& index=
"mem")
const;
903 std::string signature(
const std::string& fname)
const;
908 std::string signature_unrolled(
const std::string& fname)
const;
940 virtual std::string generate_dependencies(
const std::string& fname,
const Dict& opts)
const;
955 static std::string get_jit_directory(
const Dict& jit_options);
960 virtual void export_code(
const std::string& lang,
961 std::ostream &stream,
const Dict& options)
const;
976 void disp(std::ostream& stream,
bool more)
const override;
986 std::string definition()
const;
991 void print_dimensions(std::ostream &stream)
const;
996 virtual std::vector<std::string> get_free()
const;
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;
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(); }
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;
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();
1036 std::pair<casadi_int, casadi_int>
size_out(casadi_int ind)
const {
1037 return sparsity_out(ind).size();
1053 bool all_scalar()
const;
1056 virtual bool jac_is_symm(casadi_int oind, casadi_int iind)
const;
1059 Sparsity to_compact(casadi_int oind, casadi_int iind,
const Sparsity& sp)
const;
1062 Sparsity from_compact(casadi_int oind, casadi_int iind,
const Sparsity& sp)
const;
1066 Sparsity get_jac_sparsity_gen(casadi_int oind, casadi_int iind)
const;
1069 Sparsity get_jac_sparsity_hierarchical(casadi_int oind, casadi_int iind)
const;
1074 Sparsity get_jac_sparsity_hierarchical_symm(casadi_int oind, casadi_int iind)
const;
1077 virtual std::vector<MX> symbolic_output(
const std::vector<MX>& arg)
const;
1083 virtual size_t get_n_in();
1084 virtual size_t get_n_out();
1092 virtual std::string get_name_in(casadi_int i);
1093 virtual std::string get_name_out(casadi_int i);
1118 return std::vector<double>(nnz_in(ind), 1.);
1122 return std::vector<double>(nnz_out(ind), 1.);
1142 virtual Sparsity get_sparsity_in(casadi_int i);
1147 virtual Sparsity get_sparsity_out(casadi_int i);
1163 for (casadi_int i=0; i<name_in_.size(); ++i) {
1164 if (name_in_[i]==name)
return i;
1166 casadi_error(
"FunctionInternal::index_in: could not find entry \""
1167 + name +
"\". Available names are: " +
str(name_in_) +
".");
1175 for (casadi_int i=0; i<name_out_.size(); ++i) {
1176 if (name_out_[i]==name)
return i;
1178 casadi_error(
"FunctionInternal::index_out: could not find entry \""
1179 + name +
"\". Available names are: " +
str(name_out_) +
".");
1186 virtual int sp_forward(
const bvec_t** arg,
bvec_t** res,
1187 casadi_int* iw,
bvec_t* w,
void* mem)
const;
1196 virtual int eval_activity(
const bvec_t** arg,
bvec_t** res,
1197 casadi_int* iw,
bvec_t* w,
void* mem)
const;
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;
1208 virtual int sp_reverse(
bvec_t** arg,
bvec_t** res, casadi_int* iw,
bvec_t* w,
void* mem)
const;
1213 void sz_work(
size_t& sz_arg,
size_t& sz_res,
size_t& sz_iw,
size_t& sz_w)
const;
1218 size_t sz_arg()
const {
return sz_arg_per_ + sz_arg_tmp_;}
1223 size_t sz_res()
const {
return sz_res_per_ + sz_res_tmp_;}
1228 size_t sz_iw()
const {
return sz_iw_per_ + sz_iw_tmp_;}
1233 size_t sz_w()
const {
return sz_w_per_ + sz_w_tmp_;}
1239 virtual size_t codegen_sz_arg(
const CodeGenerator& g)
const;
1240 virtual size_t codegen_sz_res(
const CodeGenerator& g)
const;
1248 void alloc_arg(
size_t sz_arg,
bool persistent=
false);
1253 void alloc_res(
size_t sz_res,
bool persistent=
false);
1258 void alloc_iw(
size_t sz_iw,
bool persistent=
false);
1263 void alloc_w(
size_t sz_w,
bool persistent=
false);
1268 void alloc(
const Function& f,
bool persistent=
false,
int num_threads=1);
1273 virtual void set_work(
void* mem,
const double**& arg,
double**& res,
1274 casadi_int*& iw,
double*& w)
const {}
1279 virtual void set_temp(
void* mem,
const double** arg,
double** res,
1280 casadi_int* iw,
double* w)
const {}
1285 void setup(
void* mem,
const double** arg,
double** res, casadi_int* iw,
double* w)
const;
1291 virtual bool fwdViaJac(casadi_int nfwd)
const;
1292 virtual bool adjViaJac(casadi_int nadj)
const;
1296 virtual Dict info()
const;
1301 Function map(casadi_int n,
const std::string& parallelization)
const;
1306 void generate_in(
const std::string& fname,
const double** arg)
const;
1307 void generate_out(
const std::string& fname,
double** res)
const;
1394 mutable std::vector<Sparsity> jac_sparsity_[2];
1396 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
1398 mutable std::mutex jac_sparsity_mtx_;
1416 bool enable_forward_, enable_reverse_, enable_jacobian_,
enable_fd_;
1417 bool enable_forward_op_, enable_reverse_op_, enable_jacobian_op_,
enable_fd_op_;
1466 #ifdef CASADI_WITH_THREAD
1467 mutable std::atomic<casadi_int> dump_count_;
1475 virtual bool is_a(
const std::string& type,
bool recursive)
const;
1480 virtual void merge(
const std::vector<MX>& arg,
1481 std::vector<MX>& subs_from, std::vector<MX>& subs_to)
const;
1486 template<
typename MatType>
1487 static bool purgable(
const std::vector<MatType>& seed);
1492 template<
typename MatType>
1493 std::vector<std::vector<MatType> >
1494 fwd_seed(casadi_int nfwd)
const;
1499 template<
typename MatType>
1500 std::vector<std::vector<MatType> >
1501 symbolicAdjSeed(casadi_int nadj,
const std::vector<MatType>& v)
const;
1519 void print_in(std::ostream &stream,
const double** arg,
bool truncate)
const;
1524 void print_out(std::ostream &stream,
double** res,
bool truncate)
const;
1529 static void print_canonical(std::ostream &stream,
const Sparsity& sp,
const double* nz);
1534 static void print_canonical(std::ostream &stream, casadi_int sz,
const double* nz);
1539 static void print_canonical(std::ostream &stream,
double a);
1545 void set_jac_sparsity(casadi_int oind, casadi_int iind,
const Sparsity& sp);
1547 std::unique_ptr<std::ostream> open_trace(
const double** arg, casadi_int dump_id)
const;
1548 void finish_trace(std::ostream& trace,
double** res,
int ret)
const;
1549 static void trace_values(std::ostream& trace,
const double* values, casadi_int nnz);
1554 casadi_int get_dump_id()
const;
1555 void dump_in(casadi_int
id,
const double** arg)
const;
1556 void dump_out(casadi_int
id,
double** res)
const;
1563 size_t sz_arg_per_, sz_res_per_, sz_iw_per_, sz_w_per_;
1568 size_t sz_arg_tmp_, sz_res_tmp_, sz_iw_tmp_, sz_w_tmp_;
1572 template<
typename MatType>
1574 for (
auto i=v.begin(); i!=v.end(); ++i) {
1575 if (!i->is_zero())
return false;
1580 template<
typename MatType>
1581 std::vector<std::vector<MatType> >
1584 std::vector<std::vector<MatType>> fseed(nfwd);
1585 for (casadi_int dir=0; dir<nfwd; ++dir) {
1586 fseed[dir].resize(
n_in_);
1587 for (casadi_int iind=0; iind<
n_in_; ++iind) {
1588 std::string n =
"f" +
str(dir) +
"_" +
name_in_[iind];
1590 fseed[dir][iind] = MatType::sym(n, sp);
1596 template<
typename MatType>
1597 std::vector<std::vector<MatType> >
1599 symbolicAdjSeed(casadi_int nadj,
const std::vector<MatType>& v)
const {
1600 std::vector<std::vector<MatType> > aseed(nadj, v);
1601 for (casadi_int dir=0; dir<nadj; ++dir) {
1604 for (
typename std::vector<MatType>::iterator i=aseed[dir].begin();
1605 i!=aseed[dir].end();
1608 std::stringstream ss;
1610 if (nadj>1) ss << dir <<
"_";
1621 template<
typename M>
1623 bool always_inline,
bool never_inline)
const {
1627 bool matrix_call =
false;
1628 std::pair<casadi_int, casadi_int> sz;
1629 for (
auto&& a : arg) {
1630 if (!a.is_scalar() && !a.is_empty()) {
1635 }
else if (a.size()!=sz) {
1637 matrix_call =
false;
1648 for (
auto&& a : res) a = z;
1650 std::vector<M> arg1 = arg, res1;
1651 for (casadi_int c=0; c<sz.second; ++c) {
1652 for (casadi_int r=0; r<sz.first; ++r) {
1654 for (casadi_int i=0; i<arg.size(); ++i) {
1655 if (arg[i].size()==sz) arg1[i] = arg[i](r, c);
1658 call(arg1, res1, always_inline, never_inline);
1660 casadi_assert_dev(res.size() == res1.size());
1661 for (casadi_int i=0; i<res.size(); ++i) res[i](r, c) = res1[i];
1670 casadi_int npar = 1;
1672 return call(
replace_arg(arg, npar), res, always_inline, never_inline);
1676 call_gen(arg, res, npar, always_inline, never_inline);
1679 template<
typename M>
1681 project_arg(
const std::vector<M>& arg, casadi_int npar)
const {
1682 casadi_assert_dev(arg.size()==
n_in_);
1685 std::vector<bool> mapped(
n_in_);
1686 for (casadi_int i=0; i<
n_in_; ++i) {
1687 mapped[i] = arg[i].size2()!=
size2_in(i);
1691 std::vector<bool> matching(
n_in_);
1692 bool any_mismatch =
false;
1693 for (casadi_int i=0; i<
n_in_; ++i) {
1695 matching[i] = arg[i].sparsity().is_stacked(
sparsity_in(i), npar);
1699 any_mismatch = any_mismatch || !matching[i];
1704 std::vector<M> arg2(arg);
1705 for (casadi_int i=0; i<
n_in_; ++i) {
1708 arg2[i] = project(arg2[i], repmat(
sparsity_in(i), 1, npar));
1719 template<
typename M>
1721 project_res(
const std::vector<M>& arg, casadi_int npar)
const {
1725 template<
typename D>
1728 casadi_int npar,
bool always_inline,
bool never_inline)
const {
1729 std::vector< Matrix<D> > arg2 =
project_arg(arg, npar);
1732 std::vector<bool> mapped(
n_in_);
1733 for (casadi_int i=0; i<
n_in_; ++i) {
1734 mapped[i] = arg[i].size2()!=
size2_in(i);
1739 for (casadi_int i=0; i<
n_out_; ++i) {
1740 if (!res[i].sparsity().is_stacked(
sparsity_out(i), npar)) {
1746 std::vector<casadi_int> iw_tmp(
sz_iw());
1747 std::vector<D> w_tmp(
sz_w());
1750 std::vector<const D*> argp(
sz_arg());
1751 for (casadi_int i=0; i<
n_in_; ++i) argp[i]=
get_ptr(arg2[i]);
1754 std::vector<D*> resp(
sz_res());
1755 for (casadi_int i=0; i<
n_out_; ++i) resp[i]=
get_ptr(res[i]);
1758 for (casadi_int p=0; p<npar; ++p) {
1762 always_inline, never_inline)) {
1766 if (p==npar-1)
break;
1767 for (casadi_int i=0; i<
n_in_; ++i)
if (mapped[i]) argp[i] +=
nnz_in(i);
1772 template<
typename M>
1774 casadi_assert(arg.size()==
n_in_,
"Incorrect number of inputs: Expected "
1776 for (casadi_int i=0; i<
n_in_; ++i) {
1779 std::string d_arg =
str(arg[i].size1()) +
"-by-" +
str(arg[i].size2());
1781 std::string e =
"Input " +
str(i) +
" (" +
name_in_[i] +
") has mismatching shape. "
1782 "Got " + d_arg +
". Allowed dimensions, in general, are:\n"
1783 " - The input dimension N-by-M (here " + d_in +
")\n"
1784 " - A scalar, i.e. 1-by-1\n"
1785 " - M-by-N if N=1 or M=1 (i.e. a transposed vector)\n"
1786 " - N-by-M1 if K*M1=M for some K (argument repeated horizontally)\n";
1788 e +=
" - N-by-P*M, indicating evaluation with multiple arguments (P must be a "
1789 "multiple of " +
str(npar) +
" for consistency with previous inputs)";
1796 template<
typename M>
1798 casadi_assert(res.size()==
n_out_,
"Incorrect number of outputs: Expected "
1800 for (casadi_int i=0; i<
n_out_; ++i) {
1802 "Output " +
str(i) +
" (" +
name_out_[i] +
") has mismatching shape. "
1807 template<
typename M>
1810 for (casadi_int i=0; i<
n_in_; ++i) {
1811 if (arg.at(i).size1()!=
size1_in(i))
return false;
1812 if (arg.at(i).size2()!=
size2_in(i) && arg.at(i).size2()!=npar*
size2_in(i))
return false;
1817 template<
typename M>
1820 for (casadi_int i=0; i<
n_out_; ++i) {
1821 if (res.at(i).size1()!=
size1_out(i))
return false;
1822 if (res.at(i).size2()!=
size2_out(i) && res.at(i).size2()!=npar*
size2_out(i))
return false;
1827 template<
typename M>
1829 if (arg.size()==inp.
size()) {
1832 }
else if (arg.is_scalar()) {
1835 }
else if (arg.is_vector() && inp.
size()==std::make_pair(arg.size2(), arg.size1())) {
1838 }
else if (arg.size1()==inp.
size1() && arg.size2()>0 && inp.
size2()>0
1839 && inp.
size2()%arg.size2()==0) {
1841 return repmat(arg, 1, inp.
size2()/arg.size2());
1842 }
else if (npar!=-1 && arg.size1()==inp.
size1() && arg.size2()>0 && inp.
size2()>0
1843 && (npar*inp.
size2())%arg.size2()==0) {
1845 return repmat(arg, 1, (npar*inp.
size2())/arg.size2());
1849 casadi_assert_dev(arg.is_empty());
1850 return M(inp.
size());
1854 template<
typename M>
1856 replace_arg(
const std::vector<M>& arg, casadi_int npar)
const {
1857 std::vector<M> r(arg.size());
1862 template<
typename M>
1864 replace_res(
const std::vector<M>& res, casadi_int npar)
const {
1865 std::vector<M> r(res.size());
1870 template<
typename M>
1872 replace_fseed(
const std::vector<std::vector<M> >& fseed, casadi_int npar)
const {
1873 std::vector<std::vector<M> > r(fseed.size());
1874 for (casadi_int d=0; d<r.size(); ++d) r[d] =
replace_arg(fseed[d], npar);
1878 template<
typename M>
1880 replace_aseed(
const std::vector<std::vector<M> >& aseed, casadi_int npar)
const {
1881 std::vector<std::vector<M> > r(aseed.size());
1882 for (casadi_int d=0; d<r.size(); ++d) r[d] =
replace_res(aseed[d], npar);
1886 template<
typename M>
1889 casadi_assert(arg.size()==
n_in_,
"Incorrect number of inputs: Expected "
1891 std::map<std::string, M> ret;
1892 for (casadi_int i=0;i<
n_in_;++i) {
1898 template<
typename M>
1900 convert_arg(
const std::map<std::string, M>& arg)
const {
1902 std::vector<M> arg_v(
n_in_);
1903 for (casadi_int i=0; i<arg_v.size(); ++i) {
1908 for (
auto&& e : arg) {
1909 arg_v.at(
index_in(e.first)) = e.second;
1915 template<
typename M>
1918 casadi_assert(res.size()==
n_out_,
"Incorrect number of outputs: Expected "
1920 std::map<std::string, M> ret;
1921 for (casadi_int i=0;i<
n_out_;++i) {
1927 template<
typename M>
1929 convert_res(
const std::map<std::string, M>& res)
const {
1931 std::vector<M> res_v(
n_out_);
1932 for (casadi_int i=0; i<res_v.size(); ++i) {
1933 res_v[i] = std::numeric_limits<double>::quiet_NaN();
1937 for (
auto&& e : res) {
1944 template<
typename MatType>
1947 if (v.size1() == sp.
size1() && v.size2() == n * sp.
size2()) {
1949 if (v.nnz() != 0 && !v.sparsity().is_stacked(sp, n)) {
1950 return project(v, repmat(sp, 1, n));
1954 casadi_assert_dev(v.is_empty());
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.
Function custom_jacobian_
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.
std::string jit_base_name_
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.
virtual bool has_function(const std::string &fname) const
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.
std::string jit_directory_
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.
std::map< std::string, std::vector< std::string > > AuxOut
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.
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.
Helper class for Serialization.
casadi_int size1() const
Get the number of rows.
casadi_int size2() const
Get the number of columns.
std::pair< casadi_int, casadi_int > size() const
Get the shape.
const double eps
Machine epsilon.
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
std::string str(const T &v)
String representation, any type.
GenericType::Dict Dict
C++ equivalent of Python's dict or MATLAB's struct.
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.
Function memory with temporary work vectors.
Options metadata for a class.
Function memory with temporary work vectors.
std::map< std::string, FStats > fstats
void add_stat(const std::string &s)