26 #include "function_internal.hpp"
27 #include "casadi_misc.hpp"
28 #include "sx_function.hpp"
29 #include "mx_function.hpp"
31 #include "bspline.hpp"
35 #include "jit_function.hpp"
36 #include "serializing_stream.hpp"
37 #include "serializer.hpp"
39 #include "filesystem_impl.hpp"
47 #define THROW_ERROR(FNAME, WHAT) \
48 throw CasadiException("Error in Function::" FNAME " for '" + this->name() + "' "\
49 "[" + this->class_name() + "] at " + CASADI_WHERE + ":\n"\
53 #define THROW_ERROR_NOOBJ(FNAME, WHAT, CLASS_NAME) \
54 throw CasadiException("Error in Function::" FNAME " for '" + name + "' "\
55 "[" CLASS_NAME "] at " + CASADI_WHERE + ":\n"\
66 if (!file.good())
return false;
73 std::streampos cur_pos = file.tellg();
75 if (!file.good())
return false;
78 if (
str==tmp)
return true;
82 file.ignore(std::numeric_limits<std::streamsize>::max(),
'\n');
93 casadi_error(
"Not implemented");
97 const std::vector<SX>& ex_in,
const std::vector<SX>& ex_out,
103 const std::vector<SX>& ex_in,
const std::vector<SX>& ex_out,
104 const std::vector<std::string>& name_in,
105 const std::vector<std::string>& name_out,
111 const std::vector<MX>& ex_in,
const std::vector<MX>& ex_out,
117 const std::vector<MX>& ex_in,
const std::vector<MX>& ex_out,
118 const std::vector<std::string>& name_in,
119 const std::vector<std::string>& name_out,
184 const std::vector<std::string>& name_in,
const std::vector<std::string>& name_out,
190 const std::vector<std::string>& name_in,
const std::vector<std::string>& name_out,
197 const std::vector<std::string>& name_in,
198 const std::vector<std::string>& name_out,
201 for (
auto&& i : dict) {
202 std::vector<std::string>::const_iterator it;
206 ex_in[it-
name_in.begin()] = i.second;
211 ex_out[it-
name_out.begin()] = i.second;
214 casadi_error(
"Unknown dictionary entry: '" + i.first +
"'");
222 const std::vector<SX>& ex_in,
const std::vector<SX>& ex_out,
223 const std::vector<std::string>& name_in,
224 const std::vector<std::string>& name_out,
228 (*this)->construct(opts);
231 auto it = opts.find(
"external_transform");
232 if (it!=opts.end()) {
233 auto v = it->second.to_vector_vector();
234 for (
const std::vector<GenericType>& vec : v) {
235 casadi_assert(vec.size()>=2,
"external_transform: inner list must be length >=2");
236 casadi_assert(vec.size()<=3,
"external_transform: inner list must be length <=3");
237 std::string
name = vec[0].to_string();
238 std::string op = vec[1].to_string();
239 Dict opts = vec.size()==3 ? vec[2].to_dict() :
Dict();
244 }
catch(std::exception& e) {
245 THROW_ERROR_NOOBJ(
"Function", e.what(),
"SXFunction");
250 const std::vector<MX>& ex_in,
const std::vector<MX>& ex_out,
251 const std::vector<std::string>& name_in,
252 const std::vector<std::string>& name_out,
256 (*this)->construct(opts);
259 auto it = opts.find(
"post_expand");
260 if (it!=opts.end()) {
261 if (!it->second)
return;
262 auto it = opts.find(
"post_expand_options");
263 if (it==opts.end()) {
266 operator=((*this).expand((*this).name(), it->second));
271 it = opts.find(
"external_transform");
272 if (it!=opts.end()) {
273 auto v = it->second.to_vector_vector();
274 for (
const std::vector<GenericType>& vec : v) {
275 casadi_assert(vec.size()>=2,
"external_transform: inner list must be length >=2");
276 casadi_assert(vec.size()<=3,
"external_transform: inner list must be length <=3");
277 std::string
name = vec[0].to_string();
278 std::string op = vec[1].to_string();
279 Dict opts = vec.size()==3 ? vec[2].to_dict() :
Dict();
284 }
catch(std::exception& e) {
285 THROW_ERROR_NOOBJ(
"Function", e.what(),
"MXFunction");
290 const std::vector<std::string>& name_in,
291 const std::vector<std::string>& name_out,
299 const std::vector<std::string>& name_in,
300 const std::vector<std::string>& name_out,
301 const std::vector<Sparsity>& sparsity_in,
302 const std::vector<Sparsity>& sparsity_out,
307 }
catch(std::exception& e) {
308 THROW_ERROR_NOOBJ(
"jit", e.what(),
"JitFunction");
319 "Function with free symbols cannot be expanded. "
320 "List of free variables in your Function: " +
323 Dict my_opts = (*this)->generate_options(
"clone");
325 std::vector<SX> ex_in =
sx_in();
326 std::vector<SX> ex_out =
Function(*
this)(ex_in);
340 for (
size_t i=0; i<ps.size(); ++i) {
343 for (
size_t j=0; j<ps[i].size(); ++j) {
354 try { s +=
"n_nodes=" +
str(f.
n_nodes()); }
catch (...) { s +=
"n_nodes=?"; }
366 bool empty_inputs =
true;
367 bool combine_terms =
false;
369 bool ref_count =
true;
370 bool const_folding =
true;
371 bool verbose =
false;
372 for (
auto&& op : opts) {
373 if (op.first==
"empty_inputs") {
374 empty_inputs = op.second;
375 }
else if (op.first==
"combine_terms") {
376 combine_terms = op.second;
377 }
else if (op.first==
"cse") {
379 }
else if (op.first==
"ref_count") {
380 ref_count = op.second;
381 }
else if (op.first==
"const_folding") {
382 const_folding = op.second;
383 }
else if (op.first==
"verbose") {
386 casadi_error(
"transform: no such option: " + std::string(op.first) +
".\n");
389 std::vector<GenericType> simp = {std::string(
"simplify")};
390 if (empty_inputs) simp.push_back(
"empty_inputs");
391 if (combine_terms) simp.push_back(
"combine_terms");
392 if (cse) simp.push_back(
"cse");
393 if (ref_count) { simp.push_back(0); simp.push_back(
"ref_count"); }
394 if (const_folding) simp.push_back(
"const_folding");
395 return transform(fname, std::vector<std::vector<GenericType> >{simp}, {{
"verbose", verbose}});
396 }
catch(std::exception& e) {
397 THROW_ERROR(
"transform", e.what());
402 const Dict& opts)
const {
407 const std::vector<std::vector<GenericType> >& passes,
408 const Dict& opts)
const {
412 bool verbose =
false;
413 for (
auto&& op : opts) {
414 if (op.first==
"verbose") {
417 casadi_error(
"transform(passes, opts): unsupported option '" + std::string(op.first)
418 +
"' (boolean simplify options are only allowed in the dict-only form).\n");
429 for (
const auto& pass : passes) {
430 casadi_assert(!pass.empty(),
"transform: each pass must be a non-empty list");
431 std::string verb = pass.front().to_string();
432 if (verb==
"simplify") {
435 std::vector<std::pair<std::string, casadi_int> > tasks;
436 casadi_int count = 1;
437 bool have_count =
false;
438 for (
size_t i=1; i<pass.size(); ++i) {
439 if (pass[i].is_int()) {
440 count = pass[i].to_int();
443 tasks.push_back({pass[i].to_string(), count});
448 casadi_assert(!have_count,
449 "transform 'simplify': trailing run count with no following task");
451 }
else if (verb==
"expand") {
452 casadi_assert(pass.size()==1,
"transform: 'expand' pass takes no arguments");
454 }
else if (verb==
"external") {
455 casadi_assert(pass.size()>=3 && pass.size()<=4,
456 "transform: 'external' pass must be {\"external\", library, operation[, opts]}");
457 std::string lib = pass[1].to_string();
458 std::string op = pass[2].to_string();
459 Dict eopts = pass.size()==4 ? pass[3].to_dict() :
Dict();
462 casadi_error(
"transform: unknown pass verb '" + verb +
"'");
471 if (!fname.empty() && fname!=f.
name()) {
472 Dict ropts{{
"allow_free",
true}, {
"allow_duplicate_io_names",
true}};
474 if (f.
is_a(
"SXFunction",
true)) {
475 std::vector<SX> arg = f.
sx_in();
476 f =
Function(fname, arg, f(arg), ni, no, ropts);
478 std::vector<MX> arg = f.
mx_in();
479 f =
Function(fname, arg, f(arg), ni, no, ropts);
483 }
catch(std::exception& e) {
484 THROW_ERROR(
"transform", e.what());
510 bool always_inline,
bool never_inline)
const {
512 (*this)->call(arg, res, always_inline, never_inline);
513 }
catch(std::exception& e) {
514 THROW_ERROR(
"call", e.what());
519 bool always_inline,
bool never_inline)
const {
521 (*this)->call(arg, res, always_inline, never_inline);
522 }
catch(std::exception& e) {
523 THROW_ERROR(
"call", e.what());
528 bool always_inline,
bool never_inline)
const {
530 (*this)->call(arg, res, always_inline, never_inline);
531 }
catch(std::exception& e) {
532 THROW_ERROR(
"call", e.what());
537 casadi_assert_dev(arg.size()==
n_in());
538 auto arg_it=arg.begin();
539 std::vector<const double*> buf_arg(
sz_arg());
540 for (casadi_uint i=0; i<arg.size(); ++i) {
541 casadi_assert_dev(arg_it->size()==
nnz_in(i));
542 buf_arg[i] =
get_ptr(*arg_it++);
549 auto res_it=res.begin();
550 std::vector<double*> buf_res(
sz_res());
551 for (casadi_uint i=0; i<res.size(); ++i) {
553 buf_res[i] =
get_ptr(*res_it++);
559 casadi_assert_dev(res.size()==
n_out());
560 auto res_it=res.begin();
561 std::vector<double*> buf_res(
sz_res());
562 for (casadi_uint i=0; i<res.size(); ++i) {
563 casadi_assert_dev(*res_it!=0);
565 buf_res[i] =
get_ptr(**res_it++);
572 std::vector<const double*> ret(
sz_arg(),
nullptr);
575 for (
auto i=arg.begin(); i!=arg.end(); ++i) {
576 casadi_int ind =
index_in(i->first);
577 casadi_assert_dev(i->second.size()==
nnz_in(ind));
586 std::vector<double*> ret(
sz_res(),
nullptr);
589 for (
auto i=res.begin(); i!=res.end(); ++i) {
591 i->second.resize(
nnz_out(ind));
600 std::vector<double*> ret(
sz_res(),
nullptr);
603 for (
auto i=res.begin(); i!=res.end(); ++i) {
605 casadi_assert_dev(i->second!=0);
606 i->second->resize(
nnz_out(ind));
607 ret[ind] =
get_ptr(*i->second);
616 casadi_assert_dev(arg.size()>=
n_in());
620 casadi_assert_dev(res.size()>=
n_out());
624 std::vector<casadi_int> iw(
sz_iw());
625 std::vector<D> w(
sz_w());
644 int Function::rev(std::vector<bvec_t*> arg, std::vector<bvec_t*> res)
const {
646 casadi_assert_dev(arg.size()>=
n_in());
650 casadi_assert_dev(res.size()>=
n_out());
654 std::vector<casadi_int> iw(
sz_iw());
655 std::vector<bvec_t> w(
sz_w());
663 std::vector<MX> base_in = base.
mx_in();
664 std::vector<MX> out = base(base_in);
675 const Dict& opts)
const {
679 casadi_int base = 10;
680 auto it = options.find(
"base");
681 if (it!=options.end()) {
686 casadi_assert(N>0,
"mapaccum: N must be positive");
689 return mapaccum(
name, std::vector<Function>(N, *
this), n_accum, options);
690 casadi_assert(base>=2,
"mapaccum: base must be positive");
693 std::vector<Function> chain;
696 casadi_int r = N % base;
697 chain.insert(chain.end(), r, c);
699 c = c.
mapaccum(c.
name()+
"_acc"+
str(base), std::vector<Function>(base, c), n_accum, options);
705 const std::vector<Function>& chain, casadi_int n_accum,
706 const Dict& opts)
const {
710 casadi_assert(!chain.empty(),
"mapaccum: chain must be non-empty");
711 casadi_assert(n_accum<=std::min(
n_in,
n_out),
"mapaccum: too many accumulators");
713 if (chain.size()==1)
return chain[0];
715 std::vector<MX> arg =
mx_in();
718 std::vector<std::vector<MX>> varg(
n_in), vres(
n_out);
719 for (casadi_int i=0; i<n_accum; ++i) varg[i].push_back(arg[i]);
721 for (
const auto& f : chain) {
724 for (casadi_int i=n_accum; i<
n_in; ++i) {
726 varg[i].push_back(arg[i]);
732 for (casadi_int i=0; i<
n_out; ++i) vres[i].push_back(res[i]);
734 std::copy_n(res.begin(), n_accum, arg.begin());
735 for (casadi_int i=0; i<n_accum; ++i) {
737 casadi_int ncol_out=f.size2_out(i), ncol_in=
size2_in(i);
738 if (ncol_out>ncol_in) {
739 arg[i] = horzsplit(arg[i], {0, ncol_out-ncol_in, ncol_out}).back();
744 for (casadi_int i=0; i<
n_in; ++i) arg[i] = horzcat(varg[i]);
745 for (casadi_int i=0; i<
n_out; ++i) res[i] = horzcat(vres[i]);
750 const std::vector<casadi_int>& accum_in,
751 const std::vector<casadi_int>& accum_out,
752 const Dict& opts)
const {
758 casadi_assert_dev(accum_in.size()==accum_out.size());
759 casadi_int n_accum=accum_in.size();
762 if (accum_in==
range(n_accum) && accum_out==
range(n_accum)) {
768 std::vector<casadi_int> order_in = accum_in;
769 order_in.insert(order_in.end(), temp_in.begin(), temp_in.end());
771 std::vector<casadi_int> order_out = accum_out;
772 order_out.insert(order_out.end(), temp_out.begin(), temp_out.end());
780 const std::vector<std::string>& accum_in,
781 const std::vector<std::string>& accum_out,
782 const Dict& opts)
const {
783 std::vector<casadi_int> accum_in_num, accum_out_num;
784 for (
const std::string& s : accum_in) accum_in_num.push_back(
index_in(s));
785 for (
const std::string& s : accum_out) accum_out_num.push_back(
index_out(s));
786 return mapaccum(
name, n, accum_in_num, accum_out_num, opts);
790 const std::vector<bool>& reduce_in,
791 const std::vector<bool>& reduce_out,
792 const Dict& opts)
const {
794 *
this, n, reduce_in, reduce_out, opts);
798 const std::vector<casadi_int>& reduce_in,
const std::vector<casadi_int>& reduce_out,
799 const Dict& opts)
const {
803 std::vector<MX> arg = f.
mx_in();
804 std::vector<MX> f_arg = arg;
806 for (casadi_int i : reduce_in) {
808 f_arg[i] = repmat(arg[i], 1, n);
811 std::vector<MX> res = f(f_arg);
813 for (casadi_int i : reduce_out) {
814 res[i] = repsum(res[i], 1, n);
821 const std::vector<std::string>& reduce_in,
const std::vector<std::string>& reduce_out,
822 const Dict& opts)
const {
823 std::vector<casadi_int> reduce_in_num, reduce_out_num;
824 for (
const std::string& s : reduce_in) reduce_in_num.push_back(
index_in(s));
825 for (
const std::string& s : reduce_out) reduce_out_num.push_back(
index_out(s));
826 return map(
name, parallelization, n, reduce_in_num, reduce_out_num, opts);
831 casadi_int max_num_threads)
const {
832 casadi_assert(max_num_threads>=1,
"max_num_threads invalid.");
834 if (n<=max_num_threads)
return map(n, parallelization);
837 casadi_int d = n/max_num_threads;
838 if (d*max_num_threads==n) {
840 return map(d,
"serial").
map(max_num_threads, parallelization);
843 Function base =
map(d+1,
"serial").
map(max_num_threads, parallelization);
844 std::vector<MX> ret_in, base_in;
845 casadi_int rem = (d+1)*max_num_threads-n;
846 for (casadi_int i=0;i<
n_in();++i) {
848 ret_in.push_back(arg);
850 base_in.push_back(horzcat(arg, repmat(last_arg, 1, rem)));
852 std::vector<MX> ret_out = base(base_in);
853 for (casadi_int i=0;i<
n_out();++i) {
854 ret_out[i] = horzsplit(ret_out[i], {0, n*
size2_out(i), ret_out[i].size2()})[0];
863 casadi_assert(n>0,
"Degenerate map operation");
865 if (n==1)
return *
this;
867 if (parallelization==
"unroll" || parallelization==
"inline") {
869 std::vector<MX> arg(
n_in());
870 std::vector<std::vector<MX>> v(n, arg);
871 std::vector<MX> tmp(n);
872 for (casadi_int i=0; i<arg.size(); ++i) {
873 for (casadi_int k=0; k<n; ++k) {
876 arg[i] = horzcat(tmp);
879 if (parallelization==
"unroll") {
880 for (
auto&& w : v) w = (*this)(w);
882 for (
auto&& w : v)
call(std::vector<MX>(w), w, !
is_a(
"SXFunction"),
false);
885 std::vector<MX> res(
n_out());
886 for (casadi_int i=0; i<res.size(); ++i) {
887 for (casadi_int k=0; k<n; ++k) tmp[k] = v[k][i];
888 res[i] = horzcat(tmp);
894 return (*this)->map(n, parallelization);
899 slice(
const std::string& name,
const std::vector<casadi_int>& order_in,
900 const std::vector<casadi_int>& order_out,
const Dict& opts)
const {
902 return (*this)->
slice(
name, order_in, order_out, opts);
903 }
catch(std::exception& e) {
904 THROW_ERROR(
"slice", e.what());
909 const std::string& parallelization)
const {
911 return (*this)->mapsum_mx(x, parallelization);
912 }
catch(std::exception& e) {
913 THROW_ERROR(
"mapsum", e.what());
921 }
catch(std::exception& e) {
922 THROW_ERROR_NOOBJ(
"conditional", e.what(),
"Switch");
930 std::vector<MX> dummy_in = f.
mx_in();
931 std::vector<MX> dummy_out(f.
n_out());
932 for (casadi_int i = 0; i < dummy_out.size(); ++i) {
938 }
catch(std::exception& e) {
939 THROW_ERROR_NOOBJ(
"conditional", e.what(),
"Switch");
944 const std::vector< std::vector<double> >& knots,
945 const std::vector<double>& coeffs,
const std::vector<casadi_int>& degree,
946 casadi_int m,
const Dict& opts) {
948 casadi_assert(degree.size()==knots.size(),
"Degree list length (" +
str(degree.size()) +
") "
949 "must match knot list length (" +
str(knots.size()) +
").");
951 std::vector<std::string> lookup_mode;
954 opts_bspline[
"lookup_mode"] = lookup_mode;
957 }
catch(std::exception& e) {
958 THROW_ERROR_NOOBJ(
"bspline", e.what(),
"BSpline");
965 return create(
new Switch(
name, std::vector<Function>(1, f_false), f_true), opts);
966 }
catch(std::exception& e) {
967 THROW_ERROR_NOOBJ(
"if_else", e.what(),
"Switch");
972 return (*this)->n_in_;
976 return (*this)->n_out_;
980 return (*this)->size1_in(ind);
984 return (*this)->size2_in(ind);
988 return (*this)->size1_out(ind);
992 return (*this)->size2_out(ind);
996 return (*this)->size_in(ind);
1000 return (*this)->size_out(ind);
1004 return (*this)->nnz_in();
1008 return (*this)->nnz_out();
1012 return (*this)->numel_in();
1016 return (*this)->numel_out();
1020 return (*this)->nnz_in(ind);
1024 return (*this)->nnz_out(ind);
1028 return (*this)->numel_in(ind);
1032 return (*this)->numel_out(ind);
1036 return (*this)->uses_output();
1039 #ifdef WITH_DEPRECATED_FEATURES
1042 std::vector<std::string> s_in =
name_in();
1043 std::vector<std::string> s_out =
name_out();
1044 s_out.insert(s_out.begin(),
"jac:" +
name_out(oind) +
":" +
name_in(iind));
1050 std::vector<std::string> s_in =
name_in();
1051 std::vector<std::string> s_out =
name_out();
1052 s_out.insert(s_out.begin(),
"grad:" +
name_out(oind) +
":" +
name_in(iind));
1053 s_out.insert(s_out.begin(),
1059 sparsity_jac(casadi_int iind, casadi_int oind,
bool compact,
bool symmetric)
const {
1061 return (*this)->jac_sparsity(oind, iind, compact, symmetric);
1062 }
catch(std::exception& e) {
1063 THROW_ERROR(
"sparsity_jac", e.what());
1071 }
catch(std::exception& e) {
1072 THROW_ERROR(
"jacobian", e.what());
1081 if (!(*this)->has_memory(mem)) {
1082 THROW_ERROR(
"stats",
1083 "No stats available: Function/solver was not yet numerically evaluated.");
1086 return (*this)->get_stats(
memory(mem));
1087 }
catch(std::exception& e) {
1088 THROW_ERROR(
"stats", e.what());
1094 for (casadi_int oind = 0; oind <
n_out(); ++oind) {
1095 for (casadi_int iind = 0; iind <
n_in(); ++iind) {
1100 return (*this)->jac_sparsity_[compact];
1105 bool symm = (*this)->jac_is_symm(oind, iind);
1107 return (*this)->jac_sparsity(oind, iind, compact, symm);
1108 }
catch(std::exception& e) {
1109 THROW_ERROR(
"jac_sparsity", e.what());
1114 return (*this)->name_in_;
1118 return (*this)->name_out_;
1123 return (*this)->index_in(
name);
1124 }
catch(std::exception& e) {
1125 THROW_ERROR(
"index_in", e.what());
1131 return (*this)->index_out(
name);
1132 }
catch(std::exception& e) {
1133 THROW_ERROR(
"index_out", e.what());
1138 for (
const std::string& s : (*this)->name_in_) {
1139 if (s==
name)
return true;
1145 for (
const std::string& s : (*this)->name_out_) {
1146 if (s==
name)
return true;
1153 return (*this)->name_in_.at(ind);
1154 }
catch(std::exception& e) {
1155 THROW_ERROR(
"name_in", e.what());
1161 return (*this)->name_out_.at(ind);
1162 }
catch(std::exception& e) {
1163 THROW_ERROR(
"name_out", e.what());
1169 return (*this)->sparsity_in_.at(ind);
1170 }
catch(std::exception& e) {
1171 THROW_ERROR(
"sparsity_in", e.what());
1178 }
catch(std::exception& e) {
1179 THROW_ERROR(
"sparsity_in", e.what());
1185 return (*this)->sparsity_out_.at(ind);
1186 }
catch(std::exception& e) {
1187 THROW_ERROR(
"sparsity_out", e.what());
1194 }
catch(std::exception& e) {
1195 THROW_ERROR(
"sparsity_out", e.what());
1201 return (*this)->is_diff_in_.at(ind);
1202 }
catch(std::exception& e) {
1203 THROW_ERROR(
"is_diff_in", e.what());
1209 return (*this)->is_diff_out_.at(ind);
1210 }
catch(std::exception& e) {
1211 THROW_ERROR(
"is_diff_out", e.what());
1217 return (*this)->is_diff_in_;
1218 }
catch(std::exception& e) {
1219 THROW_ERROR(
"is_diff_in", e.what());
1225 return (*this)->is_diff_out_;
1226 }
catch(std::exception& e) {
1227 THROW_ERROR(
"is_diff_out", e.what());
1244 casadi_int* iw,
bvec_t* w,
int mem)
const {
1246 return (*this)->sp_forward(arg, res, iw, w,
memory(mem));
1247 }
catch(std::exception& e) {
1248 THROW_ERROR(
"operator()", e.what());
1254 return (*this)->sp_reverse(arg, res, iw, w,
memory(mem));
1255 }
catch(std::exception& e) {
1256 THROW_ERROR(
"rev", e.what());
1261 casadi_int* iw,
bvec_t* w,
int mem)
const {
1263 return (*this)->eval_activity(arg, res, iw, w,
memory(mem));
1264 }
catch(std::exception& e) {
1265 THROW_ERROR(
"eval_activity", e.what());
1270 casadi_assert(arg.size()==
static_cast<size_t>(
nnz_in()),
1271 "activity: expected mask of size nnz_in()=" +
str(
nnz_in())
1272 +
", got " +
str(arg.size()) +
".");
1275 std::vector<bvec_t> in_buf(
nnz_in()), out_buf(
nnz_out(), 0);
1276 for (casadi_int k=0; k<nnz_in(); ++k) in_buf[k] = arg[k] ? ~static_cast<bvec_t>(0) : 0;
1279 std::vector<const bvec_t*> argp(
sz_arg(),
nullptr);
1280 std::vector<bvec_t*> resp(
sz_res(),
nullptr);
1282 for (casadi_int i=0; i<
n_in(); ++i) { argp[i] =
get_ptr(in_buf)+off; off +=
nnz_in(i); }
1284 for (casadi_int i=0; i<
n_out(); ++i) { resp[i] =
get_ptr(out_buf)+off; off +=
nnz_out(i); }
1287 std::vector<casadi_int> iw(
sz_iw());
1288 std::vector<bvec_t> w(
sz_w());
1292 std::vector<bool> ret(
nnz_out());
1293 for (casadi_int k=0; k<
nnz_out(); ++k) ret[k] = out_buf[k]!=0;
1300 (*this)->set_work(
memory(mem), arg, res, iw, w);
1301 }
catch(std::exception& e) {
1302 THROW_ERROR(
"set_work", e.what());
1309 (*this)->set_temp(
memory(mem), arg, res, iw, w);
1310 }
catch(std::exception& e) {
1311 THROW_ERROR(
"set_temp", e.what());
1318 (*this)->setup(
memory(mem), arg, res, iw, w);
1319 }
catch(std::exception& e) {
1320 THROW_ERROR(
"setup", e.what());
1326 return (*this)->
forward(nfwd);
1327 }
catch(std::exception& e) {
1328 THROW_ERROR(
"forward", e.what());
1334 return (*this)->
reverse(nadj);
1335 }
catch(std::exception& e) {
1336 THROW_ERROR(
"reverse", e.what());
1341 (*this)->print_dimensions(stream);
1345 (*this)->print_options(stream);
1349 (*this)->print_option(
name, stream);
1354 return (*this)->has_option(option_name);
1355 }
catch(std::exception& e) {
1356 THROW_ERROR(
"has_option", e.what());
1365 casadi_error(
"Option '" + option_name +
"' does not exist");
1367 (*this)->change_option(option_name, option_value);
1368 }
catch(std::exception& e) {
1369 THROW_ERROR(
"change_option", e.what());
1375 (*this)->reset_dump_count();
1376 }
catch(std::exception& e) {
1377 THROW_ERROR(
"reset_dump_count", e.what());
1383 return (*this)->get_free();
1397 return (*this)->generate_dependencies(fname, opts);
1405 std::ostream& of = *of_ptr;
1409 for (casadi_int i=0; i<d.size(); ++i) {
1420 std::ostream& of = *of_ptr;
1424 for (casadi_int i=0; i<d.size(); ++i) {
1436 "Dimension mismatch: file contains a vector of size " +
str(data.
numel())
1437 +
", while size " +
str(
nnz_in()) +
" was expected.");
1448 "Dimension mismatch: file contains a vector of size " +
str(data.
numel())
1449 +
", while size " +
str(
nnz_out()) +
" was expected.");
1455 std::ostream &stream,
const Dict& options)
const {
1456 (*this)->export_code(lang, stream, options);
1460 const std::string &fname,
const Dict& options)
const {
1462 (*this)->export_code(lang, *stream_ptr, options);
1472 std::stringstream ss;
1484 s.
pack(
"Function::null",
true);
1486 s.
pack(
"Function::null",
false);
1487 (*this)->serialize(s);
1499 std::stringstream ss;
1500 (*this)->export_code(lang, ss, options);
1506 static std::string
null =
"null";
1509 return (*this)->name_;
1515 if (
name.empty())
return false;
1518 for (
const char* kw : {
"null",
"jac",
"hess"}) {
1519 if (
name==kw)
return false;
1523 auto it=
name.begin();
1524 if (!std::isalpha(*it++))
return false;
1527 for (; it!=
name.end(); ++it) {
1530 if (it+1!=
name.end() && *(it+1)==
'_')
return false;
1533 if (!std::isalnum(*it))
return false;
1549 if (t==SerializerBase::SerializationType::SERIALIZED_FUNCTION) {
1552 casadi_error(
"File is not loadable with 'load'. Use 'FileDeserializer' instead.");
1557 std::stringstream ss;
1567 if (
name.empty())
return "unnamed";
1570 std::stringstream ss;
1573 if (!std::isalpha(
name.front())) ss <<
"a";
1576 bool previous_is_underscore =
false;
1577 for (
char c :
name) {
1578 if (std::isalnum(c)) {
1581 previous_is_underscore =
false;
1582 }
else if (!previous_is_underscore) {
1585 previous_is_underscore =
true;
1590 for (
const char* kw : {
"null",
"jac",
"hess"}) {
1591 if (ss.str()==kw) ss <<
"1";
1598 std::vector<DM> res;
1604 std::vector<SX> res;
1610 std::vector<MX> res;
1615 template<
typename M>
1617 bool always_inline,
bool never_inline)
const {
1619 std::vector<M> arg_v = (*this)->convert_arg(arg);
1622 std::vector<M> res_v;
1623 call(arg_v, res_v, always_inline, never_inline);
1627 for (casadi_int i=0; i<res_v.size(); ++i) {
1651 bool always_inline,
bool never_inline)
const {
1653 call_gen(arg, res, always_inline, never_inline);
1654 }
catch(std::exception& e) {
1655 THROW_ERROR(
"call", e.what());
1660 bool always_inline,
bool never_inline)
const {
1662 call_gen(arg, res, always_inline, never_inline);
1663 }
catch(std::exception& e) {
1664 THROW_ERROR(
"call", e.what());
1669 bool always_inline,
bool never_inline)
const {
1671 call_gen(arg, res, always_inline, never_inline);
1672 }
catch(std::exception& e) {
1673 THROW_ERROR(
"call", e.what());
1678 return (*this)->get_default_in(ind);
1682 return (*this)->get_max_in(ind);
1686 return (*this)->get_min_in(ind);
1690 return (*this)->get_nominal_in(ind);
1694 return (*this)->get_nominal_out(ind);
1697 #ifdef WITH_EXTRA_CHECKS
1699 thread_local casadi_int Function::call_depth_ = 0;
1703 casadi_int* iw,
double* w)
const {
1709 casadi_int* iw,
double* w,
int mem)
const {
1711 #ifdef WITH_EXTRA_CHECKS
1713 casadi_assert_dev(call_depth_>=0);
1716 casadi_int depth = call_depth_;
1718 int ret = (*this)->eval_gen(arg, res, iw, w,
memory(mem),
false,
false);
1719 #ifdef WITH_EXTRA_CHECKS
1721 casadi_assert_dev(call_depth_==depth);
1727 #ifdef WITH_EXTRA_CHECKS
1731 }
catch(std::exception& e) {
1732 #ifdef WITH_EXTRA_CHECKS
1735 (*this)->print_in(
uerr(), arg,
true);
1736 THROW_ERROR(
"operator()", e.
what());
1741 casadi_int* iw,
SXElem* w,
int mem)
const {
1743 return (*this)->eval_sx(arg, res, iw, w,
memory(mem),
false,
false);
1744 }
catch(std::exception& e) {
1745 THROW_ERROR(
"operator()", e.what());
1751 return (*this)->sx_in(iind);
1752 }
catch(std::exception& e) {
1753 THROW_ERROR(
"sx_in", e.what());
1759 return (*this)->sx_out(oind);
1760 }
catch(std::exception& e) {
1761 THROW_ERROR(
"sx_out", e.what());
1767 return (*this)->sx_in();
1768 }
catch(std::exception& e) {
1769 THROW_ERROR(
"sx_in", e.what());
1775 return (*this)->sx_out();
1776 }
catch(std::exception& e) {
1777 THROW_ERROR(
"sx_out", e.what());
1782 return (*this)->mx_in(ind);
1786 return (*this)->mx_out(ind);
1790 return (*this)->mx_in();
1794 return (*this)->mx_out();
1798 return (*this)->nz_in(arg);
1802 return (*this)->nz_out(res);
1806 return (*this)->nz_in(arg);
1810 return (*this)->nz_out(res);
1814 return (*this)->convert_arg(arg);
1818 return (*this)->convert_arg(arg);
1822 return (*this)->convert_res(arg);
1826 return (*this)->convert_res(arg);
1830 return (*this)->convert_arg(arg);
1834 return (*this)->convert_arg(arg);
1838 return (*this)->convert_res(arg);
1842 return (*this)->convert_res(arg);
1846 return (*this)->convert_arg(arg);
1850 return (*this)->convert_arg(arg);
1854 return (*this)->convert_res(arg);
1858 return (*this)->convert_res(arg);
1862 return (*this)->is_a(type, recursive);
1866 std::vector<MX>& subs_from, std::vector<MX>& subs_to)
const {
1867 (*this)->merge(arg, subs_from, subs_to);
1872 return (*this)->free_sx();
1873 }
catch(std::exception& e) {
1874 THROW_ERROR(
"free_sx", e.what());
1880 return (*this)->free_mx();
1881 }
catch(std::exception& e) {
1882 THROW_ERROR(
"free_mx", e.what());
1887 return (*this)->has_spfwd();
1891 return (*this)->has_sprev();
1895 return (*this)->has_free();
1900 (*this)->generate_lifted(vdef_fcn, vinit_fcn);
1901 }
catch(std::exception& e) {
1902 THROW_ERROR(
"generate_lifted", e.what());
1908 return (*this)->n_instructions();
1909 }
catch(std::exception& e) {
1910 THROW_ERROR(
"n_instructions", e.what());
1916 return (*this)->instruction_MX(k);
1917 }
catch(std::exception& e) {
1918 THROW_ERROR(
"instruction_MX", e.what());
1924 return (*this)->instructions_sx();
1925 }
catch(std::exception& e) {
1926 THROW_ERROR(
"instructions_sx", e.what());
1932 return (*this)->instruction_id(k);
1933 }
catch(std::exception& e) {
1934 THROW_ERROR(
"instruction_id", e.what());
1940 return (*this)->instruction_input(k);
1941 }
catch(std::exception& e) {
1942 THROW_ERROR(
"instruction_input", e.what());
1948 return (*this)->instruction_constant(k);
1949 }
catch(std::exception& e) {
1950 THROW_ERROR(
"instruction_constant", e.what());
1956 return (*this)->instruction_output(k);
1957 }
catch(std::exception& e) {
1958 THROW_ERROR(
"instruction_output", e.what());
1964 return (*this)->n_nodes();
1965 }
catch(std::exception& e) {
1966 THROW_ERROR(
"n_nodes", e.what());
1971 return (*this)->checkout();
1975 (*this)->release(mem);
1979 return (*this)->memory(ind);
1984 "Incorrect shape for " +
str(*
this) +
" input " +
str(i) +
" \""
1985 +
name_in(i) +
"\". Expected " +
str(nrow) +
"-by-" +
str(ncol)
1992 "Incorrect shape for " +
str(*
this) +
" output " +
str(i) +
" \""
1998 casadi_int n,
bool allow_all_zero_sparse)
const {
2002 if (allow_all_zero_sparse &&
sparsity_out(i).nnz() == 0)
return;
2004 casadi_assert(
sparsity_out(i).is_stacked(sp, n),
"Mismatching sparsity "
2005 "(but correct dimensions) for " +
str(*
this) +
" output " +
name_out(i));
2009 factory(
const std::string& name,
2010 const std::vector<std::string>& s_in,
2011 const std::vector<std::string>& s_out,
2013 const Dict& opts)
const {
2015 return (*this)->
factory(
name, s_in, s_out, aux, opts);
2016 }
catch(std::exception& e) {
2017 THROW_ERROR(
"factory",
"Failed to create " +
name +
":" +
str(s_in) +
"->" +
str(s_out)
2018 +
" with " +
str(aux) +
":\n" +
str(e.what()));
2023 which_depends(
const std::string& s_in,
const std::vector<std::string>& s_out,
2024 casadi_int order,
bool tr)
const {
2026 return (*this)->which_depends(s_in, s_out,
order, tr);
2027 }
catch(std::exception& e) {
2028 THROW_ERROR(
"which_depends", e.what());
2034 return (*this)->cache();
2035 }
catch(std::exception& e) {
2036 THROW_ERROR(
"cache", e.what());
2043 return (*this)->get_function();
2044 }
catch(std::exception& e) {
2045 THROW_ERROR(
"get_function", e.what());
2052 return (*this)->get_function(
name);
2053 }
catch(std::exception& e) {
2054 THROW_ERROR(
"get_function", e.what());
2060 return (*this)->has_function(fname);
2061 }
catch(std::exception& e) {
2062 THROW_ERROR(
"has_function", e.what());
2070 if (max_depth < 0) max_depth = std::numeric_limits<casadi_int>::max();
2072 std::map<FunctionInternal*, std::pair<Function, size_t> > all_fun;
2073 (*this)->find(all_fun, max_depth);
2075 std::vector<Function> ret(all_fun.size());
2076 for (
auto&& e : all_fun) ret[e.second.second] = e.second.first;
2078 }
catch(std::exception& e) {
2079 THROW_ERROR(
"find", e.what());
2087 if (max_depth < 0) max_depth = std::numeric_limits<casadi_int>::max();
2089 std::map<FunctionInternal*, std::pair<Function, size_t> > all_fun;
2090 (*this)->find(all_fun, max_depth);
2092 for (
auto&& e : all_fun) {
2093 if (e.second.first.name() ==
name)
return e.second.first;
2096 casadi_error(
"'" +
name +
"' not found");
2097 }
catch(std::exception& e) {
2098 THROW_ERROR(
"find", e.what());
2106 return (*this)->
oracle();
2107 }
catch(std::exception& e) {
2108 THROW_ERROR(
"oracle", e.what());
2113 return (*this)->
wrap();
2130 casadi_assert(!
is_null(),
"lhs is null");
2131 casadi_assert(!f.
is_null(),
"rhs is null");
2133 }
catch(std::exception& e) {
2134 THROW_ERROR(
"operator==", e.what());
2139 return (*this)->info();
2151 w_.resize(f_.
sz_w());
2152 iw_.resize(f_.
sz_iw());
2153 arg_.resize(f_.
sz_arg());
2154 res_.resize(f_.
sz_res());
2159 mem_internal_ = f_.
memory(mem_);
2161 f_node_ = f.operator->();
2173 : f_(f.f_), w_(f.w_), iw_(f.iw_), arg_(f.arg_), res_(f.res_), f_node_(f.f_node_) {
2178 mem_internal_ = f_.
memory(mem_);
2183 if (
this == &f)
return *
this;
2192 w_ = f.w_; iw_ = f.iw_; arg_ = f.arg_; res_ = f.res_; f_node_ = f.f_node_;
2198 mem_internal_ = f_.
memory(mem_);
2205 casadi_assert(size>=f_.
nnz_in(i)*
sizeof(
double),
2206 "Buffer is not large enough. Needed " +
str(f_.
nnz_in(i)*
sizeof(
double)) +
2207 " bytes, got " +
str(size) +
".");
2211 casadi_assert(size>=f_.
nnz_out(i)*
sizeof(
double),
2212 "Buffer is not large enough. Needed " +
str(f_.
nnz_out(i)*
sizeof(
double)) +
2213 " bytes, got " +
str(size) +
".");
2217 if (f_node_->
eval_) {
2232 return f_.
stats(mem_);
const char * what() const override
Display error.
Helper class for C code generation.
void add(const Function &f, bool with_jac_sparsity=false)
Add a function (name generated)
std::string generate(const std::string &prefix="")
Generate file(s)
Function blind_unpack_function()
SerializerBase::SerializationType pop_type()
Helper class for Serialization.
void unpack(Sparsity &e)
Reconstruct an object from the input stream.
static std::unique_ptr< std::ostream > ofstream_ptr(const std::string &path, std::ios_base::openmode mode=std::ios_base::out)
Class to achieve minimal overhead function evaluations.
void set_res(casadi_int i, double *a, casadi_int size)
Set output buffer for ouput i.
void set_arg(casadi_int i, const double *a, casadi_int size)
Set input buffer for input i.
FunctionBuffer & operator=(const FunctionBuffer &f)
FunctionBuffer(const Function &f)
Main constructor.
int ret()
Get last return value.
Internal class for Function.
Function forward(casadi_int nfwd) const
Return function that calculates forward derivatives.
virtual Function slice(const std::string &name, const std::vector< casadi_int > &order_in, const std::vector< casadi_int > &order_out, const Dict &opts) const
returns a new function with a selection of inputs/outputs of the original
static Function deserialize(DeserializingStream &s)
Deserialize with type disambiguation.
virtual Function factory(const std::string &name, const std::vector< std::string > &s_in, const std::vector< std::string > &s_out, const Function::AuxOut &aux, const Dict &opts) const
casadi_release_t release_
Release redirected to a C function.
virtual int eval(const double **arg, double **res, casadi_int *iw, double *w, void *mem) const
Evaluate numerically.
eval_t eval_
Numerical evaluation redirected to a C function.
virtual Function simplify_passes(const std::vector< std::pair< std::string, casadi_int > > &tasks) const
Apply an ordered list of simplify passes (used by transform)
casadi_checkout_t checkout_
Checkout redirected to a C function.
Function wrap_as_needed(const std::string &name, const Dict &opts) const
Wrap in an Function instance consisting of only one MX call.
Function reverse(casadi_int nadj) const
Return function that calculates adjoint derivatives.
virtual const Function & oracle() const
Get oracle.
Function jacobian() const
Return Jacobian of all input elements with respect to all output elements.
Function wrap(const std::string &name) const
Wrap in an Function instance consisting of only one MX call.
Dict generate_options(const std::string &target) const override
Reconstruct options dict.
bool has_sprev() const
Is the class able to propagate seeds through the algorithm?
std::vector< double * > buf_out(VecRes res) const
Supported arguments for numerical evaluation and converters.
casadi_int numel_in() const
Get number of input elements.
Function forward(casadi_int nfwd) const
Get a function that calculates nfwd forward derivatives.
casadi_int nnz_out() const
Get number of output nonzeros.
static Function if_else(const std::string &name, const Function &f_true, const Function &f_false, const Dict &opts=Dict())
Constructor (if-else)
void sz_work(size_t &sz_arg, size_t &sz_res, size_t &sz_iw, size_t &sz_w) const
Get number of temporary variables needed.
const std::map< std::string, std::vector< double > > & MapArg
Supported arguments for numerical evaluation and converters.
void print_options(std::ostream &stream=casadi::uout()) const
Print options to a stream.
casadi_int n_instructions() const
Number of instruction in the algorithm (SXFunction/MXFunction)
size_t sz_res() const
Get required length of res field.
std::vector< bool > which_depends(const std::string &s_in, const std::vector< std::string > &s_out, casadi_int order=1, bool tr=false) const
Which variables enter with some order.
void generate_in(const std::string &fname, const std::vector< DM > &arg)
Export an input file that can be passed to generate C code with a main.
void print_option(const std::string &name, std::ostream &stream=casadi::uout()) const
Print all information there is to know about a certain option.
void construct(const std::string &name, const std::vector< SX > &ex_in, const std::vector< SX > &ex_out, const std::vector< std::string > &name_in, const std::vector< std::string > &name_out, const Dict &opts)
Called by constructors.
std::string generate_dependencies(const std::string &fname, const Dict &opts=Dict()) const
Export / Generate C code for the dependency function.
static Function deserialize(std::istream &stream)
Build function from serialization.
static Function conditional(const std::string &name, const std::vector< Function > &f, const Function &f_def, const Dict &opts=Dict())
Constuct a switch function.
void save(const std::string &fname, const Dict &opts=Dict()) const
Save Function to a file.
std::vector< bool > is_diff_in() const
Get differentiability of inputs/output.
std::vector< std::string > get_function() const
Get a list of all functions.
std::vector< double > nz_from_in(const std::vector< DM > &arg) const
Convert from/to flat vector of input/output nonzeros.
void assert_size_in(casadi_int i, casadi_int nrow, casadi_int ncol) const
Assert that an input dimension is equal so some given value.
casadi_int size2_out(casadi_int ind) const
Get output dimension.
const MX mx_in(casadi_int ind) const
Get symbolic primitives equivalent to the input expressions.
bool has_spfwd() const
Is the class able to propagate seeds through the algorithm?
void set_temp(const double **arg, double **res, casadi_int *iw, double *w, int mem=0) const
Set the (temporary) work vectors.
const std::vector< std::vector< double > > & VecArg
Supported arguments for numerical evaluation and converters.
double max_in(casadi_int ind) const
Get largest input value.
const Sparsity & sparsity_out(casadi_int ind) const
Get sparsity of a given output.
FunctionInternal * get() const
static bool proceed_to(std::istream &file, const std::string &str)
Helper function for parsing .casadi files.
casadi_int size1_in(casadi_int ind) const
Get input dimension.
std::vector< std::vector< double > * > VPrRes
Supported arguments for numerical evaluation and converters.
Function fold(casadi_int N, const Dict &opts=Dict()) const
Create a mapaccumulated version of this function.
const std::vector< MX > mx_in() const
Get symbolic primitives equivalent to the input expressions.
Function mapaccum(const std::string &name, casadi_int N, const Dict &opts=Dict()) const
Create a mapaccumulated version of this function.
Function expand() const
Expand a function to SX.
const std::vector< std::string > & name_in() const
Get input scheme.
const std::string & name() const
Name of the function.
Dict cache() const
Get all functions in the cache.
casadi_int numel_out() const
Get number of output elements.
std::vector< const double * > buf_in(VecArg arg) const
Supported arguments for numerical evaluation and converters.
Function wrap() const
Wrap in an Function instance consisting of only one MX call.
static std::string fix_name(const std::string &name)
Turn a string into a valid function name as defined by "check_name".
std::vector< Function > find_functions(casadi_int max_depth=-1) const
Get all functions embedded in the expression graphs.
void reset_dump_count()
Reset the counter used to name dump files.
Function reverse(casadi_int nadj) const
Get a function that calculates nadj adjoint derivatives.
Function oracle() const
Get oracle.
static bool test_cast(const SharedObjectInternal *ptr)
Check if a particular cast is allowed.
Function jacobian() const
Calculate all Jacobian blocks.
void call_gen(std::vector< const D * > arg, std::vector< D * > res) const
Evaluate with temporary memory allocation.
void release(int mem) const
Release a memory object.
casadi_int index_in(const std::string &name) const
Find the index for a string describing a particular entry of an input scheme.
std::vector< casadi_int > instruction_input(casadi_int k) const
Locations in the work vector for the inputs of the instruction.
static Function create(FunctionInternal *node)
Create from node.
std::vector< double > nominal_in(casadi_int ind) const
Get nominal input value.
std::vector< MX > mapsum(const std::vector< MX > &x, const std::string ¶llelization="serial") const
Evaluate symbolically in parallel and sum (matrix graph)
static Function bspline(const std::string &name, const std::vector< std::vector< double > > &knots, const std::vector< double > &coeffs, const std::vector< casadi_int > °ree, casadi_int m=1, const Dict &opts=Dict())
BSpline evaluator function.
static bool check_name(const std::string &name)
Check if a string is a valid function name.
casadi_int checkout() const
Checkout a memory object.
std::vector< MX > free_mx() const
Get all the free variables of the function.
Function hessian_old(casadi_int iind, casadi_int oind) const
[DEPRECATED] Replaced by Function::factory.
casadi_int n_nodes() const
Number of nodes in the algorithm.
const Sparsity sparsity_jac(casadi_int iind, casadi_int oind, bool compact=false, bool symmetric=false) const
std::pair< casadi_int, casadi_int > size_out(casadi_int ind) const
Get output dimension.
std::map< std::string, std::vector< double > > & MapRes
Supported arguments for numerical evaluation and converters.
int rev(bvec_t **arg, bvec_t **res, casadi_int *iw, bvec_t *w, int mem=0) const
Propagate sparsity backward.
void setup(const double **arg, double **res, casadi_int *iw, double *w, int mem=0) const
Set the (persistent and temporary) work vectors.
const Sparsity & sparsity_in(casadi_int ind) const
Get sparsity of a given input.
Function find_function(const std::string &name, casadi_int max_depth=-1) const
Get a specific function embedded in the expression graphs.
std::vector< casadi_int > instruction_output(casadi_int k) const
Location in the work vector for the output of the instruction.
std::vector< double > nz_from_out(const std::vector< DM > &arg) const
Convert from/to flat vector of input/output nonzeros.
SX instructions_sx() const
Get the SX node corresponding to all instructions (SXFunction)
void assert_sparsity_out(casadi_int i, const Sparsity &sp, casadi_int n=1, bool allow_all_zero_sparse=true) const
Assert that an output sparsity is a multiple of some given sparsity.
MX instruction_MX(casadi_int k) const
Get the MX node corresponding to an instruction (MXFunction)
const SX sx_in(casadi_int iind) const
Get symbolic primitives equivalent to the input expressions.
static Function jit(const std::string &name, const std::string &body, const std::vector< std::string > &name_in, const std::vector< std::string > &name_out, const Dict &opts=Dict())
Create a just-in-time compiled function from a C language string.
const std::vector< T > sym_in() const
Get symbolic primitives equivalent to the input expressions.
std::vector< double > nominal_out(casadi_int ind) const
Get nominal output value.
size_t sz_iw() const
Get required length of iw field.
const std::vector< SX > sx_out() const
Get symbolic primitives equivalent to the output expressions.
casadi_int n_out() const
Get the number of function outputs.
std::vector< bool > is_diff_out() const
Get differentiability of inputs/output.
casadi_int n_in() const
Get the number of function inputs.
bool has_out(const std::string &name) const
Does the function have a particularly named output?
void * memory(int ind) const
Get memory object.
static std::vector< SX > order(const std::vector< SX > &expr)
std::vector< std::string > get_free() const
Get free variables as a string.
DMDict convert_in(const std::vector< DM > &arg) const
Convert from/to input/output lists/map.
Function map(casadi_int n, const std::string ¶llelization="serial") const
Create a mapped version of this function.
DMDict convert_out(const std::vector< DM > &arg) const
Convert from/to input/output lists/map.
size_t sz_w() const
Get required length of w field.
size_t sz_arg() const
Get required length of arg field.
void generate_out(const std::string &fname, const std::vector< DM > &arg)
Export an output file that can be checked with generated C code output.
std::string generate(const std::string &fname, const Dict &opts=Dict()) const
Export / Generate C code for the function.
bool is_a(const std::string &type, bool recursive=true) const
Check if the function is of a particular type.
Function transform(const Dict &opts=Dict()) const
Apply transformation passes.
double min_in(casadi_int ind) const
Get smallest input value.
bool has_in(const std::string &name) const
Does the function have a particularly named input?
Function slice(const std::string &name, const std::vector< casadi_int > &order_in, const std::vector< casadi_int > &order_out, const Dict &opts=Dict()) const
returns a new function with a selection of inputs/outputs of the original
bool has_free() const
Does the function have free variables.
const std::vector< SX > sx_in() const
Get symbolic primitives equivalent to the input expressions.
Function wrap_as_needed(const Dict &opts) const
Wrap in a Function with options.
bool operator==(const Function &f) const
Check if same as another function.
casadi_int nnz_in() const
Get number of input nonzeros.
void generate_lifted(Function &vdef_fcn, Function &vinit_fcn) const
Extract the functions needed for the Lifted Newton method.
double instruction_constant(casadi_int k) const
Get the floating point output argument of an instruction (SXFunction)
bool uses_output() const
Do the derivative functions need nondifferentiated outputs?
bool has_function(const std::string &fname) const
Check if a particular dependency exists.
Function()
Default constructor, null pointer.
static Function load(const std::string &filename)
Build function from serialization.
void print_dimensions(std::ostream &stream=casadi::uout()) const
Print dimensions of inputs and outputs.
void merge(const std::vector< MX > &arg, std::vector< MX > &subs_from, std::vector< MX > &subs_to) const
List merge opportunitities.
std::vector< DM > operator()(const std::vector< DM > &arg) const
std::map< std::string, std::vector< double > * > MPrRes
Supported arguments for numerical evaluation and converters.
casadi_int size1_out(casadi_int ind) const
Get output dimension.
std::vector< DM > nz_to_in(const std::vector< double > &arg) const
Convert from/to flat vector of input/output nonzeros.
void export_code(const std::string &lang, const std::string &fname, const Dict &options=Dict()) const
Export function in specific language.
std::pair< casadi_int, casadi_int > size_in(casadi_int ind) const
Get input dimension.
int eval_activity(const bvec_t **arg, bvec_t **res, casadi_int *iw, bvec_t *w, int mem=0) const
Propagate signal activity forward (bit set = active (possibly nonzero))
void call(const std::vector< DM > &arg, std::vector< DM > &res, bool always_inline=false, bool never_inline=false) const
Evaluate the function symbolically or numerically.
casadi_int index_out(const std::string &name) const
Find the index for a string describing a particular entry of an output scheme.
std::vector< DM > nz_to_out(const std::vector< double > &arg) const
Convert from/to flat vector of input/output nonzeros.
Dict stats(int mem=0) const
Get all statistics obtained at the end of the last evaluate call.
const std::vector< Sparsity > & jac_sparsity(bool compact=false) const
Get, if necessary generate, the sparsity of all Jacobian blocks.
std::map< std::string, std::vector< std::string > > AuxOut
std::vector< std::vector< double > > & VecRes
Supported arguments for numerical evaluation and converters.
void set_work(const double **&arg, double **&res, casadi_int *&iw, double *&w, int mem=0) const
Set the (persistent) work vectors.
void serialize(std::ostream &stream, const Dict &opts=Dict()) const
Serialize.
std::vector< SX > free_sx() const
Get all the free variables of the function.
Function factory(const std::string &name, const std::vector< std::string > &s_in, const std::vector< std::string > &s_out, const AuxOut &aux=AuxOut(), const Dict &opts=Dict()) const
casadi_int size2_in(casadi_int ind) const
Get input dimension.
casadi_int instruction_id(casadi_int k) const
Identifier index of the instruction (SXFunction/MXFunction)
const std::vector< std::string > & name_out() const
Get output scheme.
std::vector< bool > activity(const std::vector< bool > &arg) const
Output signal activity induced by a given input activity.
void assert_size_out(casadi_int i, casadi_int nrow, casadi_int ncol) const
Assert that an output dimension is equal so some given value.
void change_option(const std::string &option_name, const GenericType &option_value)
Change option after object creation for debugging.
const std::vector< MX > mx_out() const
Get symbolic primitives equivalent to the output expressions.
Function jacobian_old(casadi_int iind, casadi_int oind) const
[DEPRECATED] Replaced by Function::factory.
FunctionInternal * operator->() const
Const access functions of the node.
double default_in(casadi_int ind) const
Get default input value.
bool has_option(const std::string &option_name) const
Does a particular option exist.
casadi_int numel() const
Get the number of elements.
bool is_dense() const
Check if the matrix expression is dense.
bool is_empty(bool both=false) const
Check if the sparsity is empty, i.e. if one of the dimensions is zero.
bool is_vector() const
Check if the matrix is a row or column vector.
static MX sym(const std::string &name, casadi_int nrow=1, casadi_int ncol=1)
Create an nrow-by-ncol symbolic primitive.
static MX zeros(casadi_int nrow=1, casadi_int ncol=1)
Create a dense matrix or a matrix with specified sparsity with all entries zero.
GenericShared & operator=(const GenericShared &ref)
Assignment operator.
SharedObjectInternal * get() const
Get a const pointer to the node.
bool is_null() const
Is a null pointer?
void own(SharedObjectInternal *node)
Generic data type, can hold different types such as bool, casadi_int, std::string etc.
bool is_string() const
Check if a particular type.
std::string to_string() const
Convert to a type.
Dict to_dict() const
Convert to a type.
casadi_int to_int() const
Convert to a type.
bool is_dict() const
Check if a particular type.
bool is_int() const
Check if a particular type.
Internal node class for MXFunction.
static std::vector< MX > order(const std::vector< MX > &expr)
static MX bspline(const MX &x, const DM &coeffs, const std::vector< std::vector< double > > &knots, const std::vector< casadi_int > °ree, casadi_int m, const Dict &opts=Dict())
static Function create(const std::string &name, const std::string ¶llelization, const Function &f, casadi_int n, const std::vector< bool > &reduce_in, const std::vector< bool > &reduce_out, const Dict &opts=Dict())
std::vector< Scalar > & nonzeros()
static Matrix< double > from_file(const std::string &filename, const std::string &format_hint="")
void construct(const Dict &opts)
Construct.
The basic scalar symbolic class of CasADi.
Internal node class for SXFunction.
static std::vector< SX > order(const std::vector< SX > &expr)
void pack(const Sparsity &e)
Helper class for Serialization.
void pack(const Sparsity &e)
Serializes an object to the output stream.
Class representing a Slice.
casadi_int size1() const
Get the number of rows.
casadi_int size2() const
Get the number of columns.
bool is_dense() const
Is dense?
std::map< std::string, MX > MXDict
std::vector< casadi_int > range(casadi_int start, casadi_int stop, casadi_int step, casadi_int len)
Range function.
std::string join(const std::vector< std::string > &l, const std::string &delim)
unsigned long long bvec_t
std::string transform_token_str(const GenericType &g)
bool isUnique(const std::vector< T > &v)
std::string transform_stats(const Function &f)
std::vector< SX > SXVector
std::vector< MX > MXVector
std::map< std::string, SX > SXDict
std::string transform_passes_str(const std::vector< std::vector< GenericType > > &ps)
std::string str(const T &v)
String representation, any type.
std::vector< casadi_int > lookupvector(const std::vector< casadi_int > &v, casadi_int size)
Returns a vector for quickly looking up entries of supplied list.
GenericType::Dict Dict
C++ equivalent of Python's dict or MATLAB's struct.
std::vector< std::string > StringVector
void normalized_setup(std::istream &stream)
void update_dict(Dict &target, const Dict &source, bool recurse)
Update the target dictionary in place with source elements.
T * get_ptr(std::vector< T > &v)
Get a pointer to the data contained in the vector.
std::initializer_list< SX > SXIList
std::initializer_list< MX > MXIList
bool in_range(const std::vector< T > &v, casadi_int upper)
Check if for each element of v holds: v_i < upper.
std::vector< casadi_int > complement(const std::vector< casadi_int > &v, casadi_int size)
Returns the list of all i in [0, size[ not found in supplied list.
void CASADI_EXPORT _function_buffer_eval(void *raw)
Dict extract_from_dict(const Dict &d, const std::string &key, T &value)
std::map< std::string, DM > DMDict
std::string filename(const std::string &path)
Function external_transform(const std::string &name, const std::string &op, const Function &f, const Dict &opts)
Apply a transformation defined externally.
void normalized_out(std::ostream &stream, double val)