27 #include "code_generator.hpp"
28 #include "function_internal.hpp"
29 #include "convexify.hpp"
30 #include <casadi_runtime_str.h>
31 #include "global_options.hpp"
32 #include "filesystem_impl.hpp"
57 bool prefix_set =
false;
69 for (
auto&& e : opts) {
70 if (e.first==
"verbose") {
72 }
else if (e.first==
"verbose_runtime") {
74 }
else if (e.first==
"mex") {
76 }
else if (e.first==
"with_sfunction") {
78 }
else if (e.first==
"unroll_args") {
80 }
else if (e.first==
"cpp") {
82 }
else if (e.first==
"main") {
83 this->
main = e.second;
84 }
else if (e.first==
"casadi_real") {
86 }
else if (e.first==
"casadi_int") {
88 }
else if (e.first==
"codegen_scalars") {
90 }
else if (e.first==
"with_header") {
92 }
else if (e.first==
"with_mem") {
94 }
else if (e.first==
"with_export") {
96 }
else if (e.first==
"with_import") {
98 }
else if (e.first==
"include_math") {
100 }
else if (e.first==
"infinity") {
101 this->
infinity = e.second.to_string();
102 }
else if (e.first==
"nan") {
103 this->
nan = e.second.to_string();
104 }
else if (e.first==
"real_min") {
105 this->
real_min = e.second.to_string();
106 }
else if (e.first==
"indent") {
109 }
else if (e.first==
"avoid_stack") {
111 }
else if (e.first==
"prefix") {
112 this->
prefix = e.second.to_string();
114 }
else if (e.first==
"max_declarations_per_line") {
117 "Option max_declarations_per_line must be >=0");
118 }
else if (e.first==
"max_initializer_elements_per_line") {
121 "Option max_initializer_elements_per_line must be >=0");
122 }
else if (e.first==
"force_canonical") {
125 casadi_error(
"Unrecognized option: " +
str(e.first));
131 std::stringstream ss;
132 ss << std::scientific << std::setprecision(std::numeric_limits<double>::digits10 + 1);
134 ss << std::numeric_limits<float>::min();
137 ss << std::numeric_limits<double>::min();
152 std::string::size_type dotpos =
name.rfind(
'.');
153 if (dotpos==std::string::npos) {
155 this->
suffix = this->
cpp ?
".cpp" :
".c";
157 this->name =
name.substr(0, dotpos);
158 this->
suffix = name.substr(dotpos);
193 this->
header <<
"#include <casadi/mem.h>\n";
210 std::map<std::string, std::set<std::pair<std::string, std::string>>> local_variables_by_type;
212 local_variables_by_type[e.second.first].insert(std::make_pair(e.first, e.second.second));
216 for (
auto&& e : local_variables_by_type) {
218 for (
auto it=e.second.begin(); it!=e.second.end(); ++it) {
219 bool split_declaration = it==e.second.begin() ||
221 if (split_declaration) {
222 if (it!=e.second.begin())
body <<
";\n";
223 body <<
" " << e.first <<
" ";
227 body << it->second << it->first;
240 auto it = funs.find(f);
241 if (it==funs.end()) {
242 casadi_int n = funs.size();
269 *
this <<
"void " << fname <<
"_incref(void) {\n";
274 *
this <<
"void " << fname <<
"_decref(void) {\n";
284 *
this <<
"int " << fname <<
"_alloc_mem(void) {\n";
292 *
this <<
"int " << fname <<
"_init_mem(int mem) {\n";
300 *
this <<
"void " << fname <<
"_free_mem(int mem) {\n";
308 *
this <<
"int " << fname <<
"_checkout(void) {\n";
316 *
this <<
"void " << fname <<
"_release(int mem) {\n";
337 <<
"return " << codegen_name <<
"(arg, res, iw, w, mem);\n"
343 for (casadi_int i=0; i<f.
n_in(); ++i) {
344 *
this <<
"arg[" << i <<
"] = " << f.
name_in(i) <<
";\n";
346 for (casadi_int i=0; i<f.
n_out(); ++i) {
347 *
this <<
"res[" << i <<
"] = " << f.
name_out(i) <<
";\n";
349 *
this <<
"return " << codegen_name <<
"(arg, res, iw, w, mem);\n";
359 if (with_jac_sparsity) {
383 std::stringstream ss;
384 ss << CASADI_MAJOR_VERSION <<
"." << CASADI_MINOR_VERSION <<
"." << CASADI_PATCH_VERSION;
385 if (!CASADI_IS_RELEASE) ss <<
"+";
394 f <<
"/* This file was automatically generated by CasADi " <<
casadi_version() <<
".\n"
395 <<
" * It consists of: \n"
396 <<
" * 1) content generated by CasADi runtime: not copyrighted\n"
397 <<
" * 2) template code copied from CasADi source: permissively licensed (MIT-0)\n"
398 <<
" * 3) user code: owned by the user\n"
404 f <<
"#ifdef __cplusplus\n"
405 <<
"extern \"C\" {\n"
413 f <<
"#ifdef __cplusplus\n"
414 <<
"} /* extern \"C\" */\n"
422 void CodeGenerator::generate_casadi_real(std::ostream &s)
const {
423 s <<
"#ifndef casadi_real\n"
428 void CodeGenerator::generate_export_symbol(std::ostream &s)
const {
429 s <<
"/* Symbol visibility in DLLs */\n"
430 <<
"#ifndef CASADI_SYMBOL_EXPORT\n"
431 <<
" #if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)\n"
432 <<
" #if defined(STATIC_LINKED)\n"
433 <<
" #define CASADI_SYMBOL_EXPORT\n"
435 <<
" #define CASADI_SYMBOL_EXPORT __declspec(dllexport)\n"
437 <<
" #elif defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY)\n"
438 <<
" #define CASADI_SYMBOL_EXPORT __attribute__ ((visibility (\"default\")))\n"
439 <<
" #else" << std::endl
440 <<
" #define CASADI_SYMBOL_EXPORT\n"
445 void CodeGenerator::generate_import_symbol(std::ostream &s)
const {
446 s <<
"/* Symbol visibility in DLLs */\n"
447 <<
"#ifndef CASADI_SYMBOL_IMPORT\n"
448 <<
" #if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)\n"
449 <<
" #if defined(STATIC_LINKED)\n"
450 <<
" #define CASADI_SYMBOL_IMPORT\n"
452 <<
" #define CASADI_SYMBOL_IMPORT __declspec(dllimport)\n"
454 <<
" #elif defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY)\n"
455 <<
" #define CASADI_SYMBOL_IMPORT __attribute__ ((visibility (\"default\")))\n"
456 <<
" #else" << std::endl
457 <<
" #define CASADI_SYMBOL_IMPORT\n"
462 void CodeGenerator::generate_casadi_int(std::ostream &s)
const {
463 s <<
"#ifndef casadi_int\n"
471 casadi_assert(
prefix.find(this->name + this->suffix)==std::string::npos,
472 "The signature of CodeGenerator::generate has changed. "
473 "Instead of providing the filename, only provide the prefix.");
484 s <<
"CASADI_SYMBOL_EXPORT casadi_real* CASADI_PREFIX(get_pool_double)(const char* name) {\n";
486 casadi_int i = e.second;
487 s <<
" if (strcmp(name, \"" + e.first +
"\")==0) "
488 <<
"return casadi_pd" +
str(i) +
";\n";
495 if (this->
mex) generate_mex(s);
498 if (this->
main) generate_main(s);
508 generate_sfunction(sfunction_name, sfunction_code);
518 generate_casadi_real(s);
521 generate_casadi_int(s);
535 void CodeGenerator::generate_mex(std::ostream &s)
const {
537 s <<
"#ifdef MATLAB_MEX_FILE\n";
540 if (this->
cpp) s <<
"extern \"C\"\n";
541 s <<
"void mexFunction(int resc, mxArray *resv[], int argc, const mxArray *argv[]) {"
549 s <<
" char buf[" << (buf_len+1) <<
"];\n";
552 s <<
" int buf_ok = argc > 0 && !mxGetString(*argv, buf, sizeof(buf));\n";
555 s <<
" if (!buf_ok) {\n";
558 s <<
" mex_" <<
exposed_fname[0] <<
"(resc, resv, argc, argv);\n"
561 s <<
" /* name error */\n";
564 s <<
" } else if (strcmp(buf, \"" <<
exposed_fname[i] <<
"\")==0) {\n"
565 <<
" mex_" <<
exposed_fname[i] <<
"(resc, resv, argc-1, argv+1);\n"
571 s <<
" mexErrMsgTxt(\"First input should be a command string. Possible values:";
582 void CodeGenerator::generate_sfunction(
const std::string& name,
583 const std::string& sfunction)
const {
589 f <<
"// Must specify the S_FUNCTION_NAME as the name of the S-function\n"
590 <<
"#define S_FUNCTION_NAME sfun_" <<
name <<
"\n"
591 <<
"#define S_FUNCTION_LEVEL 2\n\n"
592 <<
"// Need to include simstruc.h for the definition of the SimStruct and its\n"
593 <<
"// associated macro definitions\n"
594 <<
"#ifndef __SIMSTRUC__\n"
595 <<
"#include \"simstruc.h\"\n"
597 <<
"// Specific header file(s) required by the legacy code function\n"
598 <<
"#include \"" << this->name <<
".h\"\n\n\n";
607 std::string CodeGenerator::codegen_sfunction(
const Function& f)
const {
613 g <<
"/* Function: mdlInitializeSizes ===========================================\n"
615 <<
"* The sizes information is used by Simulink to determine the S-function\n"
616 <<
"* blocks characteristics (number of inputs, outputs, states, etc.).\n"
618 <<
"static void mdlInitializeSizes(SimStruct *S)\n"
620 <<
" /* Declare auxilary variables */\n"
622 <<
" const int_T* sp;\n\n"
623 <<
" /* Set number of simulink s-function block parameters "
624 "(the ones which appear by double click on simulink block) */\n"
625 <<
" ssSetNumSFcnParams(S, 0);\n\n"
626 <<
" /* Report if parameter mismatch occurs */\n"
627 <<
" if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) return;\n\n"
628 <<
" /* Specify the number of states for which a block detects "
629 "zero crossings that occur between sample points */\n"
630 <<
" ssSetNumNonsampledZCs(S, 0);\n\n"
631 <<
" /* Set number of simulink input ports */\n"
632 <<
" if (!ssSetNumInputPorts(S, " << f->n_in_ <<
")) return;\n\n"
633 <<
" /* Configure simulink input ports (inputs are assumed to be dense "
634 "vectors or matrices) */\n"
635 <<
" for (ii=0; ii<" << f->n_in_ <<
"; ++ii) {\n"
636 <<
" sp = " << f.name() <<
"_sparsity_in(ii);\n"
637 <<
" if (sp[1]==1) {\n"
638 <<
" ssSetInputPortWidth(S, ii, sp[0]);\n"
641 <<
" ssSetInputPortMatrixDimensions(S, ii, sp[0], sp[1]);\n"
643 <<
" ssSetInputPortDirectFeedThrough(S, ii, 1);\n"
645 <<
" /* Set number of simulink output ports */\n"
646 <<
" if (!ssSetNumOutputPorts(S, " << f->n_out_ <<
")) return;\n\n"
647 <<
" /* Configure simulink output ports (dense or sparse vectors or matrices allowed) */\n"
648 <<
" for (ii=0; ii<" << f->n_out_ <<
"; ++ii) {\n"
649 <<
" sp = " << f.name() <<
"_sparsity_out(ii);\n"
650 <<
" if (sp[1]==1) {\n"
651 <<
" ssSetOutputPortWidth(S, ii, sp[0]);\n"
654 <<
" ssSetOutputPortMatrixDimensions(S, ii, sp[0], sp[1]);\n"
657 <<
" ssSetOutputPortOutputExprInRTW(S, 0, 0);\n\n"
658 <<
" /* This S-function can be used in referenced model simulating in normal mode */\n"
659 <<
" ssSetModelReferenceNormalModeSupport(S, MDL_START_AND_MDL_PROCESS_PARAMS_OK);\n\n"
660 <<
" /* Set the number of sample time */\n"
661 <<
" ssSetNumSampleTimes(S, 1);\n\n"
662 <<
" /* Set the compliance with the SimState feature */\n"
663 <<
" ssSetSimStateCompliance(S, USE_DEFAULT_SIM_STATE);\n\n"
665 <<
" * All options have the form SS_OPTION_<name> and are documented in\n"
666 <<
" * matlabroot/simulink/include/simstruc.h. The options should be\n"
667 <<
" * bitwise ord together as in\n"
668 <<
" * ssSetOptions(S, (SS_OPTION_name1 | SS_OPTION_name2))\n"
673 g <<
"/* Function: mdlInitializeSampleTimes =====================================\n"
675 <<
" * This function is used to specify the sample time(s) for your\n"
676 <<
" * S-function. You must register the same number of sample times as\n"
677 <<
" * specified in ssSetNumSampleTimes.\n"
679 <<
"static void mdlInitializeSampleTimes(SimStruct *S)\n"
681 <<
" ssSetSampleTime(S, 0, INHERITED_SAMPLE_TIME);\n"
682 <<
" ssSetOffsetTime(S, 0, FIXED_IN_MINOR_STEP_OFFSET);\n"
683 <<
" #if defined(ssSetModelReferenceSampleTimeDefaultInheritance)\n"
684 <<
" ssSetModelReferenceSampleTimeDefaultInheritance(S);\n"
689 g <<
"/* Function: mdlOutputs ===================================================\n"
691 <<
" * In this function, you compute the outputs of your S-function\n"
692 <<
" * block. Generally outputs are placed in the output vector(s),\n"
693 <<
" * ssGetOutputPortSignal.\n"
695 <<
"static void mdlOutputs(SimStruct *S, int_T tid)\n"
697 <<
" /* Declare auxilary variables */\n"
698 <<
" int_T ii, jj, row, col, nnz_col, ind_start_row_index, offset = 0, jj_total = 0;\n"
699 <<
" const int_T* sp;\n\n"
700 <<
" /* Allocate buffers for casadi input and output and simulink output */\n"
701 <<
" " +
array(
"real_T",
"w", f->sz_w()+f->nnz_out())
702 <<
" " +
array(
"int_T",
"iw", f->sz_iw())
703 <<
" const real_T* arg[" << f->sz_arg() <<
"] = {0};\n"
704 <<
" real_T* res[" << f->sz_res() <<
"] = {0};\n"
705 <<
" real_T* y[" << f->n_out_ <<
"] = {0};\n\n"
706 <<
" /* Point inputs directly to casadi input buffer */\n"
707 <<
" for (ii=0; ii<" << f->n_in_ <<
";++ii) {\n"
708 <<
" arg[ii] = *ssGetInputPortRealSignalPtrs( S, ii );\n"
710 <<
" /* Point outputs to buffer */\n"
711 <<
" for (ii=0; ii<" << f->n_out_ <<
";++ii) {\n"
712 <<
" y[ii] = ssGetOutputPortRealSignal( S, ii );\n"
714 <<
" /* Point allocated working array to casadi output buffer */\n";
715 for (casadi_int ii=0; ii<f->n_out_; ++ii) {
716 g <<
" res[" << ii <<
"] = w + offset;\n"
717 <<
" offset += " << f.nnz_out(ii) <<
";\n";
720 <<
" /* Call CasADi function */\n"
721 <<
" " << f.name() <<
"( arg, res, iw, w+offset, 0 );\n\n"
722 <<
" /* Assign results to Simulink output array */\n"
723 <<
" for (ii=0; ii<" << f->n_out_ <<
"; ++ii){\n\n"
724 <<
" /* Get sparsity information of casadi function output "
725 "(sp[0] - n_rows, sp[1] - n_cols, sp[2] - dense/sparse) */\n"
726 <<
" sp = " << f.name() <<
"_sparsity_out(ii);\n\n"
727 <<
" /* Check if output is dense (sp[2]=1) or sparse (sp[2]=0) */\n"
728 <<
" if (sp[2]==0) {\n"
729 <<
" jj_total = 0;\n"
730 <<
" ind_start_row_index = 2 + sp[1] + 1;\n\n"
731 <<
" /* Distribute nonzero elements column by column */\n"
732 <<
" for (col=0; col<sp[1]; col++) {\n\n"
733 <<
" /* The cumulative sum of nonzero elements after each column starts at index 2, "
734 "after last entry of CCS array col_ptr; number of nonzero elements in current column is "
735 "obtained by the difference of two consecutive values */\n"
736 <<
" nnz_col = sp[2+col+1] - sp[2+col];\n\n"
737 <<
" /* Distribute nonzero elements of current column to correct row position */\n"
738 <<
" for (jj=0; jj<nnz_col; jj++) {\n"
739 <<
" row = sp[ind_start_row_index+jj_total];\n"
740 <<
" y[ii][row + sp[0]*col] = res[ii][jj_total];\n"
746 <<
" y[ii] = res[ii];\n"
752 g <<
"/* Function: mdlTerminate =================================================\n"
754 <<
" * In this function, you should perform any actions that are necessary\n"
755 <<
" * at the termination of a simulation.\n"
757 <<
"static void mdlTerminate(SimStruct *S)\n"
760 <<
"/* Required S-function trailer */\n"
761 <<
"#ifdef MATLAB_MEX_FILE\n"
762 <<
"# include \"simulink.c\"\n"
764 <<
"# include \"cg_sfun.h\"\n"
770 void CodeGenerator::generate_main(std::ostream &s)
const {
771 s << this->
dll_export <<
"int main(int argc, char* argv[]) {\n";
774 s <<
" if (argc<2) {\n"
775 <<
" /* name error */\n";
777 s <<
" } else if (strcmp(argv[1], \"" <<
exposed_fname[i] <<
"\")==0) {\n"
778 <<
" return main_" <<
exposed_fname[i] <<
"(argc-2, argv+2);\n";
783 s <<
" fprintf(stderr, \"First input should be a command string. Possible values:";
788 s <<
"Note: you may use function.generate_input to create a command string.";
807 return "casadi_rd" +
str(size);
821 return "casadi_ri" +
str(size);
839 return "casadi_pd" +
str(it->second);
847 s <<
"/* How to prefix internal symbols */\n"
848 <<
"#ifdef CASADI_CODEGEN_PREFIX\n"
849 <<
" #define CASADI_NAMESPACE_CONCAT(NS, ID) _CASADI_NAMESPACE_CONCAT(NS, ID)\n"
850 <<
" #define _CASADI_NAMESPACE_CONCAT(NS, ID) NS ## ID\n"
851 <<
" #define CASADI_PREFIX(ID) CASADI_NAMESPACE_CONCAT(CODEGEN_PREFIX, ID)\n"
853 <<
" #define CASADI_PREFIX(ID) " << this->
prefix <<
"_ ## ID\n"
861 generate_casadi_real(s);
864 generate_casadi_int(s);
867 s <<
"#ifndef CASADI_MAX_NUM_THREADS\n";
868 s <<
"#define CASADI_MAX_NUM_THREADS 1\n";
875 s <<
"#include <casadi/mem.h>\n" << std::endl;
880 s <<
"/* Add prefix to internal symbols */\n";
882 s <<
"#define " <<
"casadi_" << i <<
" CASADI_PREFIX(" << i <<
")\n";
933 std::vector<double> sz_zeros(
sz_zeros_, 0);
934 print_vector(s,
"casadi_zeros", std::vector<double>(sz_zeros));
939 std::vector<double> sz_ones(
sz_ones_, 0);
940 print_vector(s,
"casadi_ones", std::vector<double>(sz_ones));
948 s <<
"static casadi_real casadi_rd" +
str(i++) +
"[" +
str(it.second) +
"];\n";
957 s <<
"static casadi_real casadi_ri" +
str(i++) +
"[" +
str(it.second) +
"];\n";
966 s <<
"casadi_real casadi_pd" +
str(i) +
975 s <<
"/* External functions */\n";
979 s << std::endl << std::endl;
983 s << this->
body.str();
1003 if (n<0)
return "0";
1004 std::stringstream s;
1020 std::stringstream ss;
1027 const std::string& def) {
1028 std::stringstream s;
1031 s <<
"*" <<
name <<
" = 0";
1033 s <<
name <<
"[" << len <<
"]";
1034 if (!def.empty()) s <<
" = " << def;
1041 const std::vector<casadi_int>& v) {
1046 const std::vector<char>& v) {
1051 const std::vector<double>& v) {
1056 const std::vector<std::string>& v) {
1064 return "casadi_fabs("+a0+
")";
1067 return "casadi_sq("+a0+
")";
1070 return "casadi_sign("+a0+
")";
1073 return "casadi_log1p("+a0+
")";
1076 return "casadi_expm1("+a0+
")";
1085 return "casadi_fmin("+a0+
","+a1+
")";
1088 return "casadi_fmax("+a0+
","+a1+
")";
1091 return "casadi_hypot("+a0+
","+a1+
")";
1094 return "casadi_printme("+a0+
","+a1+
")";
1101 const std::string& use_ifdef) {
1109 if (!use_ifdef.empty()) this->
includes <<
"#ifdef " << use_ifdef << std::endl;
1112 if (relative_path) {
1113 this->
includes <<
"#include \"" << new_include <<
"\"\n";
1115 this->
includes <<
"#include <" << new_include <<
">\n";
1119 if (!use_ifdef.empty()) this->
includes <<
"#endif\n";
1126 *
this << s <<
".checkout = " <<
name <<
"_checkout;\n";
1128 *
this << s <<
".checkout = 0;\n";
1131 *
this << s <<
".eval = " <<
name <<
";\n";
1133 *
this << s <<
".release = " <<
name <<
"_release;\n";
1135 *
this << s <<
".release = 0;\n";
1141 const std::string& res,
const std::string& iw,
1142 const std::string& w,
const std::string& failure_ret) {
1146 std::string
mem =
"mid";
1147 local(
"flag",
"int");
1149 *
this <<
mem <<
" = " <<
name <<
"_checkout();\n";
1150 *
this <<
"if (" <<
mem <<
"<0) return " << failure_ret <<
";\n";
1151 *
this <<
"flag = " +
name +
"(" +
arg +
", " +
res +
", "
1152 + iw +
", " + w +
", " <<
mem <<
");\n";
1153 *
this <<
name <<
"_release(" <<
mem <<
");\n";
1157 + iw +
", " + w +
", 0)";
1167 return "casadi_" +
name;
1172 if (!allow_adding) {
1173 casadi_assert(added,
"Duplicate macro: " +
name);
1175 return "casadi_" +
name;
1194 casadi_assert_dev(
sizeof(
double) %
sizeof(
size_t)==0);
1195 const casadi_int int_len = v.size()*(
sizeof(double)/
sizeof(
size_t));
1196 const size_t* int_v =
reinterpret_cast<const size_t*
>(&v.front());
1197 for (
size_t i=0; i<int_len; ++i) {
1228 for (
auto i=eq.first; i!=eq.second; ++i) {
1239 casadi_error(
"Constant not found");
1249 std::pair<std::multimap<size_t, size_t>::iterator, std::multimap<size_t, size_t>::iterator> eq =
1251 for (std::multimap<size_t, size_t>::iterator i=eq.first; i!=eq.second; ++i) {
1262 casadi_error(
"Constant not found");
1272 std::pair<std::multimap<size_t, size_t>::iterator, std::multimap<size_t, size_t>::iterator> eq =
1274 for (std::multimap<size_t, size_t>::iterator i=eq.first; i!=eq.second; ++i) {
1285 casadi_error(
"Constant not found");
1295 std::pair<std::multimap<size_t, size_t>::iterator, std::multimap<size_t, size_t>::iterator> eq =
1297 for (std::multimap<size_t, size_t>::iterator i=eq.first; i!=eq.second; ++i) {
1308 casadi_error(
"Constant not found");
1336 const std::string& name,
const std::vector<casadi_int>& v,
const std::string& type) {
1345 (*this) <<
"for (i=0;i<" << v.size() <<
";++i) " +
name +
"[i] = " + ref +
"[i];\n";
1359 for (
auto it=f_match.first; it!=f_match.second; ++it) {
1360 if (it->second==inst)
return;
1492 std::vector<std::string> inst2 = inst;
1493 if (inst.size()==1) inst2.push_back(inst[0]);
1500 std::vector<std::string> inst2 = inst;
1501 if (inst.size()==1) inst2.push_back(inst[0]);
1670 this->
auxiliaries <<
"#define casadi_to_double(x) "
1671 <<
"(" << (this->
cpp ?
"static_cast<double>(x)" :
"(double) x") <<
")\n\n";
1675 <<
"(" << (this->
cpp ?
"static_cast<casadi_int>(x)" :
"(casadi_int) x")
1680 <<
"(" << (this->
cpp ?
"static_cast<x>(y)" :
"(x) y") <<
")\n\n";
1684 this->
auxiliaries <<
"casadi_real casadi_sq(casadi_real x) { return x*x;}\n\n";
1688 this->
auxiliaries <<
"casadi_real casadi_sign(casadi_real x) "
1689 <<
"{ return x<0 ? -1 : x>0 ? 1 : x;}\n\n";
1694 <<
"(casadi_real c, casadi_real x, casadi_real y) "
1695 <<
"{ return c!=0 ? x : y;}\n\n";
1701 <<
" #define CASADI_PRINTF mexPrintf\n"
1703 <<
" #define CASADI_PRINTF printf\n"
1707 this->
auxiliaries <<
"#define CASADI_PRINTF printf\n";
1709 this->
auxiliaries <<
"#define CASADI_SNPRINTF snprintf\n";
1716 this->
auxiliaries <<
"casadi_real casadi_fmin(casadi_real x, casadi_real y) {\n"
1717 <<
"/* Pre-c99 compatibility */\n"
1718 <<
"#if __STDC_VERSION__ < 199901L\n"
1719 <<
" return x<y ? x : y;\n"
1721 <<
" return fmin(x, y);\n"
1727 this->
auxiliaries <<
"casadi_real casadi_fmax(casadi_real x, casadi_real y) {\n"
1728 <<
"/* Pre-c99 compatibility */\n"
1729 <<
"#if __STDC_VERSION__ < 199901L\n"
1730 <<
" return x>y ? x : y;\n"
1732 <<
" return fmax(x, y);\n"
1738 this->
auxiliaries <<
"casadi_real casadi_fabs(casadi_real x) {\n"
1739 <<
"/* Pre-c99 compatibility */\n"
1740 <<
"#if __STDC_VERSION__ < 199901L\n"
1741 <<
" return x>0 ? x : -x;\n"
1743 <<
" return fabs(x);\n"
1749 this->
auxiliaries <<
"casadi_real casadi_isinf(casadi_real x) {\n"
1750 <<
"/* Pre-c99 compatibility */\n"
1751 <<
"#if __STDC_VERSION__ < 199901L\n"
1752 <<
" return x== INFINITY || x==-INFINITY;\n"
1754 <<
" return isinf(x);\n"
1759 this->
auxiliaries <<
"casadi_int casadi_min(casadi_int x, casadi_int y) {\n"
1760 <<
" return x>y ? y : x;\n"
1764 this->
auxiliaries <<
"casadi_int casadi_max(casadi_int x, casadi_int y) {\n"
1765 <<
" return x>y ? x : y;\n"
1780 <<
" #define casadi_inf " << this->
infinity <<
"\n"
1785 <<
" #define casadi_nan " << this->
nan <<
"\n"
1790 <<
" #define casadi_real_min " << this->
real_min <<
"\n"
1795 this->
auxiliaries <<
"casadi_real casadi_log1p(casadi_real x) {\n"
1796 <<
"/* Pre-c99 compatibility */\n"
1797 <<
"#if __STDC_VERSION__ < 199901L\n"
1798 <<
" return log(1+x);\n"
1800 <<
" return log1p(x);\n"
1806 this->
auxiliaries <<
"casadi_real casadi_expm1(casadi_real x) {\n"
1807 <<
"/* Pre-c99 compatibility */\n"
1808 <<
"#if __STDC_VERSION__ < 199901L\n"
1809 <<
" return exp(x)-1;\n"
1811 <<
" return expm1(x);\n"
1817 this->
auxiliaries <<
"casadi_real casadi_hypot(casadi_real x, casadi_real y) {\n"
1818 <<
"/* Pre-c99 compatibility */\n"
1819 <<
"#if __STDC_VERSION__ < 199901L\n"
1820 <<
" return sqrt(x*x+y*y);\n"
1822 <<
" return hypot(x, y);\n"
1853 std::stringstream s;
1854 s <<
"casadi_to_mex(" <<
sparsity(sp) <<
", " <<
arg <<
");";
1859 const std::string& res, std::size_t res_off,
1860 const Sparsity& sp_res,
const std::string& w) {
1865 std::stringstream s;
1866 s <<
"casadi_from_mex(" <<
arg
1867 <<
", " <<
res <<
", " <<
sparsity(sp_res) <<
", " << w <<
");";
1873 std::stringstream ret;
1875 std::istringstream stream(casadi_fmu_str);
1876 while (std::getline(stream, line)) {
1878 if (line.find(
"MODELNAME") != std::string::npos) {
1879 line =
replace(line,
"MODELNAME", modelname);
1882 ret << line <<
"\n";
1888 std::string ret = v;
1889 ret =
replace(ret,
"\\",
"\\\\");
1890 ret =
replace(ret,
"\"",
"\\\"");
1891 return "\"" + ret +
"\"";
1899 return constant(
static_cast<casadi_int
>(v));
1902 std::stringstream s;
1906 }
else if (isinf(v)) {
1911 casadi_int v_int =
static_cast<casadi_int
>(v);
1912 if (
static_cast<double>(v_int)==v) {
1917 std::ios_base::fmtflags fmtfl = s.flags();
1918 s << std::scientific << std::setprecision(std::numeric_limits<double>::digits10 + 1) << v;
1926 std::size_t n,
const std::string& res) {
1927 std::stringstream s;
1930 s <<
"casadi_copy(" <<
arg <<
", " << n <<
", " <<
res <<
");";
1940 bool check_lhs,
bool check_rhs) {
1941 std::vector<std::string> checks;
1942 if (check_lhs) checks.push_back(
arg);
1943 if (check_rhs) checks.push_back(
res);
1944 if (!checks.empty()) *
this <<
"if (" <<
join(checks,
" && ") <<
") ";
1949 const std::string& def,
bool check_rhs) {
1950 *
this <<
"if (" <<
arg <<
") {\n";
1951 if (check_rhs) *
this <<
"if (" <<
res <<
") ";
1953 *
this <<
"} else {\n";
1954 if (check_rhs) *
this <<
"if (" <<
res <<
") ";
1955 *
this <<
fill(
res, n, def) <<
"\n";
1960 std::stringstream s;
1963 s <<
"casadi_clear(" <<
res <<
", " << n <<
");";
1968 return "arg[" +
str(i) +
"]";
1972 return "res[" +
str(i) +
"]";
1978 return mem_array+
"[mem]";
1982 std::size_t n,
const std::string& v) {
1984 std::stringstream s;
1987 s <<
"casadi_fill(" <<
res <<
", " << n <<
", " << v <<
");";
1992 const std::string& y) {
1994 std::stringstream s;
1995 s <<
"casadi_dot(" << n <<
", " << x <<
", " << y <<
")";
2000 const std::string& x,
const std::string& y) {
2002 std::stringstream s;
2003 s <<
"casadi_bilin(" << A <<
", " <<
sparsity(sp_A) <<
", " << x <<
", " << y <<
")";
2008 const std::string& alpha,
const std::string& x,
2009 const std::string& y) {
2011 std::stringstream s;
2012 s <<
"casadi_rank1(" << A <<
", " <<
sparsity(sp_A) <<
", "
2013 << alpha <<
", " << x <<
", " << y <<
");";
2018 const std::string& res, casadi_int ndim,
const std::string& grid,
2019 const std::string& offset,
2020 const std::string& values,
const std::string& x,
2021 const std::string& lookup_mode, casadi_int m,
2022 const std::string& iw,
const std::string& w) {
2024 std::stringstream s;
2025 s <<
"casadi_interpn(" <<
res <<
", " << ndim <<
", " << grid <<
", " << offset <<
", "
2026 << values <<
", " << x <<
", " << lookup_mode <<
", " << m <<
", " << iw <<
", " << w <<
");";
2031 casadi_int ndim,
const std::string& grid,
const std::string& offset,
2032 const std::string& values,
const std::string& x,
2033 const std::string& lookup_mode, casadi_int m,
2034 const std::string& iw,
const std::string& w) {
2036 std::stringstream s;
2037 s <<
"casadi_interpn_grad(" << grad <<
", " << ndim <<
", " << grid <<
", " << offset <<
", "
2038 << values <<
", " << x <<
", " << lookup_mode <<
"," << m <<
", " << iw <<
", " << w <<
");";
2043 const std::string& y,
const Sparsity& sp_y,
2044 const std::string& iw) {
2046 return "casadi_trans(" + x +
"," +
sparsity(sp_x) +
", "
2047 + y +
", " +
sparsity(sp_y) +
", " + iw +
")";
2052 std::string cpp_prefix = this->
cpp ?
"extern \"C\" " :
"";
2060 return cpp_prefix + this->dll_export + s;
2065 const std::string& res,
const Sparsity& sp_res,
2066 const std::string& w) {
2072 std::stringstream s;
2073 s <<
"casadi_project(" <<
arg <<
", " <<
sparsity(sp_arg) <<
", " <<
res <<
", "
2074 <<
sparsity(sp_res) <<
", " << w <<
");";
2080 const std::string& res,
bool lower) {
2083 std::stringstream s;
2084 s <<
"casadi_tri_project(" <<
arg <<
", " <<
sparsity(sp_arg) <<
", ";
2085 s <<
res <<
", " << (lower ? 1: 0) <<
");";
2091 const std::string& res,
bool tr) {
2094 std::stringstream s;
2095 s <<
"casadi_densify(" <<
arg <<
", " <<
sparsity(sp_arg) <<
", " <<
res <<
", "
2096 << (tr ? 1 : 0) <<
");";
2105 std::stringstream s;
2106 s <<
"casadi_sparsify(" <<
arg <<
", " <<
res <<
", "
2107 <<
sparsity(sp_res) <<
", " << (tr ? 1 : 0) <<
");";
2113 std::stringstream s;
2114 s <<
"CASADI_PRINTF(\"" <<
str <<
"\"";
2115 for (casadi_int i=0; i<
arg.size(); ++i) s <<
", " <<
arg[i];
2121 std::vector<std::string>
arg;
2122 arg.push_back(arg1);
2127 const std::string& arg2) {
2128 std::vector<std::string>
arg;
2129 arg.push_back(arg1);
2130 arg.push_back(arg2);
2135 const std::string& arg2,
const std::string& arg3) {
2136 std::vector<std::string>
arg;
2137 arg.push_back(arg1);
2138 arg.push_back(arg2);
2139 arg.push_back(arg3);
2144 const std::string& x,
const std::string& y) {
2146 return "casadi_axpy(" +
str(n) +
", " + a +
", " + x +
", " + y +
");";
2150 const std::string& min,
const std::string& mask) {
2152 return "casadi_clip_min(" + x +
", " +
str(n) +
", " +
min +
", " + mask +
");";
2156 const std::string& min,
const std::string& mask) {
2158 return "casadi_clip_max(" + x +
", " +
str(n) +
", " +
min +
", " + mask +
");";
2162 const std::string& y,
const std::string& z) {
2164 return "casadi_vector_fmax(" +
str(n) +
", " + x +
", " + y +
", " + z +
");";
2168 const std::string& y,
const std::string& z) {
2170 return "casadi_vector_fmin(" +
str(n) +
", " + x +
", " + y +
", " + z +
");";
2174 const std::string& mask) {
2176 return "casadi_masked_norm_inf(" +
str(n) +
", " + x +
", " + mask +
")";
2181 return "casadi_scal(" +
str(n) +
", " + alpha +
", " + x +
");";
2185 const std::string& y,
const std::string& z,
bool tr) {
2187 return "casadi_mv(" + x +
", " +
sparsity(sp_x) +
", " + y +
", "
2188 + z +
", " + (tr ?
"1" :
"0") +
");";
2192 const std::string& y,
const std::string& z,
bool tr) {
2194 return "casadi_mv_dense(" + x +
", " +
str(nrow_x) +
", " +
str(ncol_x) +
", "
2195 + y +
", " + z +
", " + (tr ?
"1" :
"0") +
");";
2199 const std::string& y,
const Sparsity& sp_y,
2200 const std::string& z,
const Sparsity& sp_z,
2201 const std::string& w,
bool tr) {
2203 return "casadi_mtimes(" + x +
", " +
sparsity(sp_x) +
", " + y +
", " +
sparsity(sp_y) +
", "
2204 + z +
", " +
sparsity(sp_z) +
", " + w +
", " + (tr ?
"1" :
"0") +
");";
2208 const std::string& y,
bool tr,
bool unity, casadi_int nrhs) {
2210 return "casadi_trilsolve(" +
sparsity(sp_x) +
", " + x +
", " + y +
", " +
str(tr) +
", "
2211 +
str(unity) +
", " +
str(nrhs) +
");";
2215 const std::string& y,
bool tr,
bool unity, casadi_int nrhs) {
2217 return "casadi_triusolve(" +
sparsity(sp_x) +
", " + x +
", " + y +
", " +
str(tr) +
", "
2218 +
str(unity) +
", " +
str(nrhs) +
");";
2224 std::stringstream s;
2225 s <<
"casadi_logsumexp(" << A <<
", " << n <<
");";
2231 if (s.empty())
return;
2235 casadi_int shift = s.front()==
'}' ? -1 : 0;
2249 }
else if (c==
'}') {
2259 size_t pos = s.find(
'\n', off);
2260 if (pos==std::string::npos) {
2278 this->
buffer.str(std::string());
2282 const std::string& ref) {
2290 casadi_assert(it->second.first==type,
"Type mismatch for " +
name);
2291 casadi_assert(it->second.second==ref,
"Type mismatch for " +
name);
2297 return "w[" +
str(i) +
"]";
2311 casadi_assert(it->second==def,
"Initial value mismatch for " +
name);
2318 const std::vector<std::string>& inst,
bool add_shorthand) {
2321 for (
const std::string& s : inst) {
2322 if (s!=
"casadi_real") {
2323 for (
const std::string& s : inst)
suffix +=
"_" + s;
2329 std::vector<std::pair<std::string, std::string> > rep;
2330 for (casadi_int i=0; i<inst.size(); ++i) {
2331 rep.push_back(std::make_pair(
"T" +
str(i+1), inst[i]));
2335 std::stringstream ret;
2338 std::istringstream stream(src);
2339 while (std::getline(stream, line)) {
2343 if (line.find(
"template")==0)
continue;
2346 if (line.find(
"#define")==0)
continue;
2347 if (line.find(
"#undef")==0)
continue;
2350 if (line ==
"inline")
continue;
2353 if (line.find(
"// SYMBOL") != std::string::npos) {
2354 n1 = line.find(
"\"");
2355 n2 = line.find(
"\"", n1+1);
2356 std::string sym = line.substr(n1+1, n2-n1-1);
2359 rep.push_back(std::make_pair(sym, sym +
suffix));
2365 if (line.find(
"// C-REPLACE") != std::string::npos) {
2367 n1 = line.find(
"\"");
2368 n2 = line.find(
"\"", n1+1);
2369 std::string key = line.substr(n1+1, n2-n1-1);
2371 n1 = line.find(
"\"", n2+1);
2372 n2 = line.find(
"\"", n1+1);
2373 std::string sub = line.substr(n1+1, n2-n1-1);
2375 rep.push_back(std::make_pair(key, sub));
2380 if (!
verbose_runtime && line.find(
"// C-VERBOSE") != std::string::npos) {
2382 std::getline(stream, line);
2387 if ((n1 = line.find(
"//")) != std::string::npos) line.erase(n1);
2390 if ((n1 = line.find_last_not_of(
' ')) != std::string::npos) {
2397 for (
auto&& it = rep.rbegin(); it!=rep.rend(); ++it) {
2398 line =
replace(line, it->first, it->second);
2402 ret << line <<
"\n";
2412 *
this <<
"/* " << s <<
" */\n";
2418 const std::vector<Sparsity>& sp_in,
2419 const std::vector<Sparsity>& sp_out) {
2424 *
this <<
declare(
"const casadi_int* " +
name +
"_sparsity_in(casadi_int i)") <<
" {\n"
2425 <<
"switch (i) {\n";
2426 for (casadi_int i=0; i<sp_in.size(); ++i) {
2429 *
this <<
"default: return 0;\n}\n"
2433 *
this <<
declare(
"const casadi_int* " +
name +
"_sparsity_out(casadi_int i)") <<
" {\n"
2434 <<
"switch (i) {\n";
2435 for (casadi_int i=0; i<sp_out.size(); ++i) {
2438 *
this <<
"default: return 0;\n}\n"
2443 qr(
const std::string& sp,
const std::string& A,
const std::string& w,
2444 const std::string& sp_v,
const std::string& v,
const std::string& sp_r,
2445 const std::string& r,
const std::string& beta,
const std::string& prinv,
2446 const std::string& pc) {
2448 return "casadi_qr(" + sp +
", " + A +
", " + w +
", "
2449 + sp_v +
", " + v +
", " + sp_r +
", " + r +
", "
2450 + beta +
", " + prinv +
", " + pc +
");";
2454 qr_solve(
const std::string& x, casadi_int nrhs,
bool tr,
2455 const std::string& sp_v,
const std::string& v,
2456 const std::string& sp_r,
const std::string& r,
2457 const std::string& beta,
const std::string& prinv,
2458 const std::string& pc,
const std::string& w) {
2460 return "casadi_qr_solve(" + x +
", " +
str(nrhs) +
", " + (tr ?
"1" :
"0") +
", "
2461 + sp_v +
", " + v +
", " + sp_r +
", " + r +
", "
2462 + beta +
", " + prinv +
", " + pc +
", " + w +
");";
2466 lsqr_solve(
const std::string& A,
const std::string&x,
2467 casadi_int nrhs,
bool tr,
const std::string& sp,
const std::string& w) {
2469 return "casadi_lsqr_solve(" + A +
", " + x +
", " +
str(nrhs) +
", "
2470 + (tr ?
"1" :
"0") +
", " + sp +
", " + w +
");";
2474 ldl(
const std::string& sp_a,
const std::string& a,
2475 const std::string& sp_lt,
const std::string& lt,
const std::string& d,
2476 const std::string& p,
const std::string& w) {
2478 return "casadi_ldl(" + sp_a +
", " + a +
", " + sp_lt +
", " + lt +
", "
2479 + d +
", " + p +
", " + w +
");";
2483 ldl_solve(
const std::string& x, casadi_int nrhs,
2484 const std::string& sp_lt,
const std::string& lt,
const std::string& d,
2485 const std::string& p,
const std::string& w) {
2487 return "casadi_ldl_solve(" + x +
", " +
str(nrhs) +
", " + sp_lt +
", "
2488 + lt +
", " + d +
", " + p +
", " + w +
");";
2492 fmax(
const std::string& x,
const std::string& y) {
2494 return "casadi_fmax(" + x +
", " + y +
");";
2498 fmin(
const std::string& x,
const std::string& y) {
2500 return "casadi_fmin(" + x +
", " + y +
");";
2504 vfmax(
const std::string& x, casadi_int n,
const std::string& y) {
2506 return "casadi_vfmax(" + x +
", " +
str(n) +
", " + y +
");";
2510 vfmin(
const std::string& x, casadi_int n,
const std::string& y) {
2512 return "casadi_vfmin(" + x +
", " +
str(n) +
", " + y +
");";
2516 vfmax(
const std::string& x,
const std::string& n,
const std::string& y) {
2518 return "casadi_vfmax(" + x +
", " + n +
", " + y +
");";
2522 vfmin(
const std::string& x,
const std::string& n,
const std::string& y) {
2524 return "casadi_vfmin(" + x +
", " + n +
", " + y +
");";
2528 max(
const std::string& x,
const std::string& y) {
2530 return "casadi_max(" + x +
", " + y +
")";
2534 min(
const std::string& x,
const std::string& y) {
2536 return "casadi_min(" + x +
", " + y +
")";
2540 mmax(
const std::string& x, casadi_int n,
bool is_dense) {
2542 return "casadi_mmax(" + x +
", " +
str(n) +
", " +
str(casadi_int(is_dense)) +
")";
2546 mmin(
const std::string& x, casadi_int n,
bool is_dense) {
2548 return "casadi_mmin(" + x +
", " +
str(n) +
", " +
str(casadi_int(is_dense)) +
")";
2552 max_viol(casadi_int n,
const std::string& x,
const std::string& lb,
const std::string& ub) {
2554 return "casadi_max_viol(" +
str(n) +
", " + x+
", " + lb +
", " + ub +
")";
2558 sum_viol(casadi_int n,
const std::string& x,
const std::string& lb,
const std::string& ub) {
2560 return "casadi_sum_viol(" +
str(n) +
", " + x+
", " + lb +
", " + ub +
")";
2564 norm_inf(casadi_int n,
const std::string& x) {
2566 return "casadi_norm_inf(" +
str(n) +
", " + x +
")";
2570 norm_1(casadi_int n,
const std::string& x) {
2572 return "casadi_norm_1(" +
str(n) +
", " + x +
")";
2576 norm_2(casadi_int n,
const std::string& x) {
2578 return "casadi_norm_2(" +
str(n) +
", " + x +
")";
2584 return "casadi_lb_eig(" +
sparsity(sp_h) +
", " + h +
")";
2590 return "casadi_regularize(" +
sparsity(sp_h) +
", " + h +
", " + reg +
");";
2595 const std::string& Hin,
const std::string& Hout,
const std::string& iw,
const std::string& w) {
2601 low(
const std::string& x,
const std::string& grid, casadi_int ng, casadi_int lookup_mode) {
2603 return "casadi_low(" + x +
", " + grid +
", " +
str(ng) +
", " +
str(lookup_mode) +
");";
2608 const std::string& lam,
const std::string& lbx,
const std::string& ubx) {
2610 return "casadi_bound_consistency(" +
str(n) +
", " + x +
", " + lam +
2611 ", " + lbx +
", " + ubx +
")";
2615 file_slurp(
const std::string& fname, casadi_int n,
const std::string& a) {
2617 return "casadi_file_slurp(\"" + fname +
"\", " +
str(n) +
", " + a +
")";
2621 cache_check(
const std::string& key,
const std::string& cache,
const std::string& loc,
2622 casadi_int stride, casadi_int sz, casadi_int key_sz,
const std::string& val) {
2624 return "cache_check(" + key +
", " + cache +
", " + loc +
", " +
2625 str(stride) +
", " +
str(sz) +
", " +
str(key_sz) +
", " + val +
")";
2629 sz_arg = sz_res = sz_iw = sz_w = 0;
2631 sz_arg = std::max(sz_arg, f.f.sz_arg());
2632 sz_res = std::max(sz_res, f.f.sz_res());
2633 sz_iw = std::max(sz_iw, f.f.sz_iw());
2634 sz_w = std::max(sz_w, f.f.sz_w());
Helper class for C code generation.
std::string triusolve(const Sparsity &sp_x, const std::string &x, const std::string &y, bool tr, bool unity, casadi_int nrhs)
Codegen upper triangular solve.
void define_pool_double(const std::string &name, const std::vector< double > &def)
Allocate file scope double writeable memory.
bool codegen_scalars
Codegen scalar.
std::string fill(const std::string &res, std::size_t n, const std::string &v)
Create a fill operation.
std::stringstream includes
std::string axpy(casadi_int n, const std::string &a, const std::string &x, const std::string &y)
Codegen axpy: y += a*x.
static std::string fmu_helpers(const std::string &modelname)
FMU helper functions.
std::string lsqr_solve(const std::string &A, const std::string &x, casadi_int nrhs, bool tr, const std::string &sp, const std::string &w)
std::set< std::string > added_externals_
std::string logsumexp(const std::string &A, casadi_int n)
std::string clip_min(const std::string &x, casadi_int n, const std::string &min, const std::string &mask)
Codegen clip_min: Clips the smaller entries in a vector than min to the min.
std::string project(const std::string &arg, const Sparsity &sp_arg, const std::string &res, const Sparsity &sp_res, const std::string &w)
Sparse assignment.
std::string add_dependency(const Function &f)
Add a function dependency.
std::string mmax(const std::string &x, casadi_int n, bool is_dense)
mmax
std::string work(casadi_int n, casadi_int sz, bool is_ref) const
std::string arg(casadi_int i) const
Refer to argument.
std::string dump()
Generate a file, return code as string.
std::string wrapper(const Function &base, const std::string &name)
std::vector< std::string > added_sfunctions
std::string pool_double(const std::string &name) const
Access file scope double writeable memory.
void add_io_sparsities(const std::string &name, const std::vector< Sparsity > &sp_in, const std::vector< Sparsity > &sp_out)
Add io sparsity patterns of a function.
void scope_enter()
Enter a local scope.
std::string rom_integer(const void *id) const
Access file scope integer read-only memory.
std::string norm_2(casadi_int n, const std::string &x)
norm_2
std::string copy(const std::string &arg, std::size_t n, const std::string &res)
Create a copy operation.
std::map< std::string, casadi_int > pool_double_
void comment(const std::string &s)
Write a comment line (ignored if not verbose)
void reserve_work(casadi_int n)
Reserve a maximum size of work elements, used for padding of index.
std::string masked_norm_inf(casadi_int n, const std::string &x, const std::string &mask)
codegen masked_norm_inf: The mask tells what entry is used in the inf-norm.
std::set< std::string > added_includes_
std::string constant(const std::vector< casadi_int > &v)
Represent an array constant; adding it when new.
std::string casadi_real_type
void add(const Function &f, bool with_jac_sparsity=false)
Add a function (name generated)
void flush(std::ostream &s)
Flush the buffer to a stream of choice.
casadi_int add_sparsity(const Sparsity &sp, bool canonical=true)
std::string scal(casadi_int n, const std::string &alpha, const std::string &x)
What does scal do??
std::string rank1(const std::string &A, const Sparsity &sp_A, const std::string &alpha, const std::string &x, const std::string &y)
Rank-1 update.
std::string low(const std::string &x, const std::string &grid, casadi_int ng, casadi_int lookup_mode)
low
std::multimap< Auxiliary, std::vector< std::string > > added_auxiliaries_
CodeGenerator(const std::string &name, const Dict &opts=Dict())
Constructor.
std::string fmin(const std::string &x, const std::string &y)
fmin
std::string sum_viol(casadi_int n, const std::string &x, const std::string &lb, const std::string &ub)
sum_viol
std::string to_mex(const Sparsity &sp, const std::string &arg)
Create matrix in MATLAB's MEX format.
std::string printf(const std::string &str, const std::vector< std::string > &arg=std::vector< std::string >())
Printf.
std::string print_op(casadi_int op, const std::string &a0)
Print an operation to a c file.
std::map< std::string, std::pair< std::string, std::string > > local_variables_
std::string max(const std::string &x, const std::string &y)
max
void indent()
Increase indentation.
std::string rom_double(const void *id) const
Access file scope double read-only memory.
std::map< std::string, std::string > local_default_
std::vector< std::vector< char > > char_constants_
static void file_close(std::ofstream &f, bool cpp)
Print file header.
static std::string array(const std::string &type, const std::string &name, casadi_int len, const std::string &def=std::string())
std::string bilin(const std::string &A, const Sparsity &sp_A, const std::string &x, const std::string &y)
Codegen bilinear form.
std::string bound_consistency(casadi_int n, const std::string &x, const std::string &lam, const std::string &lbx, const std::string &ubx)
bound_consistency
std::string vector_fmax(casadi_int n, const std::string &x, const std::string &y, const std::string &z)
Codegen vector_fmax: Takes vectorwise max of a vector and writes the result to second vector.
std::string casadi_int_type
std::string sparsify(const std::string &arg, const std::string &res, const Sparsity &sp_res, bool tr=false)
Sparsify.
std::string mv(const std::string &x, const Sparsity &sp_x, const std::string &y, const std::string &z, bool tr)
Codegen sparse matrix-vector multiplication.
static size_t hash(const std::vector< double > &v)
std::vector< std::vector< double > > pool_double_defaults_
std::string ldl_solve(const std::string &x, casadi_int nrhs, const std::string &sp_lt, const std::string <, const std::string &d, const std::string &p, const std::string &w)
LDL solve.
CodeGenerator & operator<<(const std::string &s)
Print a string to buffer.
std::string generate(const std::string &prefix="")
Generate file(s)
std::string ldl(const std::string &sp_a, const std::string &a, const std::string &sp_lt, const std::string <, const std::string &d, const std::string &p, const std::string &w)
LDL factorization.
std::string lb_eig(const Sparsity &sp_h, const std::string &h)
lb_eig
static void file_open(std::ofstream &f, const std::string &name, bool cpp)
Print file header.
std::string operator()(const Function &f, const std::string &arg, const std::string &res, const std::string &iw, const std::string &w, const std::string &failure_ret="1")
Generate a call to a function (generic signature)
std::string mmin(const std::string &x, casadi_int n, bool is_dense)
mmin
std::string densify(const std::string &arg, const Sparsity &sp_arg, const std::string &res, bool tr=false)
Densify.
std::multimap< size_t, size_t > added_double_constants_
void local(const std::string &name, const std::string &type, const std::string &ref="")
Declare a local variable.
void add_external(const std::string &new_external)
Add an external function declaration.
std::string workel(casadi_int n) const
casadi_int current_indent_
std::string min(const std::string &x, const std::string &y)
min
void setup_callback(const std::string &s, const Function &f)
Setup a callback.
casadi_int max_initializer_elements_per_line
std::string mem(const Function &f)
Access thread-local memory.
void print_vector(std::ostream &s, const std::string &name, const std::vector< casadi_int > &v)
Print casadi_int vector to a c file.
void unindent()
Decrease indentation.
std::string from_mex(std::string &arg, const std::string &res, std::size_t res_off, const Sparsity &sp_res, const std::string &w)
Get matrix from MATLAB's MEX format.
std::vector< std::vector< double > > double_constants_
std::string res(casadi_int i) const
Refer to resuly.
std::vector< std::vector< casadi_int > > integer_constants_
std::string interpn(const std::string &res, casadi_int ndim, const std::string &grid, const std::string &offset, const std::string &values, const std::string &x, const std::string &lookup_mode, casadi_int m, const std::string &iw, const std::string &w)
Multilinear interpolation.
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 for all functions.
std::multimap< size_t, size_t > added_char_constants_
std::vector< std::vector< std::string > > string_constants_
std::string vfmax(const std::string &x, casadi_int n, const std::string &y)
vfmax
std::string norm_inf(casadi_int n, const std::string &x)
norm_inf
std::string ones(casadi_int sz)
std::string vector_fmin(casadi_int n, const std::string &x, const std::string &y, const std::string &z)
Codegen vector_fmin: Takes vectorwise min of a vector and writes the result to second vector.
std::map< const void *, casadi_int > file_scope_integer_
std::string declare(std::string s)
Declare a function.
std::string mtimes(const std::string &x, const Sparsity &sp_x, const std::string &y, const Sparsity &sp_y, const std::string &z, const Sparsity &sp_z, const std::string &w, bool tr)
Codegen sparse matrix-matrix multiplication.
void scope_exit()
Exit a local scope.
std::string vfmin(const std::string &x, casadi_int n, const std::string &y)
vfmin
void init_local(const std::string &name, const std::string &def)
Specify the default value for a local variable.
std::string cache_check(const std::string &key, const std::string &cache, const std::string &loc, casadi_int stride, casadi_int sz, casadi_int key_sz, const std::string &val)
cache check
void define_rom_integer(const void *id, casadi_int size)
Allocate file scope integer read-only memory.
std::string qr_solve(const std::string &x, casadi_int nrhs, bool tr, const std::string &sp_v, const std::string &v, const std::string &sp_r, const std::string &r, const std::string &beta, const std::string &prinv, const std::string &pc, const std::string &w)
QR solve.
casadi_int max_declarations_per_line
std::string sanitize_source(const std::string &src, const std::vector< std::string > &inst, bool add_shorthand=true)
Sanitize source files for codegen.
std::string dot(casadi_int n, const std::string &x, const std::string &y)
Codegen inner product.
std::vector< FunctionMeta > added_functions_
std::string clip_max(const std::string &x, casadi_int n, const std::string &min, const std::string &mask)
Codegen clip_max: Clips the larger entries in a vector than max to the max.
static std::string casadi_version()
Current CasADi version as string.
void define_rom_double(const void *id, casadi_int size)
Allocate file scope double read-only memory.
std::string interpn_grad(const std::string &grad, casadi_int ndim, const std::string &grid, const std::string &offset, const std::string &values, const std::string &x, const std::string &lookup_mode, casadi_int m, const std::string &iw, const std::string &w)
Multilinear interpolation - calculate gradient.
void add_include(const std::string &new_include, bool relative_path=false, const std::string &use_ifdef=std::string())
Add an include file optionally using a relative path "..." instead of an absolute path <....
std::string shorthand(const std::string &name) const
Get a shorthand.
Auxiliary
Auxiliary functions.
@ AUX_BLAZING_2D_BOOR_EVAL
@ AUX_BLAZING_1D_BOOR_EVAL
@ AUX_INTERPN_INTERPOLATE
@ AUX_BLAZING_3D_BOOR_EVAL
void constant_copy(const std::string &var_name, const std::vector< casadi_int > &v, const std::string &type="casadi_int")
Represent an array constant; adding it when new.
std::map< std::string, std::map< FunctionInternal *, casadi_int > > added_wrappers_
void copy_check(const std::string &arg, std::size_t n, const std::string &res, bool check_lhs=true, bool check_rhs=true)
std::string tri_project(const std::string &arg, const Sparsity &sp_arg, const std::string &res, bool lower)
Project triangular part.
std::multimap< size_t, size_t > added_integer_constants_
std::multimap< size_t, size_t > added_string_constants_
std::map< const void *, casadi_int > file_scope_double_
std::string file_slurp(const std::string &fname, casadi_int n, const std::string &a)
Slurp a file.
std::string initializer(const std::vector< T > &v)
Print an initializer.
std::string norm_1(casadi_int n, const std::string &x)
norm_1
std::set< std::string > sparsity_meta
std::string max_viol(casadi_int n, const std::string &x, const std::string &lb, const std::string &ub)
max_viol
std::string convexify_eval(const ConvexifyData &d, const std::string &Hin, const std::string &Hout, const std::string &iw, const std::string &w)
convexify
std::vector< std::string > exposed_fname
std::string sparsity(const Sparsity &sp, bool canonical=true)
void copy_default(const std::string &arg, std::size_t n, const std::string &res, const std::string &def, bool check_rhs=true)
std::string trans(const std::string &x, const Sparsity &sp_x, const std::string &y, const Sparsity &sp_y, const std::string &iw)
Transpose.
casadi_int padding_length_
casadi_int get_constant(const std::vector< double > &v, bool allow_adding=false)
Get or add a constant.
casadi_int get_sparsity(const Sparsity &sp) const
Get the index of an existing sparsity pattern.
void print_formatted(const std::string &s)
Print without newline characters.
bool elide_copy(casadi_int sz)
std::string zeros(casadi_int sz)
std::string trilsolve(const Sparsity &sp_x, const std::string &x, const std::string &y, bool tr, bool unity, casadi_int nrhs)
Codegen lower triangular solve.
std::set< std::string > added_shorthands_
static bool equal(const std::vector< T > &v1, const std::vector< T > &v2)
std::stringstream auxiliaries
std::string qr(const std::string &sp, const std::string &A, const std::string &w, const std::string &sp_v, const std::string &v, const std::string &sp_r, const std::string &r, const std::string &beta, const std::string &prinv, const std::string &pc)
QR factorization.
std::string fmax(const std::string &x, const std::string &y)
fmax
std::string clear(const std::string &res, std::size_t n)
Create a fill operation.
std::string format_padded(casadi_int i) const
std::string regularize(const Sparsity &sp_h, const std::string &h, const std::string ®)
regularize
void add_auxiliary(Auxiliary f, const std::vector< std::string > &inst={"casadi_real"})
Add a built-in auxiliary function.
std::string sx_work(casadi_int i)
Declare a work vector element.
void generate(CodeGenerator &g, const std::vector< casadi_int > &arg, const std::vector< casadi_int > &res, const std::vector< bool > &arg_is_ref, std::vector< bool > &res_is_ref) const override
Generate code for the operation.
static void open(std::ofstream &, const std::string &path, std::ios_base::openmode mode=std::ios_base::out)
Internal class for Function.
bool has_refcount_
Reference counting in codegen?
virtual std::string codegen_mem_type() const
Thread-local memory object type.
std::vector< Sparsity > sparsity_in_
Input and output sparsity.
virtual void codegen_free_mem(CodeGenerator &g) const
Codegen for free_mem.
virtual void codegen_incref(CodeGenerator &g) const
Codegen incref for dependencies.
std::string signature_unrolled(const std::string &fname) const
Code generate the function.
virtual std::string codegen_name(const CodeGenerator &g, bool ns=true) const
Get name in codegen.
void codegen(CodeGenerator &g, const std::string &fname) const
Generate code the function.
virtual void codegen_release(CodeGenerator &g) const
Codegen for release.
virtual void codegen_alloc_mem(CodeGenerator &g) const
Codegen decref for alloc_mem.
virtual void codegen_checkout(CodeGenerator &g) const
Codegen for checkout.
virtual void codegen_declarations(CodeGenerator &g) const
Generate code for the declarations of the C function.
std::string signature(const std::string &fname) const
Code generate the function.
void codegen_meta(CodeGenerator &g) const
Generate meta-information allowing a user to evaluate a generated function.
virtual void codegen_init_mem(CodeGenerator &g) const
Codegen decref for init_mem.
virtual void codegen_decref(CodeGenerator &g) const
Codegen decref for dependencies.
FunctionInternal * get() const
const std::vector< std::string > & name_in() const
Get input scheme.
const std::string & name() const
Name of the function.
static bool check_name(const std::string &name)
Check if a string is a valid function name.
casadi_int n_out() const
Get the number of function outputs.
casadi_int n_in() const
Get the number of function inputs.
const std::vector< Sparsity > & jac_sparsity(bool compact=false) const
Get, if necessary generate, the sparsity of all Jacobian blocks.
const std::vector< std::string > & name_out() const
Get output scheme.
static casadi_int copy_elision_min_size
casadi_int nnz() const
Get the number of (structural) non-zeros.
std::vector< casadi_int > compress(bool canonical=true) const
Compress a sparsity pattern.
std::string join(const std::vector< std::string > &l, const std::string &delim)
CASADI_EXPORT std::string replace(const std::string &s, const std::string &p, const std::string &r)
Replace all occurences of p with r in s.
std::string str(const T &v)
String representation, any type.
GenericType::Dict Dict
C++ equivalent of Python's dict or MATLAB's struct.
void hash_combine(std::size_t &seed, T v)
Generate a hash value incrementally (function taken from boost)
static std::string print(unsigned char op, const std::string &x, const std::string &y)
Print.