List of all members | Classes | Public Types | Public Member Functions | Static Public Member Functions | Public Attributes | Static Public Attributes | Protected Member Functions
casadi::SXFunction Class Reference

Internal node class for SXFunction. More...

#include <sx_function.hpp>

Detailed Description

Do not use any internal class directly - always use the public Function

Author
Joel Andersson
Date
2010-2015

Extra doc: https://github.com/casadi/casadi/wiki/L_ub


List of available options
IdTypeDescriptionUsed in
ad_weightOT_DOUBLEWeighting factor for derivative calculation.When there is an option of either using forward or reverse mode directional derivatives, the condition ad_weight*nf<=(1-ad_weight)*na is used where nf and na are estimates of the number of forward/reverse mode directional derivatives needed. By default, ad_weight is calculated automatically, but this can be overridden by setting this option. In particular, 0 means forcing forward mode and 1 forcing reverse mode. Leave unset for (class specific) heuristics.casadi::FunctionInternal
ad_weight_spOT_DOUBLEWeighting factor for sparsity pattern calculation calculation.Overrides default behavior. Set to 0 and 1 to force forward and reverse mode respectively. Cf. option "ad_weight". When set to -1, sparsity is completely ignored and dense matrices are used.casadi::FunctionInternal
allow_duplicate_io_namesOT_BOOLAllow construction with duplicate io names (Default: false)casadi::SXFunction
allow_freeOT_BOOLAllow construction with free variables (Default: false)casadi::SXFunction
always_inlineOT_BOOLForce inlining.casadi::FunctionInternal
cacheOT_DICTPrepopulate the function cache. Default: emptycasadi::FunctionInternal
compilerOT_STRINGJust-in-time compiler plugin to be used.casadi::FunctionInternal
cseOT_BOOLPerform common subexpression elimination (complexity is N*log(N) in graph size)casadi::SXFunction
custom_jacobianOT_FUNCTIONOverride CasADi's AD. Use together with 'jac_penalty': 0. Note: Highly experimental. Syntax may break often.casadi::FunctionInternal
default_inOT_DOUBLEVECTORDefault input valuescasadi::SXFunction
der_optionsOT_DICTDefault options to be used to populate forward_options, reverse_options, and jacobian_options before those options are merged in.casadi::FunctionInternal
derivative_ofOT_FUNCTIONThe function is a derivative of another function. The type of derivative (directional derivative, Jacobian) is inferred from the function name.casadi::FunctionInternal
dumpOT_BOOLDump function to file upon first evaluation. [false]casadi::FunctionInternal
dump_dirOT_STRINGDirectory to dump inputs/outputs to. Make sure the directory exists [.]casadi::FunctionInternal
dump_formatOT_STRINGChoose file format to dump matrices. See DM.from_file [mtx]casadi::FunctionInternal
dump_inOT_BOOLDump numerical values of inputs to file (readable with DM.from_file) [default: false] A counter is used to generate unique names. The counter may be reset using reset_dump_count.casadi::FunctionInternal
dump_outOT_BOOLDump numerical values of outputs to file (readable with DM.from_file) [default: false] A counter is used to generate unique names. The counter may be reset using reset_dump_count.casadi::FunctionInternal
enable_fdOT_BOOLEnable derivative calculation by finite differencing. [default: false]]casadi::FunctionInternal
enable_forwardOT_BOOLEnable derivative calculation using generated functions for Jacobian-times-vector products - typically using forward mode AD - if available. [default: true]casadi::FunctionInternal
enable_jacobianOT_BOOLEnable derivative calculation using generated functions for Jacobians of all differentiable outputs with respect to all differentiable inputs - if available. [default: true]casadi::FunctionInternal
enable_reverseOT_BOOLEnable derivative calculation using generated functions for transposed Jacobian-times-vector products - typically using reverse mode AD - if available. [default: true]casadi::FunctionInternal
error_on_failOT_BOOLThrow exceptions when function evaluation fails (default true).casadi::ProtoFunction
external_transformOT_VECTORVECTORList of external_transform instruction arguments. Default: emptycasadi::FunctionInternal
fd_methodOT_STRINGMethod for finite differencing [default 'central']casadi::FunctionInternal
fd_optionsOT_DICTOptions to be passed to the finite difference instancecasadi::FunctionInternal
forward_optionsOT_DICTOptions to be passed to a forward mode constructorcasadi::FunctionInternal
gather_statsOT_BOOLDeprecated option (ignored): Statistics are now always collected.casadi::FunctionInternal
input_schemeOT_STRINGVECTORDeprecated option (ignored)casadi::FunctionInternal
inputs_checkOT_BOOLThrow exceptions when the numerical values of the inputs don't make sensecasadi::FunctionInternal
is_diff_inOT_BOOLVECTORIndicate for each input if it should be differentiable.casadi::FunctionInternal
is_diff_outOT_BOOLVECTORIndicate for each output if it should be differentiable.casadi::FunctionInternal
jac_penaltyOT_DOUBLEWhen requested for a number of forward/reverse directions, it may be cheaper to compute first the full jacobian and then multiply with seeds, rather than obtain the requested directions in a straightforward manner. Casadi uses a heuristic to decide which is cheaper. A high value of 'jac_penalty' makes it less likely for the heurstic to chose the full Jacobian strategy. The special value -1 indicates never to use the full Jacobian strategycasadi::FunctionInternal
jacobian_optionsOT_DICTOptions to be passed to a Jacobian constructorcasadi::FunctionInternal
jitOT_BOOLUse just-in-time compiler to speed up the evaluationcasadi::FunctionInternal
jit_cleanupOT_BOOLCleanup up the temporary source file that jit creates. Default: truecasadi::FunctionInternal
jit_nameOT_STRINGThe file name used to write out code. The actual file names used depend on 'jit_temp_suffix' and include extensions. Default: 'jit_tmp'casadi::FunctionInternal
jit_optionsOT_DICTOptions to be passed to the jit compiler.casadi::FunctionInternal
jit_serializeOT_STRINGSpecify behaviour when serializing a jitted function: SOURCE|link|embed.casadi::FunctionInternal
jit_temp_suffixOT_BOOLUse a temporary (seemingly random) filename suffix for generated code and libraries. This is desired for thread-safety. This behaviour may defeat caching compiler wrappers. Default: truecasadi::FunctionInternal
just_in_time_openclOT_BOOLJust-in-time compilation for numeric evaluation using OpenCL (experimental)casadi::SXFunction
just_in_time_sparsityOT_BOOLPropagate sparsity patterns using just-in-time compilation to a CPU or GPU using OpenCLcasadi::SXFunction
live_variablesOT_BOOLReuse variables in the work vectorcasadi::SXFunction
max_ioOT_INTAcceptable number of inputs and outputs. Warn if exceeded.casadi::FunctionInternal
max_num_dirOT_INTSpecify the maximum number of directions for derivative functions. Overrules the builtin optimized_num_dir.casadi::FunctionInternal
never_inlineOT_BOOLForbid inlining.casadi::FunctionInternal
output_schemeOT_STRINGVECTORDeprecated option (ignored)casadi::FunctionInternal
post_expandOT_BOOLAfter construction, expand this Function. Default: Falsecasadi::FunctionInternal
post_expand_optionsOT_DICTOptions to be passed to post-construction expansion. Default: emptycasadi::FunctionInternal
print_canonicalOT_BOOLWhen printing numerical matrices, use a format that is exact and reproducible in generated C code.casadi::FunctionInternal
print_inOT_BOOLPrint numerical values of inputs [default: false]casadi::FunctionInternal
print_instructionsOT_BOOLPrint each operation during evaluation. Influenced by print_canonical.casadi::SXFunction
print_outOT_BOOLPrint numerical values of outputs [default: false]casadi::FunctionInternal
print_timeOT_BOOLprint information about execution time. Implies record_time.casadi::ProtoFunction
record_timeOT_BOOLrecord information about execution time, for retrieval with stats().casadi::ProtoFunction
regularity_checkOT_BOOLThrow exceptions when NaN or Inf appears during evaluationcasadi::ProtoFunction
reverse_optionsOT_DICTOptions to be passed to a reverse mode constructorcasadi::FunctionInternal
user_dataOT_VOIDPTRA user-defined field that can be used to identify the function or pass additional informationcasadi::FunctionInternal
verboseOT_BOOLVerbose evaluation – for debuggingcasadi::ProtoFunction

Definition at line 53 of file sx_function.hpp.

Inheritance diagram for casadi::SXFunction:
Inheritance graph
[legend]
Collaboration diagram for casadi::SXFunction:
Collaboration graph
[legend]

Classes

struct  CallInfo
 Metadata for call nodes. More...
 
struct  ExtendedAlgEl
 
struct  TapeEl
 An element of the tape. More...
 

Public Types

typedef ScalarAtomic AlgEl
 DATA MEMBERS. More...
 
using weak_ref_type = WeakRefInternal
 

Public Member Functions

 SXFunction (const std::string &name, const std::vector< Matrix< SXElem > > &inputv, const std::vector< Matrix< SXElem > > &outputv, const std::vector< std::string > &name_in, const std::vector< std::string > &name_out)
 Constructor. More...
 
 ~SXFunction () override
 Destructor. More...
 
int eval (const double **arg, double **res, casadi_int *iw, double *w, void *mem) const override
 Evaluate numerically, work vectors given. More...
 
int eval_sx (const SXElem **arg, SXElem **res, casadi_int *iw, SXElem *w, void *mem, bool always_inline, bool never_inline) const override
 evaluate symbolically while also propagating directional derivatives More...
 
void eval_mx (const MXVector &arg, MXVector &res, bool always_inline, bool never_inline) const override
 Evaluate symbolically, MX type. More...
 
bool should_inline (bool with_sx, bool always_inline, bool never_inline) const override
 
void ad_forward (const std::vector< std::vector< SX > > &fseed, std::vector< std::vector< SX > > &fsens) const
 Calculate forward mode directional derivatives. More...
 
void ad_reverse (const std::vector< std::vector< SX > > &aseed, std::vector< std::vector< SX > > &asens) const
 Calculate reverse mode directional derivatives. More...
 
bool is_smooth () const
 Check if smooth. More...
 
std::string print (const ScalarAtomic &a) const
 
void print_arg (std::ostream &stream, casadi_int k, const ScalarAtomic &el, const double *w) const
 
void print_arg (CodeGenerator &g, casadi_int k, const ScalarAtomic &el) const
 
void print_res (std::ostream &stream, casadi_int k, const ScalarAtomic &el, const double *w) const
 
void print_res (CodeGenerator &g, casadi_int k, const ScalarAtomic &el) const
 
void disp_more (std::ostream &stream) const override
 Print the algorithm. More...
 
std::string class_name () const override
 Get type name. More...
 
bool is_a (const std::string &type, bool recursive) const override
 Check if the function is of a particular type. More...
 
std::vector< SXfree_sx () const override
 Get free variables (SX) More...
 
bool has_free () const override
 Does the function have free variables. More...
 
std::vector< std::string > get_free () const override
 Print free variables. More...
 
SX hess (casadi_int iind=0, casadi_int oind=0)
 Hessian (forward over adjoint) via source code transformation. More...
 
casadi_int n_instructions () const override
 Get the number of atomic operations. More...
 
casadi_int instruction_id (casadi_int k) const override
 Get an atomic operation operator index. More...
 
std::vector< casadi_int > instruction_input (casadi_int k) const override
 Get the (integer) input arguments of an atomic operation. More...
 
double instruction_constant (casadi_int k) const override
 Get the floating point output argument of an atomic operation. More...
 
std::vector< casadi_int > instruction_output (casadi_int k) const override
 Get the (integer) output argument of an atomic operation. More...
 
casadi_int n_nodes () const override
 Number of nodes in the algorithm. More...
 
void serialize_body (SerializingStream &s) const override
 Serialize an object without type information. More...
 
Dict generate_options (const std::string &target="clone") const override
 Reconstruct options dict. More...
 
void init (const Dict &opts) override
 Initialize. More...
 
void init_copy_elision ()
 Part of initialize responsible of prepaprign copy elision. More...
 
size_t codegen_sz_w (const CodeGenerator &g) const override
 Get the size of the work vector, for codegen. More...
 
void codegen_declarations (CodeGenerator &g) const override
 Generate code for the declarations of the C function. More...
 
void codegen_body (CodeGenerator &g) const override
 Generate code for the body of the C function. More...
 
int sp_forward (const bvec_t **arg, bvec_t **res, casadi_int *iw, bvec_t *w, void *mem) const override
 Propagate sparsity forward. More...
 
int sp_reverse (bvec_t **arg, bvec_t **res, casadi_int *iw, bvec_t *w, void *mem) const override
 Propagate sparsity backwards. More...
 
SX instructions_sx () const override
 get SX expression associated with instructions More...
 
void find (std::map< FunctionInternal *, Function > &all_fun, casadi_int max_depth) const override
 
double get_default_in (casadi_int ind) const override
 Get default input value. More...
 
void export_code_body (const std::string &lang, std::ostream &stream, const Dict &options) const override
 Export function in a specific language. More...
 
std::vector< Matrix< SXElem > > jac (const Dict &opts) const
 Construct a complete Jacobian by compression. More...
 
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 override
 
std::vector< bool > which_depends (const std::string &s_in, const std::vector< std::string > &s_out, casadi_int order, bool tr=false) const override
 Which variables enter with some order. More...
 
Function slice (const std::string &name, const std::vector< casadi_int > &order_in, const std::vector< casadi_int > &order_out, const Dict &opts) const override
 returns a new function with a selection of inputs/outputs of the original More...
 
void export_code (const std::string &lang, std::ostream &stream, const Dict &options) const override
 Export function in a specific language. More...
 
bool has_codegen () const override
 Is codegen supported? More...
 
virtual bool isInput (const std::vector< Matrix< SXElem > > &arg) const
 Helper function: Check if a vector equals ex_in. More...
 
void call_forward (const std::vector< Matrix< SXElem > > &arg, const std::vector< Matrix< SXElem > > &res, const std::vector< std::vector< Matrix< SXElem > > > &fseed, std::vector< std::vector< Matrix< SXElem > > > &fsens, bool always_inline, bool never_inline) const override
 Create call to (cached) derivative function, forward mode. More...
 
void call_reverse (const std::vector< Matrix< SXElem > > &arg, const std::vector< Matrix< SXElem > > &res, const std::vector< std::vector< Matrix< SXElem > > > &aseed, std::vector< std::vector< Matrix< SXElem > > > &asens, bool always_inline, bool never_inline) const override
 Create call to (cached) derivative function, reverse mode. More...
 
void delayed_serialize_members (SerializingStream &s) const
 Helper functions to avoid recursion limit. More...
 
void delayed_deserialize_members (DeserializingStream &s)
 
virtual std::string getAdaptorSolverName () const
 Obtain solver name from Adaptor. More...
 
void change_option (const std::string &option_name, const GenericType &option_value) override
 Change option after object creation for debugging. More...
 
void reset_dump_count ()
 Reset the counter used to name dump files. More...
 
void finalize () override
 Finalize the object creation. More...
 
void * alloc_mem () const override
 Create memory block. More...
 
void free_mem (void *mem) const override
 Free memory block. More...
 
Dict get_stats (void *mem) const override
 Get all statistics. More...
 
Function self () const
 Get a public class instance. More...
 
virtual std::vector< std::string > get_function () const
 
virtual const Functionget_function (const std::string &name) const
 
virtual bool has_function (const std::string &fname) const
 
void add_embedded (std::map< FunctionInternal *, Function > &all_fun, const Function &dep, casadi_int max_depth) const
 
template<typename M >
void call (const std::vector< M > &arg, std::vector< M > &res, bool always_inline, bool never_inline) const
 Call a function, templated. More...
 
template<typename M >
bool matching_arg (const std::vector< M > &arg, casadi_int &npar) const
 Check if input arguments that needs to be replaced. More...
 
template<typename M >
bool matching_res (const std::vector< M > &arg, casadi_int &npar) const
 Check if output arguments that needs to be replaced. More...
 
template<typename M >
std::vector< M > replace_arg (const std::vector< M > &arg, casadi_int npar) const
 Replace 0-by-0 inputs. More...
 
template<typename M >
std::vector< M > project_arg (const std::vector< M > &arg, casadi_int npar) const
 Project sparsities. More...
 
template<typename M >
std::vector< M > project_res (const std::vector< M > &arg, casadi_int npar) const
 Project sparsities. More...
 
template<typename M >
std::vector< M > replace_res (const std::vector< M > &res, casadi_int npar) const
 Replace 0-by-0 outputs. More...
 
template<typename M >
std::vector< std::vector< M > > replace_fseed (const std::vector< std::vector< M >> &fseed, casadi_int npar) const
 Replace 0-by-0 forward seeds. More...
 
template<typename M >
std::vector< std::vector< M > > replace_fseed (const std::vector< std::vector< M > > &fseed, casadi_int npar) const
 
template<typename M >
std::vector< std::vector< M > > replace_aseed (const std::vector< std::vector< M >> &aseed, casadi_int npar) const
 Replace 0-by-0 reverse seeds. More...
 
template<typename M >
std::vector< std::vector< M > > replace_aseed (const std::vector< std::vector< M > > &aseed, casadi_int npar) const
 
std::vector< MXmapsum_mx (const std::vector< MX > &arg, const std::string &parallelization)
 Parallel evaluation. More...
 
virtual bool uses_output () const
 Do the derivative functions need nondifferentiated outputs? More...
 
std::string diff_prefix (const std::string &prefix) const
 Determine prefix for differentiated functions. More...
 
virtual const Functionoracle () const
 Get oracle. More...
 
bool has_derivative () const
 Can derivatives be calculated in any way? More...
 
virtual double ad_weight () const
 Weighting factor for chosing forward/reverse mode. More...
 
virtual double sp_weight () const
 Weighting factor for chosing forward/reverse mode,. More...
 
virtual std::vector< MXfree_mx () const
 Get free variables (MX) More...
 
virtual void generate_lifted (Function &vdef_fcn, Function &vinit_fcn) const
 Extract the functions needed for the Lifted Newton method. More...
 
virtual MX instruction_MX (casadi_int k) const
 get MX expression associated with instruction More...
 
Function wrap () const
 Wrap in an Function instance consisting of only one MX call. More...
 
Function wrap_as_needed (const Dict &opts) const
 Wrap in an Function instance consisting of only one MX call. More...
 
Dict cache () const
 Get all functions in the cache. More...
 
bool incache (const std::string &fname, Function &f, const std::string &suffix="") const
 Get function in cache. More...
 
void tocache (const Function &f, const std::string &suffix="") const
 Save function to cache. More...
 
void tocache_if_missing (Function &f, const std::string &suffix="") const
 Save function to cache, only if missing. More...
 
void codegen (CodeGenerator &g, const std::string &fname) const
 Generate code the function. More...
 
void codegen_meta (CodeGenerator &g) const
 Generate meta-information allowing a user to evaluate a generated function. More...
 
void codegen_sparsities (CodeGenerator &g) const
 Codegen sparsities. More...
 
virtual std::string codegen_name (const CodeGenerator &g, bool ns=true) const
 Get name in codegen. More...
 
std::string codegen_mem (CodeGenerator &g, const std::string &index="mem") const
 Get thread-local memory object. More...
 
virtual void codegen_incref (CodeGenerator &g) const
 Codegen incref for dependencies. More...
 
virtual void codegen_decref (CodeGenerator &g) const
 Codegen decref for dependencies. More...
 
virtual void codegen_alloc_mem (CodeGenerator &g) const
 Codegen decref for alloc_mem. More...
 
virtual void codegen_init_mem (CodeGenerator &g) const
 Codegen decref for init_mem. More...
 
virtual void codegen_free_mem (CodeGenerator &g) const
 Codegen for free_mem. More...
 
virtual void codegen_checkout (CodeGenerator &g) const
 Codegen for checkout. More...
 
virtual void codegen_release (CodeGenerator &g) const
 Codegen for release. More...
 
std::string signature (const std::string &fname) const
 Code generate the function. More...
 
std::string signature_unrolled (const std::string &fname) const
 Code generate the function. More...
 
virtual std::string codegen_mem_type () const
 Thread-local memory object type. More...
 
virtual std::string generate_dependencies (const std::string &fname, const Dict &opts) const
 Export / Generate C code for the dependency function. More...
 
virtual void jit_dependencies (const std::string &fname)
 Jit dependencies. More...
 
void serialize_type (SerializingStream &s) const override
 Serialize type information. More...
 
void disp (std::ostream &stream, bool more) const override
 Display object. More...
 
std::string definition () const
 Get function signature: name:(inputs)->(outputs) More...
 
void print_dimensions (std::ostream &stream) const
 Print dimensions of inputs and outputs. More...
 
void get_partition (casadi_int iind, casadi_int oind, Sparsity &D1, Sparsity &D2, bool compact, bool symmetric, bool allow_forward, bool allow_reverse) const
 Get the unidirectional or bidirectional partition. More...
 
virtual double get_max_in (casadi_int ind) const
 Get largest input value. More...
 
virtual double get_min_in (casadi_int ind) const
 Get smallest input value. More...
 
virtual std::vector< double > get_nominal_in (casadi_int ind) const
 
virtual std::vector< double > get_nominal_out (casadi_int ind) const
 
virtual double get_reltol () const
 Get relative tolerance. More...
 
virtual double get_abstol () const
 Get absolute tolerance. More...
 
virtual bool get_diff_in (casadi_int i)
 Which inputs are differentiable. More...
 
virtual bool get_diff_out (casadi_int i)
 Which outputs are differentiable. More...
 
casadi_int index_in (const std::string &name) const
 Get input scheme index by name. More...
 
casadi_int index_out (const std::string &name) const
 Get output scheme index by name. More...
 
virtual int sp_forward_block (const bvec_t **arg, bvec_t **res, casadi_int *iw, bvec_t *w, void *mem, casadi_int oind, casadi_int iind) const
 Propagate sparsity forward, specific block. More...
 
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. More...
 
size_t sz_arg () const
 Get required length of arg field. More...
 
size_t sz_res () const
 Get required length of res field. More...
 
size_t sz_iw () const
 Get required length of iw field. More...
 
size_t sz_w () const
 Get required length of w field. More...
 
void alloc_arg (size_t sz_arg, bool persistent=false)
 Ensure required length of arg field. More...
 
void alloc_res (size_t sz_res, bool persistent=false)
 Ensure required length of res field. More...
 
void alloc_iw (size_t sz_iw, bool persistent=false)
 Ensure required length of iw field. More...
 
void alloc_w (size_t sz_w, bool persistent=false)
 Ensure required length of w field. More...
 
void alloc (const Function &f, bool persistent=false, int num_threads=1)
 Ensure work vectors long enough to evaluate function. More...
 
virtual void set_work (void *mem, const double **&arg, double **&res, casadi_int *&iw, double *&w) const
 Set the (persistent) work vectors. More...
 
virtual void set_temp (void *mem, const double **arg, double **res, casadi_int *iw, double *w) const
 Set the (temporary) work vectors. More...
 
void setup (void *mem, const double **arg, double **res, casadi_int *iw, double *w) const
 Set the (persistent and temporary) work vectors. More...
 
virtual Dict info () const
 
Function map (casadi_int n, const std::string &parallelization) const
 Generate/retrieve cached serial map. More...
 
void generate_in (const std::string &fname, const double **arg) const
 Export an input file that can be passed to generate C code with a main. More...
 
void generate_out (const std::string &fname, double **res) const
 
virtual void merge (const std::vector< MX > &arg, std::vector< MX > &subs_from, std::vector< MX > &subs_to) const
 List merge opportunitities. More...
 
template<typename MatType >
std::vector< std::vector< MatType > > fwd_seed (casadi_int nfwd) const
 Symbolic expressions for the forward seeds. More...
 
template<typename MatType >
std::vector< std::vector< MatType > > symbolicAdjSeed (casadi_int nadj, const std::vector< MatType > &v) const
 Symbolic expressions for the adjoint seeds. More...
 
void print_in (std::ostream &stream, const double **arg, bool truncate) const
 Print inputs. More...
 
void print_out (std::ostream &stream, double **res, bool truncate) const
 Print outputs. More...
 
void construct (const Dict &opts)
 Construct. More...
 
void print_options (std::ostream &stream) const
 Print list of options. More...
 
void print_option (const std::string &name, std::ostream &stream) const
 Print all information there is to know about a certain option. More...
 
bool has_option (const std::string &option_name) const
 Does a particular option exist. More...
 
int checkout () const
 Checkout a memory object. More...
 
void release (int mem) const
 Release a memory object. More...
 
void * memory (int ind) const
 Memory objects. More...
 
bool has_memory (int ind) const
 Check for existance of memory object. More...
 
virtual void check_mem_count (casadi_int n) const
 Check for validatity of memory object count. More...
 
virtual int init_mem (void *mem) const
 Initalize memory block. More...
 
void clear_mem ()
 Clear all memory (called from destructor) More...
 
void print (const char *fmt,...) const
 C-style formatted printing during evaluation. More...
 
void sprint (char *buf, size_t buf_sz, const char *fmt,...) const
 C-style formatted printing to string. More...
 
void format_time (char *buffer, double time) const
 Format time in a fixed width 8 format. More...
 
void print_time (const std::map< std::string, FStats > &fstats) const
 Print timing statistics. More...
 
void serialize (SerializingStream &s) const
 Serialize an object. More...
 
virtual std::string serialize_base_function () const
 String used to identify the immediate FunctionInternal subclass. More...
 
casadi_int getCount () const
 Get the reference count. More...
 
std::string debug_repr (const SharedObjectInternal *) const
 
GenericWeakRef< SharedObject, SharedObjectInternal > * weak ()
 Get a weak reference to the object. More...
 
const SX sx_in (casadi_int ind) const override
 Get function input(s) and output(s) More...
 
const std::vector< SXsx_in () const override
 Get function input(s) and output(s) More...
 
bool has_spfwd () const override
 
bool has_sprev () const override
 
bool has_forward (casadi_int nfwd) const override
 Generate a function that calculates nfwd forward derivatives. More...
 
Function get_forward (casadi_int nfwd, const std::string &name, const std::vector< std::string > &inames, const std::vector< std::string > &onames, const Dict &opts) const override
 Generate a function that calculates nfwd forward derivatives. More...
 
bool has_reverse (casadi_int nadj) const override
 Generate a function that calculates nadj adjoint derivatives. More...
 
Function get_reverse (casadi_int nadj, const std::string &name, const std::vector< std::string > &inames, const std::vector< std::string > &onames, const Dict &opts) const override
 Generate a function that calculates nadj adjoint derivatives. More...
 
bool has_jacobian () const override
 Return Jacobian of all input elements with respect to all output elements. More...
 
Function get_jacobian (const std::string &name, const std::vector< std::string > &inames, const std::vector< std::string > &onames, const Dict &opts) const override
 Return Jacobian of all input elements with respect to all output elements. More...
 
virtual void call_forward (const std::vector< MX > &arg, const std::vector< MX > &res, const std::vector< std::vector< MX > > &fseed, std::vector< std::vector< MX > > &fsens, bool always_inline, bool never_inline) const
 Forward mode AD, virtual functions overloaded in derived classes. More...
 
virtual void call_forward (const std::vector< SX > &arg, const std::vector< SX > &res, const std::vector< std::vector< SX > > &fseed, std::vector< std::vector< SX > > &fsens, bool always_inline, bool never_inline) const
 Forward mode AD, virtual functions overloaded in derived classes. More...
 
virtual void call_reverse (const std::vector< MX > &arg, const std::vector< MX > &res, const std::vector< std::vector< MX > > &aseed, std::vector< std::vector< MX > > &asens, bool always_inline, bool never_inline) const
 Reverse mode, virtual functions overloaded in derived classes. More...
 
virtual void call_reverse (const std::vector< SX > &arg, const std::vector< SX > &res, const std::vector< std::vector< SX > > &aseed, std::vector< std::vector< SX > > &asens, bool always_inline, bool never_inline) const
 Reverse mode, virtual functions overloaded in derived classes. More...
 
size_t get_n_in () override
 Number of function inputs and outputs. More...
 
size_t get_n_out () override
 Number of function inputs and outputs. More...
 
Sparsity get_sparsity_in (casadi_int i) override
 Sparsities of function inputs and outputs. More...
 
Sparsity get_sparsity_out (casadi_int i) override
 Sparsities of function inputs and outputs. More...
 
int eval_gen (const double **arg, double **res, casadi_int *iw, double *w, void *mem, bool always_inline, bool never_inline) const
 Evaluate numerically. More...
 
int eval_gen (const SXElem **arg, SXElem **res, casadi_int *iw, SXElem *w, void *mem, bool always_inline, bool never_inline) const
 Evaluate a function, overloaded. More...
 
int eval_gen (const bvec_t **arg, bvec_t **res, casadi_int *iw, bvec_t *w, void *mem, bool always_inline, bool never_inline) const
 Evaluate a function, overloaded. More...
 
virtual std::vector< DMeval_dm (const std::vector< DM > &arg) const
 Evaluate with DM matrices. More...
 
virtual bool has_eval_dm () const
 Evaluate with DM matrices. More...
 
void call_gen (const MXVector &arg, MXVector &res, casadi_int npar, bool always_inline, bool never_inline) const
 Call a function, overloaded. More...
 
template<typename D >
void call_gen (const std::vector< Matrix< D > > &arg, std::vector< Matrix< D > > &res, casadi_int npar, bool always_inline, bool never_inline) const
 Call a function, overloaded. More...
 
template<typename M >
void check_arg (const std::vector< M > &arg, casadi_int &npar) const
 Check if input arguments have correct length and dimensions. More...
 
template<typename M >
void check_res (const std::vector< M > &res, casadi_int &npar) const
 Check if output arguments have correct length and dimensions. More...
 
template<typename M >
std::map< std::string, M > convert_arg (const std::vector< M > &arg) const
 Convert from/to input/output lists/map. More...
 
template<typename M >
std::vector< M > convert_arg (const std::map< std::string, M > &arg) const
 Convert from/to input/output lists/map. More...
 
template<typename M >
std::map< std::string, M > convert_res (const std::vector< M > &res) const
 Convert from/to input/output lists/map. More...
 
template<typename M >
std::vector< M > convert_res (const std::map< std::string, M > &res) const
 Convert from/to input/output lists/map. More...
 
std::vector< double > nz_in (const std::vector< DM > &arg) const
 Convert from/to flat vector of input/output nonzeros. More...
 
std::vector< DMnz_in (const std::vector< double > &arg) const
 Convert from/to flat vector of input/output nonzeros. More...
 
std::vector< double > nz_out (const std::vector< DM > &res) const
 Convert from/to flat vector of input/output nonzeros. More...
 
std::vector< DMnz_out (const std::vector< double > &res) const
 Convert from/to flat vector of input/output nonzeros. More...
 
Function jacobian () const
 Return Jacobian of all input elements with respect to all output elements. More...
 
Sparsityjac_sparsity (casadi_int oind, casadi_int iind, bool compact, bool symmetric) const
 Get Jacobian sparsity. More...
 
virtual bool has_jac_sparsity (casadi_int oind, casadi_int iind) const
 Get Jacobian sparsity. More...
 
virtual Sparsity get_jac_sparsity (casadi_int oind, casadi_int iind, bool symmetric) const
 Get Jacobian sparsity. More...
 
Function forward (casadi_int nfwd) const
 Return function that calculates forward derivatives. More...
 
Function reverse (casadi_int nadj) const
 Return function that calculates adjoint derivatives. More...
 
virtual const SX sx_out (casadi_int ind) const
 Get function input(s) and output(s) More...
 
virtual const std::vector< SXsx_out () const
 Get function input(s) and output(s) More...
 
virtual const MX mx_in (casadi_int ind) const
 Get function input(s) and output(s) More...
 
virtual const std::vector< MXmx_in () const
 Get function input(s) and output(s) More...
 
virtual const MX mx_out (casadi_int ind) const
 Get function input(s) and output(s) More...
 
virtual const std::vector< MXmx_out () const
 Get function input(s) and output(s) More...
 
const DM dm_in (casadi_int ind) const
 Get function input(s) and output(s) More...
 
const std::vector< DMdm_in () const
 Get function input(s) and output(s) More...
 
const DM dm_out (casadi_int ind) const
 Get function input(s) and output(s) More...
 
const std::vector< DMdm_out () const
 Get function input(s) and output(s) More...
 
casadi_int nnz_in () const
 Number of input/output nonzeros. More...
 
casadi_int nnz_in (casadi_int ind) const
 Number of input/output nonzeros. More...
 
casadi_int nnz_out () const
 Number of input/output nonzeros. More...
 
casadi_int nnz_out (casadi_int ind) const
 Number of input/output nonzeros. More...
 
casadi_int numel_in () const
 Number of input/output elements. More...
 
casadi_int numel_in (casadi_int ind) const
 Number of input/output elements. More...
 
casadi_int numel_out (casadi_int ind) const
 Number of input/output elements. More...
 
casadi_int numel_out () const
 Number of input/output elements. More...
 
casadi_int size1_in (casadi_int ind) const
 Input/output dimensions. More...
 
casadi_int size2_in (casadi_int ind) const
 Input/output dimensions. More...
 
casadi_int size1_out (casadi_int ind) const
 Input/output dimensions. More...
 
casadi_int size2_out (casadi_int ind) const
 Input/output dimensions. More...
 
std::pair< casadi_int, casadi_int > size_in (casadi_int ind) const
 Input/output dimensions. More...
 
std::pair< casadi_int, casadi_int > size_out (casadi_int ind) const
 Input/output dimensions. More...
 
const Sparsitysparsity_in (casadi_int ind) const
 Input/output sparsity. More...
 
const Sparsitysparsity_out (casadi_int ind) const
 Input/output sparsity. More...
 
bool all_scalar () const
 Are all inputs and outputs scalar. More...
 
virtual bool jac_is_symm (casadi_int oind, casadi_int iind) const
 Is a Jacobian block known to be symmetric a priori? More...
 
Sparsity to_compact (casadi_int oind, casadi_int iind, const Sparsity &sp) const
 Convert to compact Jacobian sparsity pattern. More...
 
Sparsity from_compact (casadi_int oind, casadi_int iind, const Sparsity &sp) const
 Convert from compact Jacobian sparsity pattern. More...
 
template<bool fwd>
Sparsity get_jac_sparsity_gen (casadi_int oind, casadi_int iind) const
 Get the sparsity pattern via sparsity seed propagation. More...
 
Sparsity get_jac_sparsity_hierarchical (casadi_int oind, casadi_int iind) const
 A flavor of get_jac_sparsity_gen that does hierarchical block structure recognition. More...
 
Sparsity get_jac_sparsity_hierarchical_symm (casadi_int oind, casadi_int iind) const
 
virtual std::vector< MXsymbolic_output (const std::vector< MX > &arg) const
 Get a vector of symbolic variables corresponding to the outputs. More...
 
virtual std::string get_name_in (casadi_int i)
 Names of function input and outputs. More...
 
virtual std::string get_name_out (casadi_int i)
 Names of function input and outputs. More...
 
virtual size_t codegen_sz_arg (const CodeGenerator &g) const
 Get required lengths, for codegen. More...
 
virtual size_t codegen_sz_res (const CodeGenerator &g) const
 Get required lengths, for codegen. More...
 
virtual size_t codegen_sz_iw (const CodeGenerator &g) const
 Get required lengths, for codegen. More...
 
virtual bool fwdViaJac (casadi_int nfwd) const
 Calculate derivatives by multiplying the full Jacobian and multiplying. More...
 
virtual bool adjViaJac (casadi_int nadj) const
 Calculate derivatives by multiplying the full Jacobian and multiplying. More...
 

Static Public Member Functions

static ProtoFunctiondeserialize (DeserializingStream &s)
 Deserialize without type information. More...
 
static std::vector< SXorder (const std::vector< SX > &expr)
 
static void sort_depth_first (std::stack< SXNode * > &s, std::vector< SXNode * > &nodes)
 Topological sorting of the nodes based on Depth-First Search (DFS) More...
 
static std::string forward_name (const std::string &fcn, casadi_int nfwd)
 Helper function: Get name of forward derivative function. More...
 
static std::string reverse_name (const std::string &fcn, casadi_int nadj)
 Helper function: Get name of adjoint derivative function. More...
 
template<typename MatType >
static MatType ensure_stacked (const MatType &v, const Sparsity &sp, casadi_int n)
 Ensure that a matrix's sparsity is a horizontal multiple of another, or empty. More...
 
template<typename MatType >
static bool purgable (const std::vector< MatType > &seed)
 Can a derivative direction be skipped. More...
 
static std::string string_from_UnifiedReturnStatus (UnifiedReturnStatus status)
 
static void print_canonical (std::ostream &stream, const Sparsity &sp, const double *nz)
 Print canonical representation of a numeric matrix. More...
 
static void print_canonical (std::ostream &stream, casadi_int sz, const double *nz)
 Print canonical representation of a numeric vector. More...
 
static void print_canonical (std::ostream &stream, double a)
 Print canonical representation of a number. More...
 
static bool check_mat (const Sparsity &arg, const Sparsity &inp, casadi_int &npar)
 

Public Attributes

std::vector< AlgElalgorithm_
 all binary nodes of the tree in the order of execution More...
 
size_t worksize_
 
std::vector< SXElemfree_vars_
 Free variables. More...
 
std::vector< SXElemoperations_
 The expressions corresponding to each binary operation. More...
 
std::vector< SXElemconstants_
 The expressions corresponding to each constant. More...
 
std::vector< double > default_in_
 Default input values. More...
 
std::vector< bool > copy_elision_
 Copy elision per algel. More...
 
bool print_instructions_
 Print each operation during evaluation. More...
 
struct casadi::SXFunction::CallInfo call_
 
bool just_in_time_opencl_
 With just-in-time compilation using OpenCL. More...
 
bool just_in_time_sparsity_
 With just-in-time compilation for the sparsity propagation. More...
 
bool live_variables_
 Live variables? More...
 
std::vector< Matrix< SXElem > > in_
 Inputs of the function (needed for symbolic calculations) More...
 
std::vector< Matrix< SXElem > > out_
 Outputs of the function (needed for symbolic calculations) More...
 
bool always_inline_
 
bool never_inline_
 
size_t n_in_
 Number of inputs and outputs. More...
 
size_t n_out_
 
std::vector< bool > is_diff_in_
 Are inputs and outputs differentiable? More...
 
std::vector< bool > is_diff_out_
 
std::vector< Sparsitysparsity_in_
 Input and output sparsity. More...
 
std::vector< Sparsitysparsity_out_
 
std::vector< std::string > name_in_
 Input and output scheme. More...
 
std::vector< std::string > name_out_
 
bool jit_
 Use just-in-time compiler. More...
 
bool jit_cleanup_
 Cleanup jit source file. More...
 
std::string jit_serialize_
 Serialize behaviour. More...
 
std::string jit_name_
 Name if jit source file. More...
 
std::string jit_base_name_
 
bool jit_temp_suffix_
 Use a temporary name. More...
 
eval_t eval_
 Numerical evaluation redirected to a C function. More...
 
casadi_checkout_t checkout_
 Checkout redirected to a C function. More...
 
casadi_release_t release_
 Release redirected to a C function. More...
 
Dict stats_
 Dict of statistics (resulting from evaluate) More...
 
bool has_refcount_
 Reference counting in codegen? More...
 
Dict cache_init_
 Values to prepopulate the function cache with. More...
 
WeakCache< std::string, Functioncache_
 Function cache. More...
 
std::vector< Sparsityjac_sparsity_ [2]
 Cache for sparsities of the Jacobian blocks. More...
 
Function derivative_of_
 If the function is the derivative of another function. More...
 
void * user_data_
 User-set field. More...
 
std::string compiler_plugin_
 Just-in-time compiler. More...
 
Importer compiler_
 
Dict jit_options_
 
double jac_penalty_
 Penalty factor for using a complete Jacobian to calculate directional derivatives. More...
 
bool enable_forward_
 
bool enable_reverse_
 
bool enable_jacobian_
 
bool enable_fd_
 
bool enable_forward_op_
 
bool enable_reverse_op_
 
bool enable_jacobian_op_
 
bool enable_fd_op_
 
double ad_weight_
 Weighting factor for derivative calculation and sparsity pattern calculation. More...
 
double ad_weight_sp_
 
casadi_int max_num_dir_
 Maximum number of sensitivity directions. More...
 
bool inputs_check_
 Errors are thrown if numerical values of inputs look bad. More...
 
Dict fd_options_
 
double fd_step_
 
std::string fd_method_
 
bool print_in_
 
bool print_out_
 
bool print_canonical_
 
casadi_int max_io_
 
bool dump_in_
 
bool dump_out_
 
bool dump_
 
std::string dump_dir_
 
std::string dump_format_
 
Dict forward_options_
 
Dict reverse_options_
 
Dict jacobian_options_
 
Dict der_options_
 
Function custom_jacobian_
 
casadi_int dump_count_
 
std::string name_
 Name. More...
 
bool verbose_
 Verbose printout. More...
 
bool print_time_
 
bool record_time_
 
bool regularity_check_
 Errors are thrown when NaN is produced. More...
 
bool error_on_fail_
 Throw an exception on failure? More...
 

Static Public Attributes

static std::map< std::string, ProtoFunction *(*)(DeserializingStream &)> deserialize_map
 

Protected Member Functions

template<typename T >
void call_fwd (const AlgEl &e, const T **arg, T **res, casadi_int *iw, T *w) const
 
template<typename T >
void call_rev (const AlgEl &e, T **arg, T **res, casadi_int *iw, T *w) const
 
template<typename T , typename CT >
void call_setup (const ExtendedAlgEl &m, CT ***call_arg, T ***call_res, casadi_int **call_iw, T **call_w, T **nz_in, T **nz_out) const
 
 SXFunction (DeserializingStream &s)
 Deserializing constructor. More...
 
void set_jac_sparsity (casadi_int oind, casadi_int iind, const Sparsity &sp)
 Populate jac_sparsity_ and jac_sparsity_compact_ during initialization. More...
 
void initSingleton ()
 
void destroySingleton ()
 
shared_from_this ()
 Get a shared object from the current internal object. More...
 
const B shared_from_this () const
 Get a shared object from the current internal object. More...
 
static const Options options_
 Options. More...
 
const Optionsget_options () const override
 Options. More...
 

Member Typedef Documentation

◆ AlgEl

Extra doc: https://github.com/casadi/casadi/wiki/L_uw

An element of the algorithm, namely a binary operation

Extra doc: https://github.com/casadi/casadi/wiki/L_ux

Definition at line 235 of file sx_function.hpp.

◆ weak_ref_type

Definition at line 152 of file shared_object.hpp.

Constructor & Destructor Documentation

◆ SXFunction() [1/2]

casadi::SXFunction::SXFunction ( const std::string &  name,
const std::vector< Matrix< SXElem > > &  inputv,
const std::vector< Matrix< SXElem > > &  outputv,
const std::vector< std::string > &  name_in,
const std::vector< std::string > &  name_out 
)

◆ ~SXFunction()

casadi::SXFunction::~SXFunction ( )
override

Extra doc: https://github.com/casadi/casadi/wiki/L_ud

Definition at line 68 of file sx_function.cpp.

68  {
69  clear_mem();
70  }
void clear_mem()
Clear all memory (called from destructor)

References casadi::ProtoFunction::clear_mem().

◆ SXFunction() [2/2]

casadi::SXFunction::SXFunction ( DeserializingStream s)
explicitprotected

Extra doc: https://github.com/casadi/casadi/wiki/L_vb

Definition at line 1824 of file sx_function.cpp.

1824  :
1825  XFunction<SXFunction, SX, SXNode>(s) {
1826  int version = s.version("SXFunction", 1, 3);
1827  size_t n_instructions;
1828  s.unpack("SXFunction::n_instr", n_instructions);
1829 
1830  s.unpack("SXFunction::worksize", worksize_);
1831  s.unpack("SXFunction::free_vars", free_vars_);
1832  s.unpack("SXFunction::operations", operations_);
1833  s.unpack("SXFunction::constants", constants_);
1834  s.unpack("SXFunction::default_in", default_in_);
1835 
1836  if (version>=2) {
1837 
1838  s.unpack("SXFunction::call_sz_arg", call_.sz_arg);
1839  s.unpack("SXFunction::call_sz_res", call_.sz_res);
1840  s.unpack("SXFunction::call_sz_iw", call_.sz_iw);
1841  s.unpack("SXFunction::call_sz_w", call_.sz_w);
1842  s.unpack("SXFunction::call_sz_arg", call_.sz_w_arg);
1843  s.unpack("SXFunction::call_sz_res", call_.sz_w_res);
1844 
1845  size_t el_size;
1846  s.unpack("SXFunction::call_el_size", el_size);
1847  call_.el.reserve(el_size);
1848 
1849  // Loop over nodes
1850  for (casadi_int k=0;k<el_size;++k) {
1851  Function f;
1852  s.unpack("SXFunction::call_el_f", f);
1853  call_.el.emplace_back(f);
1854  auto& e = call_.el[k];
1855  s.unpack("SXFunction::call_el_dep", e.dep);
1856  s.unpack("SXFunction::call_el_res", e.res);
1857  s.unpack("SXFunction::call_el_copy_elision_arg", e.copy_elision_arg);
1858  s.unpack("SXFunction::call_el_copy_elision_offset", e.copy_elision_offset);
1859  }
1860 
1861  s.unpack("SXFunction::copy_elision", copy_elision_);
1862 
1863  } else {
1864  call_.sz_arg = 0;
1865  call_.sz_res = 0;
1866  call_.sz_iw = 0;
1867  call_.sz_w = 0;
1868  call_.sz_w_arg = 0;
1869  call_.sz_w_res = 0;
1870  call_.el.clear();
1871  copy_elision_.resize(n_instructions, false);
1872  }
1873 
1874  algorithm_.resize(n_instructions);
1875  for (casadi_int k=0;k<n_instructions;++k) {
1876  AlgEl& e = algorithm_[k];
1877  s.unpack("SXFunction::ScalarAtomic::op", e.op);
1878  s.unpack("SXFunction::ScalarAtomic::i0", e.i0);
1879  s.unpack("SXFunction::ScalarAtomic::i1", e.i1);
1880  s.unpack("SXFunction::ScalarAtomic::i2", e.i2);
1881  }
1882 
1883  // Default (persistent) options
1884  just_in_time_opencl_ = false;
1885  just_in_time_sparsity_ = false;
1886 
1887  s.unpack("SXFunction::live_variables", live_variables_);
1888  if (version>=3) {
1889  s.unpack("SXFunction::print_instructions", print_instructions_);
1890  } else {
1891  print_instructions_ = false;
1892  }
1893 
1895  }
std::vector< SXElem > operations_
The expressions corresponding to each binary operation.
std::vector< bool > copy_elision_
Copy elision per algel.
ScalarAtomic AlgEl
DATA MEMBERS.
std::vector< SXElem > constants_
The expressions corresponding to each constant.
bool just_in_time_opencl_
With just-in-time compilation using OpenCL.
struct casadi::SXFunction::CallInfo call_
std::vector< AlgEl > algorithm_
all binary nodes of the tree in the order of execution
std::vector< SXElem > free_vars_
Free variables.
std::vector< double > default_in_
Default input values.
bool print_instructions_
Print each operation during evaluation.
bool live_variables_
Live variables?
casadi_int n_instructions() const override
Get the number of atomic operations.
bool just_in_time_sparsity_
With just-in-time compilation for the sparsity propagation.
void delayed_deserialize_members(DeserializingStream &s)
Definition: x_function.hpp:299
std::vector< ExtendedAlgEl > el

References algorithm_, call_, constants_, copy_elision_, default_in_, casadi::XFunction< DerivedType, MatType, NodeType >::delayed_deserialize_members(), casadi::SXFunction::CallInfo::el, free_vars_, casadi::ScalarAtomic::i0, casadi::ScalarAtomic::i1, casadi::ScalarAtomic::i2, just_in_time_opencl_, just_in_time_sparsity_, live_variables_, n_instructions(), casadi::ScalarAtomic::op, operations_, print_instructions_, casadi::SXFunction::CallInfo::sz_arg, casadi::SXFunction::CallInfo::sz_iw, casadi::SXFunction::CallInfo::sz_res, casadi::SXFunction::CallInfo::sz_w, casadi::SXFunction::CallInfo::sz_w_arg, casadi::SXFunction::CallInfo::sz_w_res, casadi::DeserializingStream::unpack(), casadi::DeserializingStream::version(), and worksize_.

Member Function Documentation

◆ ad_forward()

void casadi::SXFunction::ad_forward ( const std::vector< std::vector< SX > > &  fseed,
std::vector< std::vector< SX > > &  fsens 
) const

Extra doc: https://github.com/casadi/casadi/wiki/L_ug

Definition at line 1192 of file sx_function.cpp.

1193  {
1194  if (verbose_) casadi_message(name_ + "::ad_forward");
1195 
1196  // Number of forward seeds
1197  casadi_int nfwd = fseed.size();
1198  fsens.resize(nfwd);
1199 
1200  // Quick return if possible
1201  if (nfwd==0) return;
1202 
1203  // Check if seeds need to have dimensions corrected
1204  casadi_int npar = 1;
1205  for (auto&& r : fseed) {
1206  if (!matching_arg(r, npar)) {
1207  casadi_assert_dev(npar==1);
1208  return ad_forward(replace_fseed(fseed, npar), fsens);
1209  }
1210  }
1211 
1212  // Make sure seeds have matching sparsity patterns
1213  for (auto it=fseed.begin(); it!=fseed.end(); ++it) {
1214  casadi_assert_dev(it->size()==n_in_);
1215  for (casadi_int i=0; i<n_in_; ++i) {
1216  if (it->at(i).sparsity()!=sparsity_in_[i]) {
1217  // Correct sparsity
1218  std::vector<std::vector<SX> > fseed2(fseed);
1219  for (auto&& r : fseed2) {
1220  for (casadi_int i=0; i<n_in_; ++i) r[i] = project(r[i], sparsity_in_[i]);
1221  }
1222  return ad_forward(fseed2, fsens);
1223  }
1224  }
1225  }
1226 
1227  // Allocate results
1228  for (casadi_int d=0; d<nfwd; ++d) {
1229  fsens[d].resize(n_out_);
1230  for (casadi_int i=0; i<fsens[d].size(); ++i)
1231  if (fsens[d][i].sparsity()!=sparsity_out_[i])
1232  fsens[d][i] = SX::zeros(sparsity_out_[i]);
1233  }
1234 
1235  // Iterator to the binary operations
1236  std::vector<SXElem>::const_iterator b_it=operations_.begin();
1237 
1238  // Tape
1239  std::vector<TapeEl<SXElem> > s_pdwork(operations_.size());
1240  std::vector<TapeEl<SXElem> >::iterator it1 = s_pdwork.begin();
1241 
1242  // Evaluate algorithm
1243  if (verbose_) casadi_message("Evaluating algorithm forward");
1244  for (auto&& e : algorithm_) {
1245  switch (e.op) {
1246  case OP_INPUT:
1247  case OP_OUTPUT:
1248  case OP_CONST:
1249  case OP_PARAMETER:
1250  break;
1251  default:
1252  {
1253  const SXElem& f=*b_it++;
1254  switch (e.op) {
1255  CASADI_MATH_DER_BUILTIN(f->dep(0), f->dep(1), f, it1++->d)
1256  case OP_CALL:
1257  it1++->d[0] = f;
1258  }
1259  }
1260  }
1261  }
1262 
1263  // Work vector
1264  std::vector<SXElem> w(worksize_);
1265 
1266  // Calculate forward sensitivities
1267  if (verbose_) casadi_message("Calculating forward derivatives");
1268  for (casadi_int dir=0; dir<nfwd; ++dir) {
1269  std::vector<TapeEl<SXElem> >::const_iterator it2 = s_pdwork.begin();
1270  for (auto&& a : algorithm_) {
1271  switch (a.op) {
1272  case OP_INPUT:
1273  w[a.i0] = fseed[dir][a.i1].nonzeros()[a.i2]; break;
1274  case OP_OUTPUT:
1275  fsens[dir][a.i0].nonzeros()[a.i2] = w[a.i1]; break;
1276  case OP_CONST:
1277  case OP_PARAMETER:
1278  w[a.i0] = 0;
1279  break;
1280  case OP_IF_ELSE_ZERO:
1281  w[a.i0] = if_else_zero(it2++->d[1], w[a.i2]);
1282  break;
1283  case OP_CALL:
1284  {
1285  auto& m = call_.el.at(a.i1);
1286  CallSX* call_node = static_cast<CallSX*>(it2->d[0].get());
1287 
1288  // Construct forward sensitivity function
1289  Function ff = m.f.forward(1);
1290 
1291  // Symbolic inputs to forward sensitivity function
1292  std::vector<SXElem> deps;
1293  deps.reserve(2*m.n_dep);
1294 
1295  // Set nominal inputs from node
1296  casadi_int offset = 0;
1297  for (casadi_int i=0;i<m.f_n_in;++i) {
1298  casadi_int nnz = ff.nnz_in(i);
1299  casadi_assert(nnz==0 || nnz==m.f.nnz_in(i), "Not implemented");
1300  for (casadi_int j=0;j<nnz;++j) {
1301  deps.push_back(call_node->dep(offset+j));
1302  }
1303  offset += m.f_nnz_in[i];
1304  }
1305 
1306  // Do not set nominal outputs
1307  offset = 0;
1308  for (casadi_int i=0;i<m.f_n_out;++i) {
1309  casadi_int nnz = ff.nnz_in(i+m.f_n_in);
1310  casadi_assert(nnz==0 || nnz==m.f.nnz_out(i), "Not implemented");
1311  for (casadi_int j=0;j<nnz;++j) {
1312  deps.push_back(call_node->get_output(offset+j));
1313  }
1314  offset += m.f_nnz_out[i];
1315  }
1316 
1317  // Read in forward seeds from work vector
1318  offset = 0;
1319  for (casadi_int i=0;i<m.f_n_in;++i) {
1320  casadi_int nnz = ff.nnz_in(i+m.f_n_in+m.f_n_out);
1321  // nnz=0 occurs for is_diff_in[i] false
1322  casadi_assert(nnz==0 || nnz==m.f.nnz_in(i), "Not implemented");
1323  if (nnz) {
1324  for (casadi_int j=0;j<nnz;++j) {
1325  deps.push_back(w[m.dep[offset+j]]);
1326  }
1327  }
1328  offset += m.f_nnz_in[i];
1329  }
1330 
1331  // Call forward sensitivity function
1332  std::vector<SXElem> ret = SXElem::call(ff, deps);
1333 
1334  // Retrieve sensitivities
1335  offset = 0;
1336  casadi_int k = 0;
1337  for (casadi_int i=0;i<m.f_n_out;++i) {
1338  casadi_int nnz = ff.nnz_out(i);
1339  // nnz=0 occurs for is_diff_out[i] false
1340  casadi_assert(nnz==0 || nnz==m.f_nnz_out[i], "Not implemented");
1341  if (nnz) {
1342  for (casadi_int j=0;j<nnz;++j) {
1343  if (m.res[offset+j]>=0) w[m.res[offset+j]] = ret[k];
1344  k++;
1345  }
1346  }
1347  offset += m.f_nnz_out[i];
1348  }
1349  }
1350  it2++;
1351  break;
1352  CASADI_MATH_BINARY_BUILTIN // Binary operation
1353  w[a.i0] = it2->d[0] * w[a.i1] + it2->d[1] * w[a.i2];
1354  it2++;
1355  break;
1356  default: // Unary operation
1357  w[a.i0] = it2->d[0] * w[a.i1];
1358  it2++;
1359  }
1360  }
1361  }
1362  }
Function forward(casadi_int nfwd) const
Return function that calculates forward derivatives.
std::vector< Sparsity > sparsity_in_
Input and output sparsity.
std::vector< std::vector< M > > replace_fseed(const std::vector< std::vector< M >> &fseed, casadi_int npar) const
Replace 0-by-0 forward seeds.
size_t n_in_
Number of inputs and outputs.
bool matching_arg(const std::vector< M > &arg, casadi_int &npar) const
Check if input arguments that needs to be replaced.
std::vector< Sparsity > sparsity_out_
static Matrix< Scalar > zeros(casadi_int nrow=1, casadi_int ncol=1)
Create a dense matrix or a matrix with specified sparsity with all entries zero.
bool verbose_
Verbose printout.
static std::vector< SXElem > call(const Function &f, const std::vector< SXElem > &deps)
Definition: sx_elem.cpp:403
void ad_forward(const std::vector< std::vector< SX > > &fseed, std::vector< std::vector< SX > > &fsens) const
Calculate forward mode directional derivatives.
double if_else_zero(double x, double y)
Conditional assignment.
Definition: calculus.hpp:289
@ OP_IF_ELSE_ZERO
Definition: calculus.hpp:71
@ OP_OUTPUT
Definition: calculus.hpp:82
@ OP_CONST
Definition: calculus.hpp:79
@ OP_INPUT
Definition: calculus.hpp:82
@ OP_PARAMETER
Definition: calculus.hpp:85
@ OP_CALL
Definition: calculus.hpp:88

References algorithm_, casadi::SXElem::call(), call_, casadi::SXNode::dep(), casadi::CallSX::dep(), casadi::SXFunction::CallInfo::el, casadi::Function::forward(), casadi::CallSX::get_output(), casadi::if_else_zero(), casadi::FunctionInternal::matching_arg(), casadi::FunctionInternal::n_in_, casadi::FunctionInternal::n_out_, casadi::ProtoFunction::name_, casadi::Function::nnz_in(), casadi::Function::nnz_out(), casadi::OP_CALL, casadi::OP_CONST, casadi::OP_IF_ELSE_ZERO, casadi::OP_INPUT, casadi::OP_OUTPUT, casadi::OP_PARAMETER, operations_, casadi::FunctionInternal::replace_fseed(), casadi::FunctionInternal::sparsity_in_, casadi::FunctionInternal::sparsity_out_, casadi::ProtoFunction::verbose_, worksize_, and casadi::GenericMatrix< Matrix< Scalar > >::zeros().

◆ ad_reverse()

void casadi::SXFunction::ad_reverse ( const std::vector< std::vector< SX > > &  aseed,
std::vector< std::vector< SX > > &  asens 
) const

Extra doc: https://github.com/casadi/casadi/wiki/L_uh

Definition at line 1364 of file sx_function.cpp.

1365  {
1366  if (verbose_) casadi_message(name_ + "::ad_reverse");
1367 
1368  // number of adjoint seeds
1369  casadi_int nadj = aseed.size();
1370  asens.resize(nadj);
1371 
1372  // Quick return if possible
1373  if (nadj==0) return;
1374 
1375  // Check if seeds need to have dimensions corrected
1376  casadi_int npar = 1;
1377  for (auto&& r : aseed) {
1378  if (!matching_res(r, npar)) {
1379  casadi_assert_dev(npar==1);
1380  return ad_reverse(replace_aseed(aseed, npar), asens);
1381  }
1382  }
1383 
1384  // Make sure matching sparsity of fseed
1385  bool matching_sparsity = true;
1386  for (casadi_int d=0; d<nadj; ++d) {
1387  casadi_assert_dev(aseed[d].size()==n_out_);
1388  for (casadi_int i=0; matching_sparsity && i<n_out_; ++i)
1389  matching_sparsity = aseed[d][i].sparsity()==sparsity_out_[i];
1390  }
1391 
1392  // Correct sparsity if needed
1393  if (!matching_sparsity) {
1394  std::vector<std::vector<SX> > aseed2(aseed);
1395  for (casadi_int d=0; d<nadj; ++d)
1396  for (casadi_int i=0; i<n_out_; ++i)
1397  if (aseed2[d][i].sparsity()!=sparsity_out_[i])
1398  aseed2[d][i] = project(aseed2[d][i], sparsity_out_[i]);
1399  return ad_reverse(aseed2, asens);
1400  }
1401 
1402  // Allocate results if needed
1403  for (casadi_int d=0; d<nadj; ++d) {
1404  asens[d].resize(n_in_);
1405  for (casadi_int i=0; i<asens[d].size(); ++i) {
1406  if (asens[d][i].sparsity()!=sparsity_in_[i]) {
1407  asens[d][i] = SX::zeros(sparsity_in_[i]);
1408  } else {
1409  std::fill(asens[d][i]->begin(), asens[d][i]->end(), 0);
1410  }
1411  }
1412  }
1413 
1414  // Iterator to the binary operations
1415  std::vector<SXElem>::const_iterator b_it=operations_.begin();
1416 
1417  // Tape
1418  std::vector<TapeEl<SXElem> > s_pdwork(operations_.size());
1419  std::vector<TapeEl<SXElem> >::iterator it1 = s_pdwork.begin();
1420 
1421  // Evaluate algorithm
1422  if (verbose_) casadi_message("Evaluating algorithm forward");
1423  for (auto&& a : algorithm_) {
1424  switch (a.op) {
1425  case OP_INPUT:
1426  case OP_OUTPUT:
1427  case OP_CONST:
1428  case OP_PARAMETER:
1429  break;
1430  default:
1431  {
1432  const SXElem& f=*b_it++;
1433  switch (a.op) {
1434  CASADI_MATH_DER_BUILTIN(f->dep(0), f->dep(1), f, it1++->d)
1435  case OP_CALL:
1436  it1++->d[0] = f;
1437  }
1438  }
1439  }
1440  }
1441 
1442  // Calculate adjoint sensitivities
1443  if (verbose_) casadi_message("Calculating adjoint derivatives");
1444 
1445  // Work vector
1446  std::vector<SXElem> w(worksize_, 0);
1447 
1448  for (casadi_int dir=0; dir<nadj; ++dir) {
1449  auto it2 = s_pdwork.rbegin();
1450  for (auto it = algorithm_.rbegin(); it!=algorithm_.rend(); ++it) {
1451  SXElem seed;
1452  switch (it->op) {
1453  case OP_INPUT:
1454  asens[dir][it->i1].nonzeros()[it->i2] = w[it->i0];
1455  w[it->i0] = 0;
1456  break;
1457  case OP_OUTPUT:
1458  w[it->i1] += aseed[dir][it->i0].nonzeros()[it->i2];
1459  break;
1460  case OP_CONST:
1461  case OP_PARAMETER:
1462  w[it->i0] = 0;
1463  break;
1464  case OP_IF_ELSE_ZERO:
1465  seed = w[it->i0];
1466  w[it->i0] = 0;
1467  w[it->i2] += if_else_zero(it2++->d[1], seed);
1468  break;
1469  case OP_CALL:
1470  {
1471  auto& m = call_.el.at(it->i1);
1472  CallSX* call_node = static_cast<CallSX*>(it2->d[0].get());
1473 
1474  // Construct reverse sensitivity function
1475  Function fr = m.f.reverse(1);
1476 
1477  // Symbolic inputs to reverse sensitivity function
1478  std::vector<SXElem> deps;
1479  deps.reserve(m.n_dep+m.n_res);
1480 
1481  // Set nominal inputs from node
1482  casadi_int offset = 0;
1483  for (casadi_int i=0;i<m.f_n_in;++i) {
1484  casadi_int nnz = fr.nnz_in(i);
1485  casadi_assert(nnz==0 || nnz==m.f.nnz_in(i), "Not implemented");
1486  for (casadi_int j=0;j<nnz;++j) {
1487  deps.push_back(call_node->dep(offset+j));
1488  }
1489  offset += m.f_nnz_in[i];
1490  }
1491 
1492  // Do not set nominal outputs
1493  offset = 0;
1494  for (casadi_int i=0;i<m.f_n_out;++i) {
1495  casadi_int nnz = fr.nnz_in(i+m.f_n_in);
1496  casadi_assert(nnz==0 || nnz==m.f.nnz_out(i), "Not implemented");
1497  for (casadi_int j=0;j<nnz;++j) {
1498  deps.push_back(call_node->get_output(offset+j));
1499  }
1500  offset += m.f_nnz_out[i];
1501  }
1502 
1503  // Read in reverse seeds from work vector
1504  offset = 0;
1505  for (casadi_int i=0;i<m.f_n_out;++i) {
1506  casadi_int nnz = fr.nnz_in(i+m.f_n_in+m.f_n_out);
1507  // nnz=0 occurs for is_diff_out[i] false
1508  casadi_assert(nnz==0 || nnz==m.f.nnz_out(i), "Not implemented");
1509  if (nnz) {
1510  for (casadi_int j=0;j<nnz;++j) {
1511  deps.push_back((m.res[offset+j]>=0) ? w[m.res[offset+j]] : 0);
1512  }
1513  }
1514  offset += m.f.nnz_out(i);
1515  }
1516 
1517  // Call reverse sensitivity function
1518  std::vector<SXElem> ret = SXElem::call(fr, deps);
1519 
1520  // Clear out reverse seeds
1521  for (casadi_int i=0;i<m.n_res;++i) {
1522  if (m.res[i]>=0) w[m.res[i]] = 0;
1523  }
1524 
1525  // Store reverse sensitivities into work vector
1526  offset = 0;
1527  casadi_int k = 0;
1528  for (casadi_int i=0;i<m.f_n_in;++i) {
1529  casadi_int nnz = fr.nnz_out(i);
1530  // nnz=0 occurs for is_diff_in[i] false
1531  casadi_assert(nnz==0 || nnz==m.f_nnz_in[i], "Not implemented");
1532  if (nnz) {
1533  for (casadi_int j=0;j<nnz;++j) {
1534  w[m.dep[offset+j]] += ret[k++];
1535  }
1536  }
1537  offset += m.f_nnz_in[i];
1538  }
1539  }
1540  it2++;
1541  break;
1542  CASADI_MATH_BINARY_BUILTIN // Binary operation
1543  seed = w[it->i0];
1544  w[it->i0] = 0;
1545  w[it->i1] += it2->d[0] * seed;
1546  w[it->i2] += it2++->d[1] * seed;
1547  break;
1548  default: // Unary operation
1549  seed = w[it->i0];
1550  w[it->i0] = 0;
1551  w[it->i1] += it2++->d[0] * seed;
1552  }
1553  }
1554  }
1555  }
bool matching_res(const std::vector< M > &arg, casadi_int &npar) const
Check if output arguments that needs to be replaced.
std::vector< std::vector< M > > replace_aseed(const std::vector< std::vector< M >> &aseed, casadi_int npar) const
Replace 0-by-0 reverse seeds.
void ad_reverse(const std::vector< std::vector< SX > > &aseed, std::vector< std::vector< SX > > &asens) const
Calculate reverse mode directional derivatives.

References algorithm_, casadi::SXElem::call(), call_, casadi::SXNode::dep(), casadi::CallSX::dep(), casadi::SXFunction::CallInfo::el, casadi::CallSX::get_output(), casadi::if_else_zero(), casadi::FunctionInternal::matching_res(), casadi::FunctionInternal::n_in_, casadi::FunctionInternal::n_out_, casadi::ProtoFunction::name_, casadi::Function::nnz_in(), casadi::Function::nnz_out(), casadi::OP_CALL, casadi::OP_CONST, casadi::OP_IF_ELSE_ZERO, casadi::OP_INPUT, casadi::OP_OUTPUT, casadi::OP_PARAMETER, operations_, casadi::FunctionInternal::replace_aseed(), casadi::Function::reverse(), casadi::FunctionInternal::sparsity_in_, casadi::FunctionInternal::sparsity_out_, casadi::ProtoFunction::verbose_, worksize_, and casadi::GenericMatrix< Matrix< Scalar > >::zeros().

◆ ad_weight()

double casadi::FunctionInternal::ad_weight ( ) const
virtualinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_l5

Definition at line 3274 of file function_internal.cpp.

3274  {
3275  // If reverse mode derivatives unavailable, use forward
3276  if (!enable_reverse_) return 0;
3277 
3278  // If forward mode derivatives unavailable, use reverse
3279  if (!enable_forward_ && !enable_fd_) return 1;
3280 
3281  // Use the (potentially user set) option
3282  return ad_weight_;
3283  }
double ad_weight_
Weighting factor for derivative calculation and sparsity pattern calculation.

References casadi::FunctionInternal::ad_weight_, casadi::FunctionInternal::enable_fd_, casadi::FunctionInternal::enable_forward_, and casadi::FunctionInternal::enable_reverse_.

Referenced by casadi::FunctionInternal::adjViaJac(), casadi::Function::expand(), casadi::FunctionInternal::fwdViaJac(), casadi::FunctionInternal::get_partition(), casadi::FunctionInternal::wrap(), and casadi::FunctionInternal::wrap_as_needed().

◆ add_embedded()

void casadi::FunctionInternal::add_embedded ( std::map< FunctionInternal *, Function > &  all_fun,
const Function dep,
casadi_int  max_depth 
) const
inherited

Definition at line 3717 of file function_internal.cpp.

3718  {
3719  // Add, if not already in graph and not null
3720  if (!dep.is_null() && all_fun.find(dep.get()) == all_fun.end()) {
3721  // Add to map
3722  all_fun[dep.get()] = dep;
3723  // Also add its dependencies
3724  if (max_depth > 0) dep->find(all_fun, max_depth - 1);
3725  }
3726  }

References casadi::FunctionInternal::find(), casadi::Function::get(), and casadi::GenericShared< Shared, Internal >::is_null().

Referenced by casadi::MXFunction::find(), casadi::Switch::find(), find(), and casadi::BSplineInterpolant::find().

◆ adjViaJac()

bool casadi::FunctionInternal::adjViaJac ( casadi_int  nadj) const
virtualinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_nc

Definition at line 3009 of file function_internal.cpp.

3009  {
3010  if (!enable_reverse_) return true;
3011  if (jac_penalty_==-1) return false;
3012 
3013  // Heuristic 1: Jac calculated via reverse mode likely cheaper
3014  if (jac_penalty_*static_cast<double>(nnz_out())<nadj) return true;
3015 
3016  // Heuristic 2: Jac calculated via forward mode likely cheaper
3017  double w = ad_weight();
3018  if ((enable_forward_ || enable_fd_) &&
3019  jac_penalty_*w*static_cast<double>(nnz_in())<(1-w)*static_cast<double>(nadj))
3020  return true; // NOLINT
3021 
3022  return false;
3023  }
double jac_penalty_
Penalty factor for using a complete Jacobian to calculate directional derivatives.
virtual double ad_weight() const
Weighting factor for chosing forward/reverse mode.
casadi_int nnz_in() const
Number of input/output nonzeros.
casadi_int nnz_out() const
Number of input/output nonzeros.

References casadi::FunctionInternal::ad_weight(), casadi::FunctionInternal::enable_fd_, casadi::FunctionInternal::enable_forward_, casadi::FunctionInternal::enable_reverse_, casadi::FunctionInternal::jac_penalty_, casadi::FunctionInternal::nnz_in(), and casadi::FunctionInternal::nnz_out().

Referenced by casadi::FunctionInternal::call_reverse().

◆ all_scalar()

bool casadi::FunctionInternal::all_scalar ( ) const
inherited

Extra doc: https://github.com/casadi/casadi/wiki/L_mi

Definition at line 3748 of file function_internal.cpp.

3748  {
3749  // Check inputs
3750  for (casadi_int i=0; i<n_in_; ++i) {
3751  if (!sparsity_in_[i].is_scalar()) return false;
3752  }
3753  // Check outputs
3754  for (casadi_int i=0; i<n_out_; ++i) {
3755  if (!sparsity_out_[i].is_scalar()) return false;
3756  }
3757  // All are scalar
3758  return true;
3759  }

References casadi::FunctionInternal::n_in_, casadi::FunctionInternal::n_out_, casadi::FunctionInternal::sparsity_in_, and casadi::FunctionInternal::sparsity_out_.

Referenced by casadi::FunctionInternal::call().

◆ alloc()

void casadi::FunctionInternal::alloc ( const Function f,
bool  persistent = false,
int  num_threads = 1 
)
inherited

Extra doc: https://github.com/casadi/casadi/wiki/L_n8

Definition at line 2958 of file function_internal.cpp.

2958  {
2959  if (f.is_null()) return;
2960  size_t sz_arg, sz_res, sz_iw, sz_w;
2961  f.sz_work(sz_arg, sz_res, sz_iw, sz_w);
2962  alloc_arg(sz_arg*num_threads, persistent);
2963  alloc_res(sz_res*num_threads, persistent);
2964  alloc_iw(sz_iw*num_threads, persistent);
2965  alloc_w(sz_w*num_threads, persistent);
2966  }
void alloc_iw(size_t sz_iw, bool persistent=false)
Ensure required length of iw field.
void alloc_res(size_t sz_res, bool persistent=false)
Ensure required length of res field.
void alloc_arg(size_t sz_arg, bool persistent=false)
Ensure required length of arg field.
size_t sz_res() const
Get required length of res field.
size_t sz_w() const
Get required length of w field.
void alloc_w(size_t sz_w, bool persistent=false)
Ensure required length of w field.
size_t sz_arg() const
Get required length of arg field.
size_t sz_iw() const
Get required length of iw field.

References casadi::FunctionInternal::alloc_arg(), casadi::FunctionInternal::alloc_iw(), casadi::FunctionInternal::alloc_res(), casadi::FunctionInternal::alloc_w(), casadi::GenericShared< Shared, Internal >::is_null(), casadi::FunctionInternal::sz_arg(), casadi::FunctionInternal::sz_iw(), casadi::FunctionInternal::sz_res(), casadi::FunctionInternal::sz_w(), and casadi::Function::sz_work().

Referenced by casadi::OracleFunction::finalize(), casadi::KinsolInterface::get_jtimes(), casadi::FiniteDiff::init(), casadi::Nlpsol::init(), casadi::Rootfinder::init(), casadi::Switch::init(), casadi::Feasiblesqpmethod::init(), casadi::ImplicitToNlp::init(), casadi::QpToNlp::init(), casadi::Qrsqp::init(), casadi::Scpgen::init(), and casadi::Sqpmethod::init().

◆ alloc_arg()

void casadi::FunctionInternal::alloc_arg ( size_t  sz_arg,
bool  persistent = false 
)
inherited

◆ alloc_iw()

void casadi::FunctionInternal::alloc_iw ( size_t  sz_iw,
bool  persistent = false 
)
inherited

◆ alloc_mem()

void* casadi::FunctionInternal::alloc_mem ( ) const
inlineoverridevirtualinherited

◆ alloc_res()

void casadi::FunctionInternal::alloc_res ( size_t  sz_res,
bool  persistent = false 
)
inherited

◆ alloc_w()

void casadi::FunctionInternal::alloc_w ( size_t  sz_w,
bool  persistent = false 
)
inherited

Extra doc: https://github.com/casadi/casadi/wiki/L_n7

Definition at line 2950 of file function_internal.cpp.

2950  {
2951  if (persistent) {
2952  sz_w_per_ += sz_w;
2953  } else {
2954  sz_w_tmp_ = std::max(sz_w_tmp_, sz_w);
2955  }
2956  }

References casadi::FunctionInternal::sz_w().

Referenced by casadi::FunctionInternal::alloc(), casadi::BlazingSplineFunction::init(), casadi::External::init(), casadi::FiniteDiff::init(), casadi::FmuFunction::init(), casadi::Integrator::init(), casadi::FixedStepIntegrator::init(), casadi::Interpolant::init(), casadi::JitFunction::init(), casadi::Map::init(), casadi::OmpMap::init(), casadi::ThreadMap::init(), casadi::MapSum::init(), casadi::MXFunction::init(), casadi::Nlpsol::init(), casadi::Rootfinder::init(), casadi::Switch::init(), init(), casadi::Blocksqp::init(), casadi::BonminInterface::init(), casadi::CbcInterface::init(), casadi::ClarabelInterface::init(), casadi::ClpInterface::init(), casadi::CplexInterface::init(), casadi::DaqpInterface::init(), casadi::FatropConicInterface::init(), casadi::FatropInterface::init(), casadi::GurobiInterface::init(), casadi::HighsInterface::init(), casadi::HpipmInterface::init(), casadi::IpoptInterface::init(), casadi::KnitroInterface::init(), casadi::MadnlpInterface::init(), casadi::OoqpInterface::init(), casadi::OsqpInterface::init(), casadi::ProxqpInterface::init(), casadi::QpoasesInterface::init(), casadi::SLEQPInterface::init(), casadi::SlicotDple::init(), casadi::SlicotExpm::init(), casadi::SnoptInterface::init(), casadi::CvodesInterface::init(), casadi::IdasInterface::init(), casadi::KinsolInterface::init(), casadi::SundialsInterface::init(), casadi::SuperscsInterface::init(), casadi::WorhpInterface::init(), casadi::BSplineInterpolant::init(), casadi::FastNewton::init(), casadi::Feasiblesqpmethod::init(), casadi::ImplicitToNlp::init(), casadi::Ipqp::init(), casadi::LinearInterpolant::init(), casadi::LinearInterpolantJac::init(), casadi::Newton::init(), casadi::QpToNlp::init(), casadi::Qrqp::init(), casadi::Qrsqp::init(), casadi::Scpgen::init(), and casadi::Sqpmethod::init().

◆ cache()

Dict casadi::FunctionInternal::cache ( ) const
inherited

Extra doc: https://github.com/casadi/casadi/wiki/L_26g

Definition at line 1054 of file function_internal.cpp.

1054  {
1055  // Return value
1056  Dict ret;
1057 
1058  // Retrieve all Function instances that haven't been deleted
1059  std::vector<std::string> keys;
1060  std::vector<Function> entries;
1061  cache_.cache(keys, entries);
1062 
1063  for (size_t i=0; i<keys.size(); ++i) {
1064  // Get the name of the key
1065  std::string s = keys[i];
1066  casadi_assert_dev(s.size() > 0);
1067  // Replace ':' with '_'
1068  std::replace(s.begin(), s.end(), ':', '_');
1069  // Remove trailing underscore, if any
1070  if (s.back() == '_') s.resize(s.size() - 1);
1071  // Add entry to function return
1072  ret[s] = entries[i];
1073  }
1074 
1075  return ret;
1076  }
WeakCache< std::string, Function > cache_
Function cache.
GenericType::Dict Dict
C++ equivalent of Python's dict or MATLAB's struct.

References casadi::FunctionInternal::cache_.

◆ call()

template<typename M >
void casadi::FunctionInternal::call ( const std::vector< M > &  arg,
std::vector< M > &  res,
bool  always_inline,
bool  never_inline 
) const
inherited

Extra doc: https://github.com/casadi/casadi/wiki/L_kh

Definition at line 1559 of file function_internal.hpp.

1560  {
1561  // If all inputs are scalar ...
1562  if (all_scalar()) {
1563  // ... and some arguments are matrix-valued with matching dimensions ...
1564  bool matrix_call = false;
1565  std::pair<casadi_int, casadi_int> sz;
1566  for (auto&& a : arg) {
1567  if (!a.is_scalar() && !a.is_empty()) {
1568  if (!matrix_call) {
1569  // Matrix call
1570  matrix_call = true;
1571  sz = a.size();
1572  } else if (a.size()!=sz) {
1573  // Not same dimensions
1574  matrix_call = false;
1575  break;
1576  }
1577  }
1578  }
1579 
1580  // ... then, call multiple times
1581  if (matrix_call) {
1582  // Start with zeros
1583  res.resize(n_out_);
1584  M z = M::zeros(sz);
1585  for (auto&& a : res) a = z;
1586  // Call multiple times
1587  std::vector<M> arg1 = arg, res1;
1588  for (casadi_int c=0; c<sz.second; ++c) {
1589  for (casadi_int r=0; r<sz.first; ++r) {
1590  // Get scalar arguments
1591  for (casadi_int i=0; i<arg.size(); ++i) {
1592  if (arg[i].size()==sz) arg1[i] = arg[i](r, c);
1593  }
1594  // Call recursively with scalar arguments
1595  call(arg1, res1, always_inline, never_inline);
1596  // Get results
1597  casadi_assert_dev(res.size() == res1.size());
1598  for (casadi_int i=0; i<res.size(); ++i) res[i](r, c) = res1[i];
1599  }
1600  }
1601  // All elements assigned
1602  return;
1603  }
1604  }
1605 
1606  // Check if inputs need to be replaced
1607  casadi_int npar = 1;
1608  if (!matching_arg(arg, npar)) {
1609  return call(replace_arg(arg, npar), res, always_inline, never_inline);
1610  }
1611 
1612  // Call the type-specific method
1613  call_gen(arg, res, npar, always_inline, never_inline);
1614  }
void call_gen(const MXVector &arg, MXVector &res, casadi_int npar, bool always_inline, bool never_inline) const
Call a function, overloaded.
std::vector< M > replace_arg(const std::vector< M > &arg, casadi_int npar) const
Replace 0-by-0 inputs.
void call(const std::vector< M > &arg, std::vector< M > &res, bool always_inline, bool never_inline) const
Call a function, templated.
bool all_scalar() const
Are all inputs and outputs scalar.

References casadi::FunctionInternal::all_scalar(), casadi::FunctionInternal::call_gen(), casadi::FunctionInternal::matching_arg(), casadi::FunctionInternal::n_out_, and casadi::FunctionInternal::replace_arg().

◆ call_forward() [1/3]

void casadi::XFunction< SXFunction , Matrix< SXElem > , SXNode >::call_forward ( const std::vector< Matrix< SXElem > > &  arg,
const std::vector< Matrix< SXElem > > &  res,
const std::vector< std::vector< Matrix< SXElem > > > &  fseed,
std::vector< std::vector< Matrix< SXElem > > > &  fsens,
bool  always_inline,
bool  never_inline 
) const
overrideinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_y5

Definition at line 201 of file x_function.hpp.

1086  {
1087  casadi_assert(!(always_inline && never_inline), "Inconsistent options");
1088  if (!should_inline(MatType::type_name()=="SX", always_inline, never_inline)) {
1089  // The non-inlining version is implemented in the base class
1090  return FunctionInternal::call_forward(arg, res, fseed, fsens,
1091  always_inline, never_inline);
1092  }
1093 
1094  // Quick return if no seeds
1095  if (fseed.empty()) {
1096  fsens.clear();
1097  return;
1098  }
1099 
1100  // Call inlining
1101  if (isInput(arg)) {
1102  // Argument agrees with in_, call ad_forward directly
1103  static_cast<const DerivedType*>(this)->ad_forward(fseed, fsens);
1104  } else {
1105  // Need to create a temporary function
1106  Function f("tmp_call_forward", arg, res);
1107  static_cast<DerivedType *>(f.get())->ad_forward(fseed, fsens);
1108  }
1109  }
virtual bool should_inline(bool with_sx, bool always_inline, bool never_inline) const=0
virtual bool isInput(const std::vector< Matrix< SXElem > > &arg) const
Helper function: Check if a vector equals ex_in.

◆ call_forward() [2/3]

void casadi::FunctionInternal::call_forward ( const std::vector< MX > &  arg,
const std::vector< MX > &  res,
const std::vector< std::vector< MX > > &  fseed,
std::vector< std::vector< MX > > &  fsens,
bool  always_inline,
bool  never_inline 
) const
virtualinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_ku

Definition at line 3029 of file function_internal.cpp.

3033  {
3034  casadi_assert(!(always_inline && never_inline), "Inconsistent options");
3035  casadi_assert(!always_inline, "Class " + class_name() +
3036  " cannot be inlined in an MX expression");
3037 
3038  // Derivative information must be available
3039  casadi_assert(has_derivative(),
3040  "Derivatives cannot be calculated for " + name_);
3041 
3042  // Number of directional derivatives
3043  casadi_int nfwd = fseed.size();
3044  fsens.resize(nfwd);
3045 
3046  // Quick return if no seeds
3047  if (nfwd==0) return;
3048 
3049  // Check if seeds need to have dimensions corrected
3050  casadi_int npar = 1;
3051  for (auto&& r : fseed) {
3052  if (!matching_arg(r, npar)) {
3053  return FunctionInternal::call_forward(arg, res, replace_fseed(fseed, npar),
3054  fsens, always_inline, never_inline);
3055  }
3056  }
3057 
3058  // Calculating full Jacobian and then multiplying
3059  if (fwdViaJac(nfwd)) {
3060  // Multiply the Jacobian from the right
3061  std::vector<MX> darg = arg;
3062  darg.insert(darg.end(), res.begin(), res.end());
3063  std::vector<MX> J = jacobian()(darg);
3064  // Join forward seeds
3065  std::vector<MX> v(nfwd), all_fseed(n_in_);
3066  for (size_t i = 0; i < n_in_; ++i) {
3067  for (size_t d = 0; d < nfwd; ++d) v[d] = vec(fseed.at(d).at(i));
3068  all_fseed[i] = horzcat(v);
3069  }
3070  // Calculate forward sensitivities
3071  std::vector<MX> all_fsens(n_out_);
3072  std::vector<MX>::const_iterator J_it = J.begin();
3073  for (size_t oind = 0; oind < n_out_; ++oind) {
3074  for (size_t iind = 0; iind < n_in_; ++iind) {
3075  // Add contribution
3076  MX a = mtimes(*J_it++, all_fseed[iind]);
3077  all_fsens[oind] = all_fsens[oind].is_empty(true) ? a : all_fsens[oind] + a;
3078  }
3079  }
3080  // Split forward sensitivities
3081  for (size_t d = 0; d < nfwd; ++d) fsens[d].resize(n_out_);
3082  for (size_t i = 0; i < n_out_; ++i) {
3083  v = horzsplit(all_fsens[i]);
3084  casadi_assert_dev(v.size() == nfwd);
3085  for (size_t d = 0; d < nfwd; ++d) fsens[d][i] = reshape(v[d], size_out(i));
3086  }
3087  } else {
3088  // Evaluate in batches
3089  casadi_assert_dev(enable_forward_ || enable_fd_);
3090  casadi_int max_nfwd = max_num_dir_;
3091  if (!enable_fd_) {
3092  while (!has_forward(max_nfwd)) max_nfwd/=2;
3093  }
3094  casadi_int offset = 0;
3095  while (offset<nfwd) {
3096  // Number of derivatives, in this batch
3097  casadi_int nfwd_batch = std::min(nfwd-offset, max_nfwd);
3098 
3099  // All inputs and seeds
3100  std::vector<MX> darg;
3101  darg.reserve(n_in_ + n_out_ + n_in_);
3102  darg.insert(darg.end(), arg.begin(), arg.end());
3103  darg.insert(darg.end(), res.begin(), res.end());
3104  std::vector<MX> v(nfwd_batch);
3105  for (casadi_int i=0; i<n_in_; ++i) {
3106  for (casadi_int d=0; d<nfwd_batch; ++d) v[d] = fseed[offset+d][i];
3107  darg.push_back(horzcat(v));
3108  }
3109 
3110  // Create the evaluation node
3111  Function dfcn = self().forward(nfwd_batch);
3112  std::vector<MX> x = dfcn(darg);
3113 
3114  casadi_assert_dev(x.size()==n_out_);
3115 
3116  // Retrieve sensitivities
3117  for (casadi_int d=0; d<nfwd_batch; ++d) fsens[offset+d].resize(n_out_);
3118  for (casadi_int i=0; i<n_out_; ++i) {
3119  if (size2_out(i)>0) {
3120  v = horzsplit(x[i], size2_out(i));
3121  casadi_assert_dev(v.size()==nfwd_batch);
3122  } else {
3123  v = std::vector<MX>(nfwd_batch, MX(size_out(i)));
3124  }
3125  for (casadi_int d=0; d<nfwd_batch; ++d) fsens[offset+d][i] = v[d];
3126  }
3127 
3128  // Update offset
3129  offset += nfwd_batch;
3130  }
3131  }
3132  }
virtual void call_forward(const std::vector< MX > &arg, const std::vector< MX > &res, const std::vector< std::vector< MX > > &fseed, std::vector< std::vector< MX > > &fsens, bool always_inline, bool never_inline) const
Forward mode AD, virtual functions overloaded in derived classes.
virtual bool has_forward(casadi_int nfwd) const
Return function that calculates forward derivatives.
bool has_derivative() const
Can derivatives be calculated in any way?
casadi_int size2_out(casadi_int ind) const
Input/output dimensions.
std::pair< casadi_int, casadi_int > size_out(casadi_int ind) const
Input/output dimensions.
casadi_int max_num_dir_
Maximum number of sensitivity directions.
virtual bool fwdViaJac(casadi_int nfwd) const
Calculate derivatives by multiplying the full Jacobian and multiplying.
Function jacobian() const
Return Jacobian of all input elements with respect to all output elements.
virtual std::string class_name() const =0
Readable name of the internal class.

References casadi::SharedObjectInternal::class_name(), casadi::FunctionInternal::enable_fd_, casadi::FunctionInternal::enable_forward_, casadi::FunctionInternal::forward(), casadi::FunctionInternal::fwdViaJac(), casadi::FunctionInternal::has_derivative(), casadi::FunctionInternal::has_forward(), casadi::FunctionInternal::jacobian(), casadi::FunctionInternal::matching_arg(), casadi::FunctionInternal::max_num_dir_, casadi::FunctionInternal::n_in_, casadi::FunctionInternal::n_out_, casadi::ProtoFunction::name_, casadi::FunctionInternal::replace_fseed(), casadi::FunctionInternal::size2_out(), and casadi::FunctionInternal::size_out().

Referenced by casadi::Rootfinder::ad_forward(), casadi::Call::ad_forward(), casadi::MXFunction::ad_forward(), casadi::XFunction< DerivedType, MatType, NodeType >::call_forward(), casadi::MX::forward(), casadi::Integrator::get_forward_dae(), and casadi::Scpgen::init().

◆ call_forward() [3/3]

void casadi::FunctionInternal::call_forward ( const std::vector< SX > &  arg,
const std::vector< SX > &  res,
const std::vector< std::vector< SX > > &  fseed,
std::vector< std::vector< SX > > &  fsens,
bool  always_inline,
bool  never_inline 
) const
virtualinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_ku

Definition at line 3248 of file function_internal.cpp.

3252  {
3253  casadi_assert(!(always_inline && never_inline), "Inconsistent options");
3254  if (fseed.empty()) { // Quick return if no seeds
3255  fsens.clear();
3256  return;
3257  }
3258  casadi_error("'forward' (SX) not defined for " + class_name());
3259  }

References casadi::SharedObjectInternal::class_name().

◆ call_fwd()

template<typename T >
void casadi::SXFunction::call_fwd ( const AlgEl e,
const T **  arg,
T **  res,
casadi_int *  iw,
T *  w 
) const
protected

Definition at line 1582 of file sx_function.cpp.

1582  {
1583  auto& m = call_.el[e.i1];
1584  const T** call_arg = arg;
1585  T** call_res = res;
1586  casadi_int* call_iw = iw;
1587  T* call_w = w;
1588  T* nz_in;
1589  T* nz_out;
1590 
1591  call_setup(m, &call_arg, &call_res, &call_iw, &call_w, &nz_in, &nz_out);
1592 
1593  // Populate nz_in from work vector
1594  for (casadi_int i=0;i<m.n_dep;++i) {
1595  nz_in[i] = w[m.dep[i]];
1596  }
1597  // Perform call nz_in -> nz_out
1598  m.f(call_arg, call_res, call_iw, call_w);
1599 
1600  // Store nz_out results back in workvector
1601  for (casadi_int i=0;i<m.n_res;++i) {
1602  // Only if the result is actually needed
1603  if (m.res[i]>=0) {
1604  w[m.res[i]] = nz_out[i];
1605  }
1606  }
1607  }
std::vector< double > nz_in(const std::vector< DM > &arg) const
Convert from/to flat vector of input/output nonzeros.
std::vector< double > nz_out(const std::vector< DM > &res) const
Convert from/to flat vector of input/output nonzeros.
void call_setup(const ExtendedAlgEl &m, CT ***call_arg, T ***call_res, casadi_int **call_iw, T **call_w, T **nz_in, T **nz_out) const

References call_, call_setup(), casadi::SXFunction::CallInfo::el, casadi::ScalarAtomic::i1, casadi::FunctionInternal::nz_in(), casadi::FunctionInternal::nz_out(), and casadi::T.

Referenced by eval(), and sp_forward().

◆ call_gen() [1/2]

void casadi::FunctionInternal::call_gen ( const MXVector arg,
MXVector res,
casadi_int  npar,
bool  always_inline,
bool  never_inline 
) const
inherited

Extra doc: https://github.com/casadi/casadi/wiki/L_kg

Definition at line 3922 of file function_internal.cpp.

3924  {
3925  if (npar==1) {
3926  eval_mx(arg, res, always_inline, never_inline);
3927  } else {
3928  // Split it up arguments
3929  std::vector<std::vector<MX>> v(npar, arg);
3930  std::vector<MX> t;
3931  for (int i=0; i<n_in_; ++i) {
3932  if (arg[i].size2()!=size2_in(i)) {
3933  t = horzsplit(arg[i], size2_in(i));
3934  casadi_assert_dev(t.size()==npar);
3935  for (int p=0; p<npar; ++p) v[p][i] = t[p];
3936  }
3937  }
3938  // Unroll the loop
3939  for (int p=0; p<npar; ++p) {
3940  eval_mx(v[p], t, always_inline, never_inline);
3941  v[p] = t;
3942  }
3943  // Concatenate results
3944  t.resize(npar);
3945  res.resize(n_out_);
3946  for (int i=0; i<n_out_; ++i) {
3947  for (int p=0; p<npar; ++p) t[p] = v[p][i];
3948  res[i] = horzcat(t);
3949  }
3950  }
3951  }
virtual void eval_mx(const MXVector &arg, MXVector &res, bool always_inline, bool never_inline) const
Evaluate with symbolic matrices.
casadi_int size2_in(casadi_int ind) const
Input/output dimensions.

References casadi::FunctionInternal::eval_mx(), casadi::FunctionInternal::n_in_, casadi::FunctionInternal::n_out_, and casadi::FunctionInternal::size2_in().

Referenced by casadi::FunctionInternal::call().

◆ call_gen() [2/2]

template<typename D >
void casadi::FunctionInternal::call_gen ( const std::vector< Matrix< D > > &  arg,
std::vector< Matrix< D > > &  res,
casadi_int  npar,
bool  always_inline,
bool  never_inline 
) const
inherited

Extra doc: https://github.com/casadi/casadi/wiki/L_kg

Definition at line 1663 of file function_internal.hpp.

1665  {
1666  std::vector< Matrix<D> > arg2 = project_arg(arg, npar);
1667 
1668  // Which arguments require mapped evaluation
1669  std::vector<bool> mapped(n_in_);
1670  for (casadi_int i=0; i<n_in_; ++i) {
1671  mapped[i] = arg[i].size2()!=size2_in(i);
1672  }
1673 
1674  // Allocate results
1675  res.resize(n_out_);
1676  for (casadi_int i=0; i<n_out_; ++i) {
1677  if (!res[i].sparsity().is_stacked(sparsity_out(i), npar)) {
1678  res[i] = Matrix<D>::zeros(repmat(sparsity_out(i), 1, npar));
1679  }
1680  }
1681 
1682  // Allocate temporary memory if needed
1683  std::vector<casadi_int> iw_tmp(sz_iw());
1684  std::vector<D> w_tmp(sz_w());
1685 
1686  // Get pointers to input arguments
1687  std::vector<const D*> argp(sz_arg());
1688  for (casadi_int i=0; i<n_in_; ++i) argp[i]=get_ptr(arg2[i]);
1689 
1690  // Get pointers to output arguments
1691  std::vector<D*> resp(sz_res());
1692  for (casadi_int i=0; i<n_out_; ++i) resp[i]=get_ptr(res[i]);
1693 
1694  // For all parallel calls
1695  for (casadi_int p=0; p<npar; ++p) {
1696  // Call memory-less
1697  if (eval_gen(get_ptr(argp), get_ptr(resp),
1698  get_ptr(iw_tmp), get_ptr(w_tmp), memory(0),
1699  always_inline, never_inline)) {
1700  if (error_on_fail_) casadi_error("Evaluation failed");
1701  }
1702  // Update offsets
1703  if (p==npar-1) break;
1704  for (casadi_int i=0; i<n_in_; ++i) if (mapped[i]) argp[i] += nnz_in(i);
1705  for (casadi_int i=0; i<n_out_; ++i) resp[i] += nnz_out(i);
1706  }
1707  }
std::vector< M > project_arg(const std::vector< M > &arg, casadi_int npar) const
Project sparsities.
const Sparsity & sparsity_out(casadi_int ind) const
Input/output sparsity.
int eval_gen(const double **arg, double **res, casadi_int *iw, double *w, void *mem, bool always_inline, bool never_inline) const
Evaluate numerically.
bool error_on_fail_
Throw an exception on failure?
void * memory(int ind) const
Memory objects.
T * get_ptr(std::vector< T > &v)
Get a pointer to the data contained in the vector.

References casadi::ProtoFunction::error_on_fail_, casadi::FunctionInternal::eval_gen(), casadi::get_ptr(), casadi::ProtoFunction::memory(), casadi::FunctionInternal::n_in_, casadi::FunctionInternal::n_out_, casadi::FunctionInternal::nnz_in(), casadi::FunctionInternal::nnz_out(), casadi::FunctionInternal::project_arg(), casadi::FunctionInternal::size2_in(), casadi::FunctionInternal::sparsity_out(), casadi::FunctionInternal::sz_arg(), casadi::FunctionInternal::sz_iw(), casadi::FunctionInternal::sz_res(), casadi::FunctionInternal::sz_w(), and casadi::GenericMatrix< Matrix< Scalar > >::zeros().

◆ call_rev()

template<typename T >
void casadi::SXFunction::call_rev ( const AlgEl e,
T **  arg,
T **  res,
casadi_int *  iw,
T *  w 
) const
protected

Definition at line 1611 of file sx_function.cpp.

1611  {
1612  auto& m = call_.el[e.i1];
1613  bvec_t** call_arg = arg;
1614  bvec_t** call_res = res;
1615  casadi_int* call_iw = iw;
1616  bvec_t* call_w = w;
1617  bvec_t* nz_in;
1618  bvec_t* nz_out;
1619 
1620  call_setup(m, &call_arg, &call_res, &call_iw, &call_w, &nz_in, &nz_out);
1621 
1622  std::fill_n(nz_in, m.n_dep, 0);
1623 
1624  // Read in reverse seeds nz_out from work vector
1625  for (casadi_int i=0;i<m.n_res;++i) {
1626  nz_out[i] = (m.res[i]>=0) ? w[m.res[i]] : 0;
1627  }
1628 
1629  // Perform reverse mode call nz_out -> nz_in
1630  m.f.rev(call_arg, call_res, call_iw, call_w);
1631 
1632  // Clear out reverse seeds
1633  for (casadi_int i=0;i<m.n_res;++i) {
1634  if (m.res[i]>=0) w[m.res[i]] = 0;
1635  }
1636 
1637  // Store reverse sensitivities into work vector
1638  for (casadi_int i=0;i<m.n_dep;++i) {
1639  w[m.dep[i]] |= nz_in[i];
1640  }
1641  }
unsigned long long bvec_t

References call_, call_setup(), casadi::SXFunction::CallInfo::el, casadi::ScalarAtomic::i1, casadi::FunctionInternal::nz_in(), and casadi::FunctionInternal::nz_out().

Referenced by sp_reverse().

◆ call_reverse() [1/3]

void casadi::XFunction< SXFunction , Matrix< SXElem > , SXNode >::call_reverse ( const std::vector< Matrix< SXElem > > &  arg,
const std::vector< Matrix< SXElem > > &  res,
const std::vector< std::vector< Matrix< SXElem > > > &  aseed,
std::vector< std::vector< Matrix< SXElem > > > &  asens,
bool  always_inline,
bool  never_inline 
) const
overrideinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_y6

Definition at line 210 of file x_function.hpp.

1117  {
1118  casadi_assert(!(always_inline && never_inline), "Inconsistent options");
1119  if (!should_inline(MatType::type_name()=="SX", always_inline, never_inline)) {
1120  // The non-inlining version is implemented in the base class
1121  return FunctionInternal::call_reverse(arg, res, aseed, asens,
1122  always_inline, never_inline);
1123  }
1124 
1125  // Quick return if no seeds
1126  if (aseed.empty()) {
1127  asens.clear();
1128  return;
1129  }
1130 
1131  // Call inlining
1132  if (isInput(arg)) {
1133  // Argument agrees with in_, call ad_reverse directly
1134  static_cast<const DerivedType*>(this)->ad_reverse(aseed, asens);
1135  } else {
1136  // Need to create a temporary function
1137  Function f("tmp_call_reverse", arg, res);
1138  static_cast<DerivedType *>(f.get())->ad_reverse(aseed, asens);
1139  }
1140  }

◆ call_reverse() [2/3]

void casadi::FunctionInternal::call_reverse ( const std::vector< MX > &  arg,
const std::vector< MX > &  res,
const std::vector< std::vector< MX > > &  aseed,
std::vector< std::vector< MX > > &  asens,
bool  always_inline,
bool  never_inline 
) const
virtualinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_kv

Definition at line 3134 of file function_internal.cpp.

3138  {
3139  casadi_assert(!(always_inline && never_inline), "Inconsistent options");
3140  casadi_assert(!always_inline, "Class " + class_name() +
3141  " cannot be inlined in an MX expression");
3142 
3143  // Derivative information must be available
3144  casadi_assert(has_derivative(),
3145  "Derivatives cannot be calculated for " + name_);
3146 
3147  // Number of directional derivatives
3148  casadi_int nadj = aseed.size();
3149  asens.resize(nadj);
3150 
3151  // Quick return if no seeds
3152  if (nadj==0) return;
3153 
3154  // Check if seeds need to have dimensions corrected
3155  casadi_int npar = 1;
3156  for (auto&& r : aseed) {
3157  if (!matching_res(r, npar)) {
3158  return FunctionInternal::call_reverse(arg, res, replace_aseed(aseed, npar),
3159  asens, always_inline, never_inline);
3160  }
3161  }
3162 
3163  // Calculating full Jacobian and then multiplying likely cheaper
3164  if (adjViaJac(nadj)) {
3165  // Multiply the transposed Jacobian from the right
3166  std::vector<MX> darg = arg;
3167  darg.insert(darg.end(), res.begin(), res.end());
3168  std::vector<MX> J = jacobian()(darg);
3169  // Join adjoint seeds
3170  std::vector<MX> v(nadj), all_aseed(n_out_);
3171  for (size_t i = 0; i < n_out_; ++i) {
3172  for (size_t d = 0; d < nadj; ++d) v[d] = vec(aseed.at(d).at(i));
3173  all_aseed[i] = horzcat(v);
3174  }
3175  // Calculate adjoint sensitivities
3176  std::vector<MX> all_asens(n_in_);
3177  std::vector<MX>::const_iterator J_it = J.begin();
3178  for (size_t oind = 0; oind < n_out_; ++oind) {
3179  for (size_t iind = 0; iind < n_in_; ++iind) {
3180  // Add contribution
3181  MX a = mtimes((*J_it++).T(), all_aseed[oind]);
3182  all_asens[iind] = all_asens[iind].is_empty(true) ? a : all_asens[iind] + a;
3183  }
3184  }
3185  // Split adjoint sensitivities
3186  for (size_t d = 0; d < nadj; ++d) asens[d].resize(n_in_);
3187  for (size_t i = 0; i < n_in_; ++i) {
3188  v = horzsplit(all_asens[i]);
3189  casadi_assert_dev(v.size() == nadj);
3190  for (size_t d = 0; d < nadj; ++d) {
3191  if (asens[d][i].is_empty(true)) {
3192  asens[d][i] = reshape(v[d], size_in(i));
3193  } else {
3194  asens[d][i] += reshape(v[d], size_in(i));
3195  }
3196  }
3197  }
3198  } else {
3199  // Evaluate in batches
3200  casadi_assert_dev(enable_reverse_);
3201  casadi_int max_nadj = max_num_dir_;
3202 
3203  while (!has_reverse(max_nadj)) max_nadj/=2;
3204  casadi_int offset = 0;
3205  while (offset<nadj) {
3206  // Number of derivatives, in this batch
3207  casadi_int nadj_batch = std::min(nadj-offset, max_nadj);
3208 
3209  // All inputs and seeds
3210  std::vector<MX> darg;
3211  darg.reserve(n_in_ + n_out_ + n_out_);
3212  darg.insert(darg.end(), arg.begin(), arg.end());
3213  darg.insert(darg.end(), res.begin(), res.end());
3214  std::vector<MX> v(nadj_batch);
3215  for (casadi_int i=0; i<n_out_; ++i) {
3216  for (casadi_int d=0; d<nadj_batch; ++d) v[d] = aseed[offset+d][i];
3217  darg.push_back(horzcat(v));
3218  }
3219 
3220  // Create the evaluation node
3221  Function dfcn = self().reverse(nadj_batch);
3222  std::vector<MX> x = dfcn(darg);
3223  casadi_assert_dev(x.size()==n_in_);
3224 
3225  // Retrieve sensitivities
3226  for (casadi_int d=0; d<nadj_batch; ++d) asens[offset+d].resize(n_in_);
3227  for (casadi_int i=0; i<n_in_; ++i) {
3228  if (size2_in(i)>0) {
3229  v = horzsplit(x[i], size2_in(i));
3230  casadi_assert_dev(v.size()==nadj_batch);
3231  } else {
3232  v = std::vector<MX>(nadj_batch, MX(size_in(i)));
3233  }
3234  for (casadi_int d=0; d<nadj_batch; ++d) {
3235  if (asens[offset+d][i].is_empty(true)) {
3236  asens[offset+d][i] = v[d];
3237  } else {
3238  asens[offset+d][i] += v[d];
3239  }
3240  }
3241  }
3242  // Update offset
3243  offset += nadj_batch;
3244  }
3245  }
3246  }
virtual bool adjViaJac(casadi_int nadj) const
Calculate derivatives by multiplying the full Jacobian and multiplying.
std::pair< casadi_int, casadi_int > size_in(casadi_int ind) const
Input/output dimensions.
virtual void call_reverse(const std::vector< MX > &arg, const std::vector< MX > &res, const std::vector< std::vector< MX > > &aseed, std::vector< std::vector< MX > > &asens, bool always_inline, bool never_inline) const
Reverse mode, virtual functions overloaded in derived classes.
Function reverse(casadi_int nadj) const
Return function that calculates adjoint derivatives.
virtual bool has_reverse(casadi_int nadj) const
Return function that calculates adjoint derivatives.

References casadi::FunctionInternal::adjViaJac(), casadi::SharedObjectInternal::class_name(), casadi::FunctionInternal::enable_reverse_, casadi::FunctionInternal::has_derivative(), casadi::FunctionInternal::has_reverse(), casadi::FunctionInternal::jacobian(), casadi::FunctionInternal::matching_res(), casadi::FunctionInternal::max_num_dir_, casadi::FunctionInternal::n_in_, casadi::FunctionInternal::n_out_, casadi::ProtoFunction::name_, casadi::FunctionInternal::replace_aseed(), casadi::FunctionInternal::reverse(), casadi::FunctionInternal::size2_in(), casadi::FunctionInternal::size_in(), and casadi::T.

Referenced by casadi::Rootfinder::ad_reverse(), casadi::MXFunction::ad_reverse(), casadi::Call::ad_reverse(), casadi::XFunction< DerivedType, MatType, NodeType >::call_reverse(), casadi::Scpgen::init(), and casadi::MX::reverse().

◆ call_reverse() [3/3]

void casadi::FunctionInternal::call_reverse ( const std::vector< SX > &  arg,
const std::vector< SX > &  res,
const std::vector< std::vector< SX > > &  aseed,
std::vector< std::vector< SX > > &  asens,
bool  always_inline,
bool  never_inline 
) const
virtualinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_kv

Definition at line 3261 of file function_internal.cpp.

3265  {
3266  casadi_assert(!(always_inline && never_inline), "Inconsistent options");
3267  if (aseed.empty()) { // Quick return if no seeds
3268  asens.clear();
3269  return;
3270  }
3271  casadi_error("'reverse' (SX) not defined for " + class_name());
3272  }

References casadi::SharedObjectInternal::class_name().

◆ call_setup()

template<typename T , typename CT >
void casadi::SXFunction::call_setup ( const ExtendedAlgEl m,
CT ***  call_arg,
T ***  call_res,
casadi_int **  call_iw,
T **  call_w,
T **  nz_in,
T **  nz_out 
) const
protected

Definition at line 1558 of file sx_function.cpp.

1559  {
1560  *call_arg += n_in_;
1561  *call_res += n_out_;
1562  *nz_in = *call_w + worksize_;
1563  *nz_out = *call_w + worksize_ + call_.sz_w_arg;
1564  *call_w = *call_w + worksize_ + call_.sz_w_arg + call_.sz_w_res;
1565 
1566  // Set up call_arg to point to nz_in
1567  T* ptr_w = *nz_in;
1568  for (casadi_int i=0;i<m.f_n_in;++i) {
1569  (*call_arg)[i] = ptr_w;
1570  ptr_w+=m.f_nnz_in[i];
1571  }
1572 
1573  // Set up call_res to point to nz_out
1574  ptr_w = *nz_out;
1575  for (casadi_int i=0;i<m.f_n_out;++i) {
1576  (*call_res)[i] = ptr_w;
1577  ptr_w+=m.f_nnz_out[i];
1578  }
1579  }

References call_, casadi::SXFunction::ExtendedAlgEl::f_n_in, casadi::SXFunction::ExtendedAlgEl::f_n_out, casadi::SXFunction::ExtendedAlgEl::f_nnz_in, casadi::SXFunction::ExtendedAlgEl::f_nnz_out, casadi::FunctionInternal::n_in_, casadi::FunctionInternal::n_out_, casadi::FunctionInternal::nz_in(), casadi::FunctionInternal::nz_out(), casadi::SXFunction::CallInfo::sz_w_arg, casadi::SXFunction::CallInfo::sz_w_res, casadi::T, and worksize_.

Referenced by call_fwd(), and call_rev().

◆ change_option()

void casadi::FunctionInternal::change_option ( const std::string &  option_name,
const GenericType option_value 
)
overridevirtualinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_k5

Reimplemented from casadi::ProtoFunction.

Reimplemented in casadi::MXFunction.

Definition at line 433 of file function_internal.cpp.

434  {
435  if (option_name == "print_in") {
436  print_in_ = option_value;
437  } else if (option_name == "print_out") {
438  print_out_ = option_value;
439  } else if (option_name == "print_canonical") {
440  print_canonical_ = option_value;
441  } else if (option_name=="ad_weight") {
442  ad_weight_ = option_value;
443  } else if (option_name=="ad_weight_sp") {
444  ad_weight_sp_ = option_value;
445  } else if (option_name=="dump") {
446  dump_ = option_value;
447  } else if (option_name=="dump_in") {
448  dump_in_ = option_value;
449  } else if (option_name=="dump_out") {
450  dump_out_ = option_value;
451  } else if (option_name=="dump_dir") {
452  dump_dir_ = option_value.to_string();
453  } else if (option_name=="dump_format") {
454  dump_format_ = option_value.to_string();
455  } else {
456  // Option not found - continue to base classes
457  ProtoFunction::change_option(option_name, option_value);
458  }
459  }
virtual void change_option(const std::string &option_name, const GenericType &option_value)
Change option after object creation for debugging.

References casadi::FunctionInternal::ad_weight_, casadi::FunctionInternal::ad_weight_sp_, casadi::ProtoFunction::change_option(), casadi::FunctionInternal::dump_, casadi::FunctionInternal::dump_dir_, casadi::FunctionInternal::dump_format_, casadi::FunctionInternal::dump_in_, casadi::FunctionInternal::dump_out_, casadi::FunctionInternal::print_canonical_, casadi::FunctionInternal::print_in_, casadi::FunctionInternal::print_out_, and casadi::GenericType::to_string().

Referenced by casadi::FmuFunction::change_option(), and casadi::MXFunction::change_option().

◆ check_arg()

template<typename M >
void casadi::FunctionInternal::check_arg ( const std::vector< M > &  arg,
casadi_int &  npar 
) const
inherited

Raises errors.

Parameters
npar[in]normal usage: 1, disallow pararallel calls: -1
[out]nparmax number of horizontal repetitions across all arguments (or -1)

Extra doc: https://github.com/casadi/casadi/wiki/L_ki

Definition at line 1710 of file function_internal.hpp.

1710  {
1711  casadi_assert(arg.size()==n_in_, "Incorrect number of inputs: Expected "
1712  + str(n_in_) + ", got " + str(arg.size()));
1713  for (casadi_int i=0; i<n_in_; ++i) {
1714  if (!check_mat(arg[i].sparsity(), sparsity_in(i), npar)) {
1715  // Dimensions
1716  std::string d_arg = str(arg[i].size1()) + "-by-" + str(arg[i].size2());
1717  std::string d_in = str(size1_in(i)) + "-by-" + str(size2_in(i));
1718  std::string e = "Input " + str(i) + " (" + name_in_[i] + ") has mismatching shape. "
1719  "Got " + d_arg + ". Allowed dimensions, in general, are:\n"
1720  " - The input dimension N-by-M (here " + d_in + ")\n"
1721  " - A scalar, i.e. 1-by-1\n"
1722  " - M-by-N if N=1 or M=1 (i.e. a transposed vector)\n"
1723  " - N-by-M1 if K*M1=M for some K (argument repeated horizontally)\n";
1724  if (npar!=-1) {
1725  e += " - N-by-P*M, indicating evaluation with multiple arguments (P must be a "
1726  "multiple of " + str(npar) + " for consistency with previous inputs)";
1727  }
1728  casadi_error(e);
1729  }
1730  }
1731  }
casadi_int size1_in(casadi_int ind) const
Input/output dimensions.
const Sparsity & sparsity_in(casadi_int ind) const
Input/output sparsity.
static bool check_mat(const Sparsity &arg, const Sparsity &inp, casadi_int &npar)
std::vector< std::string > name_in_
Input and output scheme.
std::string str(const T &v)
String representation, any type.

References casadi::FunctionInternal::check_mat(), casadi::FunctionInternal::n_in_, casadi::FunctionInternal::name_in_, casadi::FunctionInternal::size1_in(), casadi::FunctionInternal::size2_in(), casadi::FunctionInternal::sparsity_in(), and casadi::str().

Referenced by casadi::FunctionInternal::mapsum_mx(), and casadi::FunctionInternal::matching_arg().

◆ check_mat()

bool casadi::FunctionInternal::check_mat ( const Sparsity arg,
const Sparsity inp,
casadi_int &  npar 
)
staticinherited

Helper function

Parameters
npar[in]normal usage: 1, disallow pararallel calls: -1
npar[out]required number of parallel calls (or -1)

Definition at line 3460 of file function_internal.cpp.

3460  {
3461  // Matching dimensions
3462  if (arg.size()==inp.size()) return true;
3463  // Calling with empty matrix - set all to zero
3464  if (arg.is_empty()) return true;
3465  // Calling with a scalar - set all
3466  if (arg.is_scalar()) return true;
3467  // Vectors that are transposes of each other
3468  if (arg.is_vector() && inp.size()==std::make_pair(arg.size2(), arg.size1())) return true;
3469  // Horizontal repmat
3470  if (arg.size1()==inp.size1() && arg.size2()>0 && inp.size2()>0
3471  && inp.size2()%arg.size2()==0) return true;
3472  if (npar==-1) return false;
3473  // Evaluate with multiple arguments
3474  if (arg.size1()==inp.size1() && arg.size2()>0 && inp.size2()>0
3475  && arg.size2()%(npar*inp.size2())==0) {
3476  npar *= arg.size2()/(npar*inp.size2());
3477  return true;
3478  }
3479  // No match
3480  return false;
3481  }

References casadi::Sparsity::is_empty(), casadi::Sparsity::is_scalar(), casadi::Sparsity::is_vector(), casadi::Sparsity::size(), casadi::Sparsity::size1(), and casadi::Sparsity::size2().

Referenced by casadi::FunctionInternal::check_arg(), casadi::FunctionInternal::check_res(), and casadi::FunctionInternal::mapsum_mx().

◆ check_mem_count()

virtual void casadi::ProtoFunction::check_mem_count ( casadi_int  n) const
inlinevirtualinherited

Purpose if to allow more helpful error messages

Extra doc: https://github.com/casadi/casadi/wiki/L_2b7

Reimplemented in casadi::FmuFunction.

Definition at line 179 of file function_internal.hpp.

179 { }

Referenced by casadi::ProtoFunction::checkout().

◆ check_res()

template<typename M >
void casadi::FunctionInternal::check_res ( const std::vector< M > &  res,
casadi_int &  npar 
) const
inherited

Raises errors.

Parameters
npar[in]normal usage: 1, disallow pararallel calls: -1
[out]nparmax number of horizontal repetitions across all arguments (or -1)

Extra doc: https://github.com/casadi/casadi/wiki/L_kj

Definition at line 1734 of file function_internal.hpp.

1734  {
1735  casadi_assert(res.size()==n_out_, "Incorrect number of outputs: Expected "
1736  + str(n_out_) + ", got " + str(res.size()));
1737  for (casadi_int i=0; i<n_out_; ++i) {
1738  casadi_assert(check_mat(res[i].sparsity(), sparsity_out(i), npar),
1739  "Output " + str(i) + " (" + name_out_[i] + ") has mismatching shape. "
1740  "Expected " + str(size_out(i)) + ", got " + str(res[i].size()));
1741  }
1742  }
std::vector< std::string > name_out_

References casadi::FunctionInternal::check_mat(), casadi::FunctionInternal::n_out_, casadi::FunctionInternal::name_out_, casadi::FunctionInternal::size_out(), casadi::FunctionInternal::sparsity_out(), and casadi::str().

Referenced by casadi::FunctionInternal::matching_res().

◆ checkout()

int casadi::ProtoFunction::checkout ( ) const
inherited

Definition at line 3669 of file function_internal.cpp.

3669  {
3670 #ifdef CASADI_WITH_THREAD
3671  std::lock_guard<std::mutex> lock(mtx_);
3672 #endif //CASADI_WITH_THREAD
3673  if (unused_.empty()) {
3674  check_mem_count(mem_.size()+1);
3675  // Allocate a new memory object
3676  void* m = alloc_mem();
3677  mem_.push_back(m);
3678  if (init_mem(m)) {
3679  casadi_error("Failed to create or initialize memory object");
3680  }
3681  return static_cast<int>(mem_.size()) - 1;
3682  } else {
3683  // Use an unused memory object
3684  int m = unused_.top();
3685  unused_.pop();
3686  return m;
3687  }
3688  }
virtual int init_mem(void *mem) const
Initalize memory block.
virtual void * alloc_mem() const
Create memory block.
virtual void check_mem_count(casadi_int n) const
Check for validatity of memory object count.

References casadi::ProtoFunction::alloc_mem(), casadi::ProtoFunction::check_mem_count(), and casadi::ProtoFunction::init_mem().

Referenced by casadi::ProtoFunction::finalize(), casadi::FunctionBuffer::FunctionBuffer(), and casadi::Sqpmethod::init_mem().

◆ class_name()

std::string casadi::SXFunction::class_name ( ) const
inlineoverridevirtual

Extra doc: https://github.com/casadi/casadi/wiki/L_uk

Implements casadi::SharedObjectInternal.

Definition at line 133 of file sx_function.hpp.

133 {return "SXFunction";}

◆ clear_mem()

void casadi::ProtoFunction::clear_mem ( )
inherited

Extra doc: https://github.com/casadi/casadi/wiki/L_jq

Definition at line 3557 of file function_internal.cpp.

3557  {
3558  for (auto&& i : mem_) {
3559  if (i!=nullptr) free_mem(i);
3560  }
3561  mem_.clear();
3562  }
virtual void free_mem(void *mem) const
Free memory block.

References casadi::ProtoFunction::free_mem().

Referenced by casadi::AlpaqaInterface::~AlpaqaInterface(), casadi::AmplInterface::~AmplInterface(), casadi::BlazingSplineFunction::~BlazingSplineFunction(), casadi::Blocksqp::~Blocksqp(), casadi::BonminInterface::~BonminInterface(), casadi::BSplineInterpolant::~BSplineInterpolant(), casadi::CallbackInternal::~CallbackInternal(), casadi::CbcInterface::~CbcInterface(), casadi::ClarabelInterface::~ClarabelInterface(), casadi::ClpInterface::~ClpInterface(), casadi::CplexInterface::~CplexInterface(), casadi::CsparseInterface::~CsparseInterface(), casadi::CvodesInterface::~CvodesInterface(), casadi::DaqpInterface::~DaqpInterface(), casadi::External::~External(), casadi::FastNewton::~FastNewton(), casadi::FatropConicInterface::~FatropConicInterface(), casadi::FatropInterface::~FatropInterface(), casadi::Feasiblesqpmethod::~Feasiblesqpmethod(), casadi::FiniteDiff::~FiniteDiff(), casadi::FixedStepIntegrator::~FixedStepIntegrator(), casadi::FmuFunction::~FmuFunction(), casadi::GurobiInterface::~GurobiInterface(), casadi::HighsInterface::~HighsInterface(), casadi::HpipmInterface::~HpipmInterface(), casadi::HpmpcInterface::~HpmpcInterface(), casadi::IdasInterface::~IdasInterface(), casadi::ImplicitToNlp::~ImplicitToNlp(), casadi::IpoptInterface::~IpoptInterface(), casadi::Ipqp::~Ipqp(), casadi::JitFunction::~JitFunction(), casadi::KinsolInterface::~KinsolInterface(), casadi::KnitroInterface::~KnitroInterface(), casadi::LapackLu::~LapackLu(), casadi::LapackQr::~LapackQr(), casadi::LinearInterpolant::~LinearInterpolant(), casadi::LinearInterpolantJac::~LinearInterpolantJac(), casadi::LinsolLdl::~LinsolLdl(), casadi::LinsolQr::~LinsolQr(), casadi::LinsolTridiag::~LinsolTridiag(), casadi::Lsqr::~Lsqr(), casadi::Ma27Interface::~Ma27Interface(), casadi::MadnlpInterface::~MadnlpInterface(), casadi::Map::~Map(), casadi::MapSum::~MapSum(), casadi::MumpsInterface::~MumpsInterface(), casadi::MXFunction::~MXFunction(), casadi::Newton::~Newton(), casadi::Nlpsol::~Nlpsol(), casadi::OmpMap::~OmpMap(), casadi::OoqpInterface::~OoqpInterface(), casadi::OsqpInterface::~OsqpInterface(), casadi::ProxqpInterface::~ProxqpInterface(), casadi::QpoasesInterface::~QpoasesInterface(), casadi::QpToNlp::~QpToNlp(), casadi::Qrqp::~Qrqp(), casadi::Qrsqp::~Qrsqp(), casadi::Scpgen::~Scpgen(), casadi::SLEQPInterface::~SLEQPInterface(), casadi::SlicotDple::~SlicotDple(), casadi::SlicotExpm::~SlicotExpm(), casadi::SnoptInterface::~SnoptInterface(), casadi::Sqpmethod::~Sqpmethod(), casadi::SuperscsInterface::~SuperscsInterface(), casadi::Switch::~Switch(), ~SXFunction(), casadi::SymbolicQr::~SymbolicQr(), casadi::ThreadMap::~ThreadMap(), and casadi::WorhpInterface::~WorhpInterface().

◆ codegen()

void casadi::FunctionInternal::codegen ( CodeGenerator g,
const std::string &  fname 
) const
inherited

Extra doc: https://github.com/casadi/casadi/wiki/L_lm

Definition at line 2390 of file function_internal.cpp.

2390  {
2391  // Define function
2392  g << "/* " << definition() << " */\n";
2393  g << "static " << signature(fname) << " {\n";
2394 
2395  // Reset local variables, flush buffer
2396  g.flush(g.body);
2397 
2398  g.scope_enter();
2399 
2400  // Generate function body (to buffer)
2401  codegen_body(g);
2402 
2403  g.scope_exit();
2404 
2405  // Finalize the function
2406  g << "return 0;\n";
2407  g << "}\n\n";
2408 
2409  // Flush to function body
2410  g.flush(g.body);
2411  }
std::string definition() const
Get function signature: name:(inputs)->(outputs)
virtual void codegen_body(CodeGenerator &g) const
Generate code for the function body.
std::string signature(const std::string &fname) const
Code generate the function.

References casadi::CodeGenerator::body, casadi::FunctionInternal::codegen_body(), casadi::FunctionInternal::definition(), casadi::CodeGenerator::flush(), casadi::CodeGenerator::scope_enter(), casadi::CodeGenerator::scope_exit(), and casadi::FunctionInternal::signature().

Referenced by casadi::CodeGenerator::add_dependency().

◆ codegen_alloc_mem()

void casadi::FunctionInternal::codegen_alloc_mem ( CodeGenerator g) const
virtualinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_lt

Reimplemented in casadi::External.

Definition at line 2438 of file function_internal.cpp.

2438  {
2439  bool needs_mem = !codegen_mem_type().empty();
2440  if (needs_mem) {
2441  std::string name = codegen_name(g, false);
2442  std::string mem_counter = g.shorthand(name + "_mem_counter");
2443  g << "return " + mem_counter + "++;\n";
2444  }
2445  }
virtual std::string codegen_mem_type() const
Thread-local memory object type.
virtual std::string codegen_name(const CodeGenerator &g, bool ns=true) const
Get name in codegen.

References casadi::FunctionInternal::codegen_mem_type(), casadi::FunctionInternal::codegen_name(), and casadi::CodeGenerator::shorthand().

Referenced by casadi::CodeGenerator::add_dependency().

◆ codegen_body()

void casadi::SXFunction::codegen_body ( CodeGenerator g) const
overridevirtual

Extra doc: https://github.com/casadi/casadi/wiki/L_v5

Implements casadi::XFunction< SXFunction, Matrix< SXElem >, SXNode >.

Definition at line 344 of file sx_function.cpp.

344  {
345  g.reserve_work(worksize_);
346 
347  casadi_int cnt = 0;
348  // Run the algorithm
349  for (auto&& a : algorithm_) {
350  if (a.op==OP_OUTPUT) {
351  g << "if (res[" << a.i0 << "]!=0) "
352  << g.res(a.i0) << "[" << a.i2 << "]=" << g.sx_work(a.i1) << ";\n";
353  } else if (a.op==OP_CALL) {
354  const ExtendedAlgEl& m = call_.el[a.i1];
355 
356  casadi_int worksize = g.avoid_stack() ? worksize_ : 0;
357 
358  // Collect input arguments
359  casadi_int offset = worksize;
360  for (casadi_int i=0; i<m.f_n_in; ++i) {
361  if (m.copy_elision_arg[i]>=0) {
362  g << "arg[" << n_in_+i << "] = "
363  << "arg[" + str(m.copy_elision_arg[i]) << "]? "
364  << "arg[" + str(m.copy_elision_arg[i]) << "] + "
365  << str(m.copy_elision_offset[i]) << " : 0;\n";
366  } else {
367  if (m.f_nnz_in[i]==0) {
368  g << "arg[" << n_in_+i << "]=" << 0 << ";\n";
369  } else {
370  g << "arg[" << n_in_+i << "]=" << "w+" + str(offset) << ";\n";
371  }
372  }
373  offset += m.f_nnz_in[i];
374  }
375 
376 
377  casadi_int out_offset = offset;
378 
379  // Collect output arguments
380  for (casadi_int i=0; i<m.f_n_out; ++i) {
381  g << "res[" << n_out_+i << "]=" << "w+" + str(offset) << ";\n";
382  offset += m.f_nnz_out[i];
383  }
384  casadi_int k=0;
385  for (casadi_int i=0; i<m.f_n_in; ++i) {
386  if (m.copy_elision_arg[i]==-1) {
387  for (casadi_int j=0; j<m.f_nnz_in[i]; ++j) {
388  g << "w["+str(k+worksize) + "] = " << g.sx_work(m.dep[k]) << ";\n";
389  k++;
390  }
391  } else {
392  k+=m.f_nnz_in[i];
393  }
394  }
395  if (print_instructions_) print_arg(g, cnt, a);
396  std::string flag =
397  g(m.f, "arg+"+str(n_in_), "res+"+str(n_out_), "iw", "w+" + str(offset));
398  // Call function
399  g << "if (" << flag << ") return 1;\n";
400  if (print_instructions_) print_res(g, cnt, a);
401  for (casadi_int i=0;i<m.n_res;++i) {
402  if (m.res[i]>=0) {
403  g << g.sx_work(m.res[i]) << " = ";
404  g << "w[" + str(i+out_offset) + "];\n";
405  }
406  }
407  } else if (a.op==OP_INPUT) {
408  if (!copy_elision_[cnt]) {
409  g << g.sx_work(a.i0) << "="
410  << g.arg(a.i1) << "? " << g.arg(a.i1) << "[" << a.i2 << "] : 0;\n";
411  }
412  } else {
413  if (print_instructions_) print_arg(g, cnt, a);
414 
415  // Where to store the result
416  g << g.sx_work(a.i0) << "=";
417 
418  // What to store
419  if (a.op==OP_CONST) {
420  g << g.constant(a.d);
421  } else {
422  casadi_int ndep = casadi_math<double>::ndeps(a.op);
423  casadi_assert_dev(ndep>0);
424  if (ndep==1) g << g.print_op(a.op, g.sx_work(a.i1));
425  if (ndep==2) g << g.print_op(a.op, g.sx_work(a.i1), g.sx_work(a.i2));
426  }
427 
428  g << ";\n";
429 
430  if (print_instructions_) print_res(g, cnt, a);
431  }
432  cnt++;
433  }
434  }
void print_res(std::ostream &stream, casadi_int k, const ScalarAtomic &el, const double *w) const
void print_arg(std::ostream &stream, casadi_int k, const ScalarAtomic &el, const double *w) const
static casadi_int ndeps(unsigned char op)
Number of dependencies.
Definition: calculus.hpp:1623

References algorithm_, casadi::CodeGenerator::arg(), casadi::CodeGenerator::avoid_stack(), call_, casadi::CodeGenerator::constant(), copy_elision_, casadi::SXFunction::ExtendedAlgEl::copy_elision_arg, casadi::SXFunction::ExtendedAlgEl::copy_elision_offset, casadi::SXFunction::ExtendedAlgEl::dep, casadi::SXFunction::CallInfo::el, casadi::SXFunction::ExtendedAlgEl::f, casadi::SXFunction::ExtendedAlgEl::f_n_in, casadi::SXFunction::ExtendedAlgEl::f_n_out, casadi::SXFunction::ExtendedAlgEl::f_nnz_in, casadi::SXFunction::ExtendedAlgEl::f_nnz_out, casadi::FunctionInternal::n_in_, casadi::FunctionInternal::n_out_, casadi::SXFunction::ExtendedAlgEl::n_res, casadi::casadi_math< T >::ndeps(), casadi::OP_CALL, casadi::OP_CONST, casadi::OP_INPUT, casadi::OP_OUTPUT, print_arg(), print_instructions_, casadi::CodeGenerator::print_op(), print_res(), casadi::CodeGenerator::res(), casadi::SXFunction::ExtendedAlgEl::res, casadi::CodeGenerator::reserve_work(), casadi::str(), casadi::CodeGenerator::sx_work(), and worksize_.

◆ codegen_checkout()

void casadi::FunctionInternal::codegen_checkout ( CodeGenerator g) const
virtualinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_lw

Reimplemented in casadi::External.

Definition at line 2447 of file function_internal.cpp.

2447  {
2448  std::string name = codegen_name(g, false);
2449  std::string stack_counter = g.shorthand(name + "_unused_stack_counter");
2450  std::string stack = g.shorthand(name + "_unused_stack");
2451  std::string mem_counter = g.shorthand(name + "_mem_counter");
2452  std::string mem_array = g.shorthand(name + "_mem");
2453  std::string alloc_mem = g.shorthand(name + "_alloc_mem");
2454  std::string init_mem = g.shorthand(name + "_init_mem");
2455 
2456  g.auxiliaries << "static int " << mem_counter << " = 0;\n";
2457  g.auxiliaries << "static int " << stack_counter << " = -1;\n";
2458  g.auxiliaries << "static int " << stack << "[CASADI_MAX_NUM_THREADS];\n";
2459  g.auxiliaries << "static " << codegen_mem_type() <<
2460  " " << mem_array << "[CASADI_MAX_NUM_THREADS];\n\n";
2461  g << "int mid;\n";
2462  g << "if (" << stack_counter << ">=0) {\n";
2463  g << "return " << stack << "[" << stack_counter << "--];\n";
2464  g << "} else {\n";
2465  g << "if (" << mem_counter << "==CASADI_MAX_NUM_THREADS) return -1;\n";
2466  g << "mid = " << alloc_mem << "();\n";
2467  g << "if (mid<0) return -1;\n";
2468  g << "if(" << init_mem << "(mid)) return -1;\n";
2469  g << "return mid;\n";
2470  g << "}\n";
2471  }
void * alloc_mem() const override
Create memory block.

References casadi::FunctionInternal::alloc_mem(), casadi::CodeGenerator::auxiliaries, casadi::FunctionInternal::codegen_mem_type(), casadi::FunctionInternal::codegen_name(), casadi::ProtoFunction::init_mem(), and casadi::CodeGenerator::shorthand().

Referenced by casadi::CodeGenerator::add_dependency().

◆ codegen_declarations()

void casadi::SXFunction::codegen_declarations ( CodeGenerator g) const
overridevirtual

Extra doc: https://github.com/casadi/casadi/wiki/L_v4

Implements casadi::XFunction< SXFunction, Matrix< SXElem >, SXNode >.

Definition at line 219 of file sx_function.cpp.

219  {
220 
221  // Make sure that there are no free variables
222  if (!free_vars_.empty()) {
223  casadi_error("Code generation of '" + name_ + "' is not possible since variables "
224  + str(free_vars_) + " are free.");
225  }
226 
227  // Generate code for the call nodes
228  for (auto&& m : call_.el) {
229  g.add_dependency(m.f);
230  }
231  }

References casadi::CodeGenerator::add_dependency(), call_, casadi::SXFunction::CallInfo::el, free_vars_, casadi::ProtoFunction::name_, and casadi::str().

◆ codegen_decref()

virtual void casadi::FunctionInternal::codegen_decref ( CodeGenerator g) const
inlinevirtualinherited

◆ codegen_free_mem()

virtual void casadi::FunctionInternal::codegen_free_mem ( CodeGenerator g) const
inlinevirtualinherited

◆ codegen_incref()

virtual void casadi::FunctionInternal::codegen_incref ( CodeGenerator g) const
inlinevirtualinherited

◆ codegen_init_mem()

void casadi::FunctionInternal::codegen_init_mem ( CodeGenerator g) const
virtualinherited

◆ codegen_mem()

std::string casadi::FunctionInternal::codegen_mem ( CodeGenerator g,
const std::string &  index = "mem" 
) const
inherited

◆ codegen_mem_type()

virtual std::string casadi::FunctionInternal::codegen_mem_type ( ) const
inlinevirtualinherited

◆ codegen_meta()

void casadi::FunctionInternal::codegen_meta ( CodeGenerator g) const
inherited

Extra doc: https://github.com/casadi/casadi/wiki/L_ln

Definition at line 2484 of file function_internal.cpp.

2484  {
2485  bool needs_mem = !codegen_mem_type().empty();
2486 
2487  g << g.declare("int " + name_ + "_alloc_mem(void)") << " {\n";
2488  if (needs_mem) {
2489  g << "return " << codegen_name(g) << "_alloc_mem();\n";
2490  } else {
2491  g << "return 0;\n";
2492  }
2493  g << "}\n\n";
2494 
2495  g << g.declare("int " + name_ + "_init_mem(int mem)") << " {\n";
2496  if (needs_mem) {
2497  g << "return " << codegen_name(g) << "_init_mem(mem);\n";
2498  } else {
2499  g << "return 0;\n";
2500  }
2501  g << "}\n\n";
2502 
2503  g << g.declare("void " + name_ + "_free_mem(int mem)") << " {\n";
2504  if (needs_mem) {
2505  g << codegen_name(g) << "_free_mem(mem);\n";
2506  }
2507  g << "}\n\n";
2508 
2509  // Checkout/release routines
2510  g << g.declare("int " + name_ + "_checkout(void)") << " {\n";
2511  if (needs_mem) {
2512  g << "return " << codegen_name(g) << "_checkout();\n";
2513  } else {
2514  g << "return 0;\n";
2515  }
2516  g << "}\n\n";
2517 
2518  if (needs_mem) {
2519  g << g.declare("void " + name_ + "_release(int mem)") << " {\n";
2520  g << codegen_name(g) << "_release(mem);\n";
2521  } else {
2522  g << g.declare("void " + name_ + "_release(int mem)") << " {\n";
2523  }
2524  g << "}\n\n";
2525 
2526  // Reference counter routines
2527  g << g.declare("void " + name_ + "_incref(void)") << " {\n";
2528  codegen_incref(g);
2529  g << "}\n\n"
2530  << g.declare("void " + name_ + "_decref(void)") << " {\n";
2531  codegen_decref(g);
2532  g << "}\n\n";
2533 
2534  // Number of inputs and outptus
2535  g << g.declare("casadi_int " + name_ + "_n_in(void)")
2536  << " { return " << n_in_ << ";}\n\n"
2537  << g.declare("casadi_int " + name_ + "_n_out(void)")
2538  << " { return " << n_out_ << ";}\n\n";
2539 
2540  // Default inputs
2541  g << g.declare("casadi_real " + name_ + "_default_in(casadi_int i)") << " {\n"
2542  << "switch (i) {\n";
2543  for (casadi_int i=0; i<n_in_; ++i) {
2544  double def = get_default_in(i);
2545  if (def!=0) g << "case " << i << ": return " << g.constant(def) << ";\n";
2546  }
2547  g << "default: return 0;\n}\n"
2548  << "}\n\n";
2549 
2550  // Input names
2551  g << g.declare("const char* " + name_ + "_name_in(casadi_int i)") << " {\n"
2552  << "switch (i) {\n";
2553  for (casadi_int i=0; i<n_in_; ++i) {
2554  g << "case " << i << ": return \"" << name_in_[i] << "\";\n";
2555  }
2556  g << "default: return 0;\n}\n"
2557  << "}\n\n";
2558 
2559  // Output names
2560  g << g.declare("const char* " + name_ + "_name_out(casadi_int i)") << " {\n"
2561  << "switch (i) {\n";
2562  for (casadi_int i=0; i<n_out_; ++i) {
2563  g << "case " << i << ": return \"" << name_out_[i] << "\";\n";
2564  }
2565  g << "default: return 0;\n}\n"
2566  << "}\n\n";
2567 
2568  // Codegen sparsities
2569  codegen_sparsities(g);
2570 
2571  // Function that returns work vector lengths
2572  g << g.declare(
2573  "int " + name_ + "_work(casadi_int *sz_arg, casadi_int* sz_res, "
2574  "casadi_int *sz_iw, casadi_int *sz_w)")
2575  << " {\n"
2576  << "if (sz_arg) *sz_arg = " << codegen_sz_arg(g) << ";\n"
2577  << "if (sz_res) *sz_res = " << codegen_sz_res(g) << ";\n"
2578  << "if (sz_iw) *sz_iw = " << codegen_sz_iw(g) << ";\n"
2579  << "if (sz_w) *sz_w = " << codegen_sz_w(g) << ";\n"
2580  << "return 0;\n"
2581  << "}\n\n";
2582 
2583  // Function that returns work vector lengths in bytes
2584  g << g.declare(
2585  "int " + name_ + "_work_bytes(casadi_int *sz_arg, casadi_int* sz_res, "
2586  "casadi_int *sz_iw, casadi_int *sz_w)")
2587  << " {\n"
2588  << "if (sz_arg) *sz_arg = " << codegen_sz_arg(g) << "*sizeof(const casadi_real*);\n"
2589  << "if (sz_res) *sz_res = " << codegen_sz_res(g) << "*sizeof(casadi_real*);\n"
2590  << "if (sz_iw) *sz_iw = " << codegen_sz_iw(g) << "*sizeof(casadi_int);\n"
2591  << "if (sz_w) *sz_w = " << codegen_sz_w(g) << "*sizeof(casadi_real);\n"
2592  << "return 0;\n"
2593  << "}\n\n";
2594 
2595  // Also add to header file to allow getting
2596  if (g.with_header) {
2597  g.header
2598  << "#define " << name_ << "_SZ_ARG " << codegen_sz_arg(g) << "\n"
2599  << "#define " << name_ << "_SZ_RES " << codegen_sz_res(g) << "\n"
2600  << "#define " << name_ << "_SZ_IW " << codegen_sz_iw(g) << "\n"
2601  << "#define " << name_ << "_SZ_W " << codegen_sz_w(g) << "\n";
2602  }
2603 
2604  // Which inputs are differentiable
2605  if (!all(is_diff_in_)) {
2606  g << g.declare("int " + name_ + "_diff_in(casadi_int i)") << " {\n"
2607  << "switch (i) {\n";
2608  for (casadi_int i=0; i<n_in_; ++i) {
2609  g << "case " << i << ": return " << is_diff_in_[i] << ";\n";
2610  }
2611  g << "default: return -1;\n}\n"
2612  << "}\n\n";
2613  }
2614 
2615  // Which outputs are differentiable
2616  if (!all(is_diff_out_)) {
2617  g << g.declare("int " + name_ + "_diff_out(casadi_int i)") << " {\n"
2618  << "switch (i) {\n";
2619  for (casadi_int i=0; i<n_out_; ++i) {
2620  g << "case " << i << ": return " << is_diff_out_[i] << ";\n";
2621  }
2622  g << "default: return -1;\n}\n"
2623  << "}\n\n";
2624  }
2625 
2626  // Generate mex gateway for the function
2627  if (g.mex) {
2628  // Begin conditional compilation
2629  g << "#ifdef MATLAB_MEX_FILE\n";
2630 
2631  // Declare wrapper
2632  g << "void mex_" << name_
2633  << "(int resc, mxArray *resv[], int argc, const mxArray *argv[]) {\n"
2634  << "casadi_int i;\n";
2635  g << "int mem;\n";
2636  // Work vectors, including input and output buffers
2637  casadi_int i_nnz = nnz_in(), o_nnz = nnz_out();
2638  size_t sz_w = this->sz_w();
2639  for (casadi_int i=0; i<n_in_; ++i) {
2640  const Sparsity& s = sparsity_in_[i];
2641  sz_w = std::max(sz_w, static_cast<size_t>(s.size1())); // To be able to copy a column
2642  sz_w = std::max(sz_w, static_cast<size_t>(s.size2())); // To be able to copy a row
2643  }
2644  sz_w += i_nnz + o_nnz;
2645  g << CodeGenerator::array("casadi_real", "w", sz_w);
2646  g << CodeGenerator::array("casadi_int", "iw", sz_iw());
2647  std::string fw = "w+" + str(i_nnz + o_nnz);
2648 
2649  // Copy inputs to buffers
2650  casadi_int offset=0;
2651  g << CodeGenerator::array("const casadi_real*", "arg", sz_arg(), "{0}");
2652 
2653  // Allocate output buffers
2654  g << "casadi_real* res[" << sz_res() << "] = {0};\n";
2655 
2656  // Check arguments
2657  g << "if (argc>" << n_in_ << ") mexErrMsgIdAndTxt(\"Casadi:RuntimeError\","
2658  << "\"Evaluation of \\\"" << name_ << "\\\" failed. Too many input arguments "
2659  << "(%d, max " << n_in_ << ")\", argc);\n";
2660 
2661  g << "if (resc>" << n_out_ << ") mexErrMsgIdAndTxt(\"Casadi:RuntimeError\","
2662  << "\"Evaluation of \\\"" << name_ << "\\\" failed. "
2663  << "Too many output arguments (%d, max " << n_out_ << ")\", resc);\n";
2664 
2665  for (casadi_int i=0; i<n_in_; ++i) {
2666  std::string p = "argv[" + str(i) + "]";
2667  g << "if (--argc>=0) arg[" << i << "] = "
2668  << g.from_mex(p, "w", offset, sparsity_in_[i], fw) << "\n";
2669  offset += nnz_in(i);
2670  }
2671 
2672  for (casadi_int i=0; i<n_out_; ++i) {
2673  if (i==0) {
2674  // if i==0, always store output (possibly ans output)
2675  g << "--resc;\n";
2676  } else {
2677  // Store output, if it exists
2678  g << "if (--resc>=0) ";
2679  }
2680  // Create and get pointer
2681  g << g.res(i) << " = w+" << str(offset) << ";\n";
2682  offset += nnz_out(i);
2683  }
2684  g << name_ << "_incref();\n";
2685  g << "mem = " << name_ << "_checkout();\n";
2686 
2687  // Call the function
2688  g << "i = " << name_ << "(arg, res, iw, " << fw << ", mem);\n"
2689  << "if (i) mexErrMsgIdAndTxt(\"Casadi:RuntimeError\",\"Evaluation of \\\"" << name_
2690  << "\\\" failed.\");\n";
2691  g << name_ << "_release(mem);\n";
2692  g << name_ << "_decref();\n";
2693 
2694  // Save results
2695  for (casadi_int i=0; i<n_out_; ++i) {
2696  g << "if (" << g.res(i) << ") resv[" << i << "] = "
2697  << g.to_mex(sparsity_out_[i], g.res(i)) << "\n";
2698  }
2699 
2700  // End conditional compilation and function
2701  g << "}\n"
2702  << "#endif\n\n";
2703  }
2704 
2705  if (g.main) {
2706  // Declare wrapper
2707  g << "casadi_int main_" << name_ << "(casadi_int argc, char* argv[]) {\n";
2708 
2709  g << "casadi_int j;\n";
2710  g << "casadi_real* a;\n";
2711  g << "const casadi_real* r;\n";
2712  g << "casadi_int flag;\n";
2713  if (needs_mem) g << "int mem;\n";
2714 
2715 
2716 
2717  // Work vectors and input and output buffers
2718  size_t nr = sz_w() + nnz_in() + nnz_out();
2719  g << CodeGenerator::array("casadi_int", "iw", sz_iw())
2720  << CodeGenerator::array("casadi_real", "w", nr);
2721 
2722  // Input buffers
2723  g << "const casadi_real* arg[" << sz_arg() << "];\n";
2724 
2725  // Output buffers
2726  g << "casadi_real* res[" << sz_res() << "];\n";
2727 
2728  casadi_int off=0;
2729  for (casadi_int i=0; i<n_in_; ++i) {
2730  g << "arg[" << i << "] = w+" << off << ";\n";
2731  off += nnz_in(i);
2732  }
2733  for (casadi_int i=0; i<n_out_; ++i) {
2734  g << "res[" << i << "] = w+" << off << ";\n";
2735  off += nnz_out(i);
2736  }
2737 
2738  // TODO(@jaeandersson): Read inputs from file. For now; read from stdin
2739  g << "a = w;\n"
2740  << "for (j=0; j<" << nnz_in() << "; ++j) "
2741  << "if (scanf(\"%lg\", a++)<=0) return 2;\n";
2742 
2743  if (needs_mem) {
2744  g << "mem = " << name_ << "_checkout();\n";
2745  }
2746 
2747  // Call the function
2748  g << "flag = " << name_ << "(arg, res, iw, w+" << off << ", ";
2749  if (needs_mem) {
2750  g << "mem";
2751  } else {
2752  g << "0";
2753  }
2754  g << ");\n";
2755  if (needs_mem) {
2756  g << name_ << "_release(mem);\n";
2757  }
2758  g << "if (flag) return flag;\n";
2759 
2760  // TODO(@jaeandersson): Write outputs to file. For now: print to stdout
2761  g << "r = w+" << nnz_in() << ";\n"
2762  << "for (j=0; j<" << nnz_out() << "; ++j) "
2763  << g.printf("%g ", "*r++") << "\n";
2764 
2765  // End with newline
2766  g << g.printf("\\n") << "\n";
2767 
2768  // Finalize function
2769  g << "return 0;\n"
2770  << "}\n\n";
2771  }
2772 
2773  if (g.with_mem) {
2774  // Allocate memory
2775  g << g.declare("casadi_functions* " + name_ + "_functions(void)") << " {\n"
2776  << "static casadi_functions fun = {\n"
2777  << name_ << "_incref,\n"
2778  << name_ << "_decref,\n"
2779  << name_ << "_checkout,\n"
2780  << name_ << "_release,\n"
2781  << name_ << "_default_in,\n"
2782  //<< name_ << "_alloc_mem,\n"
2783  //<< name_ << "_init_mem,\n"
2784  //<< name_ << "_free_mem,\n"
2785  << name_ << "_n_in,\n"
2786  << name_ << "_n_out,\n"
2787  << name_ << "_name_in,\n"
2788  << name_ << "_name_out,\n"
2789  << name_ << "_sparsity_in,\n"
2790  << name_ << "_sparsity_out,\n"
2791  << name_ << "_work,\n"
2792  << name_ << "\n"
2793  << "};\n"
2794  << "return &fun;\n"
2795  << "}\n";
2796  }
2797  // Flush
2798  g.flush(g.body);
2799  }
static std::string array(const std::string &type, const std::string &name, casadi_int len, const std::string &def=std::string())
virtual size_t codegen_sz_res(const CodeGenerator &g) const
Get required lengths, for codegen.
virtual size_t codegen_sz_arg(const CodeGenerator &g) const
Get required lengths, for codegen.
std::vector< bool > is_diff_out_
virtual size_t codegen_sz_iw(const CodeGenerator &g) const
Get required lengths, for codegen.
virtual void codegen_incref(CodeGenerator &g) const
Codegen incref for dependencies.
virtual size_t codegen_sz_w(const CodeGenerator &g) const
Get required lengths, for codegen.
std::vector< bool > is_diff_in_
Are inputs and outputs differentiable?
virtual void codegen_decref(CodeGenerator &g) const
Codegen decref for dependencies.
void codegen_sparsities(CodeGenerator &g) const
Codegen sparsities.
virtual double get_default_in(casadi_int ind) const
Get default input value.
bool all(const std::vector< bool > &v)
Check if all arguments are true.
Definition: casadi_misc.cpp:77

References casadi::all(), casadi::CodeGenerator::array(), casadi::CodeGenerator::body, casadi::FunctionInternal::codegen_decref(), casadi::FunctionInternal::codegen_incref(), casadi::FunctionInternal::codegen_mem_type(), casadi::FunctionInternal::codegen_name(), casadi::FunctionInternal::codegen_sparsities(), casadi::FunctionInternal::codegen_sz_arg(), casadi::FunctionInternal::codegen_sz_iw(), casadi::FunctionInternal::codegen_sz_res(), casadi::FunctionInternal::codegen_sz_w(), casadi::CodeGenerator::constant(), casadi::CodeGenerator::declare(), casadi::CodeGenerator::flush(), casadi::CodeGenerator::from_mex(), casadi::FunctionInternal::get_default_in(), casadi::CodeGenerator::header, casadi::FunctionInternal::is_diff_in_, casadi::FunctionInternal::is_diff_out_, casadi::CodeGenerator::main, casadi::CodeGenerator::mex, casadi::FunctionInternal::n_in_, casadi::FunctionInternal::n_out_, casadi::ProtoFunction::name_, casadi::FunctionInternal::name_in_, casadi::FunctionInternal::name_out_, casadi::FunctionInternal::nnz_in(), casadi::FunctionInternal::nnz_out(), casadi::CodeGenerator::printf(), casadi::CodeGenerator::res(), casadi::Sparsity::size1(), casadi::Sparsity::size2(), casadi::FunctionInternal::sparsity_in_, casadi::FunctionInternal::sparsity_out_, casadi::str(), casadi::FunctionInternal::sz_arg(), casadi::FunctionInternal::sz_iw(), casadi::FunctionInternal::sz_res(), casadi::FunctionInternal::sz_w(), casadi::CodeGenerator::to_mex(), casadi::CodeGenerator::with_header, and casadi::CodeGenerator::with_mem.

Referenced by casadi::CodeGenerator::add().

◆ codegen_name()

std::string casadi::FunctionInternal::codegen_name ( const CodeGenerator g,
bool  ns = true 
) const
virtualinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_lp

Definition at line 2801 of file function_internal.cpp.

2801  {
2802  if (ns) {
2803  // Get the index of the function
2804  for (auto&& e : g.added_functions_) {
2805  if (e.f.get()==this) return e.codegen_name;
2806  }
2807  } else {
2808  for (casadi_int i=0;i<g.added_functions_.size();++i) {
2809  const auto & e = g.added_functions_[i];
2810  if (e.f.get()==this) return "f" + str(i);
2811  }
2812  }
2813  casadi_error("Function '" + name_ + "' not found");
2814  }

References casadi::CodeGenerator::added_functions_, casadi::ProtoFunction::name_, and casadi::str().

Referenced by casadi::FunctionInternal::codegen_alloc_mem(), casadi::FunctionInternal::codegen_checkout(), casadi::Call::codegen_decref(), casadi::Call::codegen_incref(), casadi::FunctionInternal::codegen_mem(), casadi::FunctionInternal::codegen_meta(), casadi::FunctionInternal::codegen_release(), and casadi::CodeGenerator::mem().

◆ codegen_release()

void casadi::FunctionInternal::codegen_release ( CodeGenerator g) const
virtualinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_lx

Reimplemented in casadi::External.

Definition at line 2473 of file function_internal.cpp.

2473  {
2474  std::string name = codegen_name(g, false);
2475  std::string stack_counter = g.shorthand(name + "_unused_stack_counter");
2476  std::string stack = g.shorthand(name + "_unused_stack");
2477  g << stack << "[++" << stack_counter << "] = mem;\n";
2478  }

References casadi::FunctionInternal::codegen_name(), and casadi::CodeGenerator::shorthand().

Referenced by casadi::CodeGenerator::add_dependency().

◆ codegen_sparsities()

void casadi::FunctionInternal::codegen_sparsities ( CodeGenerator g) const
inherited

◆ codegen_sz_arg()

size_t casadi::FunctionInternal::codegen_sz_arg ( const CodeGenerator g) const
virtualinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_29g

Definition at line 2913 of file function_internal.cpp.

2913  {
2914  return sz_arg();
2915  }

References casadi::FunctionInternal::sz_arg().

Referenced by casadi::FunctionInternal::codegen_meta().

◆ codegen_sz_iw()

size_t casadi::FunctionInternal::codegen_sz_iw ( const CodeGenerator g) const
virtualinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_29g

Definition at line 2919 of file function_internal.cpp.

2919  {
2920  return sz_iw();
2921  }

References casadi::FunctionInternal::sz_iw().

Referenced by casadi::FunctionInternal::codegen_meta().

◆ codegen_sz_res()

size_t casadi::FunctionInternal::codegen_sz_res ( const CodeGenerator g) const
virtualinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_29g

Definition at line 2916 of file function_internal.cpp.

2916  {
2917  return sz_res();
2918  }

References casadi::FunctionInternal::sz_res().

Referenced by casadi::FunctionInternal::codegen_meta().

◆ codegen_sz_w()

size_t casadi::SXFunction::codegen_sz_w ( const CodeGenerator g) const
overridevirtual

◆ construct()

void casadi::ProtoFunction::construct ( const Dict opts)
inherited

Prepares the function for evaluation

Extra doc: https://github.com/casadi/casadi/wiki/L_jf

Definition at line 138 of file function_internal.cpp.

138  {
139  // Sanitize dictionary is needed
140  if (!Options::is_sane(opts)) {
141  // Call recursively
142  return construct(Options::sanitize(opts));
143  }
144 
145  // Make sure all options exist
146  get_options().check(opts);
147 
148  // Initialize the class hierarchy
149  try {
150  init(opts);
151  } catch(std::exception& e) {
152  casadi_error("Error calling " + class_name() + "::init for '" + name_ + "':\n"
153  + std::string(e.what()));
154  }
155 
156  // Revisit class hierarchy in reverse order
157  try {
158  finalize();
159  } catch(std::exception& e) {
160  casadi_error("Error calling " + class_name() + "::finalize for '" + name_ + "':\n"
161  + std::string(e.what()));
162  }
163  }
void construct(const Dict &opts)
Construct.
virtual const Options & get_options() const
Options.
virtual void init(const Dict &opts)
Initialize.
virtual void finalize()
Finalize the object creation.
static bool is_sane(const Dict &opts)
Is the dictionary sane.
Definition: options.cpp:169
static Dict sanitize(const Dict &opts, bool top_level=true)
Sanitize a options dictionary.
Definition: options.cpp:173
void check(const Dict &opts) const
Check if options exist.
Definition: options.cpp:240

References casadi::Options::check(), casadi::SharedObjectInternal::class_name(), casadi::ProtoFunction::finalize(), casadi::ProtoFunction::get_options(), casadi::ProtoFunction::init(), casadi::Options::is_sane(), casadi::ProtoFunction::name_, and casadi::Options::sanitize().

Referenced by casadi::Function::create(), casadi::FmuFunction::factory(), casadi::FmuFunction::get_forward(), casadi::FmuFunction::get_jacobian(), casadi::LinearInterpolant::get_jacobian(), and casadi::FmuFunction::get_reverse().

◆ convert_arg() [1/2]

template<typename M >
std::vector< M > casadi::FunctionInternal::convert_arg ( const std::map< std::string, M > &  arg) const
inherited

Extra doc: https://github.com/casadi/casadi/wiki/L_ks

Definition at line 1834 of file function_internal.hpp.

1835  {
1836  // Get default inputs
1837  std::vector<M> arg_v(n_in_);
1838  for (casadi_int i=0; i<arg_v.size(); ++i) {
1839  arg_v[i] = get_default_in(i);
1840  }
1841 
1842  // Assign provided inputs
1843  for (auto&& e : arg) {
1844  arg_v.at(index_in(e.first)) = e.second;
1845  }
1846 
1847  return arg_v;
1848  }
casadi_int index_in(const std::string &name) const
Get input scheme index by name.

References casadi::FunctionInternal::get_default_in(), casadi::FunctionInternal::index_in(), and casadi::FunctionInternal::n_in_.

◆ convert_arg() [2/2]

template<typename M >
std::map< std::string, M > casadi::FunctionInternal::convert_arg ( const std::vector< M > &  arg) const
inherited

Extra doc: https://github.com/casadi/casadi/wiki/L_ks

Definition at line 1822 of file function_internal.hpp.

1823  {
1824  casadi_assert(arg.size()==n_in_, "Incorrect number of inputs: Expected "
1825  + str(n_in_) + ", got " + str(arg.size()));
1826  std::map<std::string, M> ret;
1827  for (casadi_int i=0;i<n_in_;++i) {
1828  ret[name_in_[i]] = arg[i];
1829  }
1830  return ret;
1831  }

References casadi::FunctionInternal::n_in_, casadi::FunctionInternal::name_in_, and casadi::str().

◆ convert_res() [1/2]

template<typename M >
std::vector< M > casadi::FunctionInternal::convert_res ( const std::map< std::string, M > &  res) const
inherited

Extra doc: https://github.com/casadi/casadi/wiki/L_ks

Definition at line 1863 of file function_internal.hpp.

1864  {
1865  // Get default inputs
1866  std::vector<M> res_v(n_out_);
1867  for (casadi_int i=0; i<res_v.size(); ++i) {
1868  res_v[i] = std::numeric_limits<double>::quiet_NaN();
1869  }
1870 
1871  // Assign provided inputs
1872  for (auto&& e : res) {
1873  M a = e.second;
1874  res_v.at(index_out(e.first)) = a;
1875  }
1876  return res_v;
1877  }
casadi_int index_out(const std::string &name) const
Get output scheme index by name.

References casadi::FunctionInternal::index_out(), and casadi::FunctionInternal::n_out_.

◆ convert_res() [2/2]

template<typename M >
std::map< std::string, M > casadi::FunctionInternal::convert_res ( const std::vector< M > &  res) const
inherited

Extra doc: https://github.com/casadi/casadi/wiki/L_ks

Definition at line 1851 of file function_internal.hpp.

1852  {
1853  casadi_assert(res.size()==n_out_, "Incorrect number of outputs: Expected "
1854  + str(n_out_) + ", got " + str(res.size()));
1855  std::map<std::string, M> ret;
1856  for (casadi_int i=0;i<n_out_;++i) {
1857  ret[name_out_[i]] = res[i];
1858  }
1859  return ret;
1860  }

References casadi::FunctionInternal::n_out_, casadi::FunctionInternal::name_out_, and casadi::str().

◆ debug_repr()

std::string casadi::GenericSharedInternal< SharedObject , SharedObjectInternal >::debug_repr ( const Internal *  i) const
inherited

Definition at line 62 of file generic_shared_internal.hpp.

162  {
163  // Note: i != this because of something something multiple inheritance
164  return str( (casadi_int)(i)) + "/" + static_cast<const Internal*>(this)->class_name();
165  }

◆ definition()

std::string casadi::FunctionInternal::definition ( ) const
inherited

Extra doc: https://github.com/casadi/casadi/wiki/L_ma

Definition at line 1025 of file function_internal.cpp.

1025  {
1026  std::stringstream s;
1027 
1028  // Print name
1029  s << name_ << ":(";
1030  // Print input arguments
1031  for (casadi_int i=0; i<n_in_; ++i) {
1032  if (!is_diff_in_.empty() && !is_diff_in_[i]) s << "#";
1033  s << name_in_[i] << sparsity_in_[i].postfix_dim() << (i==n_in_-1 ? "" : ",");
1034  }
1035  s << ")->(";
1036  // Print output arguments
1037  for (casadi_int i=0; i<n_out_; ++i) {
1038  if (!is_diff_out_.empty() && !is_diff_out_[i]) s << "#";
1039  s << name_out_[i] << sparsity_out_[i].postfix_dim() << (i==n_out_-1 ? "" : ",");
1040  }
1041  s << ")";
1042 
1043  return s.str();
1044  }

References casadi::FunctionInternal::is_diff_in_, casadi::FunctionInternal::is_diff_out_, casadi::FunctionInternal::n_in_, casadi::FunctionInternal::n_out_, casadi::ProtoFunction::name_, casadi::FunctionInternal::name_in_, casadi::FunctionInternal::name_out_, casadi::FunctionInternal::sparsity_in_, and casadi::FunctionInternal::sparsity_out_.

Referenced by casadi::FunctionInternal::codegen(), casadi::FunctionInternal::disp(), casadi::MXFunction::should_inline(), and should_inline().

◆ delayed_deserialize_members()

void casadi::XFunction< SXFunction , Matrix< SXElem > , SXNode >::delayed_deserialize_members ( DeserializingStream s)
inherited

Definition at line 249 of file x_function.hpp.

299  {
300  s.unpack("XFunction::out", out_);
301  }
std::vector< Matrix< SXElem > > out_
Outputs of the function (needed for symbolic calculations)
Definition: x_function.hpp:262

◆ delayed_serialize_members()

void casadi::XFunction< SXFunction , Matrix< SXElem > , SXNode >::delayed_serialize_members ( SerializingStream s) const
inherited

The out member is problematic to de/serialize before the sorted algorithm has a chance of laying out the expression graph efficiently

Extra doc: https://github.com/casadi/casadi/wiki/L_yb

Definition at line 248 of file x_function.hpp.

305  {
306  s.pack("XFunction::out", out_);
307  }

◆ deserialize()

ProtoFunction * casadi::SXFunction::deserialize ( DeserializingStream s)
static

Extra doc: https://github.com/casadi/casadi/wiki/L_v1

Definition at line 1941 of file sx_function.cpp.

1941  {
1942  return new SXFunction(s);
1943  }
SXFunction(const std::string &name, const std::vector< Matrix< SXElem > > &inputv, const std::vector< Matrix< SXElem > > &outputv, const std::vector< std::string > &name_in, const std::vector< std::string > &name_out)
Constructor.

References SXFunction().

◆ destroySingleton()

void casadi::GenericSharedInternal< SharedObject , SharedObjectInternal >::destroySingleton ( )
inlineprotectedinherited

Called in the destructor of singletons

Definition at line 77 of file generic_shared_internal.hpp.

77  {
78  static_cast<Internal*>(this)->count--;
79  }

◆ diff_prefix()

std::string casadi::FunctionInternal::diff_prefix ( const std::string &  prefix) const
inherited

Definition at line 2127 of file function_internal.cpp.

2127  {
2128  // Highest index found in current inputs and outputs
2129  casadi_int highest_index = 0;
2130  // Loop over both input names and output names
2131  for (const std::vector<std::string>& name_io : {name_in_, name_out_}) {
2132  for (const std::string& n : name_io) {
2133  // Find end of prefix, skip if no prefix
2134  size_t end = n.find('_');
2135  if (end >= n.size()) continue;
2136  // Skip if too short
2137  if (end < prefix.size()) continue;
2138  // Skip if wrong prefix
2139  if (n.compare(0, prefix.size(), prefix) != 0) continue;
2140  // Beginning of index
2141  size_t begin = prefix.size();
2142  // Check if any index
2143  casadi_int this_index;
2144  if (begin == end) {
2145  // No prefix, implicitly 1
2146  this_index = 1;
2147  } else {
2148  // Read index from string
2149  this_index = std::stoi(n.substr(begin, end - begin));
2150  }
2151  // Find the highest index
2152  if (this_index > highest_index) highest_index = this_index;
2153  }
2154  }
2155  // Return one higher index
2156  if (highest_index == 0) {
2157  return prefix + "_";
2158  } else {
2159  return prefix + std::to_string(highest_index + 1) + "_";
2160  }
2161  }

References casadi::FunctionInternal::name_in_, and casadi::FunctionInternal::name_out_.

Referenced by casadi::FunctionInternal::forward(), and casadi::FunctionInternal::reverse().

◆ disp()

void casadi::FunctionInternal::disp ( std::ostream &  stream,
bool  more 
) const
overridevirtualinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_m8

Implements casadi::SharedObjectInternal.

Definition at line 1046 of file function_internal.cpp.

1046  {
1047  stream << definition() << " " << class_name();
1048  if (more) {
1049  stream << std::endl;
1050  disp_more(stream);
1051  }
1052  }
virtual void disp_more(std::ostream &stream) const
Print more.

References casadi::SharedObjectInternal::class_name(), casadi::FunctionInternal::definition(), and casadi::FunctionInternal::disp_more().

Referenced by casadi::MXFunction::eval(), and eval().

◆ disp_more()

void casadi::SXFunction::disp_more ( std::ostream &  stream) const
overridevirtual

Extra doc: https://github.com/casadi/casadi/wiki/L_uj

Reimplemented from casadi::FunctionInternal.

Definition at line 202 of file sx_function.cpp.

202  {
203  stream << "Algorithm:";
204 
205  // Normal, interpreted output
206  for (auto&& a : algorithm_) {
208  stream << std::endl;
209  stream << print(a);
210  stream << ";";
211  }
212  }
static void check()
Raises an error if an interrupt was captured.
std::string print(const ScalarAtomic &a) const

References algorithm_, casadi::InterruptHandler::check(), and print().

◆ dm_in() [1/2]

const std::vector< DM > casadi::FunctionInternal::dm_in ( ) const
inherited

Extra doc: https://github.com/casadi/casadi/wiki/L_l7

Definition at line 3328 of file function_internal.cpp.

3328  {
3329  std::vector<DM> ret(n_in_);
3330  for (casadi_int i=0; i<ret.size(); ++i) {
3331  ret[i] = dm_in(i);
3332  }
3333  return ret;
3334  }
const std::vector< DM > dm_in() const
Get function input(s) and output(s)

References casadi::FunctionInternal::n_in_.

Referenced by casadi::FunctionInternal::nz_in().

◆ dm_in() [2/2]

const DM casadi::FunctionInternal::dm_in ( casadi_int  ind) const
inherited

◆ dm_out() [1/2]

const std::vector< DM > casadi::FunctionInternal::dm_out ( ) const
inherited

Extra doc: https://github.com/casadi/casadi/wiki/L_l7

Definition at line 3336 of file function_internal.cpp.

3336  {
3337  std::vector<DM> ret(n_out_);
3338  for (casadi_int i=0; i<ret.size(); ++i) {
3339  ret[i] = dm_out(i);
3340  }
3341  return ret;
3342  }
const std::vector< DM > dm_out() const
Get function input(s) and output(s)

References casadi::FunctionInternal::n_out_.

Referenced by casadi::FunctionInternal::nz_out().

◆ dm_out() [2/2]

const DM casadi::FunctionInternal::dm_out ( casadi_int  ind) const
inherited

◆ ensure_stacked()

template<typename MatType >
MatType casadi::FunctionInternal::ensure_stacked ( const MatType &  v,
const Sparsity sp,
casadi_int  n 
)
staticinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_26j

Definition at line 1880 of file function_internal.hpp.

1880  {
1881  // Check dimensions
1882  if (v.size1() == sp.size1() && v.size2() == n * sp.size2()) {
1883  // Ensure that sparsity is a horizontal multiple of original input, or has no entries
1884  if (v.nnz() != 0 && !v.sparsity().is_stacked(sp, n)) {
1885  return project(v, repmat(sp, 1, n));
1886  }
1887  } else {
1888  // Correct empty sparsity
1889  casadi_assert_dev(v.is_empty());
1890  return MatType(sp.size1(), sp.size2() * n);
1891  }
1892  // No correction needed
1893  return v;
1894  }

References casadi::Sparsity::size1(), and casadi::Sparsity::size2().

◆ eval()

int casadi::SXFunction::eval ( const double **  arg,
double **  res,
casadi_int *  iw,
double *  w,
void *  mem 
) const
overridevirtual

Extra doc: https://github.com/casadi/casadi/wiki/L_ue

Reimplemented from casadi::FunctionInternal.

Definition at line 72 of file sx_function.cpp.

73  {
74  if (verbose_) casadi_message(name_ + "::eval");
75  setup(mem, arg, res, iw, w);
76 
77  // Make sure no free parameters
78  if (!free_vars_.empty()) {
79  std::stringstream ss;
80  disp(ss, false);
81  casadi_error("Cannot evaluate \"" + ss.str() + "\" since variables "
82  + str(free_vars_) + " are free.");
83  }
84 
85  // NOTE: The implementation of this function is very delicate. Small changes in the
86  // class structure can cause large performance losses. For this reason,
87  // the preprocessor macros are used below
88 
89  if (print_instructions_) {
90  int k = 0;
91  // Evaluate the algorithm
92  for (auto&& e : algorithm_) {
93  print_arg(uout(), k, e, w);
94  switch (e.op) {
95  CASADI_MATH_FUN_BUILTIN(w[e.i1], w[e.i2], w[e.i0])
96 
97  case OP_CONST: w[e.i0] = e.d; break;
98  case OP_INPUT: w[e.i0] = arg[e.i1]==nullptr ? 0 : arg[e.i1][e.i2]; break;
99  case OP_OUTPUT: if (res[e.i0]!=nullptr) res[e.i0][e.i2] = w[e.i1]; break;
100  case OP_CALL:
101  call_fwd(e, arg, res, iw, w);
102  break;
103  default:
104  casadi_error("Unknown operation" + str(e.op));
105  }
106  print_res(uout(), k, e, w);
107  k++;
108  }
109  } else {
110  // Evaluate the algorithm
111  for (auto&& e : algorithm_) {
112  switch (e.op) {
113  CASADI_MATH_FUN_BUILTIN(w[e.i1], w[e.i2], w[e.i0])
114 
115  case OP_CONST: w[e.i0] = e.d; break;
116  case OP_INPUT: w[e.i0] = arg[e.i1]==nullptr ? 0 : arg[e.i1][e.i2]; break;
117  case OP_OUTPUT: if (res[e.i0]!=nullptr) res[e.i0][e.i2] = w[e.i1]; break;
118  case OP_CALL:
119  call_fwd(e, arg, res, iw, w);
120  break;
121  default:
122  casadi_error("Unknown operation" + str(e.op));
123  }
124  }
125  }
126  return 0;
127  }
void disp(std::ostream &stream, bool more) const override
Display object.
void setup(void *mem, const double **arg, double **res, casadi_int *iw, double *w) const
Set the (persistent and temporary) work vectors.
void call_fwd(const AlgEl &e, const T **arg, T **res, casadi_int *iw, T *w) const
std::ostream & uout()

References algorithm_, call_fwd(), casadi::FunctionInternal::disp(), free_vars_, casadi::ProtoFunction::name_, casadi::OP_CALL, casadi::OP_CONST, casadi::OP_INPUT, casadi::OP_OUTPUT, print_arg(), print_instructions_, print_res(), casadi::FunctionInternal::setup(), casadi::str(), casadi::uout(), and casadi::ProtoFunction::verbose_.

◆ eval_dm()

std::vector< DM > casadi::FunctionInternal::eval_dm ( const std::vector< DM > &  arg) const
virtualinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_ke

Reimplemented in casadi::CallbackInternal.

Definition at line 2110 of file function_internal.cpp.

2110  {
2111  casadi_error("'eval_dm' not defined for " + class_name());
2112  }

References casadi::SharedObjectInternal::class_name().

Referenced by casadi::FunctionInternal::eval().

◆ eval_gen() [1/3]

int casadi::FunctionInternal::eval_gen ( const bvec_t **  arg,
bvec_t **  res,
casadi_int *  iw,
bvec_t w,
void *  mem,
bool  always_inline,
bool  never_inline 
) const
inlineinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_kf

Definition at line 435 of file function_internal.hpp.

436  {
437  return sp_forward(arg, res, iw, w, mem);
438  }
virtual int sp_forward(const bvec_t **arg, bvec_t **res, casadi_int *iw, bvec_t *w, void *mem) const
Propagate sparsity forward.

◆ eval_gen() [2/3]

int casadi::FunctionInternal::eval_gen ( const double **  arg,
double **  res,
casadi_int *  iw,
double *  w,
void *  mem,
bool  always_inline,
bool  never_inline 
) const
inherited

Extra doc: https://github.com/casadi/casadi/wiki/L_kb

Definition at line 914 of file function_internal.cpp.

916  {
917  casadi_int dump_id = (dump_in_ || dump_out_ || dump_) ? get_dump_id() : 0;
918  if (dump_in_) dump_in(dump_id, arg);
919  if (dump_ && dump_id==0) dump();
920  if (print_in_) print_in(uout(), arg, false);
921  auto m = static_cast<ProtoFunctionMemory*>(mem);
922 
923  // Avoid memory corruption
924  for (casadi_int i=0;i<n_in_;++i) {
925  casadi_assert(arg[i]==0 || arg[i]+nnz_in(i)<=w || arg[i]>=w+sz_w(),
926  "Memory corruption detected for input " + name_in_[i] + ".\n"+
927  "arg[" + str(i) + "] " + str(arg[i]) + "-" + str(arg[i]+nnz_in(i)) +
928  " intersects with w " + str(w)+"-"+str(w+sz_w())+".");
929  }
930  for (casadi_int i=0;i<n_out_;++i) {
931  casadi_assert(res[i]==0 || res[i]+nnz_out(i)<=w || res[i]>=w+sz_w(),
932  "Memory corruption detected for output " + name_out_[i]);
933  }
934  // Reset statistics
935  for (auto&& s : m->fstats) s.second.reset();
936  if (m->t_total) m->t_total->tic();
937  int ret;
938  if (eval_) {
939  auto m = static_cast<FunctionMemory*>(mem);
940  m->stats_available = true;
941  int mem_ = 0;
942  if (checkout_) {
943 #ifdef CASADI_WITH_THREAD
944  std::lock_guard<std::mutex> lock(mtx_);
945 #endif //CASADI_WITH_THREAD
946  mem_ = checkout_();
947  }
948  ret = eval_(arg, res, iw, w, mem_);
949  if (release_) {
950 #ifdef CASADI_WITH_THREAD
951  std::lock_guard<std::mutex> lock(mtx_);
952 #endif //CASADI_WITH_THREAD
953  release_(mem_);
954  }
955  } else {
956  ret = eval(arg, res, iw, w, mem);
957  }
958  if (m->t_total) m->t_total->toc();
959  // Show statistics
960  print_time(m->fstats);
961 
962  if (dump_out_) dump_out(dump_id, res);
963  if (print_out_) print_out(uout(), res, false);
964  // Check all outputs for NaNs
965  if (regularity_check_) {
966  for (casadi_int i = 0; i < n_out_; ++i) {
967  // Skip of not calculated
968  if (!res[i]) continue;
969  // Loop over nonzeros
970  casadi_int nnz = this->nnz_out(i);
971  for (casadi_int nz = 0; nz < nnz; ++nz) {
972  if (isnan(res[i][nz]) || isinf(res[i][nz])) {
973  // Throw readable error message
974  casadi_error(str(res[i][nz]) + " detected for output " + name_out_[i] + " at "
975  + sparsity_out(i).repr_el(nz));
976  }
977  }
978  }
979  }
980  return ret;
981  }
void print_in(std::ostream &stream, const double **arg, bool truncate) const
Print inputs.
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.
casadi_checkout_t checkout_
Checkout redirected to a C function.
void print_out(std::ostream &stream, double **res, bool truncate) const
Print outputs.
bool regularity_check_
Errors are thrown when NaN is produced.
void print_time(const std::map< std::string, FStats > &fstats) const
Print timing statistics.

References casadi::FunctionInternal::checkout_, casadi::FunctionInternal::dump_, casadi::FunctionInternal::dump_in_, casadi::FunctionInternal::dump_out_, casadi::FunctionInternal::eval(), casadi::FunctionInternal::eval_, casadi::FunctionInternal::n_in_, casadi::FunctionInternal::n_out_, casadi::FunctionInternal::name_in_, casadi::FunctionInternal::name_out_, casadi::FunctionInternal::nnz_in(), casadi::FunctionInternal::nnz_out(), casadi::FunctionInternal::print_in(), casadi::FunctionInternal::print_in_, casadi::FunctionInternal::print_out(), casadi::FunctionInternal::print_out_, casadi::ProtoFunction::print_time(), casadi::ProtoFunction::regularity_check_, casadi::FunctionInternal::release_, casadi::FunctionInternal::sparsity_out(), casadi::FunctionMemory::stats_available, casadi::str(), casadi::FunctionInternal::sz_w(), and casadi::uout().

Referenced by casadi::FunctionInternal::call_gen().

◆ eval_gen() [3/3]

int casadi::FunctionInternal::eval_gen ( const SXElem **  arg,
SXElem **  res,
casadi_int *  iw,
SXElem w,
void *  mem,
bool  always_inline,
bool  never_inline 
) const
inlineinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_kf

Definition at line 431 of file function_internal.hpp.

432  {
433  return eval_sx(arg, res, iw, w, mem, always_inline, never_inline);
434  }
virtual int eval_sx(const SXElem **arg, SXElem **res, casadi_int *iw, SXElem *w, void *mem, bool always_inline, bool never_inline) const
Evaluate with symbolic scalars.

◆ eval_mx()

void casadi::SXFunction::eval_mx ( const MXVector arg,
MXVector res,
bool  always_inline,
bool  never_inline 
) const
overridevirtual

Extra doc: https://github.com/casadi/casadi/wiki/L_2bd

Reimplemented from casadi::FunctionInternal.

Definition at line 1068 of file sx_function.cpp.

1069  {
1070  always_inline = always_inline || always_inline_;
1071  never_inline = never_inline || never_inline_;
1072 
1073  // non-inlining call is implemented in the base-class
1074  if (!always_inline) {
1075  return FunctionInternal::eval_mx(arg, res, false, true);
1076  }
1077 
1078  if (verbose_) casadi_message(name_ + "::eval_mx");
1079 
1080  // Iterator to stack of constants
1081  std::vector<SXElem>::const_iterator c_it = constants_.begin();
1082 
1083  casadi_assert(!has_free(),
1084  "Free variables not supported in inlining call to SXFunction::eval_mx");
1085 
1086  // Resize the number of outputs
1087  casadi_assert(arg.size()==n_in_, "Wrong number of input arguments");
1088  res.resize(out_.size());
1089 
1090  // Symbolic work, non-differentiated
1091  std::vector<MX> w(sz_w());
1092  if (verbose_) casadi_message("Allocated work vector");
1093 
1094  // Split up inputs analogous to symbolic primitives
1095  std::vector<std::vector<MX> > arg_split(in_.size());
1096  for (casadi_int i=0; i<in_.size(); ++i) {
1097  // Get nonzeros of argument
1098  std::vector<MX> orig = arg[i].get_nonzeros();
1099 
1100  // Project to needed sparsity
1101  std::vector<MX> target(sparsity_in_[i].nnz(), 0);
1102  std::vector<MX> w(arg[i].size1());
1103  casadi_project(get_ptr(orig), arg[i].sparsity(),
1104  get_ptr(target), sparsity_in_[i], get_ptr(w));
1105 
1106  // Store
1107  arg_split[i] = target;
1108  }
1109 
1110  // Allocate storage for split outputs
1111  std::vector<std::vector<MX> > res_split(out_.size());
1112  for (casadi_int i=0; i<out_.size(); ++i) res_split[i].resize(nnz_out(i));
1113 
1114  // Evaluate algorithm
1115  if (verbose_) casadi_message("Evaluating algorithm forward");
1116  for (auto&& a : algorithm_) {
1117  switch (a.op) {
1118  case OP_INPUT:
1119  w[a.i0] = arg_split[a.i1][a.i2];
1120  break;
1121  case OP_OUTPUT:
1122  res_split[a.i0][a.i2] = w[a.i1];
1123  break;
1124  case OP_CONST:
1125  w[a.i0] = static_cast<double>(*c_it++);
1126  break;
1127  case OP_CALL:
1128  {
1129  const ExtendedAlgEl& m = call_.el.at(a.i1);
1130  std::vector<MX> deps(m.n_dep);
1131  std::vector<MX> args;
1132 
1133  casadi_int k = 0;
1134  // Construct matrix-valued function arguments
1135  for (casadi_int i=0;i<m.f_n_in;++i) {
1136  std::vector<MX> arg;
1137  for (casadi_int j=0;j<m.f_nnz_in[i];++j) {
1138  arg.push_back(w[m.dep[k++]]);
1139  }
1140  args.push_back(sparsity_cast(vertcat(arg), m.f.sparsity_in(i)));
1141  }
1142 
1143 
1144  std::vector<MX> ret = m.f(args);
1145  std::vector<MX> res;
1146 
1147  // Break apart matriv-valued outputs into scalar components
1148  for (casadi_int i=0;i<m.f_n_out;++i) {
1149  std::vector<MX> nz = ret[i].get_nonzeros();
1150  res.insert(res.end(), nz.begin(), nz.end());
1151  }
1152 
1153  // Store into work vector
1154  for (casadi_int i=0;i<m.n_res;++i) {
1155  if (m.res[i]>=0) w[m.res[i]] = res[i];
1156  }
1157  }
1158  break;
1159  default:
1160  // Evaluate the function to a temporary value
1161  // (as it might overwrite the children in the work vector)
1162  MX f;
1163  switch (a.op) {
1164  CASADI_MATH_FUN_BUILTIN(w[a.i1], w[a.i2], f)
1165  }
1166 
1167  // Finally save the function value
1168  w[a.i0] = f;
1169  }
1170  }
1171 
1172  // Join split outputs
1173  for (casadi_int i=0; i<res.size(); ++i) {
1174  res[i] = sparsity_cast(vertcat(res_split[i]), sparsity_out_[i]);
1175  }
1176  }
bool has_free() const override
Does the function have free variables.
std::vector< Matrix< SXElem > > in_
Inputs of the function (needed for symbolic calculations)
Definition: x_function.hpp:257
void casadi_project(const T1 *x, const casadi_int *sp_x, T1 *y, const casadi_int *sp_y, T1 *w)
Sparse copy: y <- x, w work vector (length >= number of rows)

References algorithm_, casadi::FunctionInternal::always_inline_, call_, casadi::casadi_project(), constants_, casadi::SXFunction::ExtendedAlgEl::dep, casadi::SXFunction::CallInfo::el, casadi::FunctionInternal::eval_mx(), casadi::SXFunction::ExtendedAlgEl::f, casadi::SXFunction::ExtendedAlgEl::f_n_in, casadi::SXFunction::ExtendedAlgEl::f_n_out, casadi::SXFunction::ExtendedAlgEl::f_nnz_in, casadi::get_ptr(), has_free(), casadi::XFunction< SXFunction, Matrix< SXElem >, SXNode >::in_, casadi::SXFunction::ExtendedAlgEl::n_dep, casadi::FunctionInternal::n_in_, casadi::SXFunction::ExtendedAlgEl::n_res, casadi::ProtoFunction::name_, casadi::FunctionInternal::never_inline_, casadi::FunctionInternal::nnz_out(), casadi::OP_CALL, casadi::OP_CONST, casadi::OP_INPUT, casadi::OP_OUTPUT, casadi::XFunction< SXFunction, Matrix< SXElem >, SXNode >::out_, casadi::SXFunction::ExtendedAlgEl::res, casadi::Function::sparsity_in(), casadi::FunctionInternal::sparsity_in_, casadi::FunctionInternal::sparsity_out_, casadi::FunctionInternal::sz_w(), and casadi::ProtoFunction::verbose_.

◆ eval_sx()

int casadi::SXFunction::eval_sx ( const SXElem **  arg,
SXElem **  res,
casadi_int *  iw,
SXElem w,
void *  mem,
bool  always_inline,
bool  never_inline 
) const
overridevirtual

Extra doc: https://github.com/casadi/casadi/wiki/L_uf

Reimplemented from casadi::FunctionInternal.

Definition at line 986 of file sx_function.cpp.

988  {
989 
990  always_inline = always_inline || always_inline_;
991  never_inline = never_inline || never_inline_;
992 
993  // non-inlining call is implemented in the base-class
994  if (!should_inline(true, always_inline, never_inline)) {
995  return FunctionInternal::eval_sx(arg, res, iw, w, mem, false, true);
996  }
997 
998  if (verbose_) casadi_message(name_ + "::eval_sx");
999 
1000  // Iterator to the binary operations
1001  std::vector<SXElem>::const_iterator b_it=operations_.begin();
1002 
1003  // Iterator to stack of constants
1004  std::vector<SXElem>::const_iterator c_it = constants_.begin();
1005 
1006  // Iterator to free variables
1007  std::vector<SXElem>::const_iterator p_it = free_vars_.begin();
1008 
1009  // Evaluate algorithm
1010  if (verbose_) casadi_message("Evaluating algorithm forward");
1011  for (auto&& a : algorithm_) {
1012  switch (a.op) {
1013  case OP_INPUT:
1014  w[a.i0] = arg[a.i1]==nullptr ? 0 : arg[a.i1][a.i2];
1015  break;
1016  case OP_OUTPUT:
1017  if (res[a.i0]!=nullptr) res[a.i0][a.i2] = w[a.i1];
1018  break;
1019  case OP_CONST:
1020  w[a.i0] = *c_it++;
1021  break;
1022  case OP_PARAMETER:
1023  w[a.i0] = *p_it++; break;
1024  case OP_CALL:
1025  {
1026  const ExtendedAlgEl& m = call_.el.at(a.i1);
1027  const SXElem& orig = *b_it++;
1028  std::vector<SXElem> deps(m.n_dep);
1029  bool identical = true;
1030 
1031  std::vector<SXElem> ret;
1032  for (casadi_int i=0;i<m.n_dep;++i) {
1033  identical &= SXElem::is_equal(w[m.dep.at(i)], orig->dep(i), 2);
1034  }
1035  if (identical) {
1036  ret = OutputSX::split(orig, m.n_res);
1037  } else {
1038  for (casadi_int i=0;i<m.n_dep;++i) deps[i] = w[m.dep[i]];
1039  ret = SXElem::call(m.f, deps);
1040  }
1041  for (casadi_int i=0;i<m.n_res;++i) {
1042  if (m.res[i]>=0) w[m.res[i]] = ret[i];
1043  }
1044  }
1045  break;
1046  default:
1047  {
1048  // Evaluate the function to a temporary value
1049  // (as it might overwrite the children in the work vector)
1050  SXElem f;
1051  switch (a.op) {
1052  CASADI_MATH_FUN_BUILTIN(w[a.i1], w[a.i2], f)
1053  }
1054 
1055  // If this new expression is identical to the expression used
1056  // to define the algorithm, then reuse
1057  const casadi_int depth = 2; // NOTE: a higher depth could possibly give more savings
1058  f.assignIfDuplicate(*b_it++, depth);
1059 
1060  // Finally save the function value
1061  w[a.i0] = f;
1062  }
1063  }
1064  }
1065  return 0;
1066  }
static std::vector< SXElem > split(const SXElem &e, casadi_int n)
Definition: output_sx.hpp:139
static bool is_equal(const SXElem &x, const SXElem &y, casadi_int depth=0)
Check equality up to a given depth.
Definition: sx_elem.cpp:529
bool should_inline(bool with_sx, bool always_inline, bool never_inline) const override

References algorithm_, casadi::FunctionInternal::always_inline_, casadi::SXElem::assignIfDuplicate(), casadi::SXElem::call(), call_, constants_, casadi::SXFunction::ExtendedAlgEl::dep, casadi::SXNode::dep(), casadi::SXFunction::CallInfo::el, casadi::FunctionInternal::eval_sx(), casadi::SXFunction::ExtendedAlgEl::f, free_vars_, casadi::SXElem::is_equal(), casadi::SXFunction::ExtendedAlgEl::n_dep, casadi::SXFunction::ExtendedAlgEl::n_res, casadi::ProtoFunction::name_, casadi::FunctionInternal::never_inline_, casadi::OP_CALL, casadi::OP_CONST, casadi::OP_INPUT, casadi::OP_OUTPUT, casadi::OP_PARAMETER, operations_, casadi::SXFunction::ExtendedAlgEl::res, should_inline(), casadi::OutputSX::split(), and casadi::ProtoFunction::verbose_.

◆ export_code()

void casadi::XFunction< SXFunction , Matrix< SXElem > , SXNode >::export_code ( const std::string &  lang,
std::ostream &  stream,
const Dict options 
) const
overridevirtualinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_y1

Reimplemented from casadi::FunctionInternal.

Definition at line 176 of file x_function.hpp.

1000  {
1001 
1002  casadi_assert(!has_free(), "export_code needs a Function without free variables");
1003 
1004  casadi_assert(lang=="matlab", "Only matlab language supported for now.");
1005 
1006  // start function
1007  stream << "function [varargout] = " << name_ << "(varargin)" << std::endl;
1008 
1009  // Allocate space for output argument (segments)
1010  for (casadi_int i=0;i<n_out_;++i) {
1011  stream << " argout_" << i << " = cell(" << nnz_out(i) << ",1);" << std::endl;
1012  }
1013 
1014  Dict opts;
1015  opts["indent_level"] = 1;
1016  export_code_body(lang, stream, opts);
1017 
1018  // Process the outputs
1019  for (casadi_int i=0;i<n_out_;++i) {
1020  const Sparsity& out = sparsity_out_.at(i);
1021  if (out.is_dense()) {
1022  // Special case if dense
1023  stream << " varargout{" << i+1 << "} = reshape(vertcat(argout_" << i << "{:}), ";
1024  stream << out.size1() << ", " << out.size2() << ");" << std::endl;
1025  } else {
1026  // For sparse outputs, export sparsity and call 'sparse'
1027  Dict opts;
1028  opts["name"] = "sp";
1029  opts["indent_level"] = 1;
1030  opts["as_matrix"] = false;
1031  out.export_code("matlab", stream, opts);
1032  stream << " varargout{" << i+1 << "} = ";
1033  stream << "sparse(sp_i, sp_j, vertcat(argout_" << i << "{:}), sp_m, sp_n);" << std::endl;
1034  }
1035  }
1036 
1037  // end function
1038  stream << "end" << std::endl;
1039  stream << "function y=nonzeros_gen(x)" << std::endl;
1040  stream << " if isa(x,'casadi.SX') || isa(x,'casadi.MX') || isa(x,'casadi.DM')" << std::endl;
1041  stream << " y = x{:};" << std::endl;
1042  stream << " elseif isa(x,'sdpvar')" << std::endl;
1043  stream << " b = getbase(x);" << std::endl;
1044  stream << " f = find(sum(b~=0,2));" << std::endl;
1045  stream << " y = sdpvar(length(f),1,[],getvariables(x),b(f,:));" << std::endl;
1046  stream << " else" << std::endl;
1047  stream << " y = nonzeros(x);" << std::endl;
1048  stream << " end" << std::endl;
1049  stream << "end" << std::endl;
1050  stream << "function y=if_else_zero_gen(c,e)" << std::endl;
1051  stream << " if isa(c+e,'casadi.SX') || isa(c+e,'casadi.MX') "
1052  "|| isa(c+e,'casadi.DM')" << std::endl;
1053  stream << " y = if_else(c, e, 0);" << std::endl;
1054  stream << " else" << std::endl;
1055  stream << " if c" << std::endl;
1056  stream << " y = x;" << std::endl;
1057  stream << " else" << std::endl;
1058  stream << " y = 0;" << std::endl;
1059  stream << " end" << std::endl;
1060  stream << " end" << std::endl;
1061  stream << "end" << std::endl;
1062 
1063 
1064  }
virtual bool has_free() const
Does the function have free variables.
virtual void export_code_body(const std::string &lang, std::ostream &stream, const Dict &options) const=0
Export function body in a specific language.

◆ export_code_body()

void casadi::SXFunction::export_code_body ( const std::string &  lang,
std::ostream &  stream,
const Dict options 
) const
overridevirtual

Extra doc: https://github.com/casadi/casadi/wiki/L_va

Implements casadi::XFunction< SXFunction, Matrix< SXElem >, SXNode >.

Definition at line 1724 of file sx_function.cpp.

1725  {
1726 
1727  // Default values for options
1728  casadi_int indent_level = 0;
1729 
1730  // Read options
1731  for (auto&& op : options) {
1732  if (op.first=="indent_level") {
1733  indent_level = op.second;
1734  } else {
1735  casadi_error("Unknown option '" + op.first + "'.");
1736  }
1737  }
1738 
1739  // Construct indent string
1740  std::string indent;
1741  for (casadi_int i=0;i<indent_level;++i) {
1742  indent += " ";
1743  }
1744 
1745  // Non-cell aliases for inputs
1746  for (casadi_int i=0;i<n_in_;++i) {
1747  ss << indent << "argin_" << i << " = nonzeros_gen(varargin{" << i+1 << "});" << std::endl;
1748  }
1749 
1750  Function f = shared_from_this<Function>();
1751 
1752  for (casadi_int k=0;k<f.n_instructions();++k) {
1753  // Get operation
1754  casadi_int op = static_cast<casadi_int>(f.instruction_id(k));
1755  // Get input positions into workvector
1756  std::vector<casadi_int> o = f.instruction_output(k);
1757  // Get output positions into workvector
1758  std::vector<casadi_int> i = f.instruction_input(k);
1759  switch (op) {
1760  case OP_INPUT:
1761  {
1762  ss << indent << "w" << o[0] << " = " << "argin_" << i[0] << "(" << i[1]+1 << ");";
1763  ss << std::endl;
1764  }
1765  break;
1766  case OP_OUTPUT:
1767  {
1768  ss << indent << "argout_" << o[0] << "{" << o[1]+1 << "} = w" << i[0] << ";";
1769  ss << std::endl;
1770  }
1771  break;
1772  case OP_CONST:
1773  {
1774  std::ios_base::fmtflags fmtfl = ss.flags();
1775  ss << indent << "w" << o[0] << " = ";
1776  ss << std::scientific << std::setprecision(std::numeric_limits<double>::digits10 + 1);
1777  ss << f.instruction_constant(k) << ";" << std::endl;
1778  ss.flags(fmtfl);
1779  }
1780  break;
1781  case OP_SQ:
1782  {
1783  ss << indent << "w" << o[0] << " = " << "w" << i[0] << "^2;" << std::endl;
1784  }
1785  break;
1786  case OP_FABS:
1787  {
1788  ss << indent << "w" << o[0] << " = abs(" << "w" << i[0] << ");" << std::endl;
1789  }
1790  break;
1791  case OP_POW:
1792  case OP_CONSTPOW:
1793  ss << indent << "w" << o[0] << " = " << "w" << i[0] << ".^w" << i[1] << ";" << std::endl;
1794  break;
1795  case OP_NOT:
1796  ss << indent << "w" << o[0] << " = ~" << "w" << i[0] << ";" << std::endl;
1797  break;
1798  case OP_OR:
1799  ss << indent << "w" << o[0] << " = w" << i[0] << " | w" << i[1] << ";" << std::endl;
1800  break;
1801  case OP_AND:
1802  ss << indent << "w" << o[0] << " = w" << i[0] << " & w" << i[1] << ";" << std::endl;
1803  break;
1804  case OP_NE:
1805  ss << indent << "w" << o[0] << " = w" << i[0] << " ~= w" << i[1] << ";" << std::endl;
1806  break;
1807  case OP_IF_ELSE_ZERO:
1808  ss << indent << "w" << o[0] << " = ";
1809  ss << "if_else_zero_gen(w" << i[0] << ", w" << i[1] << ");" << std::endl;
1810  break;
1811  default:
1813  ss << indent << "w" << o[0] << " = " << casadi::casadi_math<double>::print(op,
1814  "w"+std::to_string(i[0]), "w"+std::to_string(i[1])) << ";" << std::endl;
1815  } else {
1816  ss << indent << "w" << o[0] << " = " << casadi::casadi_math<double>::print(op,
1817  "w"+std::to_string(i[0])) << ";" << std::endl;
1818  }
1819  }
1820  }
1821 
1822  }
@ OP_NE
Definition: calculus.hpp:70
@ OP_AND
Definition: calculus.hpp:70
@ OP_OR
Definition: calculus.hpp:70
@ OP_POW
Definition: calculus.hpp:66
@ OP_FABS
Definition: calculus.hpp:71
@ OP_CONSTPOW
Definition: calculus.hpp:66
@ OP_NOT
Definition: calculus.hpp:70
@ OP_SQ
Definition: calculus.hpp:67
Easy access to all the functions for a particular type.
Definition: calculus.hpp:1125
static std::string print(unsigned char op, const std::string &x, const std::string &y)
Print.
Definition: calculus.hpp:1641

References casadi::Function::instruction_constant(), casadi::Function::instruction_id(), casadi::Function::instruction_input(), casadi::Function::instruction_output(), casadi::FunctionInternal::n_in_, casadi::Function::n_instructions(), casadi::OP_AND, casadi::OP_CONST, casadi::OP_CONSTPOW, casadi::OP_FABS, casadi::OP_IF_ELSE_ZERO, casadi::OP_INPUT, casadi::OP_NE, casadi::OP_NOT, casadi::OP_OR, casadi::OP_OUTPUT, casadi::OP_POW, casadi::OP_SQ, and casadi::casadi_math< T >::print().

◆ factory()

Function casadi::XFunction< SXFunction , Matrix< SXElem > , SXNode >::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
overridevirtualinherited

Reimplemented from casadi::FunctionInternal.

Definition at line 108 of file x_function.hpp.

1148  {
1149 
1150  Dict g_ops = generate_options("clone");
1151  Dict f_options;
1152  f_options["helper_options"] = g_ops;
1153  f_options["final_options"] = g_ops;
1154  update_dict(f_options, opts, true);
1155 
1156  Dict final_options;
1157  extract_from_dict_inplace(f_options, "final_options", final_options);
1158  final_options["allow_duplicate_io_names"] = true;
1159 
1160  // Create an expression factory
1161  Factory<MatType> f;
1162  for (casadi_int i=0; i<in_.size(); ++i) f.add_input(name_in_[i], in_[i], is_diff_in_[i]);
1163  for (casadi_int i=0; i<out_.size(); ++i) f.add_output(name_out_[i], out_[i], is_diff_out_[i]);
1164  f.add_dual(aux);
1165 
1166  // Specify input expressions to be calculated
1167  std::vector<std::string> ret_iname;
1168  for (const std::string& s : s_in) {
1169  try {
1170  ret_iname.push_back(f.request_input(s));
1171  } catch (CasadiException& ex) {
1172  casadi_error("Cannot process factory input \"" + s + "\":" + ex.what());
1173  }
1174  }
1175 
1176  // Specify output expressions to be calculated
1177  std::vector<std::string> ret_oname;
1178  for (const std::string& s : s_out) {
1179  try {
1180  ret_oname.push_back(f.request_output(s));
1181  } catch (CasadiException& ex) {
1182  casadi_error("Cannot process factory output \"" + s + "\":" + ex.what());
1183  }
1184  }
1185 
1186  // Calculate expressions
1187  f.calculate(f_options);
1188 
1189  // Get input expressions
1190  std::vector<MatType> ret_in;
1191  ret_in.reserve(s_in.size());
1192  for (const std::string& s : s_in) ret_in.push_back(f.get_input(s));
1193 
1194  // Get output expressions
1195  std::vector<MatType> ret_out;
1196  ret_out.reserve(s_out.size());
1197  for (const std::string& s : s_out) ret_out.push_back(f.get_output(s));
1198 
1199  // Create function and return
1200  Dict final_options_allow_free = final_options;
1201  final_options_allow_free["allow_free"] = true;
1202  final_options_allow_free["allow_duplicate_io_names"] = true;
1203  Function ret(name, ret_in, ret_out, ret_iname, ret_oname, final_options_allow_free);
1204  if (ret.has_free()) {
1205  // Substitute free variables with zeros
1206  // We assume that the free variables are caused by false positive dependencies
1207  std::vector<MatType> free_in = MatType::get_free(ret);
1208  std::vector<MatType> free_sub = free_in;
1209  for (auto&& e : free_sub) e = MatType::zeros(e.sparsity());
1210  ret_out = substitute(ret_out, free_in, free_sub);
1211  ret = Function(name, ret_in, ret_out, ret_iname, ret_oname, final_options);
1212  }
1213  return ret;
1214  }
Dict generate_options(const std::string &target) const override
Reconstruct options dict.
void extract_from_dict_inplace(Dict &d, const std::string &key, T &value)
void update_dict(Dict &target, const Dict &source, bool recurse)
Update the target dictionary in place with source elements.

◆ finalize()

void casadi::FunctionInternal::finalize ( )
overridevirtualinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_k7

Reimplemented from casadi::ProtoFunction.

Reimplemented in casadi::OracleFunction.

Definition at line 704 of file function_internal.cpp.

704  {
705  if (jit_) {
707  if (jit_temp_suffix_) {
709  jit_name_ = std::string(jit_name_.begin(), jit_name_.begin()+jit_name_.size()-2);
710  }
711  if (has_codegen()) {
712  if (compiler_.is_null()) {
713  if (verbose_) casadi_message("Codegenerating function '" + name_ + "'.");
714  // JIT everything
715  Dict opts;
716  // Override the default to avoid random strings in the generated code
717  opts["prefix"] = "jit";
718  CodeGenerator gen(jit_name_, opts);
719  gen.add(self());
720  if (verbose_) casadi_message("Compiling function '" + name_ + "'..");
721  std::string jit_directory = get_from_dict(jit_options_, "directory", std::string(""));
722  compiler_ = Importer(gen.generate(jit_directory), compiler_plugin_, jit_options_);
723  if (verbose_) casadi_message("Compiling function '" + name_ + "' done.");
724  }
725  // Try to load
729  casadi_assert(eval_!=nullptr, "Cannot load JIT'ed function.");
730  } else {
731  // Just jit dependencies
733  }
734  }
735 
736  // Finalize base classes
738 
739  // Dump if requested
740  if (dump_) dump();
741  }
virtual void jit_dependencies(const std::string &fname)
Jit dependencies.
std::string jit_name_
Name if jit source file.
std::string compiler_plugin_
Just-in-time compiler.
bool jit_
Use just-in-time compiler.
bool jit_temp_suffix_
Use a temporary name.
virtual bool has_codegen() const
Is codegen supported?
bool is_null() const
Is a null pointer?
signal_t get_function(const std::string &symname)
Get a function pointer for numerical evaluation.
Definition: importer.cpp:79
T get_from_dict(const std::map< std::string, T > &d, const std::string &key, const T &default_value)
int(* casadi_checkout_t)(void)
Function pointer types for the C API.
std::string temporary_file(const std::string &prefix, const std::string &suffix)
int(* eval_t)(const double **arg, double **res, casadi_int *iw, double *w, int)
Function pointer types for the C API.
void(* casadi_release_t)(int)
Function pointer types for the C API.

References casadi::CodeGenerator::add(), casadi::FunctionInternal::checkout_, casadi::FunctionInternal::compiler_, casadi::FunctionInternal::compiler_plugin_, casadi::FunctionInternal::dump_, casadi::FunctionInternal::eval_, casadi::ProtoFunction::finalize(), casadi::CodeGenerator::generate(), casadi::get_from_dict(), casadi::Importer::get_function(), casadi::FunctionInternal::has_codegen(), casadi::GenericShared< Shared, Internal >::is_null(), casadi::FunctionInternal::jit_, casadi::FunctionInternal::jit_base_name_, casadi::FunctionInternal::jit_dependencies(), casadi::FunctionInternal::jit_name_, casadi::FunctionInternal::jit_options_, casadi::FunctionInternal::jit_temp_suffix_, casadi::ProtoFunction::name_, casadi::FunctionInternal::release_, casadi::temporary_file(), and casadi::ProtoFunction::verbose_.

Referenced by casadi::FunctionInternal::deserialize(), casadi::CallbackInternal::finalize(), and casadi::OracleFunction::finalize().

◆ find()

void casadi::SXFunction::find ( std::map< FunctionInternal *, Function > &  all_fun,
casadi_int  max_depth 
) const
overridevirtual

Reimplemented from casadi::FunctionInternal.

Definition at line 1945 of file sx_function.cpp.

1946  {
1947  for (auto&& e : algorithm_) {
1948  if (e.op == OP_CALL) {
1949  const ExtendedAlgEl& m = call_.el.at(e.i1);
1950  add_embedded(all_fun, m.f, max_depth);
1951  }
1952  }
1953  }
void add_embedded(std::map< FunctionInternal *, Function > &all_fun, const Function &dep, casadi_int max_depth) const

References casadi::FunctionInternal::add_embedded(), algorithm_, call_, casadi::SXFunction::CallInfo::el, casadi::SXFunction::ExtendedAlgEl::f, and casadi::OP_CALL.

◆ format_time()

void casadi::ProtoFunction::format_time ( char *  buffer,
double  time 
) const
inherited

Extra doc: https://github.com/casadi/casadi/wiki/L_jt

Definition at line 3856 of file function_internal.cpp.

3856  {
3857  // Always of width 8
3858  casadi_assert_dev(time>=0);
3859  double log_time = log10(time);
3860  int magn = static_cast<int>(floor(log_time));
3861  int iprefix = static_cast<int>(floor(log_time/3));
3862  if (iprefix<-4) {
3863  sprint(buffer, 10, " 0");
3864  return;
3865  }
3866  if (iprefix>=5) {
3867  sprint(buffer, 10, " inf");
3868  return;
3869  }
3870  char prefixes[] = "TGMk munp";
3871  char prefix = prefixes[4-iprefix];
3872 
3873  int rem = magn-3*iprefix;
3874  double time_normalized = time/pow(10, 3*iprefix);
3875 
3876  if (rem==0) {
3877  sprint(buffer, 10, " %1.2f%cs", time_normalized, prefix);
3878  } else if (rem==1) {
3879  sprint(buffer, 10, " %2.2f%cs", time_normalized, prefix);
3880  } else {
3881  sprint(buffer, 10, "%3.2f%cs", time_normalized, prefix);
3882  }
3883  }
void sprint(char *buf, size_t buf_sz, const char *fmt,...) const
C-style formatted printing to string.

References casadi::ProtoFunction::sprint().

Referenced by casadi::ProtoFunction::print_time().

◆ forward()

Function casadi::FunctionInternal::forward ( casadi_int  nfwd) const
inherited

forward(nfwd) returns a cached instance if available, and calls Function get_forward(casadi_int nfwd) if no cached version is available.

Extra doc: https://github.com/casadi/casadi/wiki/L_l0

Definition at line 2163 of file function_internal.cpp.

2163  {
2164  casadi_assert_dev(nfwd>=0);
2165  // Used wrapped function if forward not available
2166  if (!enable_forward_ && !enable_fd_) {
2167  // Derivative information must be available
2168  casadi_assert(has_derivative(), "Derivatives cannot be calculated for " + name_);
2169  return wrap().forward(nfwd);
2170  }
2171  // Retrieve/generate cached
2172  Function f;
2173  std::string fname = forward_name(name_, nfwd);
2174  if (!incache(fname, f)) {
2175  casadi_int i;
2176  // Prefix to be used for forward seeds, sensitivities
2177  std::string pref = diff_prefix("fwd");
2178  // Names of inputs
2179  std::vector<std::string> inames;
2180  for (i=0; i<n_in_; ++i) inames.push_back(name_in_[i]);
2181  for (i=0; i<n_out_; ++i) inames.push_back("out_" + name_out_[i]);
2182  for (i=0; i<n_in_; ++i) inames.push_back(pref + name_in_[i]);
2183  // Names of outputs
2184  std::vector<std::string> onames;
2185  for (i=0; i<n_out_; ++i) onames.push_back(pref + name_out_[i]);
2186  // Options
2188  opts = combine(opts, generate_options("forward"));
2189  if (!enable_forward_) opts = fd_options_;
2190  opts["derivative_of"] = self();
2191  // Generate derivative function
2192  casadi_assert_dev(enable_forward_ || enable_fd_);
2193  if (enable_forward_) {
2194  f = get_forward(nfwd, fname, inames, onames, opts);
2195  } else {
2196  // Get FD method
2197  if (fd_method_.empty() || fd_method_=="central") {
2198  f = Function::create(new CentralDiff(fname, nfwd), opts);
2199  } else if (fd_method_=="forward") {
2200  f = Function::create(new ForwardDiff(fname, nfwd), opts);
2201  } else if (fd_method_=="backward") {
2202  f = Function::create(new BackwardDiff(fname, nfwd), opts);
2203  } else if (fd_method_=="smoothing") {
2204  f = Function::create(new Smoothing(fname, nfwd), opts);
2205  } else {
2206  casadi_error("Unknown 'fd_method': " + fd_method_);
2207  }
2208  }
2209  // Consistency check for inputs
2210  casadi_assert_dev(f.n_in()==n_in_ + n_out_ + n_in_);
2211  casadi_int ind=0;
2212  for (i=0; i<n_in_; ++i) f.assert_size_in(ind++, size1_in(i), size2_in(i));
2213  for (i=0; i<n_out_; ++i) f.assert_size_in(ind++, size1_out(i), size2_out(i));
2214  for (i=0; i<n_in_; ++i) f.assert_size_in(ind++, size1_in(i), nfwd*size2_in(i));
2215  // Consistency check for outputs
2216  casadi_assert_dev(f.n_out()==n_out_);
2217  for (i=0; i<n_out_; ++i) f.assert_sparsity_out(i, sparsity_out(i), nfwd);
2218  // Save to cache
2219  tocache_if_missing(f);
2220  }
2221  return f;
2222  }
std::string diff_prefix(const std::string &prefix) const
Determine prefix for differentiated functions.
void tocache_if_missing(Function &f, const std::string &suffix="") const
Save function to cache, only if missing.
static std::string forward_name(const std::string &fcn, casadi_int nfwd)
Helper function: Get name of forward derivative function.
Function wrap() const
Wrap in an Function instance consisting of only one MX call.
bool incache(const std::string &fname, Function &f, const std::string &suffix="") const
Get function in cache.
casadi_int size1_out(casadi_int ind) const
Input/output dimensions.
virtual Function get_forward(casadi_int nfwd, const std::string &name, const std::vector< std::string > &inames, const std::vector< std::string > &onames, const Dict &opts) const
Return function that calculates forward derivatives.
Function forward(casadi_int nfwd) const
Get a function that calculates nfwd forward derivatives.
Definition: function.cpp:1135
static Function create(FunctionInternal *node)
Create from node.
Definition: function.cpp:336
Dict combine(const Dict &first, const Dict &second, bool recurse)
Combine two dicts. First has priority.

References casadi::Function::assert_size_in(), casadi::Function::assert_sparsity_out(), casadi::combine(), casadi::Function::create(), casadi::FunctionInternal::der_options_, casadi::FunctionInternal::diff_prefix(), casadi::FunctionInternal::enable_fd_, casadi::FunctionInternal::enable_forward_, casadi::FunctionInternal::fd_method_, casadi::FunctionInternal::fd_options_, casadi::Function::forward(), casadi::FunctionInternal::forward_name(), casadi::FunctionInternal::forward_options_, casadi::FunctionInternal::generate_options(), casadi::FunctionInternal::get_forward(), casadi::FunctionInternal::has_derivative(), casadi::FunctionInternal::incache(), casadi::Function::n_in(), casadi::FunctionInternal::n_in_, casadi::Function::n_out(), casadi::FunctionInternal::n_out_, casadi::ProtoFunction::name_, casadi::FunctionInternal::name_in_, casadi::FunctionInternal::name_out_, casadi::FunctionInternal::size1_in(), casadi::FunctionInternal::size1_out(), casadi::FunctionInternal::size2_in(), casadi::FunctionInternal::size2_out(), casadi::FunctionInternal::sparsity_out(), casadi::FunctionInternal::tocache_if_missing(), and casadi::FunctionInternal::wrap().

Referenced by casadi::FunctionInternal::call_forward(), and casadi::Function::forward().

◆ forward_name()

static std::string casadi::FunctionInternal::forward_name ( const std::string &  fcn,
casadi_int  nfwd 
)
inlinestaticinherited

◆ free_mem()

void casadi::FunctionInternal::free_mem ( void *  mem) const
inlineoverridevirtualinherited

◆ free_mx()

std::vector< MX > casadi::FunctionInternal::free_mx ( ) const
virtualinherited

Reimplemented in casadi::MXFunction.

Definition at line 3377 of file function_internal.cpp.

3377  {
3378  casadi_error("'free_mx' only defined for 'MXFunction'");
3379  }

◆ free_sx()

std::vector<SX> casadi::SXFunction::free_sx ( ) const
inlineoverridevirtual

Reimplemented from casadi::FunctionInternal.

Definition at line 149 of file sx_function.hpp.

149  {
150  std::vector<SX> ret(free_vars_.size());
151  std::copy(free_vars_.begin(), free_vars_.end(), ret.begin());
152  return ret;
153  }

◆ from_compact()

Sparsity casadi::FunctionInternal::from_compact ( casadi_int  oind,
casadi_int  iind,
const Sparsity sp 
) const
inherited

Definition at line 1928 of file function_internal.cpp.

1929  {
1930  // Return value
1931  Sparsity r = sp;
1932  // Insert rows if sparse output
1933  if (numel_out(oind) != r.size1()) {
1934  casadi_assert_dev(r.size1() == nnz_out(oind));
1935  r.enlargeRows(numel_out(oind), sparsity_out(oind).find());
1936  }
1937  // Insert columns if sparse input
1938  if (numel_in(iind) != r.size2()) {
1939  casadi_assert_dev(r.size2() == nnz_in(iind));
1940  r.enlargeColumns(numel_in(iind), sparsity_in(iind).find());
1941  }
1942  // Return non-compact pattern
1943  return r;
1944  }
casadi_int numel_out() const
Number of input/output elements.
virtual void find(std::map< FunctionInternal *, Function > &all_fun, casadi_int max_depth) const
casadi_int numel_in() const
Number of input/output elements.

References casadi::Sparsity::enlargeColumns(), casadi::Sparsity::enlargeRows(), casadi::FunctionInternal::find(), casadi::FunctionInternal::nnz_in(), casadi::FunctionInternal::nnz_out(), casadi::FunctionInternal::numel_in(), casadi::FunctionInternal::numel_out(), casadi::Sparsity::size1(), casadi::Sparsity::size2(), casadi::FunctionInternal::sparsity_in(), and casadi::FunctionInternal::sparsity_out().

Referenced by casadi::FunctionInternal::jac_sparsity().

◆ fwd_seed()

template<typename MatType >
std::vector< std::vector< MatType > > casadi::FunctionInternal::fwd_seed ( casadi_int  nfwd) const
inherited

Extra doc: https://github.com/casadi/casadi/wiki/L_nr

Definition at line 1519 of file function_internal.hpp.

1520  {
1521  std::vector<std::vector<MatType>> fseed(nfwd);
1522  for (casadi_int dir=0; dir<nfwd; ++dir) {
1523  fseed[dir].resize(n_in_);
1524  for (casadi_int iind=0; iind<n_in_; ++iind) {
1525  std::string n = "f" + str(dir) + "_" + name_in_[iind];
1526  Sparsity sp = is_diff_in_[iind] ? sparsity_in(iind) : Sparsity(size_in(iind));
1527  fseed[dir][iind] = MatType::sym(n, sp);
1528  }
1529  }
1530  return fseed;
1531  }

References casadi::FunctionInternal::is_diff_in_, casadi::FunctionInternal::n_in_, casadi::FunctionInternal::name_in_, casadi::FunctionInternal::size_in(), casadi::FunctionInternal::sparsity_in(), and casadi::str().

◆ fwdViaJac()

bool casadi::FunctionInternal::fwdViaJac ( casadi_int  nfwd) const
virtualinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_nc

Definition at line 2993 of file function_internal.cpp.

2993  {
2994  if (!enable_forward_ && !enable_fd_) return true;
2995  if (jac_penalty_==-1) return false;
2996 
2997  // Heuristic 1: Jac calculated via forward mode likely cheaper
2998  if (jac_penalty_*static_cast<double>(nnz_in())<nfwd) return true;
2999 
3000  // Heuristic 2: Jac calculated via reverse mode likely cheaper
3001  double w = ad_weight();
3002  if (enable_reverse_ &&
3003  jac_penalty_*(1-w)*static_cast<double>(nnz_out())<w*static_cast<double>(nfwd))
3004  return true; // NOLINT
3005 
3006  return false;
3007  }

References casadi::FunctionInternal::ad_weight(), casadi::FunctionInternal::enable_fd_, casadi::FunctionInternal::enable_forward_, casadi::FunctionInternal::enable_reverse_, casadi::FunctionInternal::jac_penalty_, casadi::FunctionInternal::nnz_in(), and casadi::FunctionInternal::nnz_out().

Referenced by casadi::FunctionInternal::call_forward().

◆ generate_dependencies()

std::string casadi::FunctionInternal::generate_dependencies ( const std::string &  fname,
const Dict opts 
) const
virtualinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_m2

Reimplemented in casadi::OracleFunction.

Definition at line 2833 of file function_internal.cpp.

2834  {
2835  casadi_error("'generate_dependencies' not defined for " + class_name());
2836  }

References casadi::SharedObjectInternal::class_name().

◆ generate_in()

void casadi::FunctionInternal::generate_in ( const std::string &  fname,
const double **  arg 
) const
inherited

Extra doc: https://github.com/casadi/casadi/wiki/L_ne

Definition at line 749 of file function_internal.cpp.

749  {
750  // Set up output stream
751  auto of_ptr = Filesystem::ofstream_ptr(fname);
752  std::ostream& of = *of_ptr;
753  normalized_setup(of);
754 
755  // Encode each input
756  for (casadi_int i=0; i<n_in_; ++i) {
757  const double* v = arg[i];
758  for (casadi_int k=0;k<nnz_in(i);++k) {
759  normalized_out(of, v ? v[k] : 0);
760  of << std::endl;
761  }
762  }
763  }
static std::unique_ptr< std::ostream > ofstream_ptr(const std::string &path, std::ios_base::openmode mode=std::ios_base::out)
Definition: filesystem.cpp:115
void normalized_setup(std::istream &stream)
void normalized_out(std::ostream &stream, double val)

References casadi::FunctionInternal::n_in_, casadi::FunctionInternal::nnz_in(), casadi::normalized_out(), casadi::normalized_setup(), and casadi::Filesystem::ofstream_ptr().

◆ generate_lifted()

void casadi::FunctionInternal::generate_lifted ( Function vdef_fcn,
Function vinit_fcn 
) const
virtualinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_l9

Reimplemented in casadi::MXFunction.

Definition at line 3385 of file function_internal.cpp.

3386  {
3387  casadi_error("'generate_lifted' only defined for 'MXFunction'");
3388  }

◆ generate_options()

Dict casadi::SXFunction::generate_options ( const std::string &  target = "clone") const
overridevirtual

Reimplemented from casadi::FunctionInternal.

Definition at line 466 of file sx_function.cpp.

466  {
468  //opts["default_in"] = default_in_;
469  opts["live_variables"] = live_variables_;
470  opts["just_in_time_sparsity"] = just_in_time_sparsity_;
471  opts["just_in_time_opencl"] = just_in_time_opencl_;
472  return opts;
473  }

References casadi::FunctionInternal::generate_options(), just_in_time_opencl_, just_in_time_sparsity_, and live_variables_.

◆ generate_out()

void casadi::FunctionInternal::generate_out ( const std::string &  fname,
double **  res 
) const
inherited

Definition at line 765 of file function_internal.cpp.

765  {
766  // Set up output stream
767  auto of_ptr = Filesystem::ofstream_ptr(fname);
768  std::ostream& of = *of_ptr;
769  normalized_setup(of);
770 
771  // Encode each input
772  for (casadi_int i=0; i<n_out_; ++i) {
773  const double* v = res[i];
774  for (casadi_int k=0;k<nnz_out(i);++k) {
775  normalized_out(of, v ? v[k] : std::numeric_limits<double>::quiet_NaN());
776  of << std::endl;
777  }
778  }
779  }

References casadi::FunctionInternal::n_out_, casadi::FunctionInternal::nnz_out(), casadi::normalized_out(), casadi::normalized_setup(), and casadi::Filesystem::ofstream_ptr().

◆ get_abstol()

virtual double casadi::FunctionInternal::get_abstol ( ) const
inlinevirtualinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_mp

Reimplemented in casadi::SundialsInterface, casadi::Smoothing, casadi::CentralDiff, and casadi::ForwardDiff.

Definition at line 1099 of file function_internal.hpp.

1099  {
1100  return eps;
1101  }
const double eps
Machine epsilon.
Definition: calculus.hpp:56

References casadi::eps.

Referenced by casadi::FiniteDiff::init().

◆ get_default_in()

double casadi::SXFunction::get_default_in ( casadi_int  ind) const
inlineoverridevirtual

Extra doc: https://github.com/casadi/casadi/wiki/L_v9

Reimplemented from casadi::FunctionInternal.

Definition at line 370 of file sx_function.hpp.

370 { return default_in_.at(ind);}

◆ get_diff_in()

virtual bool casadi::FunctionInternal::get_diff_in ( casadi_int  i)
inlinevirtualinherited

◆ get_diff_out()

virtual bool casadi::FunctionInternal::get_diff_out ( casadi_int  i)
inlinevirtualinherited

◆ get_forward()

Function casadi::XFunction< SXFunction , Matrix< SXElem > , SXNode >::get_forward ( casadi_int  nfwd,
const std::string &  name,
const std::vector< std::string > &  inames,
const std::vector< std::string > &  onames,
const Dict opts 
) const
overridevirtualinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_xv

Reimplemented from casadi::FunctionInternal.

Definition at line 129 of file x_function.hpp.

821  {
822  try {
823  // Seeds
824  std::vector<std::vector<MatType> > fseed = fwd_seed<MatType>(nfwd), fsens;
825 
826  // Evaluate symbolically
827  static_cast<const DerivedType*>(this)->ad_forward(fseed, fsens);
828  casadi_assert_dev(fsens.size()==fseed.size());
829 
830  // All inputs of the return function
831  std::vector<MatType> ret_in(inames.size());
832  std::copy(in_.begin(), in_.end(), ret_in.begin());
833  for (casadi_int i=0; i<n_out_; ++i) {
834  ret_in.at(n_in_+i) = MatType::sym(inames[n_in_+i], Sparsity(out_.at(i).size()));
835  }
836  std::vector<MatType> v(nfwd);
837  for (casadi_int i=0; i<n_in_; ++i) {
838  for (casadi_int d=0; d<nfwd; ++d) v[d] = fseed[d][i];
839  ret_in.at(n_in_ + n_out_ + i) = horzcat(v);
840  }
841 
842  // All outputs of the return function
843  std::vector<MatType> ret_out(onames.size());
844  for (casadi_int i=0; i<n_out_; ++i) {
845  if (is_diff_out_[i]) {
846  // Concatenate sensitivities, correct sparsity pattern if needed
847  for (casadi_int d=0; d<nfwd; ++d) v[d] = fsens[d][i];
848  ret_out.at(i) = ensure_stacked(horzcat(v), sparsity_out(i), nfwd);
849  } else {
850  // Output is non-differentable
851  ret_out.at(i) = MatType(size1_out(i), size2_out(i) * nfwd);
852  }
853  }
854 
855  Dict options = opts;
856  if (opts.find("is_diff_in")==opts.end())
857  options["is_diff_in"] = join(is_diff_in_, is_diff_out_, is_diff_in_);
858  if (opts.find("is_diff_out")==opts.end())
859  options["is_diff_out"] = is_diff_out_;
860  options["allow_duplicate_io_names"] = true;
861  // Assemble function and return
862  return Function(name, ret_in, ret_out, inames, onames, options);
863  } catch (std::exception& e) {
864  CASADI_THROW_ERROR("get_forward", e.what());
865  }
866  }
static MatType ensure_stacked(const MatType &v, const Sparsity &sp, casadi_int n)
Ensure that a matrix's sparsity is a horizontal multiple of another, or empty.
std::string join(const std::vector< std::string > &l, const std::string &delim)

◆ get_free()

std::vector<std::string> casadi::SXFunction::get_free ( ) const
inlineoverridevirtual

Extra doc: https://github.com/casadi/casadi/wiki/L_uo

Reimplemented from casadi::FunctionInternal.

Definition at line 163 of file sx_function.hpp.

163  {
164  std::vector<std::string> ret;
165  for (auto&& e : free_vars_) ret.push_back(e.name());
166  return ret;
167  }

Referenced by init().

◆ get_function() [1/2]

std::vector< std::string > casadi::FunctionInternal::get_function ( ) const
virtualinherited

Reimplemented in casadi::OracleFunction, casadi::MapSum, and casadi::Map.

Definition at line 3706 of file function_internal.cpp.

3706  {
3707  // No functions
3708  return std::vector<std::string>();
3709  }

◆ get_function() [2/2]

const Function & casadi::FunctionInternal::get_function ( const std::string &  name) const
virtualinherited

Reimplemented in casadi::OracleFunction, casadi::MapSum, and casadi::Map.

Definition at line 3711 of file function_internal.cpp.

3711  {
3712  casadi_error("'get_function' not defined for " + class_name());
3713  static Function singleton;
3714  return singleton;
3715  }

References casadi::SharedObjectInternal::class_name().

◆ get_jac_sparsity()

Sparsity casadi::FunctionInternal::get_jac_sparsity ( casadi_int  oind,
casadi_int  iind,
bool  symmetric 
) const
virtualinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_kz Get, if necessary generate, the sparsity of a Jacobian block

Reimplemented in casadi::FmuFunction, casadi::GenericExternal, casadi::Expm, and casadi::CallbackInternal.

Definition at line 1871 of file function_internal.cpp.

1872  {
1873  if (symmetric) {
1874  casadi_assert(sparsity_out_[oind].is_dense(),
1875  "Symmetry exploitation in Jacobian assumes dense expression. "
1876  "A potential workaround is to apply densify().");
1877  }
1878  // Check if we are able to propagate dependencies through the function
1879  if (has_spfwd() || has_sprev()) {
1880  // Get weighting factor
1881  double w = sp_weight();
1882 
1883  // Skip generation, assume dense
1884  if (w == -1) return Sparsity();
1885 
1886  Sparsity sp;
1887  if (nnz_in(iind) > 3*bvec_size && nnz_out(oind) > 3*bvec_size &&
1889  if (symmetric) {
1890  sp = get_jac_sparsity_hierarchical_symm(oind, iind);
1891  } else {
1892  sp = get_jac_sparsity_hierarchical(oind, iind);
1893  }
1894  } else {
1895  // Number of nonzero inputs and outputs
1896  casadi_int nz_in = nnz_in(iind);
1897  casadi_int nz_out = nnz_out(oind);
1898 
1899  // Number of forward sweeps we must make
1900  casadi_int nsweep_fwd = nz_in/bvec_size;
1901  if (nz_in%bvec_size) nsweep_fwd++;
1902 
1903  // Number of adjoint sweeps we must make
1904  casadi_int nsweep_adj = nz_out/bvec_size;
1905  if (nz_out%bvec_size) nsweep_adj++;
1906 
1907  // Use forward mode?
1908  if (w*static_cast<double>(nsweep_fwd) <= (1-w)*static_cast<double>(nsweep_adj)) {
1909  sp = get_jac_sparsity_gen<true>(oind, iind);
1910  } else {
1911  sp = get_jac_sparsity_gen<false>(oind, iind);
1912  }
1913  }
1914  return sp;
1915  } else {
1916  // Not calculated
1917  return Sparsity();
1918  }
1919  }
virtual bool has_sprev() const
Is the class able to propagate seeds through the algorithm?
Sparsity get_jac_sparsity_hierarchical_symm(casadi_int oind, casadi_int iind) const
virtual double sp_weight() const
Weighting factor for chosing forward/reverse mode,.
Sparsity get_jac_sparsity_hierarchical(casadi_int oind, casadi_int iind) const
A flavor of get_jac_sparsity_gen that does hierarchical block structure recognition.
virtual bool has_spfwd() const
Is the class able to propagate seeds through the algorithm?
static bool hierarchical_sparsity
const int bvec_size

References casadi::bvec_size, casadi::FunctionInternal::get_jac_sparsity_hierarchical(), casadi::FunctionInternal::get_jac_sparsity_hierarchical_symm(), casadi::FunctionInternal::has_spfwd(), casadi::FunctionInternal::has_sprev(), casadi::GlobalOptions::hierarchical_sparsity, casadi::FunctionInternal::nnz_in(), casadi::FunctionInternal::nnz_out(), casadi::FunctionInternal::nz_in(), casadi::FunctionInternal::nz_out(), casadi::FunctionInternal::sp_weight(), and casadi::FunctionInternal::sparsity_out_.

Referenced by casadi::Expm::get_jac_sparsity(), casadi::GenericExternal::get_jac_sparsity(), and casadi::FunctionInternal::jac_sparsity().

◆ get_jac_sparsity_gen()

template<bool fwd>
Sparsity casadi::FunctionInternal::get_jac_sparsity_gen ( casadi_int  oind,
casadi_int  iind 
) const
inherited

Definition at line 1216 of file function_internal.cpp.

1216  {
1217  // Number of nonzero inputs and outputs
1218  casadi_int nz_in = nnz_in(iind);
1219  casadi_int nz_out = nnz_out(oind);
1220 
1221  // Evaluation buffers
1222  std::vector<typename JacSparsityTraits<fwd>::arg_t> arg(sz_arg(), nullptr);
1223  std::vector<bvec_t*> res(sz_res(), nullptr);
1224  std::vector<casadi_int> iw(sz_iw());
1225  std::vector<bvec_t> w(sz_w(), 0);
1226 
1227  // Seeds and sensitivities
1228  std::vector<bvec_t> seed(nz_in, 0);
1229  arg[iind] = get_ptr(seed);
1230  std::vector<bvec_t> sens(nz_out, 0);
1231  res[oind] = get_ptr(sens);
1232  if (!fwd) std::swap(seed, sens);
1233 
1234  // Number of forward sweeps we must make
1235  casadi_int nsweep = seed.size() / bvec_size;
1236  if (seed.size() % bvec_size) nsweep++;
1237 
1238  // Print
1239  if (verbose_) {
1240  casadi_message(str(nsweep) + std::string(fwd ? " forward" : " reverse") + " sweeps "
1241  "needed for " + str(seed.size()) + " directions");
1242  }
1243 
1244  // Progress
1245  casadi_int progress = -10;
1246 
1247  // Temporary vectors
1248  std::vector<casadi_int> jcol, jrow;
1249 
1250  // Loop over the variables, bvec_size variables at a time
1251  for (casadi_int s=0; s<nsweep; ++s) {
1252 
1253  // Print progress
1254  if (verbose_) {
1255  casadi_int progress_new = (s*100)/nsweep;
1256  // Print when entering a new decade
1257  if (progress_new / 10 > progress / 10) {
1258  progress = progress_new;
1259  casadi_message(str(progress) + " %");
1260  }
1261  }
1262 
1263  // Nonzero offset
1264  casadi_int offset = s*bvec_size;
1265 
1266  // Number of local seed directions
1267  casadi_int ndir_local = seed.size()-offset;
1268  ndir_local = std::min(static_cast<casadi_int>(bvec_size), ndir_local);
1269 
1270  for (casadi_int i=0; i<ndir_local; ++i) {
1271  seed[offset+i] |= bvec_t(1)<<i;
1272  }
1273 
1274  // Propagate the dependencies
1275  JacSparsityTraits<fwd>::sp(this, get_ptr(arg), get_ptr(res),
1276  get_ptr(iw), get_ptr(w), memory(0));
1277 
1278  // Loop over the nonzeros of the output
1279  for (casadi_int el=0; el<sens.size(); ++el) {
1280 
1281  // Get the sparsity sensitivity
1282  bvec_t spsens = sens[el];
1283 
1284  if (!fwd) {
1285  // Clear the sensitivities for the next sweep
1286  sens[el] = 0;
1287  }
1288 
1289  // If there is a dependency in any of the directions
1290  if (spsens!=0) {
1291 
1292  // Loop over seed directions
1293  for (casadi_int i=0; i<ndir_local; ++i) {
1294 
1295  // If dependents on the variable
1296  if ((bvec_t(1) << i) & spsens) {
1297  // Add to pattern
1298  jcol.push_back(el);
1299  jrow.push_back(i+offset);
1300  }
1301  }
1302  }
1303  }
1304 
1305  // Remove the seeds
1306  for (casadi_int i=0; i<ndir_local; ++i) {
1307  seed[offset+i] = 0;
1308  }
1309  }
1310 
1311  // Construct sparsity pattern and return
1312  if (!fwd) swap(jrow, jcol);
1313  Sparsity ret = Sparsity::triplet(nz_out, nz_in, jcol, jrow);
1314  if (verbose_) {
1315  casadi_message("Formed Jacobian sparsity pattern (dimension " + str(ret.size()) + ", "
1316  + str(ret.nnz()) + " (" + str(ret.density()) + " %) nonzeros.");
1317  }
1318  return ret;
1319  }
static Sparsity triplet(casadi_int nrow, casadi_int ncol, const std::vector< casadi_int > &row, const std::vector< casadi_int > &col, std::vector< casadi_int > &mapping, bool invert_mapping)
Create a sparsity pattern given the nonzeros in sparse triplet form *.
Definition: sparsity.cpp:1127

References casadi::bvec_size, casadi::Sparsity::density(), casadi::get_ptr(), casadi::ProtoFunction::memory(), casadi::Sparsity::nnz(), casadi::FunctionInternal::nnz_in(), casadi::FunctionInternal::nnz_out(), casadi::FunctionInternal::nz_in(), casadi::FunctionInternal::nz_out(), casadi::Sparsity::size(), casadi::str(), casadi::FunctionInternal::sz_arg(), casadi::FunctionInternal::sz_iw(), casadi::FunctionInternal::sz_res(), casadi::FunctionInternal::sz_w(), casadi::Sparsity::triplet(), and casadi::ProtoFunction::verbose_.

◆ get_jac_sparsity_hierarchical()

Sparsity casadi::FunctionInternal::get_jac_sparsity_hierarchical ( casadi_int  oind,
casadi_int  iind 
) const
inherited

Decide which ad_mode to take

Definition at line 1556 of file function_internal.cpp.

1556  {
1557  // Number of nonzero inputs
1558  casadi_int nz_in = nnz_in(iind);
1559 
1560  // Number of nonzero outputs
1561  casadi_int nz_out = nnz_out(oind);
1562 
1563  // Seeds and sensitivities
1564  std::vector<bvec_t> s_in(nz_in, 0);
1565  std::vector<bvec_t> s_out(nz_out, 0);
1566 
1567  // Evaluation buffers
1568  std::vector<const bvec_t*> arg_fwd(sz_arg(), nullptr);
1569  std::vector<bvec_t*> arg_adj(sz_arg(), nullptr);
1570  arg_fwd[iind] = arg_adj[iind] = get_ptr(s_in);
1571  std::vector<bvec_t*> res(sz_res(), nullptr);
1572  res[oind] = get_ptr(s_out);
1573  std::vector<casadi_int> iw(sz_iw());
1574  std::vector<bvec_t> w(sz_w());
1575 
1576  // Sparsity triplet accumulator
1577  std::vector<casadi_int> jcol, jrow;
1578 
1579  // Cols of the coarse blocks
1580  std::vector<casadi_int> coarse_col(2, 0); coarse_col[1] = nz_out;
1581  // Rows of the coarse blocks
1582  std::vector<casadi_int> coarse_row(2, 0); coarse_row[1] = nz_in;
1583 
1584  // Cols of the fine blocks
1585  std::vector<casadi_int> fine_col;
1586 
1587  // Rows of the fine blocks
1588  std::vector<casadi_int> fine_row;
1589 
1590  // In each iteration, subdivide each coarse block in this many fine blocks
1591  casadi_int subdivision = bvec_size;
1592 
1593  Sparsity r = Sparsity::dense(1, 1);
1594 
1595  // The size of a block
1596  casadi_int granularity_row = nz_in;
1597  casadi_int granularity_col = nz_out;
1598 
1599  bool use_fwd = true;
1600 
1601  casadi_int nsweeps = 0;
1602 
1603  bool hasrun = false;
1604 
1605  // Get weighting factor
1606  double sp_w = sp_weight();
1607 
1608  // Lookup table for bvec_t
1609  std::vector<bvec_t> bvec_lookup;
1610  bvec_lookup.reserve(bvec_size);
1611  for (casadi_int i=0;i<bvec_size;++i) {
1612  bvec_lookup.push_back(bvec_t(1) << i);
1613  }
1614 
1615  while (!hasrun || coarse_col.size()!=nz_out+1 || coarse_row.size()!=nz_in+1) {
1616  if (verbose_) {
1617  casadi_message("Block size: " + str(granularity_col) + " x " + str(granularity_row));
1618  }
1619 
1620  // Clear the sparsity triplet acccumulator
1621  jcol.clear();
1622  jrow.clear();
1623 
1624  // Clear the fine block structure
1625  fine_row.clear();
1626  fine_col.clear();
1627 
1628  // r transpose will be needed in the algorithm
1629  Sparsity rT = r.T();
1630 
1633  // Forward mode
1634  Sparsity D1 = rT.uni_coloring(r);
1635  // Adjoint mode
1636  Sparsity D2 = r.uni_coloring(rT);
1637  if (verbose_) {
1638  casadi_message("Coloring on " + str(r.dim()) + " (fwd seeps: " + str(D1.size2()) +
1639  " , adj sweeps: " + str(D2.size1()) + ")");
1640  }
1641 
1642  // Use whatever required less colors if we tried both (with preference to forward mode)
1643  double fwd_cost = static_cast<double>(use_fwd ? granularity_row : granularity_col) *
1644  sp_w*static_cast<double>(D1.size2());
1645  double adj_cost = static_cast<double>(use_fwd ? granularity_col : granularity_row) *
1646  (1-sp_w)*static_cast<double>(D2.size2());
1647  use_fwd = fwd_cost <= adj_cost;
1648  if (verbose_) {
1649  casadi_message(std::string(use_fwd ? "Forward" : "Reverse") + " mode chosen "
1650  "(fwd cost: " + str(fwd_cost) + ", adj cost: " + str(adj_cost) + ")");
1651  }
1652 
1653  // Get seeds and sensitivities
1654  bvec_t* seed_v = use_fwd ? get_ptr(s_in) : get_ptr(s_out);
1655  bvec_t* sens_v = use_fwd ? get_ptr(s_out) : get_ptr(s_in);
1656 
1657  // The number of zeros in the seed and sensitivity directions
1658  casadi_int nz_seed = use_fwd ? nz_in : nz_out;
1659  casadi_int nz_sens = use_fwd ? nz_out : nz_in;
1660 
1661  // Clear the seeds
1662  for (casadi_int i=0; i<nz_seed; ++i) seed_v[i]=0;
1663 
1664  // Choose the active jacobian coloring scheme
1665  Sparsity D = use_fwd ? D1 : D2;
1666 
1667  // Adjoint mode amounts to swapping
1668  if (!use_fwd) {
1669  std::swap(coarse_col, coarse_row);
1670  std::swap(granularity_col, granularity_row);
1671  std::swap(r, rT);
1672  }
1673 
1674  // Subdivide the coarse block cols
1675  for (casadi_int k=0;k<coarse_col.size()-1;++k) {
1676  casadi_int diff = coarse_col[k+1]-coarse_col[k];
1677  casadi_int new_diff = diff/subdivision;
1678  if (diff%subdivision>0) new_diff++;
1679  std::vector<casadi_int> temp = range(coarse_col[k], coarse_col[k+1], new_diff);
1680  fine_col.insert(fine_col.end(), temp.begin(), temp.end());
1681  }
1682  // Subdivide the coarse block rows
1683  for (casadi_int k=0;k<coarse_row.size()-1;++k) {
1684  casadi_int diff = coarse_row[k+1]-coarse_row[k];
1685  casadi_int new_diff = diff/subdivision;
1686  if (diff%subdivision>0) new_diff++;
1687  std::vector<casadi_int> temp = range(coarse_row[k], coarse_row[k+1], new_diff);
1688  fine_row.insert(fine_row.end(), temp.begin(), temp.end());
1689  }
1690  if (fine_row.back()!=coarse_row.back()) fine_row.push_back(coarse_row.back());
1691  if (fine_col.back()!=coarse_col.back()) fine_col.push_back(coarse_col.back());
1692 
1693  granularity_col = fine_col[1] - fine_col[0];
1694  granularity_row = fine_row[1] - fine_row[0];
1695 
1696  // The index into the bvec bit vector
1697  casadi_int bvec_i = 0;
1698 
1699  // Create lookup tables for the fine blocks
1700  std::vector<casadi_int> fine_col_lookup = lookupvector(fine_col, nz_sens+1);
1701  std::vector<casadi_int> fine_row_lookup = lookupvector(fine_row, nz_seed+1);
1702 
1703  // Triplet data used as a lookup table
1704  std::vector<casadi_int> lookup_col;
1705  std::vector<casadi_int> lookup_row;
1706  std::vector<casadi_int> lookup_value;
1707 
1708 
1709  // The maximum number of fine blocks contained in one coarse block
1710  casadi_int n_fine_blocks_max = 0;
1711  for (casadi_int i=0;i<coarse_row.size()-1;++i) {
1712  casadi_int del = fine_row_lookup[coarse_row[i+1]]-fine_row_lookup[coarse_row[i]];
1713  n_fine_blocks_max = std::max(n_fine_blocks_max, del);
1714  }
1715 
1716  // Loop over all coarse seed directions from the coloring
1717  for (casadi_int csd=0; csd<D.size2(); ++csd) {
1718 
1719  casadi_int fci_offset = 0;
1720  casadi_int fci_cap = bvec_size-bvec_i;
1721 
1722  // Flag to indicate if all fine blocks have been handled
1723  bool f_finished = false;
1724 
1725  // Loop while not finished
1726  while (!f_finished) {
1727 
1728  // Loop over all coarse rows that are found in the coloring for this coarse seed direction
1729  for (casadi_int k=D.colind(csd); k<D.colind(csd+1); ++k) {
1730  casadi_int cci = D.row(k);
1731 
1732  // The first and last rows of the fine block
1733  casadi_int fci_start = fine_row_lookup[coarse_row[cci]];
1734  casadi_int fci_end = fine_row_lookup[coarse_row[cci+1]];
1735 
1736  // Local counter that modifies index into bvec
1737  casadi_int bvec_i_mod = 0;
1738 
1739  casadi_int value = -bvec_i + fci_offset + fci_start;
1740 
1741  // Loop over the rows of the fine block
1742  for (casadi_int fci = fci_offset; fci < std::min(fci_end-fci_start, fci_cap); ++fci) {
1743 
1744  // Loop over the coarse block cols that appear in the coloring
1745  // for the current coarse seed direction
1746  for (casadi_int cri=rT.colind(cci);cri<rT.colind(cci+1);++cri) {
1747  lookup_col.push_back(rT.row(cri));
1748  lookup_row.push_back(bvec_i+bvec_i_mod);
1749  lookup_value.push_back(value);
1750  }
1751 
1752  // Toggle on seeds
1753  bvec_toggle(seed_v, fine_row[fci+fci_start], fine_row[fci+fci_start+1],
1754  bvec_i+bvec_i_mod);
1755  bvec_i_mod++;
1756  }
1757  }
1758 
1759  // Bump bvec_i for next major coarse direction
1760  bvec_i+= std::min(n_fine_blocks_max, fci_cap);
1761 
1762  // Check if bvec buffer is full
1763  if (bvec_i==bvec_size || csd==D.size2()-1) {
1764  // Calculate sparsity for bvec_size directions at once
1765 
1766  // Statistics
1767  nsweeps+=1;
1768 
1769  // Construct lookup table
1770  IM lookup = IM::triplet(lookup_row, lookup_col, lookup_value, bvec_size,
1771  coarse_col.size());
1772 
1773  // Propagate the dependencies
1774  if (use_fwd) {
1775  JacSparsityTraits<true>::sp(this, get_ptr(arg_fwd), get_ptr(res),
1776  get_ptr(iw), get_ptr(w), memory(0));
1777  } else {
1778  std::fill(w.begin(), w.end(), 0);
1779  JacSparsityTraits<false>::sp(this, get_ptr(arg_adj), get_ptr(res),
1780  get_ptr(iw), get_ptr(w), memory(0));
1781  }
1782 
1783  // Temporary bit work vector
1784  bvec_t spsens;
1785 
1786  // Loop over the cols of coarse blocks
1787  for (casadi_int cri=0;cri<coarse_col.size()-1;++cri) {
1788 
1789  // Loop over the cols of fine blocks within the current coarse block
1790  for (casadi_int fri=fine_col_lookup[coarse_col[cri]];
1791  fri<fine_col_lookup[coarse_col[cri+1]];++fri) {
1792  // Lump individual sensitivities together into fine block
1793  bvec_or(sens_v, spsens, fine_col[fri], fine_col[fri+1]);
1794 
1795  // Next iteration if no sparsity
1796  if (!spsens) continue;
1797 
1798  // Loop over all bvec_bits
1799  for (casadi_int bvec_i=0;bvec_i<bvec_size;++bvec_i) {
1800  if (spsens & bvec_lookup[bvec_i]) {
1801  // if dependency is found, add it to the new sparsity pattern
1802  casadi_int ind = lookup.sparsity().get_nz(bvec_i, cri);
1803  if (ind==-1) continue;
1804  jrow.push_back(bvec_i+lookup->at(ind));
1805  jcol.push_back(fri);
1806  }
1807  }
1808  }
1809  }
1810 
1811  // Clear the forward seeds/adjoint sensitivities, ready for next bvec sweep
1812  std::fill(s_in.begin(), s_in.end(), 0);
1813 
1814  // Clear the adjoint seeds/forward sensitivities, ready for next bvec sweep
1815  std::fill(s_out.begin(), s_out.end(), 0);
1816 
1817  // Clean lookup table
1818  lookup_col.clear();
1819  lookup_row.clear();
1820  lookup_value.clear();
1821  }
1822 
1823  if (n_fine_blocks_max>fci_cap) {
1824  fci_offset += std::min(n_fine_blocks_max, fci_cap);
1825  bvec_i = 0;
1826  fci_cap = bvec_size;
1827  } else {
1828  f_finished = true;
1829  }
1830 
1831  }
1832 
1833  }
1834 
1835  // Swap results if adjoint mode was used
1836  if (use_fwd) {
1837  // Construct fine sparsity pattern
1838  r = Sparsity::triplet(fine_row.size()-1, fine_col.size()-1, jrow, jcol);
1839  coarse_col = fine_col;
1840  coarse_row = fine_row;
1841  } else {
1842  // Construct fine sparsity pattern
1843  r = Sparsity::triplet(fine_col.size()-1, fine_row.size()-1, jcol, jrow);
1844  coarse_col = fine_row;
1845  coarse_row = fine_col;
1846  }
1847  hasrun = true;
1848  }
1849  if (verbose_) {
1850  casadi_message("Number of sweeps: " + str(nsweeps));
1851  casadi_message("Formed Jacobian sparsity pattern (dimension " + str(r.size()) + ", " +
1852  str(r.nnz()) + " (" + str(r.density()) + " %) nonzeros.");
1853  }
1854 
1855  return r.T();
1856  }
static Matrix< casadi_int > triplet(const std::vector< casadi_int > &row, const std::vector< casadi_int > &col, const Matrix< casadi_int > &d)
Construct a sparse matrix from triplet form.
static Sparsity dense(casadi_int nrow, casadi_int ncol=1)
Create a dense rectangular sparsity pattern *.
Definition: sparsity.cpp:1012
std::vector< casadi_int > range(casadi_int start, casadi_int stop, casadi_int step, casadi_int len)
Range function.
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.
Matrix< casadi_int > IM
Definition: im_fwd.hpp:31
std::vector< T > diff(const std::vector< T > &values)
diff
bvec_t bvec_or(const bvec_t *arg, casadi_int n)
Bit-wise or operation on bvec_t array.
void bvec_toggle(bvec_t *s, casadi_int begin, casadi_int end, casadi_int j)

References casadi::bvec_or(), casadi::bvec_size, casadi::bvec_toggle(), casadi::Sparsity::colind(), casadi::D, casadi::Sparsity::dense(), casadi::Sparsity::density(), casadi::diff(), casadi::Sparsity::dim(), casadi::Sparsity::get_nz(), casadi::get_ptr(), casadi::lookupvector(), casadi::ProtoFunction::memory(), casadi::Sparsity::nnz(), casadi::FunctionInternal::nnz_in(), casadi::FunctionInternal::nnz_out(), casadi::FunctionInternal::nz_in(), casadi::FunctionInternal::nz_out(), casadi::range(), casadi::Sparsity::row(), casadi::Sparsity::size(), casadi::Sparsity::size1(), casadi::Sparsity::size2(), casadi::FunctionInternal::sp_weight(), casadi::Matrix< Scalar >::sparsity(), casadi::str(), casadi::FunctionInternal::sz_arg(), casadi::FunctionInternal::sz_iw(), casadi::FunctionInternal::sz_res(), casadi::FunctionInternal::sz_w(), casadi::Sparsity::T(), casadi::Sparsity::triplet(), casadi::Matrix< casadi_int >::triplet(), casadi::Sparsity::uni_coloring(), and casadi::ProtoFunction::verbose_.

Referenced by casadi::FunctionInternal::get_jac_sparsity().

◆ get_jac_sparsity_hierarchical_symm()

Sparsity casadi::FunctionInternal::get_jac_sparsity_hierarchical_symm ( casadi_int  oind,
casadi_int  iind 
) const
inherited

A flavor of get_jac_sparsity_gen that does hierarchical block structure recognition for symmetric Jacobians

Definition at line 1321 of file function_internal.cpp.

1322  {
1323  casadi_assert_dev(has_spfwd());
1324 
1325  // Number of nonzero inputs
1326  casadi_int nz = nnz_in(iind);
1327  casadi_assert_dev(nz==nnz_out(oind));
1328 
1329  // Evaluation buffers
1330  std::vector<const bvec_t*> arg(sz_arg(), nullptr);
1331  std::vector<bvec_t*> res(sz_res(), nullptr);
1332  std::vector<casadi_int> iw(sz_iw());
1333  std::vector<bvec_t> w(sz_w());
1334 
1335  // Seeds
1336  std::vector<bvec_t> seed(nz, 0);
1337  arg[iind] = get_ptr(seed);
1338 
1339  // Sensitivities
1340  std::vector<bvec_t> sens(nz, 0);
1341  res[oind] = get_ptr(sens);
1342 
1343  // Sparsity triplet accumulator
1344  std::vector<casadi_int> jcol, jrow;
1345 
1346  // Cols/rows of the coarse blocks
1347  std::vector<casadi_int> coarse(2, 0); coarse[1] = nz;
1348 
1349  // Cols/rows of the fine blocks
1350  std::vector<casadi_int> fine;
1351 
1352  // In each iteration, subdivide each coarse block in this many fine blocks
1353  casadi_int subdivision = bvec_size;
1354 
1355  Sparsity r = Sparsity::dense(1, 1);
1356 
1357  // The size of a block
1358  casadi_int granularity = nz;
1359 
1360  casadi_int nsweeps = 0;
1361 
1362  bool hasrun = false;
1363 
1364  while (!hasrun || coarse.size()!=nz+1) {
1365  if (verbose_) casadi_message("Block size: " + str(granularity));
1366 
1367  // Clear the sparsity triplet acccumulator
1368  jcol.clear();
1369  jrow.clear();
1370 
1371  // Clear the fine block structure
1372  fine.clear();
1373 
1374  Sparsity D = r.star_coloring();
1375 
1376  if (verbose_) {
1377  casadi_message("Star coloring on " + str(r.dim()) + ": "
1378  + str(D.size2()) + " <-> " + str(D.size1()));
1379  }
1380 
1381  // Clear the seeds
1382  std::fill(seed.begin(), seed.end(), 0);
1383 
1384  // Subdivide the coarse block
1385  for (casadi_int k=0; k<coarse.size()-1; ++k) {
1386  casadi_int diff = coarse[k+1]-coarse[k];
1387  casadi_int new_diff = diff/subdivision;
1388  if (diff%subdivision>0) new_diff++;
1389  std::vector<casadi_int> temp = range(coarse[k], coarse[k+1], new_diff);
1390  fine.insert(fine.end(), temp.begin(), temp.end());
1391  }
1392  if (fine.back()!=coarse.back()) fine.push_back(coarse.back());
1393 
1394  granularity = fine[1] - fine[0];
1395 
1396  // The index into the bvec bit vector
1397  casadi_int bvec_i = 0;
1398 
1399  // Create lookup tables for the fine blocks
1400  std::vector<casadi_int> fine_lookup = lookupvector(fine, nz+1);
1401 
1402  // Triplet data used as a lookup table
1403  std::vector<casadi_int> lookup_col;
1404  std::vector<casadi_int> lookup_row;
1405  std::vector<casadi_int> lookup_value;
1406 
1407  // The maximum number of fine blocks contained in one coarse block
1408  casadi_int n_fine_blocks_max = 0;
1409  for (casadi_int i=0;i<coarse.size()-1;++i) {
1410  casadi_int del = fine_lookup[coarse[i+1]]-fine_lookup[coarse[i]];
1411  n_fine_blocks_max = std::max(n_fine_blocks_max, del);
1412  }
1413 
1414  // Loop over all coarse seed directions from the coloring
1415  for (casadi_int csd=0; csd<D.size2(); ++csd) {
1416 
1417 
1418  casadi_int fci_offset = 0;
1419  casadi_int fci_cap = bvec_size-bvec_i;
1420 
1421  // Flag to indicate if all fine blocks have been handled
1422  bool f_finished = false;
1423 
1424  // Loop while not finished
1425  while (!f_finished) {
1426 
1427  // Loop over all coarse rows that are found in the coloring for this coarse seed direction
1428  for (casadi_int k=D.colind(csd); k<D.colind(csd+1); ++k) {
1429  casadi_int cci = D.row(k);
1430 
1431  // The first and last rows of the fine block
1432  casadi_int fci_start = fine_lookup[coarse[cci]];
1433  casadi_int fci_end = fine_lookup[coarse[cci+1]];
1434 
1435  // Local counter that modifies index into bvec
1436  casadi_int bvec_i_mod = 0;
1437 
1438  casadi_int value = -bvec_i + fci_offset + fci_start;
1439 
1440  //casadi_assert_dev(value>=0);
1441 
1442  // Loop over the rows of the fine block
1443  for (casadi_int fci = fci_offset; fci<std::min(fci_end-fci_start, fci_cap); ++fci) {
1444 
1445  // Loop over the coarse block cols that appear in the
1446  // coloring for the current coarse seed direction
1447  for (casadi_int cri=r.colind(cci);cri<r.colind(cci+1);++cri) {
1448  lookup_col.push_back(r.row(cri));
1449  lookup_row.push_back(bvec_i+bvec_i_mod);
1450  lookup_value.push_back(value);
1451  }
1452 
1453  // Toggle on seeds
1454  bvec_toggle(get_ptr(seed), fine[fci+fci_start], fine[fci+fci_start+1],
1455  bvec_i+bvec_i_mod);
1456  bvec_i_mod++;
1457  }
1458  }
1459 
1460  // Bump bvec_i for next major coarse direction
1461  bvec_i += std::min(n_fine_blocks_max, fci_cap);
1462 
1463  // Check if bvec buffer is full
1464  if (bvec_i==bvec_size || csd==D.size2()-1) {
1465  // Calculate sparsity for bvec_size directions at once
1466 
1467  // Statistics
1468  nsweeps+=1;
1469 
1470  // Construct lookup table
1471  IM lookup = IM::triplet(lookup_row, lookup_col, lookup_value,
1472  bvec_size, coarse.size());
1473 
1474  std::reverse(lookup_col.begin(), lookup_col.end());
1475  std::reverse(lookup_row.begin(), lookup_row.end());
1476  std::reverse(lookup_value.begin(), lookup_value.end());
1477  IM duplicates =
1478  IM::triplet(lookup_row, lookup_col, lookup_value, bvec_size, coarse.size())
1479  - lookup;
1480  duplicates = sparsify(duplicates);
1481  lookup(duplicates.sparsity()) = -bvec_size;
1482 
1483  // Propagate the dependencies
1484  JacSparsityTraits<true>::sp(this, get_ptr(arg), get_ptr(res),
1485  get_ptr(iw), get_ptr(w), nullptr);
1486 
1487  // Temporary bit work vector
1488  bvec_t spsens;
1489 
1490  // Loop over the cols of coarse blocks
1491  for (casadi_int cri=0; cri<coarse.size()-1; ++cri) {
1492 
1493  // Loop over the cols of fine blocks within the current coarse block
1494  for (casadi_int fri=fine_lookup[coarse[cri]];fri<fine_lookup[coarse[cri+1]];++fri) {
1495  // Lump individual sensitivities together into fine block
1496  bvec_or(get_ptr(sens), spsens, fine[fri], fine[fri+1]);
1497 
1498  // Loop over all bvec_bits
1499  for (casadi_int bvec_i=0;bvec_i<bvec_size;++bvec_i) {
1500  if (spsens & (bvec_t(1) << bvec_i)) {
1501  // if dependency is found, add it to the new sparsity pattern
1502  casadi_int ind = lookup.sparsity().get_nz(bvec_i, cri);
1503  if (ind==-1) continue;
1504  casadi_int lk = lookup->at(ind);
1505  if (lk>-bvec_size) {
1506  jrow.push_back(bvec_i+lk);
1507  jcol.push_back(fri);
1508  jrow.push_back(fri);
1509  jcol.push_back(bvec_i+lk);
1510  }
1511  }
1512  }
1513  }
1514  }
1515 
1516  // Clear the forward seeds/adjoint sensitivities, ready for next bvec sweep
1517  std::fill(seed.begin(), seed.end(), 0);
1518 
1519  // Clean lookup table
1520  lookup_col.clear();
1521  lookup_row.clear();
1522  lookup_value.clear();
1523  }
1524 
1525  if (n_fine_blocks_max>fci_cap) {
1526  fci_offset += std::min(n_fine_blocks_max, fci_cap);
1527  bvec_i = 0;
1528  fci_cap = bvec_size;
1529  } else {
1530  f_finished = true;
1531  }
1532  }
1533  }
1534 
1535  // Construct fine sparsity pattern
1536  r = Sparsity::triplet(fine.size()-1, fine.size()-1, jrow, jcol);
1537 
1538  // There may be false positives here that are not present
1539  // in the reverse mode that precedes it.
1540  // This can lead to an assymetrical result
1541  // cf. #1522
1542  r=r*r.T();
1543 
1544  coarse = fine;
1545  hasrun = true;
1546  }
1547  if (verbose_) {
1548  casadi_message("Number of sweeps: " + str(nsweeps));
1549  casadi_message("Formed Jacobian sparsity pattern (dimension " + str(r.size()) +
1550  ", " + str(r.nnz()) + " (" + str(r.density()) + " %) nonzeros.");
1551  }
1552 
1553  return r.T();
1554  }

References casadi::bvec_or(), casadi::bvec_size, casadi::bvec_toggle(), casadi::Sparsity::colind(), casadi::D, casadi::Sparsity::dense(), casadi::Sparsity::density(), casadi::diff(), casadi::Sparsity::dim(), casadi::Sparsity::get_nz(), casadi::get_ptr(), casadi::FunctionInternal::has_spfwd(), casadi::lookupvector(), casadi::Sparsity::nnz(), casadi::FunctionInternal::nnz_in(), casadi::FunctionInternal::nnz_out(), casadi::range(), casadi::Sparsity::row(), casadi::Sparsity::size(), casadi::Matrix< Scalar >::sparsity(), casadi::Sparsity::star_coloring(), casadi::str(), casadi::FunctionInternal::sz_arg(), casadi::FunctionInternal::sz_iw(), casadi::FunctionInternal::sz_res(), casadi::FunctionInternal::sz_w(), casadi::Sparsity::T(), casadi::Sparsity::triplet(), casadi::Matrix< casadi_int >::triplet(), and casadi::ProtoFunction::verbose_.

Referenced by casadi::FunctionInternal::get_jac_sparsity().

◆ get_jacobian()

Function casadi::XFunction< SXFunction , Matrix< SXElem > , SXNode >::get_jacobian ( const std::string &  name,
const std::vector< std::string > &  inames,
const std::vector< std::string > &  onames,
const Dict opts 
) const
overridevirtualinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_xx

Reimplemented from casadi::FunctionInternal.

Definition at line 151 of file x_function.hpp.

925  {
926  try {
927  Dict tmp_options = generate_options("tmp");
928  tmp_options["allow_free"] = true;
929  tmp_options["allow_duplicate_io_names"] = true;
930  // Temporary single-input, single-output function FIXME(@jaeandersson)
931  Function tmp("flattened_" + name, {veccat(in_)}, {veccat(out_)}, tmp_options);
932 
933  // Expression for the extended Jacobian
934  MatType J = tmp.get<DerivedType>()->jac(Dict()).at(0);
935 
936  // Split up extended Jacobian
937  std::vector<casadi_int> r_offset = {0}, c_offset = {0};
938  for (auto& e : out_) r_offset.push_back(r_offset.back() + e.numel());
939  for (auto& e : in_) c_offset.push_back(c_offset.back() + e.numel());
940  auto Jblocks = MatType::blocksplit(J, r_offset, c_offset);
941 
942  // Collect all outputs
943  std::vector<MatType> ret_out;
944  ret_out.reserve(onames.size());
945  for (casadi_int i = 0; i < n_out_; ++i) {
946  for (casadi_int j = 0; j < n_in_; ++j) {
947  MatType b = Jblocks.at(i).at(j);
948  if (!is_diff_out_.at(i) || !is_diff_in_.at(j)) {
949  b = MatType(b.size());
950  }
951  ret_out.push_back(b);
952  }
953  }
954 
955  // All inputs of the return function
956  std::vector<MatType> ret_in(inames.size());
957  std::copy(in_.begin(), in_.end(), ret_in.begin());
958  for (casadi_int i=0; i<n_out_; ++i) {
959  ret_in.at(n_in_+i) = MatType::sym(inames[n_in_+i], Sparsity(out_.at(i).size()));
960  }
961 
962  Dict options = opts;
963  options["allow_free"] = true;
964  options["allow_duplicate_io_names"] = true;
965 
966  // Assemble function and return
967  return Function(name, ret_in, ret_out, inames, onames, options);
968  } catch (std::exception& e) {
969  CASADI_THROW_ERROR("get_jacobian", e.what());
970  }
971  }
std::vector< Matrix< SXElem > > jac(const Dict &opts) const
Construct a complete Jacobian by compression.
Definition: x_function.hpp:425

◆ get_max_in()

virtual double casadi::FunctionInternal::get_max_in ( casadi_int  ind) const
inlinevirtualinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_mm

Definition at line 1070 of file function_internal.hpp.

1070  {
1071  return inf;
1072  }
const double inf
infinity
Definition: calculus.hpp:50

References casadi::inf.

◆ get_min_in()

virtual double casadi::FunctionInternal::get_min_in ( casadi_int  ind) const
inlinevirtualinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_mn

Definition at line 1077 of file function_internal.hpp.

1077  {
1078  return -inf;
1079  }

References casadi::inf.

◆ get_n_in()

size_t casadi::XFunction< SXFunction , Matrix< SXElem > , SXNode >::get_n_in ( )
inlineoverridevirtualinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_y7

Reimplemented from casadi::FunctionInternal.

Definition at line 220 of file x_function.hpp.

220 { return in_.size(); }

◆ get_n_out()

size_t casadi::XFunction< SXFunction , Matrix< SXElem > , SXNode >::get_n_out ( )
inlineoverridevirtualinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_y7

Reimplemented from casadi::FunctionInternal.

Definition at line 221 of file x_function.hpp.

221 { return out_.size(); }

◆ get_name_in()

std::string casadi::FunctionInternal::get_name_in ( casadi_int  i)
virtualinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_mk

Reimplemented in casadi::Rootfinder, casadi::Nlpsol, casadi::MapSum, casadi::Map, casadi::Interpolant, casadi::Integrator, casadi::FiniteDiff, casadi::External, casadi::Dple, casadi::Conic, casadi::CallbackInternal, and casadi::BlazingSplineFunction.

Definition at line 667 of file function_internal.cpp.

667  {
668  if (!derivative_of_.is_null()) {
669  std::string n = derivative_of_.name();
670  if (name_ == "jac_" + n || name_ == "adj1_" + n) {
671  if (i < derivative_of_.n_in()) {
672  // Same as nondifferentiated function
673  return derivative_of_.name_in(i);
674  } else if (i < derivative_of_.n_in() + derivative_of_.n_out()) {
675  // Nondifferentiated output
676  return "out_" + derivative_of_.name_out(i - derivative_of_.n_in());
677  } else {
678  // Adjoint seed
679  return "adj_" + derivative_of_.name_out(i - derivative_of_.n_in()
680  - derivative_of_.n_out());
681  }
682  }
683  }
684  // Default name
685  return "i" + str(i);
686  }
Function derivative_of_
If the function is the derivative of another function.
const std::vector< std::string > & name_in() const
Get input scheme.
Definition: function.cpp:961
const std::string & name() const
Name of the function.
Definition: function.cpp:1315
casadi_int n_out() const
Get the number of function outputs.
Definition: function.cpp:823
casadi_int n_in() const
Get the number of function inputs.
Definition: function.cpp:819
const std::vector< std::string > & name_out() const
Get output scheme.
Definition: function.cpp:965

References casadi::FunctionInternal::derivative_of_, casadi::GenericShared< Shared, Internal >::is_null(), casadi::Function::n_in(), casadi::Function::n_out(), casadi::Function::name(), casadi::ProtoFunction::name_, casadi::Function::name_in(), casadi::Function::name_out(), and casadi::str().

Referenced by casadi::External::get_name_in(), and casadi::FunctionInternal::init().

◆ get_name_out()

std::string casadi::FunctionInternal::get_name_out ( casadi_int  i)
virtualinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_mk

Reimplemented in casadi::Rootfinder, casadi::Nlpsol, casadi::MapSum, casadi::Map, casadi::Interpolant, casadi::Integrator, casadi::FiniteDiff, casadi::External, casadi::Dple, casadi::Conic, casadi::CallbackInternal, and casadi::BlazingSplineFunction.

Definition at line 688 of file function_internal.cpp.

688  {
689  if (!derivative_of_.is_null()) {
690  std::string n = derivative_of_.name();
691  if (name_ == "jac_" + n) {
692  // Jacobian block
693  casadi_int oind = i / derivative_of_.n_in(), iind = i % derivative_of_.n_in();
694  return "jac_" + derivative_of_.name_out(oind) + "_" + derivative_of_.name_in(iind);
695  } else if (name_ == "adj1_" + n) {
696  // Adjoint sensitivity
697  return "adj_" + derivative_of_.name_in(i);
698  }
699  }
700  // Default name
701  return "o" + str(i);
702  }

References casadi::FunctionInternal::derivative_of_, casadi::GenericShared< Shared, Internal >::is_null(), casadi::Function::n_in(), casadi::Function::name(), casadi::ProtoFunction::name_, casadi::Function::name_in(), casadi::Function::name_out(), and casadi::str().

Referenced by casadi::External::get_name_out(), and casadi::FunctionInternal::init().

◆ get_nominal_in()

virtual std::vector<double> casadi::FunctionInternal::get_nominal_in ( casadi_int  ind) const
inlinevirtualinherited

Reimplemented in casadi::FmuFunction.

Definition at line 1081 of file function_internal.hpp.

1081  {
1082  return std::vector<double>(nnz_in(ind), 1.);
1083  }

Referenced by casadi::FmuFunction::get_nominal_in().

◆ get_nominal_out()

virtual std::vector<double> casadi::FunctionInternal::get_nominal_out ( casadi_int  ind) const
inlinevirtualinherited

Reimplemented in casadi::FmuFunction.

Definition at line 1085 of file function_internal.hpp.

1085  {
1086  return std::vector<double>(nnz_out(ind), 1.);
1087  }

Referenced by casadi::FmuFunction::get_nominal_out().

◆ get_options()

const Options& casadi::SXFunction::get_options ( ) const
inlineoverridevirtual

Extra doc: https://github.com/casadi/casadi/wiki/L_v2

Reimplemented from casadi::FunctionInternal.

Definition at line 317 of file sx_function.hpp.

317 { return options_;}
static const Options options_
Options.

◆ get_partition()

void casadi::FunctionInternal::get_partition ( casadi_int  iind,
casadi_int  oind,
Sparsity D1,
Sparsity D2,
bool  compact,
bool  symmetric,
bool  allow_forward,
bool  allow_reverse 
) const
inherited

Extra doc: https://github.com/casadi/casadi/wiki/L_md

Definition at line 2011 of file function_internal.cpp.

2013  {
2014  if (verbose_) casadi_message(name_ + "::get_partition");
2015  casadi_assert(allow_forward || allow_reverse, "Inconsistent options");
2016 
2017  // Sparsity pattern with transpose
2018  Sparsity &AT = jac_sparsity(oind, iind, compact, symmetric);
2019  Sparsity A = symmetric ? AT : AT.T();
2020 
2021  // Get seed matrices by graph coloring
2022  if (symmetric) {
2023  casadi_assert_dev(enable_forward_ || enable_fd_);
2024  casadi_assert_dev(allow_forward);
2025 
2026  // Star coloring if symmetric
2027  if (verbose_) casadi_message("FunctionInternal::getPartition star_coloring");
2028  D1 = A.star_coloring();
2029  if (verbose_) {
2030  casadi_message("Star coloring completed: " + str(D1.size2())
2031  + " directional derivatives needed ("
2032  + str(A.size1()) + " without coloring).");
2033  }
2034 
2035  } else {
2036  casadi_assert_dev(enable_forward_ || enable_fd_ || enable_reverse_);
2037  // Get weighting factor
2038  double w = ad_weight();
2039 
2040  // Which AD mode?
2041  if (w==1) allow_forward = false;
2042  if (w==0) allow_reverse = false;
2043  casadi_assert(allow_forward || allow_reverse, "Conflicting ad weights");
2044 
2045  // Best coloring encountered so far (relatively tight upper bound)
2046  double best_coloring = std::numeric_limits<double>::infinity();
2047 
2048  // Test forward mode first?
2049  bool test_fwd_first = allow_forward && w*static_cast<double>(A.size1()) <=
2050  (1-w)*static_cast<double>(A.size2());
2051  casadi_int mode_fwd = test_fwd_first ? 0 : 1;
2052 
2053  // Test both coloring modes
2054  for (casadi_int mode=0; mode<2; ++mode) {
2055  // Is this the forward mode?
2056  bool fwd = mode==mode_fwd;
2057 
2058  // Skip?
2059  if (!allow_forward && fwd) continue;
2060  if (!allow_reverse && !fwd) continue;
2061 
2062  // Perform the coloring
2063  if (fwd) {
2064  if (verbose_) casadi_message("Unidirectional coloring (forward mode)");
2065  bool d = best_coloring>=w*static_cast<double>(A.size1());
2066  casadi_int max_colorings_to_test =
2067  d ? A.size1() : static_cast<casadi_int>(floor(best_coloring/w));
2068  D1 = AT.uni_coloring(A, max_colorings_to_test);
2069  if (D1.is_null()) {
2070  if (verbose_) {
2071  casadi_message("Forward mode coloring interrupted (more than "
2072  + str(max_colorings_to_test) + " needed).");
2073  }
2074  } else {
2075  if (verbose_) {
2076  casadi_message("Forward mode coloring completed: "
2077  + str(D1.size2()) + " directional derivatives needed ("
2078  + str(A.size1()) + " without coloring).");
2079  }
2080  D2 = Sparsity();
2081  best_coloring = w*static_cast<double>(D1.size2());
2082  }
2083  } else {
2084  if (verbose_) casadi_message("Unidirectional coloring (adjoint mode)");
2085  bool d = best_coloring>=(1-w)*static_cast<double>(A.size2());
2086  casadi_int max_colorings_to_test =
2087  d ? A.size2() : static_cast<casadi_int>(floor(best_coloring/(1-w)));
2088 
2089  D2 = A.uni_coloring(AT, max_colorings_to_test);
2090  if (D2.is_null()) {
2091  if (verbose_) {
2092  casadi_message("Adjoint mode coloring interrupted (more than "
2093  + str(max_colorings_to_test) + " needed).");
2094  }
2095  } else {
2096  if (verbose_) {
2097  casadi_message("Adjoint mode coloring completed: "
2098  + str(D2.size2()) + " directional derivatives needed ("
2099  + str(A.size2()) + " without coloring).");
2100  }
2101  D1 = Sparsity();
2102  best_coloring = (1-w)*static_cast<double>(D2.size2());
2103  }
2104  }
2105  }
2106 
2107  }
2108  }
Sparsity & jac_sparsity(casadi_int oind, casadi_int iind, bool compact, bool symmetric) const
Get Jacobian sparsity.

References casadi::FunctionInternal::ad_weight(), casadi::FunctionInternal::enable_fd_, casadi::FunctionInternal::enable_forward_, casadi::FunctionInternal::enable_reverse_, casadi::GenericShared< Shared, Internal >::is_null(), casadi::FunctionInternal::jac_sparsity(), casadi::ProtoFunction::name_, casadi::Sparsity::size1(), casadi::Sparsity::size2(), casadi::Sparsity::star_coloring(), casadi::str(), casadi::Sparsity::T(), casadi::Sparsity::uni_coloring(), and casadi::ProtoFunction::verbose_.

◆ get_reltol()

virtual double casadi::FunctionInternal::get_reltol ( ) const
inlinevirtualinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_mo

Reimplemented in casadi::SundialsInterface.

Definition at line 1092 of file function_internal.hpp.

1092  {
1093  return eps;
1094  }

References casadi::eps.

Referenced by casadi::FiniteDiff::init().

◆ get_reverse()

Function casadi::XFunction< SXFunction , Matrix< SXElem > , SXNode >::get_reverse ( casadi_int  nadj,
const std::string &  name,
const std::vector< std::string > &  inames,
const std::vector< std::string > &  onames,
const Dict opts 
) const
overridevirtualinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_xw

Reimplemented from casadi::FunctionInternal.

Definition at line 140 of file x_function.hpp.

873  {
874  try {
875  // Seeds
876  std::vector<std::vector<MatType> > aseed = symbolicAdjSeed(nadj, out_), asens;
877 
878  // Evaluate symbolically
879  static_cast<const DerivedType*>(this)->ad_reverse(aseed, asens);
880 
881  // All inputs of the return function
882  std::vector<MatType> ret_in(inames.size());
883  std::copy(in_.begin(), in_.end(), ret_in.begin());
884  for (casadi_int i=0; i<n_out_; ++i) {
885  ret_in.at(n_in_ + i) = MatType::sym(inames[n_in_+i], Sparsity(out_.at(i).size()));
886  }
887  std::vector<MatType> v(nadj);
888  for (casadi_int i=0; i<n_out_; ++i) {
889  for (casadi_int d=0; d<nadj; ++d) v[d] = aseed[d][i];
890  ret_in.at(n_in_ + n_out_ + i) = horzcat(v);
891  }
892 
893  // All outputs of the return function
894  std::vector<MatType> ret_out(onames.size());
895  for (casadi_int i=0; i<n_in_; ++i) {
896  if (is_diff_in_[i]) {
897  // Concatenate sensitivities, correct sparsity pattern if needed
898  for (casadi_int d=0; d<nadj; ++d) v[d] = asens[d][i];
899  ret_out.at(i) = ensure_stacked(horzcat(v), sparsity_in(i), nadj);
900  } else {
901  // Input is non-differentable
902  ret_out.at(i) = MatType(size1_in(i), size2_in(i) * nadj);
903  }
904  }
905 
906  Dict options = opts;
907  if (opts.find("is_diff_in")==opts.end())
908  options["is_diff_in"] = join(is_diff_in_, is_diff_out_, is_diff_out_);
909  if (opts.find("is_diff_out")==opts.end())
910  options["is_diff_out"] = is_diff_in_;
911 
912  options["allow_duplicate_io_names"] = true;
913  // Assemble function and return
914  return Function(name, ret_in, ret_out, inames, onames, options);
915  } catch (std::exception& e) {
916  CASADI_THROW_ERROR("get_reverse", e.what());
917  }
918  }
std::vector< std::vector< MatType > > symbolicAdjSeed(casadi_int nadj, const std::vector< MatType > &v) const
Symbolic expressions for the adjoint seeds.

◆ get_sparsity_in()

Sparsity casadi::XFunction< SXFunction , Matrix< SXElem > , SXNode >::get_sparsity_in ( casadi_int  i)
inlineoverridevirtualinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_y8

Reimplemented from casadi::FunctionInternal.

Definition at line 228 of file x_function.hpp.

228 { return in_.at(i).sparsity();}

◆ get_sparsity_out()

Sparsity casadi::XFunction< SXFunction , Matrix< SXElem > , SXNode >::get_sparsity_out ( casadi_int  i)
inlineoverridevirtualinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_y8

Reimplemented from casadi::FunctionInternal.

Definition at line 229 of file x_function.hpp.

229 { return out_.at(i).sparsity();}

◆ get_stats()

Dict casadi::FunctionInternal::get_stats ( void *  mem) const
overridevirtualinherited

Reimplemented from casadi::ProtoFunction.

Reimplemented in casadi::Sqpmethod, casadi::Scpgen, casadi::Qrsqp, casadi::Qrqp, casadi::QpToNlp, casadi::Newton, casadi::Ipqp, casadi::ImplicitToNlp, casadi::Feasiblesqpmethod, casadi::FastNewton, casadi::WorhpInterface, casadi::SuperscsInterface, casadi::SundialsInterface, casadi::SnoptInterface, casadi::SLEQPInterface, casadi::QpoasesInterface, casadi::ProxqpInterface, casadi::OsqpInterface, casadi::OoqpInterface, casadi::MadnlpInterface, casadi::KnitroInterface, casadi::IpoptInterface, casadi::HpmpcInterface, casadi::HpipmInterface, casadi::HighsInterface, casadi::GurobiInterface, casadi::FatropInterface, casadi::FatropConicInterface, casadi::DaqpInterface, casadi::CplexInterface, casadi::ClpInterface, casadi::ClarabelInterface, casadi::CbcInterface, casadi::BonminInterface, casadi::AlpaqaInterface, casadi::Rootfinder, casadi::OracleFunction, casadi::Nlpsol, and casadi::MXFunction.

Definition at line 2980 of file function_internal.cpp.

2980  {
2981  Dict stats = ProtoFunction::get_stats(mem);
2982  auto m = static_cast<FunctionMemory*>(mem);
2983  casadi_assert(m->stats_available,
2984  "No stats available: Function '" + name_ + "' not set up. "
2985  "To get statistics, first evaluate it numerically.");
2986  return stats;
2987  }
virtual Dict get_stats(void *mem) const
Get all statistics.

References casadi::ProtoFunction::get_stats(), and casadi::ProtoFunction::name_.

Referenced by casadi::Conic::get_stats(), casadi::FmuFunction::get_stats(), casadi::MXFunction::get_stats(), casadi::OracleFunction::get_stats(), and casadi::QpToNlp::get_stats().

◆ getAdaptorSolverName()

virtual std::string casadi::FunctionInternal::getAdaptorSolverName ( ) const
inlinevirtualinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_k3

Definition at line 304 of file function_internal.hpp.

304 { return ""; }

◆ getCount()

Definition at line 60 of file generic_shared_internal.hpp.

186  {
187  return static_cast<const Internal*>(this)->count;
188  }

◆ has_codegen()

bool casadi::XFunction< SXFunction , Matrix< SXElem > , SXNode >::has_codegen ( ) const
inlineoverridevirtualinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_y3

Reimplemented from casadi::FunctionInternal.

Definition at line 188 of file x_function.hpp.

188 { return true;}

◆ has_derivative()

bool casadi::FunctionInternal::has_derivative ( ) const
inherited

◆ has_eval_dm()

virtual bool casadi::FunctionInternal::has_eval_dm ( ) const
inlinevirtualinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_ke

Reimplemented in casadi::CallbackInternal.

Definition at line 424 of file function_internal.hpp.

424 { return false;}

Referenced by casadi::FunctionInternal::eval().

◆ has_forward()

bool casadi::XFunction< SXFunction , Matrix< SXElem > , SXNode >::has_forward ( casadi_int  nfwd) const
inlineoverridevirtualinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_xv

Reimplemented from casadi::FunctionInternal.

Definition at line 128 of file x_function.hpp.

128 { return true;}

◆ has_free()

bool casadi::SXFunction::has_free ( ) const
inlineoverridevirtual

Extra doc: https://github.com/casadi/casadi/wiki/L_un

Reimplemented from casadi::FunctionInternal.

Definition at line 158 of file sx_function.hpp.

158 { return !free_vars_.empty();}

Referenced by eval_mx(), init(), and should_inline().

◆ has_function()

virtual bool casadi::FunctionInternal::has_function ( const std::string &  fname) const
inlinevirtualinherited

Reimplemented in casadi::OracleFunction, casadi::MapSum, and casadi::Map.

Definition at line 369 of file function_internal.hpp.

369 {return false;}

◆ has_jac_sparsity()

virtual bool casadi::FunctionInternal::has_jac_sparsity ( casadi_int  oind,
casadi_int  iind 
) const
inlinevirtualinherited

◆ has_jacobian()

bool casadi::XFunction< SXFunction , Matrix< SXElem > , SXNode >::has_jacobian ( ) const
inlineoverridevirtualinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_xx

Reimplemented from casadi::FunctionInternal.

Definition at line 150 of file x_function.hpp.

150 { return true;}

◆ has_memory()

bool casadi::ProtoFunction::has_memory ( int  ind) const
inherited

Definition at line 3665 of file function_internal.cpp.

3665  {
3666  return ind<mem_.size();
3667  }

◆ has_option()

bool casadi::ProtoFunction::has_option ( const std::string &  option_name) const
inherited

Extra doc: https://github.com/casadi/casadi/wiki/L_jj

Definition at line 1004 of file function_internal.cpp.

1004  {
1005  return get_options().find(option_name) != 0;
1006  }
const Options::Entry * find(const std::string &name) const
Definition: options.cpp:32

References casadi::Options::find(), and casadi::ProtoFunction::get_options().

◆ has_reverse()

bool casadi::XFunction< SXFunction , Matrix< SXElem > , SXNode >::has_reverse ( casadi_int  nadj) const
inlineoverridevirtualinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_xw

Reimplemented from casadi::FunctionInternal.

Definition at line 139 of file x_function.hpp.

139 { return true;}

◆ has_spfwd()

bool casadi::XFunction< SXFunction , Matrix< SXElem > , SXNode >::has_spfwd ( ) const
inlineoverridevirtualinherited

Is the class able to propagate seeds through the algorithm?

Reimplemented from casadi::FunctionInternal.

Definition at line 82 of file x_function.hpp.

82 { return true;}

◆ has_sprev()

bool casadi::XFunction< SXFunction , Matrix< SXElem > , SXNode >::has_sprev ( ) const
inlineoverridevirtualinherited

Is the class able to propagate seeds through the algorithm?

Reimplemented from casadi::FunctionInternal.

Definition at line 83 of file x_function.hpp.

83 { return true;}

◆ hess()

SX casadi::SXFunction::hess ( casadi_int  iind = 0,
casadi_int  oind = 0 
)

◆ incache()

bool casadi::FunctionInternal::incache ( const std::string &  fname,
Function f,
const std::string &  suffix = "" 
) const
inherited

◆ index_in()

casadi_int casadi::FunctionInternal::index_in ( const std::string &  name) const
inlineinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_mu

Definition at line 1126 of file function_internal.hpp.

1126  {
1127  for (casadi_int i=0; i<name_in_.size(); ++i) {
1128  if (name_in_[i]==name) return i;
1129  }
1130  casadi_error("FunctionInternal::index_in: could not find entry \""
1131  + name + "\". Available names are: " + str(name_in_) + ".");
1132  return -1;
1133  }

References casadi::str().

Referenced by casadi::FunctionInternal::convert_arg().

◆ index_out()

casadi_int casadi::FunctionInternal::index_out ( const std::string &  name) const
inlineinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_mv

Definition at line 1138 of file function_internal.hpp.

1138  {
1139  for (casadi_int i=0; i<name_out_.size(); ++i) {
1140  if (name_out_[i]==name) return i;
1141  }
1142  casadi_error("FunctionInternal::index_out: could not find entry \""
1143  + name + "\". Available names are: " + str(name_out_) + ".");
1144  return -1;
1145  }

References casadi::str().

Referenced by casadi::FunctionInternal::convert_res().

◆ info()

Dict casadi::FunctionInternal::info ( ) const
virtualinherited

◆ init()

void casadi::SXFunction::init ( const Dict opts)
overridevirtual

Extra doc: https://github.com/casadi/casadi/wiki/L_v3

Reimplemented from casadi::FunctionInternal.

Definition at line 475 of file sx_function.cpp.

475  {
476  // Call the init function of the base class
478  if (verbose_) casadi_message(name_ + "::init");
479 
480  // Default (temporary) options
481  live_variables_ = true;
482 
483  bool cse_opt = false;
484  bool allow_free = false;
485 
486  // Read options
487  for (auto&& op : opts) {
488  if (op.first=="default_in") {
489  default_in_ = op.second;
490  } else if (op.first=="live_variables") {
491  live_variables_ = op.second;
492  } else if (op.first=="just_in_time_opencl") {
493  just_in_time_opencl_ = op.second;
494  } else if (op.first=="just_in_time_sparsity") {
495  just_in_time_sparsity_ = op.second;
496  } else if (op.first=="cse") {
497  cse_opt = op.second;
498  } else if (op.first=="allow_free") {
499  allow_free = op.second;
500  } else if (op.first=="print_instructions") {
501  print_instructions_ = op.second;
502  }
503  }
504 
505  // Perform common subexpression elimination
506  // This must be done before the lock, to avoid deadlocks
507  if (cse_opt) out_ = cse(out_);
508 
509  // Check/set default inputs
510  if (default_in_.empty()) {
511  default_in_.resize(n_in_, 0);
512  } else {
513  casadi_assert(default_in_.size()==n_in_,
514  "Option 'default_in' has incorrect length");
515  }
516 
517 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
518  std::lock_guard<std::mutex> lock(SX::get_mutex_temp());
519 #endif // CASADI_WITH_THREADSAFE_SYMBOLICS
520 
521  // Stack used to sort the computational graph
522  std::stack<SXNode*> s;
523 
524  // All nodes
525  std::vector<SXNode*> nodes;
526 
527  // Add the list of nodes
528  casadi_int ind=0;
529  for (auto it = out_.begin(); it != out_.end(); ++it, ++ind) {
530  casadi_int nz=0;
531  for (auto itc = (*it)->begin(); itc != (*it)->end(); ++itc, ++nz) {
532  // Add outputs to the list
533  s.push(itc->get());
534  sort_depth_first(s, nodes);
535 
536  // A null pointer means an output instruction
537  nodes.push_back(static_cast<SXNode*>(nullptr));
538  }
539  }
540 
541  casadi_assert(nodes.size() <= std::numeric_limits<int>::max(), "Integer overflow");
542  // Set the temporary variables to be the corresponding place in the sorted graph
543  for (casadi_int i=0; i<nodes.size(); ++i) {
544  if (nodes[i]) {
545  nodes[i]->temp = static_cast<int>(i);
546  }
547  }
548 
549  // Sort the nodes by type
550  constants_.clear();
551  operations_.clear();
552  for (std::vector<SXNode*>::iterator it = nodes.begin(); it != nodes.end(); ++it) {
553  SXNode* t = *it;
554  if (t) {
555  if (t->is_constant())
556  constants_.push_back(SXElem::create(t));
557  else if (!t->is_symbolic() && t->op()>=0)
558  operations_.push_back(SXElem::create(t));
559  }
560  }
561 
562  // Input instructions
563  std::vector<std::pair<int, SXNode*> > symb_loc;
564 
565  // Current output and nonzero, start with the first one
566  int curr_oind, curr_nz=0;
567  casadi_assert(out_.size() <= std::numeric_limits<int>::max(), "Integer overflow");
568  for (curr_oind=0; curr_oind<out_.size(); ++curr_oind) {
569  if (out_[curr_oind].nnz()!=0) {
570  break;
571  }
572  }
573 
574  // Count the number of times each node is used
575  std::vector<casadi_int> refcount(nodes.size(), 0);
576 
577  // Get the sequence of instructions for the virtual machine
578  algorithm_.resize(0);
579  algorithm_.reserve(nodes.size());
580 
581  // Mapping of node index (cfr. temp) to algorithm index
582  std::vector<int> alg_index;
583  alg_index.reserve(nodes.size());
584 
585  for (std::vector<SXNode*>::iterator it=nodes.begin(); it!=nodes.end(); ++it) {
586  // Current node
587  SXNode* n = *it;
588 
589  // New element in the algorithm
590  AlgEl ae;
591 
592  // Get operation
593  ae.op = n==nullptr ? static_cast<int>(OP_OUTPUT) : static_cast<int>(n->op());
594 
595  // Default dependencies
596  int* dep = &ae.i1;
597  casadi_int ndeps = ae.op == -1 ? 1 : casadi_math<double>::ndeps(ae.op);
598 
599  // Get instruction
600  switch (ae.op) {
601  case OP_CONST: // constant
602  ae.d = n->to_double();
603  ae.i0 = n->temp;
604  break;
605  case OP_PARAMETER: // a parameter or input
606  symb_loc.push_back(std::make_pair(algorithm_.size(), n));
607  ae.i0 = n->temp;
608  ae.d = 0; // value not used, but set here to avoid uninitialized data in serialization
609  break;
610  case OP_OUTPUT: // output instruction
611  ae.i0 = curr_oind;
612  ae.i1 = out_[curr_oind]->at(curr_nz)->temp;
613  ae.i2 = curr_nz;
614 
615  // Go to the next nonzero
616  casadi_assert(curr_nz < std::numeric_limits<int>::max(), "Integer overflow");
617  curr_nz++;
618  if (curr_nz>=out_[curr_oind].nnz()) {
619  curr_nz=0;
620  casadi_assert(curr_oind < std::numeric_limits<int>::max(), "Integer overflow");
621  curr_oind++;
622  for (; curr_oind<out_.size(); ++curr_oind) {
623  if (out_[curr_oind].nnz()!=0) {
624  break;
625  }
626  }
627  }
628  break;
629  case OP_CALL: // Call node
630  {
631  ae.i0 = n->temp;
632 
633  // Index into ExtentedAlgEl collection
634  ae.i1 = call_.el.size();
635 
636  // Create ExtentedAlgEl instance
637  // This allocates space for dep and res
638  const Function& f = static_cast<const CallSX*>(n)->f_;
639  call_.el.emplace_back(f);
640 
641  // Make sure we have enough space to evaluate the Function call,
642  // noting that we wil only ever evaluate one call at a time.
643  call_.sz_arg = std::max(call_.sz_arg, f.sz_arg());
644  call_.sz_res = std::max(call_.sz_res, f.sz_res());
645  call_.sz_iw = std::max(call_.sz_iw, f.sz_iw());
646  call_.sz_w = std::max(call_.sz_w, f.sz_w());
647  call_.sz_w_arg = std::max(call_.sz_w_arg, static_cast<size_t>(f.nnz_in()));
648  call_.sz_w_res = std::max(call_.sz_w_res, static_cast<size_t>(f.nnz_out()));
649 
650  // Set the dependency pointer to the (uninitialised) slots of the ExtendedAlgEl
651  ExtendedAlgEl& m = call_.el.at(ae.i1);
652  dep = get_ptr(m.dep);
653  ndeps = m.n_dep;
654 
655  // Populate the dependency slots with node ids.
656  for (casadi_int i=0; i<ndeps; ++i) {
657  dep[i] = n->dep(i).get()->temp;
658  }
659  }
660  break;
661  case -1: // Output extraction node
662  {
663  dep = &algorithm_.at(alg_index.at(n->dep(0).get()->temp)).i1;
664  int oind = static_cast<OutputSX*>(n)->oind_;
665  casadi_assert(call_.el.at(dep[0]).res.at(oind)==-1, "Duplicate");
666  call_.el.at(dep[0]).res.at(oind) = n->temp;
667  }
668  break;
669  default: // Unary or binary operation
670  ae.i0 = n->temp;
671  ae.i1 = n->dep(0).get()->temp;
672  ae.i2 = n->dep(1).get()->temp;
673  }
674 
675  // Increase count of dependencies
676  for (casadi_int c=0; c<ndeps; ++c) {
677  refcount.at(dep[c])++;
678  }
679 
680  // Amend node index to algorithm index mapping
681  alg_index.push_back(algorithm_.size());
682 
683  // Add to algorithm
684  if (ae.op>=0) algorithm_.push_back(ae);
685 
686  }
687 
688  // Place in the work vector for each of the nodes in the tree (overwrites the reference counter)
689  std::vector<int> place(nodes.size());
690 
691  // Stack with unused elements in the work vector
692  std::stack<int> unused;
693 
694  // Work vector size
695  int worksize = 0;
696 
697  // Find a place in the work vector for the operation
698  for (auto&& a : algorithm_) {
699 
700  // Default dependencies
701  int* dep = &a.i1;
702  casadi_int ndeps = casadi_math<double>::ndeps(a.op);
703 
704  // Default outputs
705  int* res = &a.i0;
706  casadi_int nres = 1;
707 
708  // Call node overrides these defaults
709  if (a.op==OP_CALL) {
710  ExtendedAlgEl& e = call_.el.at(a.i1);
711  ndeps = e.n_dep;
712  dep = get_ptr(e.dep);
713  nres = e.n_res;
714  res = get_ptr(e.res);
715  }
716 
717  // decrease reference count of children
718  // reverse order so that the first argument will end up at the top of the stack
719  for (casadi_int c=ndeps-1; c>=0; --c) {
720  casadi_int ch_ind = dep[c];
721  casadi_int remaining = --refcount.at(ch_ind);
722  if (remaining==0) unused.push(place[ch_ind]);
723  }
724 
725  // Find a place to store the variable
726  if (a.op!=OP_OUTPUT) {
727  for (casadi_int c=0; c<nres; ++c) {
728  if (res[c]<0) continue;
729  if (live_variables_ && !unused.empty()) {
730  // Try to reuse a variable from the stack if possible (last in, first out)
731  res[c] = place[res[c]] = unused.top();
732  unused.pop();
733  } else {
734  // Allocate a new variable
735  res[c] = place[res[c]] = worksize++;
736  }
737  }
738  }
739 
740  // Save the location of the children
741  for (casadi_int c=0; c<ndeps; ++c) {
742  dep[c] = place[dep[c]];
743  }
744 
745  // If binary, make sure that the second argument is the same as the first one
746  // (in order to treat all operations as binary) NOTE: ugly
747  if (ndeps==1 && a.op!=OP_OUTPUT) {
748  a.i2 = a.i1;
749  }
750  }
751 
752  worksize_ = worksize;
753 
754  if (verbose_) {
755  if (live_variables_) {
756  casadi_message("Using live variables: work array is " + str(worksize_)
757  + " instead of " + str(nodes.size()));
758  } else {
759  casadi_message("Live variables disabled.");
760  }
761  }
762 
763  // Allocate work vectors (symbolic/numeric)
765 
766  alloc_arg(call_.sz_arg, true);
767  alloc_res(call_.sz_res, true);
768  alloc_iw(call_.sz_iw, true);
770 
771  // Reset the temporary variables
772  for (casadi_int i=0; i<nodes.size(); ++i) {
773  if (nodes[i]) {
774  nodes[i]->temp = 0;
775  }
776  }
777 
778  // Now mark each input's place in the algorithm
779  for (auto it=symb_loc.begin(); it!=symb_loc.end(); ++it) {
780  it->second->temp = it->first+1;
781  }
782 
783  // Add input instructions
784  casadi_assert(in_.size() <= std::numeric_limits<int>::max(), "Integer overflow");
785  for (int ind=0; ind<in_.size(); ++ind) {
786  int nz=0;
787  for (auto itc = in_[ind]->begin(); itc != in_[ind]->end(); ++itc, ++nz) {
788  int i = itc->get_temp()-1;
789  if (i>=0) {
790  // Mark as input
791  algorithm_[i].op = OP_INPUT;
792 
793  // Location of the input
794  algorithm_[i].i1 = ind;
795  algorithm_[i].i2 = nz;
796 
797  // Mark input as read
798  itc->set_temp(0);
799  }
800  }
801  }
802 
803  // Locate free variables
804  free_vars_.clear();
805  for (std::vector<std::pair<int, SXNode*> >::const_iterator it=symb_loc.begin();
806  it!=symb_loc.end(); ++it) {
807  if (it->second->temp!=0) {
808  // Store the index into free_vars
809  algorithm_[it->first].i1 = free_vars_.size();
810 
811  // Save to list of free parameters
812  free_vars_.push_back(SXElem::create(it->second));
813 
814  // Remove marker
815  it->second->temp=0;
816  }
817  }
818 
819  if (!allow_free && has_free()) {
820  casadi_error(name_ + "::init: Initialization failed since variables [" +
821  join(get_free(), ", ") + "] are free. These symbols occur in the output expressions "
822  "but you forgot to declare these as inputs. "
823  "Set option 'allow_free' to allow free variables.");
824  }
825 
827 
828  // Initialize just-in-time compilation for numeric evaluation using OpenCL
829  if (just_in_time_opencl_) {
830  casadi_error("OpenCL is not supported in this version of CasADi");
831  }
832 
833  // Initialize just-in-time compilation for sparsity propagation using OpenCL
835  casadi_error("OpenCL is not supported in this version of CasADi");
836  }
837 
838  // Print
839  if (verbose_) casadi_message(str(algorithm_.size()) + " elementary operations");
840  }
static SXElem create(SXNode *node)
Definition: sx_elem.cpp:62
void init_copy_elision()
Part of initialize responsible of prepaprign copy elision.
std::vector< std::string > get_free() const override
Print free variables.
void init(const Dict &opts) override
Initialize.
Definition: x_function.hpp:319
static void sort_depth_first(std::stack< SXNode * > &s, std::vector< SXNode * > &nodes)
Topological sorting of the nodes based on Depth-First Search (DFS)
Definition: x_function.hpp:395

References algorithm_, casadi::FunctionInternal::alloc_arg(), casadi::FunctionInternal::alloc_iw(), casadi::FunctionInternal::alloc_res(), casadi::FunctionInternal::alloc_w(), call_, constants_, casadi::SXElem::create(), casadi::ScalarAtomic::d, default_in_, casadi::SXFunction::ExtendedAlgEl::dep, casadi::SXNode::dep(), casadi::SXFunction::CallInfo::el, free_vars_, casadi::SXElem::get(), get_free(), casadi::get_ptr(), has_free(), casadi::ScalarAtomic::i0, casadi::ScalarAtomic::i1, casadi::ScalarAtomic::i2, casadi::XFunction< SXFunction, Matrix< SXElem >, SXNode >::in_, casadi::XFunction< DerivedType, MatType, NodeType >::init(), init_copy_elision(), casadi::SXNode::is_constant(), casadi::SXNode::is_symbolic(), casadi::join(), just_in_time_opencl_, just_in_time_sparsity_, live_variables_, casadi::SXFunction::ExtendedAlgEl::n_dep, casadi::FunctionInternal::n_in_, casadi::SXFunction::ExtendedAlgEl::n_res, casadi::ProtoFunction::name_, casadi::casadi_math< T >::ndeps(), casadi::Function::nnz_in(), casadi::Function::nnz_out(), casadi::ScalarAtomic::op, casadi::SXNode::op(), casadi::OP_CALL, casadi::OP_CONST, casadi::OP_INPUT, casadi::OP_OUTPUT, casadi::OP_PARAMETER, operations_, casadi::XFunction< SXFunction, Matrix< SXElem >, SXNode >::out_, print_instructions_, casadi::SXFunction::ExtendedAlgEl::res, casadi::XFunction< SXFunction, Matrix< SXElem >, SXNode >::sort_depth_first(), casadi::str(), casadi::Function::sz_arg(), casadi::SXFunction::CallInfo::sz_arg, casadi::Function::sz_iw(), casadi::SXFunction::CallInfo::sz_iw, casadi::Function::sz_res(), casadi::SXFunction::CallInfo::sz_res, casadi::Function::sz_w(), casadi::SXFunction::CallInfo::sz_w, casadi::SXFunction::CallInfo::sz_w_arg, casadi::SXFunction::CallInfo::sz_w_res, casadi::SXNode::temp, casadi::SXNode::to_double(), casadi::ProtoFunction::verbose_, and worksize_.

◆ init_copy_elision()

void casadi::SXFunction::init_copy_elision ( )

Extra doc: https://github.com/casadi/casadi/wiki/L_29h

Definition at line 842 of file sx_function.cpp.

842  {
844  copy_elision_.resize(algorithm_.size(), false);
845  return;
846  }
847  // Perform copy elision (codegen-only)
848  // Remove nodes that only serve to compose CALL inputs
849 
850  // For work vector elements, store the arg source (-1 for no trivial source)
851  std::vector<int> arg_i(worksize_, -1);
852  std::vector<int> nz_i(worksize_, -1);
853 
854  // Which algel corresponds to this source?
855  std::vector<casadi_int> alg_i(worksize_, -1);
856 
857  // Is this algel to be elided?
858  copy_elision_.resize(algorithm_.size(), false);
859 
860  casadi_int k=0;
861  for (auto&& e : algorithm_) {
862  switch (e.op) {
863  case OP_INPUT:
864  // Make source association
865  arg_i[e.i0] = e.i1;
866  nz_i[e.i0] = e.i2;
867  alg_i[e.i0] = k;
868  copy_elision_[k] = true;
869  break;
870  case OP_OUTPUT:
871  if (arg_i[e.i1]>=0) {
872  copy_elision_[alg_i[e.i1]] = false;
873  }
874  break;
875  case OP_CALL:
876  {
877  auto& m = call_.el[e.i1];
878 
879  // Inspect input arguments
880  casadi_int offset_input = 0;
881  for (casadi_int i=0; i<m.f_n_in; ++i) {
882  // Pattern match results
883  casadi_int arg = -1;
884  casadi_int offset = -1;
885  for (casadi_int j=0; j<m.f_nnz_in[i]; ++j) {
886  casadi_int k = offset_input+j;
887  if (j==0) {
888  arg = arg_i[m.dep[k]];
889  offset = nz_i[m.dep[k]];
890  }
891  if (arg_i[m.dep[k]]==-1) {
892  arg = -1;
893  // Pattern match failed
894  break;
895  }
896  if (nz_i[m.dep[k]]!=offset+j) {
897  arg = -1;
898  // Pattern match failed
899  break;
900  }
901  }
902 
903  // If we cannot perform elision
904  if (arg==-1) {
905  // We need copies for all nonzeros of input i
906  for (casadi_int j=0; j<m.f_nnz_in[i]; ++j) {
907  casadi_int k = offset_input+j;
908  if (arg_i[m.dep[k]]>=0) {
909  copy_elision_[alg_i[m.dep[k]]] = false;
910  }
911  }
912  }
913  // Store pattern match results
914  m.copy_elision_arg[i] = arg;
915  m.copy_elision_offset[i] = offset;
916 
917  offset += m.f_nnz_in[i];
918  offset_input += m.f_nnz_in[i];
919  }
920 
921  // Remove source association of all outputs
922  for (casadi_int i=0; i<m.n_res; ++i) {
923  if (m.res[i]>=0) {
924  arg_i[m.res[i]] = -1;
925  }
926  }
927  }
928  break;
929  case OP_CONST:
930  case OP_PARAMETER:
931  // Remove source association
932  arg_i[e.i0] = -1;
933  break;
934  default:
935  if (arg_i[e.i1]>=0) {
936  copy_elision_[alg_i[e.i1]] = false;
937  }
938  if (!casadi_math<double>::is_unary(e.op)) {
939  if (arg_i[e.i2]>=0) {
940  copy_elision_[alg_i[e.i2]] = false;
941  }
942  }
943  // Remove source association
944  arg_i[e.i0] = -1;
945  }
946  k++;
947  }
948  }
static casadi_int copy_elision_min_size
static bool is_unary(unsigned char op)
Is unary operation?
Definition: calculus.hpp:1613

References algorithm_, call_, copy_elision_, casadi::GlobalOptions::copy_elision_min_size, casadi::SXFunction::CallInfo::el, casadi::OP_CALL, casadi::OP_CONST, casadi::OP_INPUT, casadi::OP_OUTPUT, casadi::OP_PARAMETER, and worksize_.

Referenced by init().

◆ init_mem()

int casadi::ProtoFunction::init_mem ( void *  mem) const
virtualinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_jo

Reimplemented in casadi::SymbolicQr, casadi::Sqpmethod, casadi::Scpgen, casadi::Qrqp, casadi::Newton, casadi::Lsqr, casadi::LinsolTridiag, casadi::LinsolQr, casadi::LinsolLdl, casadi::Ipqp, casadi::Feasiblesqpmethod, casadi::FastNewton, casadi::WorhpInterface, casadi::SuperscsInterface, casadi::SundialsInterface, casadi::KinsolInterface, casadi::IdasInterface, casadi::CvodesInterface, casadi::SnoptInterface, casadi::SlicotExpm, casadi::SlicotDple, casadi::SLEQPInterface, casadi::QpoasesInterface, casadi::ProxqpInterface, casadi::OsqpInterface, casadi::MumpsInterface, casadi::MadnlpInterface, casadi::LapackQr, casadi::LapackLu, casadi::KnitroInterface, casadi::IpoptInterface, casadi::Ma27Interface, casadi::HpmpcInterface, casadi::HpipmInterface, casadi::HighsInterface, casadi::GurobiInterface, casadi::FatropInterface, casadi::FatropConicInterface, casadi::DaqpInterface, casadi::CsparseInterface, casadi::CSparseCholeskyInterface, casadi::CplexInterface, casadi::ClpInterface, casadi::ClarabelInterface, casadi::CbcInterface, casadi::BonminInterface, casadi::Blocksqp, casadi::AmplInterface, casadi::AlpaqaInterface, casadi::Rootfinder, casadi::OracleFunction, casadi::Nlpsol, casadi::LinsolInternal, casadi::FixedStepIntegrator, casadi::Integrator, casadi::FmuFunction, and casadi::Conic.

Definition at line 813 of file function_internal.cpp.

813  {
814  auto m = static_cast<ProtoFunctionMemory*>(mem);
815  if (record_time_) {
816  m->add_stat("total");
817  m->t_total = &m->fstats.at("total");
818  } else {
819  m->t_total = nullptr;
820  }
821  return 0;
822  }

References casadi::ProtoFunctionMemory::add_stat(), and casadi::ProtoFunction::record_time_.

Referenced by casadi::ProtoFunction::checkout(), casadi::FunctionInternal::codegen_checkout(), casadi::Conic::init_mem(), casadi::FmuFunction::init_mem(), casadi::LinsolInternal::init_mem(), casadi::OracleFunction::init_mem(), casadi::SlicotDple::init_mem(), casadi::SlicotExpm::init_mem(), and casadi::OracleFunction::local_init_mem().

◆ initSingleton()

void casadi::GenericSharedInternal< SharedObject , SharedObjectInternal >::initSingleton ( )
inlineprotectedinherited

Called in the constructor of singletons to avoid that the counter reaches zero

Definition at line 71 of file generic_shared_internal.hpp.

71  {
72  casadi_assert_dev(static_cast<Internal*>(this)->count==0);
73  static_cast<Internal*>(this)->count++;
74  }

◆ instruction_constant()

double casadi::SXFunction::instruction_constant ( casadi_int  k) const
inlineoverridevirtual

Extra doc: https://github.com/casadi/casadi/wiki/L_ut

Reimplemented from casadi::FunctionInternal.

Definition at line 204 of file sx_function.hpp.

204  {
205  return algorithm_.at(k).d;
206  }

◆ instruction_id()

casadi_int casadi::SXFunction::instruction_id ( casadi_int  k) const
inlineoverridevirtual

Extra doc: https://github.com/casadi/casadi/wiki/L_ur

Reimplemented from casadi::FunctionInternal.

Definition at line 182 of file sx_function.hpp.

182 { return algorithm_.at(k).op;}

◆ instruction_input()

std::vector<casadi_int> casadi::SXFunction::instruction_input ( casadi_int  k) const
inlineoverridevirtual

Extra doc: https://github.com/casadi/casadi/wiki/L_us

Reimplemented from casadi::FunctionInternal.

Definition at line 187 of file sx_function.hpp.

187  {
188  auto e = algorithm_.at(k);
189  if (e.op==OP_CALL) {
190  const ExtendedAlgEl& m = call_.el[e.i1];
191  return vector_static_cast<casadi_int>(m.dep);
192  } else if (casadi_math<double>::ndeps(e.op)==2 || e.op==OP_INPUT) {
193  return {e.i1, e.i2};
194  } else if (casadi_math<double>::ndeps(e.op)==1) {
195  return {e.i1};
196  } else {
197  return {};
198  }
199  }

References casadi::SXFunction::ExtendedAlgEl::dep, casadi::OP_CALL, and casadi::OP_INPUT.

◆ instruction_MX()

MX casadi::FunctionInternal::instruction_MX ( casadi_int  k) const
virtualinherited

Reimplemented in casadi::MXFunction.

Definition at line 3410 of file function_internal.cpp.

3410  {
3411  casadi_error("'instruction_MX' not defined for " + class_name());
3412  }

References casadi::SharedObjectInternal::class_name().

◆ instruction_output()

std::vector<casadi_int> casadi::SXFunction::instruction_output ( casadi_int  k) const
inlineoverridevirtual

Extra doc: https://github.com/casadi/casadi/wiki/L_uu

Reimplemented from casadi::FunctionInternal.

Definition at line 211 of file sx_function.hpp.

211  {
212  auto e = algorithm_.at(k);
213  if (e.op==OP_CALL) {
214  const ExtendedAlgEl& m = call_.el[e.i1];
215  return vector_static_cast<casadi_int>(m.res);
216  } else if (e.op==OP_OUTPUT) {
217  return {e.i0, e.i2};
218  } else {
219  return {e.i0};
220  }
221  }

References casadi::OP_CALL, casadi::OP_OUTPUT, and casadi::SXFunction::ExtendedAlgEl::res.

◆ instructions_sx()

SX casadi::SXFunction::instructions_sx ( ) const
overridevirtual

Reimplemented from casadi::FunctionInternal.

Definition at line 950 of file sx_function.cpp.

950  {
951  std::vector<SXElem> ret(algorithm_.size(), casadi_limits<SXElem>::nan);
952 
953  std::vector<SXElem>::iterator it=ret.begin();
954 
955  // Iterator to the binary operations
956  std::vector<SXElem>::const_iterator b_it = operations_.begin();
957 
958  // Iterator to stack of constants
959  std::vector<SXElem>::const_iterator c_it = constants_.begin();
960 
961  // Iterator to free variables
962  std::vector<SXElem>::const_iterator p_it = free_vars_.begin();
963 
964  // Evaluate algorithm
965  if (verbose_) casadi_message("Evaluating algorithm forward");
966  for (auto&& a : algorithm_) {
967  switch (a.op) {
968  case OP_INPUT:
969  case OP_OUTPUT:
970  it++;
971  break;
972  case OP_CONST:
973  *it++ = *c_it++;
974  break;
975  case OP_PARAMETER:
976  *it++ = *p_it++;
977  break;
978  default:
979  *it++ = *b_it++;
980  }
981  }
982  casadi_assert(it==ret.end(), "Dimension mismatch");
983  return ret;
984  }
static const SXElem nan
Definition: sx_elem.hpp:323

References algorithm_, constants_, free_vars_, casadi::OP_CONST, casadi::OP_INPUT, casadi::OP_OUTPUT, casadi::OP_PARAMETER, operations_, and casadi::ProtoFunction::verbose_.

◆ is_a()

bool casadi::SXFunction::is_a ( const std::string &  type,
bool  recursive 
) const
overridevirtual

Extra doc: https://github.com/casadi/casadi/wiki/L_ul

Reimplemented from casadi::FunctionInternal.

Definition at line 1719 of file sx_function.cpp.

1719  {
1720  return type=="SXFunction" || (recursive && XFunction<SXFunction,
1721  SX, SXNode>::is_a(type, recursive));
1722  }
bool is_a(const std::string &type, bool recursive) const override
Check if the function is of a particular type.
XFunction(const std::string &name, const std::vector< Matrix< SXElem > > &ex_in, const std::vector< Matrix< SXElem > > &ex_out, const std::vector< std::string > &name_in, const std::vector< std::string > &name_out)
Constructor.
Definition: x_function.hpp:269
Matrix< SXElem > SX
Definition: sx_fwd.hpp:32

References SXFunction().

◆ is_smooth()

bool casadi::SXFunction::is_smooth ( ) const

Extra doc: https://github.com/casadi/casadi/wiki/L_ui

Definition at line 129 of file sx_function.cpp.

129  {
130  // Go through all nodes and check if any node is non-smooth
131  for (auto&& a : algorithm_) {
132  if (!operation_checker<SmoothChecker>(a.op)) {
133  return false;
134  }
135  }
136  return true;
137  }

References algorithm_.

Referenced by casadi::Matrix< Scalar >::is_smooth().

◆ isInput()

bool casadi::XFunction< SXFunction , Matrix< SXElem > , SXNode >::isInput ( const std::vector< Matrix< SXElem > > &  arg) const
virtualinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_y4

Definition at line 193 of file x_function.hpp.

1068  {
1069  // Check if arguments matches the input expressions, in which case
1070  // the output is known to be the output expressions
1071  const casadi_int checking_depth = 2;
1072  for (casadi_int i=0; i<arg.size(); ++i) {
1073  if (!is_equal(arg[i], in_[i], checking_depth)) {
1074  return false;
1075  }
1076  }
1077  return true;
1078  }
bool is_equal(double x, double y, casadi_int depth=0)
Definition: calculus.hpp:281

◆ jac()

std::vector< Matrix< SXElem > > casadi::XFunction< SXFunction , Matrix< SXElem > , SXNode >::jac ( const Dict opts) const
inherited

Extra doc: https://github.com/casadi/casadi/wiki/L_xs

Definition at line 98 of file x_function.hpp.

425  {
426  try {
427  // Read options
428  bool compact = false;
429  bool symmetric = false;
430  bool allow_forward = true;
431  bool allow_reverse = true;
432  for (auto&& op : opts) {
433  if (op.first=="compact") {
434  compact = op.second;
435  } else if (op.first=="symmetric") {
436  symmetric = op.second;
437  } else if (op.first=="allow_forward") {
438  allow_forward = op.second;
439  } else if (op.first=="allow_reverse") {
440  allow_reverse = op.second;
441  } else if (op.first=="verbose") {
442  continue;
443  } else {
444  casadi_error("No such Jacobian option: " + std::string(op.first));
445  }
446  }
447 
448  // Return object
449  std::vector<MatType> ret(n_in_ * n_out_);
450 
451  // Quick return if trivially empty
452  if (nnz_in() == 0 || nnz_out() == 0) {
453  for (casadi_int i = 0; i < n_out_; ++i) {
454  for (casadi_int j = 0; j < n_in_; ++j) {
455  if (compact) {
456  ret[i * n_in_ + j] = MatType(nnz_out(i), nnz_in(j));
457  } else {
458  ret[i * n_in_ + j] = MatType(numel_out(i), numel_in(j));
459  }
460  }
461  }
462  return ret;
463  }
464 
465  // FIXME(@jaeandersson)
466  casadi_int iind = 0, oind = 0;
467  casadi_assert(n_in_ == 1, "Not implemented");
468  casadi_assert(n_out_ == 1, "Not implemented");
469 
470  // Create return object
471  ret.at(0) = MatType::zeros(jac_sparsity(0, 0, false, symmetric).T());
472  if (verbose_) casadi_message("Allocated return value");
473 
474  // Quick return if empty
475  if (ret.at(0).nnz()==0) {
476  ret.at(0) = ret.at(0).T();
477  return ret;
478  }
479 
480  // Get a bidirectional partition
481  Sparsity D1, D2;
482  get_partition(iind, oind, D1, D2, true, symmetric, allow_forward, allow_reverse);
483  if (verbose_) casadi_message("Graph coloring completed");
484 
485  // Get the number of forward and adjoint sweeps
486  casadi_int nfdir = D1.is_null() ? 0 : D1.size2();
487  casadi_int nadir = D2.is_null() ? 0 : D2.size2();
488 
489  // Number of derivative directions supported by the function
490  casadi_int max_nfdir = max_num_dir_;
491  casadi_int max_nadir = max_num_dir_;
492 
493  // Current forward and adjoint direction
494  casadi_int offset_nfdir = 0, offset_nadir = 0;
495 
496  // Evaluation result (known)
497  std::vector<MatType> res(out_);
498 
499  // Forward and adjoint seeds and sensitivities
500  std::vector<std::vector<MatType> > fseed, aseed, fsens, asens;
501 
502  // Get the sparsity of the Jacobian block
503  Sparsity jsp = jac_sparsity(0, 0, true, symmetric).T();
504  const casadi_int* jsp_colind = jsp.colind();
505  const casadi_int* jsp_row = jsp.row();
506 
507  // Input sparsity
508  std::vector<casadi_int> input_col = sparsity_in_.at(iind).get_col();
509  const casadi_int* input_row = sparsity_in_.at(iind).row();
510 
511  // Output sparsity
512  std::vector<casadi_int> output_col = sparsity_out_.at(oind).get_col();
513  const casadi_int* output_row = sparsity_out_.at(oind).row();
514 
515  // Get transposes and mappings for jacobian sparsity pattern if we are using forward mode
516  if (verbose_) casadi_message("jac transposes and mapping");
517  std::vector<casadi_int> mapping;
518  Sparsity jsp_trans;
519  if (nfdir>0) {
520  jsp_trans = jsp.transpose(mapping);
521  }
522 
523  // The nonzeros of the sensitivity matrix
524  std::vector<casadi_int> nzmap, nzmap2;
525 
526  // Additions to the jacobian matrix
527  std::vector<casadi_int> adds, adds2;
528 
529  // Temporary vector
530  std::vector<casadi_int> tmp;
531 
532  // Progress
533  casadi_int progress = -10;
534 
535  // Number of sweeps
536  casadi_int nsweep_fwd = nfdir/max_nfdir; // Number of sweeps needed for the forward mode
537  if (nfdir%max_nfdir>0) nsweep_fwd++;
538  casadi_int nsweep_adj = nadir/max_nadir; // Number of sweeps needed for the adjoint mode
539  if (nadir%max_nadir>0) nsweep_adj++;
540  casadi_int nsweep = std::max(nsweep_fwd, nsweep_adj);
541  if (verbose_) {
542  casadi_message(str(nsweep) + " sweeps needed for " + str(nfdir) + " forward and "
543  + str(nadir) + " reverse directions");
544  }
545 
546  // Sparsity of the seeds
547  std::vector<casadi_int> seed_col, seed_row;
548 
549  // Evaluate until everything has been determined
550  for (casadi_int s=0; s<nsweep; ++s) {
551  // Print progress
552  if (verbose_) {
553  casadi_int progress_new = (s*100)/nsweep;
554  // Print when entering a new decade
555  if (progress_new / 10 > progress / 10) {
556  progress = progress_new;
557  casadi_message(str(progress) + " %");
558  }
559  }
560 
561  // Number of forward and adjoint directions in the current "batch"
562  casadi_int nfdir_batch = std::min(nfdir - offset_nfdir, max_nfdir);
563  casadi_int nadir_batch = std::min(nadir - offset_nadir, max_nadir);
564 
565  // Forward seeds
566  fseed.resize(nfdir_batch);
567  for (casadi_int d=0; d<nfdir_batch; ++d) {
568  // Nonzeros of the seed matrix
569  seed_col.clear();
570  seed_row.clear();
571 
572  // For all the directions
573  for (casadi_int el = D1.colind(offset_nfdir+d); el<D1.colind(offset_nfdir+d+1); ++el) {
574 
575  // Get the direction
576  casadi_int c = D1.row(el);
577 
578  // Give a seed in the direction
579  seed_col.push_back(input_col[c]);
580  seed_row.push_back(input_row[c]);
581  }
582 
583  // initialize to zero
584  fseed[d].resize(n_in_);
585  for (casadi_int ind=0; ind<fseed[d].size(); ++ind) {
586  casadi_int nrow = size1_in(ind), ncol = size2_in(ind); // Input dimensions
587  if (ind==iind) {
588  fseed[d][ind] = MatType::ones(Sparsity::triplet(nrow, ncol, seed_row, seed_col));
589  } else {
590  fseed[d][ind] = MatType(nrow, ncol);
591  }
592  }
593  }
594 
595  // Adjoint seeds
596  aseed.resize(nadir_batch);
597  for (casadi_int d=0; d<nadir_batch; ++d) {
598  // Nonzeros of the seed matrix
599  seed_col.clear();
600  seed_row.clear();
601 
602  // For all the directions
603  for (casadi_int el = D2.colind(offset_nadir+d); el<D2.colind(offset_nadir+d+1); ++el) {
604 
605  // Get the direction
606  casadi_int c = D2.row(el);
607 
608  // Give a seed in the direction
609  seed_col.push_back(output_col[c]);
610  seed_row.push_back(output_row[c]);
611  }
612 
613  //initialize to zero
614  aseed[d].resize(n_out_);
615  for (casadi_int ind=0; ind<aseed[d].size(); ++ind) {
616  casadi_int nrow = size1_out(ind), ncol = size2_out(ind); // Output dimensions
617  if (ind==oind) {
618  aseed[d][ind] = MatType::ones(Sparsity::triplet(nrow, ncol, seed_row, seed_col));
619  } else {
620  aseed[d][ind] = MatType(nrow, ncol);
621  }
622  }
623  }
624 
625  // Forward sensitivities
626  fsens.resize(nfdir_batch);
627  for (casadi_int d=0; d<nfdir_batch; ++d) {
628  // initialize to zero
629  fsens[d].resize(n_out_);
630  for (casadi_int oind=0; oind<fsens[d].size(); ++oind) {
631  fsens[d][oind] = MatType::zeros(sparsity_out_.at(oind));
632  }
633  }
634 
635  // Adjoint sensitivities
636  asens.resize(nadir_batch);
637  for (casadi_int d=0; d<nadir_batch; ++d) {
638  // initialize to zero
639  asens[d].resize(n_in_);
640  for (casadi_int ind=0; ind<asens[d].size(); ++ind) {
641  asens[d][ind] = MatType::zeros(sparsity_in_.at(ind));
642  }
643  }
644 
645  // Evaluate symbolically
646  if (!fseed.empty()) {
647  casadi_assert_dev(aseed.empty());
648  if (verbose_) casadi_message("Calling 'ad_forward'");
649  static_cast<const DerivedType*>(this)->ad_forward(fseed, fsens);
650  if (verbose_) casadi_message("Back from 'ad_forward'");
651  } else if (!aseed.empty()) {
652  casadi_assert_dev(fseed.empty());
653  if (verbose_) casadi_message("Calling 'ad_reverse'");
654  static_cast<const DerivedType*>(this)->ad_reverse(aseed, asens);
655  if (verbose_) casadi_message("Back from 'ad_reverse'");
656  }
657 
658  // Carry out the forward sweeps
659  for (casadi_int d=0; d<nfdir_batch; ++d) {
660  // Skip if nothing to add
661  if (fsens[d][oind].nnz()==0) {
662  continue;
663  }
664 
665  // If symmetric, see how many times each output appears
666  if (symmetric) {
667  // Initialize to zero
668  tmp.resize(nnz_out(oind));
669  std::fill(tmp.begin(), tmp.end(), 0);
670 
671  // "Multiply" Jacobian sparsity by seed vector
672  for (casadi_int el = D1.colind(offset_nfdir+d); el<D1.colind(offset_nfdir+d+1); ++el) {
673 
674  // Get the input nonzero
675  casadi_int c = D1.row(el);
676 
677  // Propagate dependencies
678  for (casadi_int el_jsp=jsp_colind[c]; el_jsp<jsp_colind[c+1]; ++el_jsp) {
679  tmp[jsp_row[el_jsp]]++;
680  }
681  }
682  }
683 
684  // Locate the nonzeros of the forward sensitivity matrix
685  sparsity_out_.at(oind).find(nzmap);
686  fsens[d][oind].sparsity().get_nz(nzmap);
687 
688  if (symmetric) {
689  sparsity_in_.at(iind).find(nzmap2);
690  fsens[d][oind].sparsity().get_nz(nzmap2);
691  }
692 
693  // Assignments to the Jacobian
694  adds.resize(fsens[d][oind].nnz());
695  std::fill(adds.begin(), adds.end(), -1);
696  if (symmetric) {
697  adds2.resize(adds.size());
698  std::fill(adds2.begin(), adds2.end(), -1);
699  }
700 
701  // For all the input nonzeros treated in the sweep
702  for (casadi_int el = D1.colind(offset_nfdir+d); el<D1.colind(offset_nfdir+d+1); ++el) {
703 
704  // Get the input nonzero
705  casadi_int c = D1.row(el);
706  //casadi_int f2_out;
707  //if (symmetric) {
708  // f2_out = nzmap2[c];
709  //}
710 
711  // Loop over the output nonzeros corresponding to this input nonzero
712  for (casadi_int el_out = jsp_trans.colind(c); el_out<jsp_trans.colind(c+1); ++el_out) {
713 
714  // Get the output nonzero
715  casadi_int r_out = jsp_trans.row(el_out);
716 
717  // Get the forward sensitivity nonzero
718  casadi_int f_out = nzmap[r_out];
719  if (f_out<0) continue; // Skip if structurally zero
720 
721  // The nonzero of the Jacobian now treated
722  casadi_int elJ = mapping[el_out];
723 
724  if (symmetric) {
725  if (tmp[r_out]==1) {
726  adds[f_out] = el_out;
727  adds2[f_out] = elJ;
728  }
729  } else {
730  // Get the output seed
731  adds[f_out] = elJ;
732  }
733  }
734  }
735 
736  // Get entries in fsens[d][oind] with nonnegative indices
737  tmp.resize(adds.size());
738  casadi_int sz = 0;
739  for (casadi_int i=0; i<adds.size(); ++i) {
740  if (adds[i]>=0) {
741  adds[sz] = adds[i];
742  tmp[sz++] = i;
743  }
744  }
745  adds.resize(sz);
746  tmp.resize(sz);
747 
748  // Add contribution to the Jacobian
749  ret.at(0).nz(adds) = fsens[d][oind].nz(tmp);
750 
751  if (symmetric) {
752  // Get entries in fsens[d][oind] with nonnegative indices
753  tmp.resize(adds2.size());
754  sz = 0;
755  for (casadi_int i=0; i<adds2.size(); ++i) {
756  if (adds2[i]>=0) {
757  adds2[sz] = adds2[i];
758  tmp[sz++] = i;
759  }
760  }
761  adds2.resize(sz);
762  tmp.resize(sz);
763 
764  // Add contribution to the Jacobian
765  ret.at(0).nz(adds2) = fsens[d][oind].nz(tmp);
766  }
767  }
768 
769  // Add elements to the Jacobian matrix
770  for (casadi_int d=0; d<nadir_batch; ++d) {
771  // Skip if nothing to add
772  if (asens[d][iind].nnz()==0) {
773  continue;
774  }
775 
776  // Locate the nonzeros of the adjoint sensitivity matrix
777  sparsity_in_.at(iind).find(nzmap);
778  asens[d][iind].sparsity().get_nz(nzmap);
779 
780  // For all the output nonzeros treated in the sweep
781  for (casadi_int el = D2.colind(offset_nadir+d); el<D2.colind(offset_nadir+d+1); ++el) {
782 
783  // Get the output nonzero
784  casadi_int r = D2.row(el);
785 
786  // Loop over the input nonzeros that influences this output nonzero
787  for (casadi_int elJ = jsp.colind(r); elJ<jsp.colind(r+1); ++elJ) {
788 
789  // Get the input nonzero
790  casadi_int inz = jsp.row(elJ);
791 
792  // Get the corresponding adjoint sensitivity nonzero
793  casadi_int anz = nzmap[inz];
794  if (anz<0) continue;
795 
796  // Get the input seed
797  ret.at(0).nz(elJ) = asens[d][iind].nz(anz);
798  }
799  }
800  }
801 
802  // Update direction offsets
803  offset_nfdir += nfdir_batch;
804  offset_nadir += nadir_batch;
805  }
806 
807  // Return
808  for (MatType& Jb : ret) Jb = Jb.T();
809  return ret;
810 
811  } catch (std::exception& e) {
812  CASADI_THROW_ERROR("jac", e.what());
813  }
814  }
void get_partition(casadi_int iind, casadi_int oind, Sparsity &D1, Sparsity &D2, bool compact, bool symmetric, bool allow_forward, bool allow_reverse) const
Get the unidirectional or bidirectional partition.
Sparsity T() const
Transpose the matrix.
Definition: sparsity.cpp:394
const casadi_int * colind() const
Get a reference to the colindex of all column element (see class description)
Definition: sparsity.cpp:168

◆ jac_is_symm()

bool casadi::FunctionInternal::jac_is_symm ( casadi_int  oind,
casadi_int  iind 
) const
virtualinherited

Definition at line 1858 of file function_internal.cpp.

1858  {
1859  // If derivative expression
1860  if (!derivative_of_.is_null()) {
1861  std::string n = derivative_of_.name();
1862  // Reverse move
1863  if (name_ == "adj1_" + n) {
1864  if (iind == oind) return true;
1865  }
1866  }
1867  // Not symmetric by default
1868  return false;
1869  }

References casadi::FunctionInternal::derivative_of_, casadi::GenericShared< Shared, Internal >::is_null(), casadi::Function::name(), and casadi::ProtoFunction::name_.

◆ jac_sparsity()

Sparsity & casadi::FunctionInternal::jac_sparsity ( casadi_int  oind,
casadi_int  iind,
bool  compact,
bool  symmetric 
) const
inherited

Extra doc: https://github.com/casadi/casadi/wiki/L_kz Get, if necessary generate, the sparsity of a Jacobian block

Definition at line 1946 of file function_internal.cpp.

1947  {
1948 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
1949  // Safe access to jac_sparsity_
1950  std::lock_guard<std::mutex> lock(jac_sparsity_mtx_);
1951 #endif // CASADI_WITH_THREADSAFE_SYMBOLICS
1952  // If first call, allocate cache
1953  for (bool c : {false, true}) {
1954  if (jac_sparsity_[c].empty()) jac_sparsity_[c].resize(n_in_ * n_out_);
1955  }
1956  // Flat index
1957  casadi_int ind = iind + oind * n_in_;
1958  // Reference to the block
1959  Sparsity& jsp = jac_sparsity_[compact].at(ind);
1960  // If null, generate
1961  if (jsp.is_null()) {
1962  // Use (non)-compact pattern, if given
1963  Sparsity& jsp_other = jac_sparsity_[!compact].at(ind);
1964  if (!jsp_other.is_null()) {
1965  jsp = compact ? to_compact(oind, iind, jsp_other) : from_compact(oind, iind, jsp_other);
1966  } else {
1967  // Generate pattern
1968  Sparsity sp;
1969  bool sp_is_compact;
1970  if (!is_diff_out_.at(oind) || !is_diff_in_.at(iind)) {
1971  // All-zero sparse
1972  sp = Sparsity(nnz_out(oind), nnz_in(iind));
1973  sp_is_compact = true;
1974  } else {
1975  // Use internal routine to determine sparsity
1976  if (has_spfwd() || has_sprev() || has_jac_sparsity(oind, iind)) {
1977  sp = get_jac_sparsity(oind, iind, symmetric);
1978  }
1979  // If null, dense
1980  if (sp.is_null()) sp = Sparsity::dense(nnz_out(oind), nnz_in(iind));
1981  // Is the return the compact pattern?
1982  sp_is_compact = sp.size1() == nnz_out(oind) && sp.size2() == nnz_in(iind);
1983  }
1984  // Save to cache and convert if needed
1985  if (sp_is_compact == compact) {
1986  jsp = sp;
1987  } else {
1988  jsp_other = sp;
1989  jsp = compact ? to_compact(oind, iind, sp) : from_compact(oind, iind, sp);
1990  }
1991  }
1992  }
1993 
1994  // Make sure the Jacobian is symmetric if requested, cf. #1522, #3074, #3134
1995  if (symmetric) {
1996  if (compact) {
1997  Sparsity sp = from_compact(oind, iind, jsp);
1998  if (!sp.is_symmetric()) {
1999  sp = sp * sp.T();
2000  jsp = to_compact(oind, iind, sp);
2001  }
2002  } else {
2003  if (!jsp.is_symmetric()) jsp = jsp * jsp.T();
2004  }
2005  }
2006 
2007  // Return a reference to the block
2008  return jsp;
2009  }
std::vector< Sparsity > jac_sparsity_[2]
Cache for sparsities of the Jacobian blocks.
Sparsity to_compact(casadi_int oind, casadi_int iind, const Sparsity &sp) const
Convert to compact Jacobian sparsity pattern.
virtual bool has_jac_sparsity(casadi_int oind, casadi_int iind) const
Get Jacobian sparsity.
Sparsity from_compact(casadi_int oind, casadi_int iind, const Sparsity &sp) const
Convert from compact Jacobian sparsity pattern.
virtual Sparsity get_jac_sparsity(casadi_int oind, casadi_int iind, bool symmetric) const
Get Jacobian sparsity.

References casadi::Sparsity::dense(), casadi::FunctionInternal::from_compact(), casadi::FunctionInternal::get_jac_sparsity(), casadi::FunctionInternal::has_jac_sparsity(), casadi::FunctionInternal::has_spfwd(), casadi::FunctionInternal::has_sprev(), casadi::FunctionInternal::is_diff_in_, casadi::FunctionInternal::is_diff_out_, casadi::GenericShared< Shared, Internal >::is_null(), casadi::Sparsity::is_symmetric(), casadi::FunctionInternal::jac_sparsity_, casadi::FunctionInternal::n_in_, casadi::FunctionInternal::n_out_, casadi::FunctionInternal::nnz_in(), casadi::FunctionInternal::nnz_out(), casadi::Sparsity::size1(), casadi::Sparsity::size2(), casadi::Sparsity::T(), and casadi::FunctionInternal::to_compact().

Referenced by casadi::FunctionInternal::get_partition(), casadi::FunctionInternal::sp_forward_block(), and casadi::FunctionInternal::sp_reverse().

◆ jacobian()

Function casadi::FunctionInternal::jacobian ( ) const
inherited

Extra doc: https://github.com/casadi/casadi/wiki/L_ky

Definition at line 2341 of file function_internal.cpp.

2341  {
2342  // Used wrapped function if jacobian not available
2343  if (!has_jacobian()) {
2344  // Derivative information must be available
2345  casadi_assert(has_derivative(),
2346  "Derivatives cannot be calculated for " + name_);
2347  return wrap().jacobian();
2348  }
2349  // Retrieve/generate cached
2350  Function f;
2351  std::string fname = "jac_" + name_;
2352  if (!incache(fname, f)) {
2353  // Names of inputs
2354  std::vector<std::string> inames;
2355  for (casadi_int i=0; i<n_in_; ++i) inames.push_back(name_in_[i]);
2356  for (casadi_int i=0; i<n_out_; ++i) inames.push_back("out_" + name_out_[i]);
2357  // Names of outputs
2358  std::vector<std::string> onames;
2359  onames.reserve(n_in_ * n_out_);
2360  for (size_t oind = 0; oind < n_out_; ++oind) {
2361  for (size_t iind = 0; iind < n_in_; ++iind) {
2362  onames.push_back("jac_" + name_out_[oind] + "_" + name_in_[iind]);
2363  }
2364  }
2365  // Options
2367  opts["derivative_of"] = self();
2368  // Generate derivative function
2369  casadi_assert_dev(enable_jacobian_);
2370  f = get_jacobian(fname, inames, onames, opts);
2371  // Consistency checks
2372  casadi_assert(f.n_in() == inames.size(),
2373  "Mismatching input signature, expected " + str(inames));
2374  casadi_assert(f.n_out() == onames.size(),
2375  "Mismatching output signature, expected " + str(onames));
2376  // Save to cache
2377  tocache_if_missing(f);
2378  }
2379  return f;
2380  }
virtual bool has_jacobian() const
Return Jacobian of all input elements with respect to all output elements.
virtual Function get_jacobian(const std::string &name, const std::vector< std::string > &inames, const std::vector< std::string > &onames, const Dict &opts) const
Return Jacobian of all input elements with respect to all output elements.
Function jacobian() const
Calculate all Jacobian blocks.
Definition: function.cpp:916

References casadi::combine(), casadi::FunctionInternal::der_options_, casadi::FunctionInternal::enable_jacobian_, casadi::FunctionInternal::get_jacobian(), casadi::FunctionInternal::has_derivative(), casadi::FunctionInternal::has_jacobian(), casadi::FunctionInternal::incache(), casadi::Function::jacobian(), casadi::FunctionInternal::jacobian_options_, casadi::Function::n_in(), casadi::FunctionInternal::n_in_, casadi::Function::n_out(), casadi::FunctionInternal::n_out_, casadi::ProtoFunction::name_, casadi::FunctionInternal::name_in_, casadi::FunctionInternal::name_out_, casadi::str(), casadi::FunctionInternal::tocache_if_missing(), and casadi::FunctionInternal::wrap().

Referenced by casadi::FunctionInternal::call_forward(), casadi::FunctionInternal::call_reverse(), and casadi::Function::jacobian().

◆ jit_dependencies()

virtual void casadi::FunctionInternal::jit_dependencies ( const std::string &  fname)
inlinevirtualinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_m4

Reimplemented in casadi::OracleFunction.

Definition at line 919 of file function_internal.hpp.

919 {}

Referenced by casadi::FunctionInternal::finalize().

◆ map()

Function casadi::FunctionInternal::map ( casadi_int  n,
const std::string &  parallelization 
) const
inherited

Extra doc: https://github.com/casadi/casadi/wiki/L_nd

Definition at line 1091 of file function_internal.cpp.

1091  {
1092  Function f;
1093  if (parallelization=="serial") {
1094  // Serial maps are cached
1095  std::string fname = "map" + str(n) + "_" + name_;
1096  if (!incache(fname, f)) {
1097  // Create new serial map
1098  f = Map::create(parallelization, self(), n);
1099  casadi_assert_dev(f.name()==fname);
1100  // Save in cache
1101  tocache_if_missing(f);
1102  }
1103  } else {
1104  // Non-serial maps are not cached
1105  f = Map::create(parallelization, self(), n);
1106  }
1107  return f;
1108  }
static Function create(const std::string &parallelization, const Function &f, casadi_int n)
Definition: map.cpp:39

References casadi::Map::create(), casadi::FunctionInternal::incache(), casadi::Function::name(), casadi::ProtoFunction::name_, casadi::str(), and casadi::FunctionInternal::tocache_if_missing().

Referenced by casadi::Dple::get_forward(), casadi::Dple::get_reverse(), and casadi::FunctionInternal::mapsum_mx().

◆ mapsum_mx()

std::vector< MX > casadi::FunctionInternal::mapsum_mx ( const std::vector< MX > &  arg,
const std::string &  parallelization 
)
inherited

Extra doc: https://github.com/casadi/casadi/wiki/L_kw

Definition at line 3423 of file function_internal.cpp.

3424  {
3425  if (x.empty()) return x;
3426  // Check number of arguments
3427  casadi_assert(x.size()==n_in_, "mapsum_mx: Wrong number_i of arguments");
3428  // Number of parallel calls
3429  casadi_int npar = 1;
3430  // Check/replace arguments
3431  std::vector<MX> x_mod(x.size());
3432  for (casadi_int i=0; i<n_in_; ++i) {
3433  if (check_mat(x[i].sparsity(), sparsity_in_[i], npar)) {
3434  x_mod[i] = replace_mat(x[i], sparsity_in_[i], npar);
3435  } else {
3436  // Mismatching sparsity: The following will throw an error message
3437  npar = 0;
3438  check_arg(x, npar);
3439  }
3440  }
3441 
3442  casadi_int n = 1;
3443  for (casadi_int i=0; i<x_mod.size(); ++i) {
3444  n = std::max(x_mod[i].size2() / size2_in(i), n);
3445  }
3446 
3447  std::vector<casadi_int> reduce_in;
3448  for (casadi_int i=0; i<x_mod.size(); ++i) {
3449  if (x_mod[i].size2()/size2_in(i)!=n) {
3450  reduce_in.push_back(i);
3451  }
3452  }
3453 
3454  Function ms = self().map("mapsum", parallelization, n, reduce_in, range(n_out_));
3455 
3456  // Call the internal function
3457  return ms(x_mod);
3458  }
Function map(casadi_int n, const std::string &parallelization) const
Generate/retrieve cached serial map.
void check_arg(const std::vector< M > &arg, casadi_int &npar) const
Check if input arguments have correct length and dimensions.
M replace_mat(const M &arg, const Sparsity &inp, casadi_int npar)

References casadi::FunctionInternal::check_arg(), casadi::FunctionInternal::check_mat(), casadi::FunctionInternal::map(), casadi::FunctionInternal::n_in_, casadi::FunctionInternal::n_out_, casadi::range(), casadi::replace_mat(), casadi::FunctionInternal::size2_in(), and casadi::FunctionInternal::sparsity_in_.

◆ matching_arg()

template<typename M >
bool casadi::FunctionInternal::matching_arg ( const std::vector< M > &  arg,
casadi_int &  npar 
) const
inherited

Raises errors

Parameters
npar[in]normal usage: 1, disallow pararallel calls: -1
[out]nparmax number of horizontal repetitions across all arguments (or -1)

Extra doc: https://github.com/casadi/casadi/wiki/L_kk

Definition at line 1745 of file function_internal.hpp.

1745  {
1746  check_arg(arg, npar);
1747  for (casadi_int i=0; i<n_in_; ++i) {
1748  if (arg.at(i).size1()!=size1_in(i)) return false;
1749  if (arg.at(i).size2()!=size2_in(i) && arg.at(i).size2()!=npar*size2_in(i)) return false;
1750  }
1751  return true;
1752  }

References casadi::FunctionInternal::check_arg(), casadi::FunctionInternal::n_in_, casadi::FunctionInternal::size1_in(), and casadi::FunctionInternal::size2_in().

Referenced by casadi::MXFunction::ad_forward(), ad_forward(), casadi::FunctionInternal::call(), casadi::FunctionInternal::call_forward(), and casadi::FunctionInternal::nz_in().

◆ matching_res()

template<typename M >
bool casadi::FunctionInternal::matching_res ( const std::vector< M > &  arg,
casadi_int &  npar 
) const
inherited

Raises errors

Parameters
npar[in]normal usage: 1, disallow pararallel calls: -1
[out]nparmax number of horizontal repetitions across all arguments (or -1)

Extra doc: https://github.com/casadi/casadi/wiki/L_kl

Definition at line 1755 of file function_internal.hpp.

1755  {
1756  check_res(res, npar);
1757  for (casadi_int i=0; i<n_out_; ++i) {
1758  if (res.at(i).size1()!=size1_out(i)) return false;
1759  if (res.at(i).size2()!=size2_out(i) && res.at(i).size2()!=npar*size2_out(i)) return false;
1760  }
1761  return true;
1762  }
void check_res(const std::vector< M > &res, casadi_int &npar) const
Check if output arguments have correct length and dimensions.

References casadi::FunctionInternal::check_res(), casadi::FunctionInternal::n_out_, casadi::FunctionInternal::size1_out(), and casadi::FunctionInternal::size2_out().

Referenced by casadi::MXFunction::ad_reverse(), ad_reverse(), casadi::FunctionInternal::call_reverse(), and casadi::FunctionInternal::nz_out().

◆ memory()

void * casadi::ProtoFunction::memory ( int  ind) const
inherited

Definition at line 3658 of file function_internal.cpp.

3658  {
3659 #ifdef CASADI_WITH_THREAD
3660  std::lock_guard<std::mutex> lock(mtx_);
3661 #endif //CASADI_WITH_THREAD
3662  return mem_.at(ind);
3663  }

Referenced by casadi::FunctionInternal::call_gen(), casadi::FunctionInternal::get_jac_sparsity_gen(), casadi::FunctionInternal::get_jac_sparsity_hierarchical(), casadi::Sqpmethod::solve_ela_QP(), and casadi::Sqpmethod::solve_QP().

◆ merge()

void casadi::FunctionInternal::merge ( const std::vector< MX > &  arg,
std::vector< MX > &  subs_from,
std::vector< MX > &  subs_to 
) const
virtualinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_2b8

Reimplemented in casadi::BlazingSplineFunction.

Definition at line 3372 of file function_internal.cpp.

3373  {
3374  return;
3375  }

◆ mx_in() [1/2]

const std::vector< MX > casadi::FunctionInternal::mx_in ( ) const
virtualinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_l7

Reimplemented in casadi::MXFunction.

Definition at line 3352 of file function_internal.cpp.

3352  {
3353  std::vector<MX> ret(n_in_);
3354  for (casadi_int i=0; i<ret.size(); ++i) {
3355  ret[i] = mx_in(i);
3356  }
3357  return ret;
3358  }
virtual const std::vector< MX > mx_in() const
Get function input(s) and output(s)

References casadi::FunctionInternal::n_in_.

Referenced by casadi::Nlpsol::get_forward(), casadi::LinearInterpolantJac::get_jacobian(), casadi::Nlpsol::get_reverse(), casadi::FunctionInternal::wrap(), and casadi::FunctionInternal::wrap_as_needed().

◆ mx_in() [2/2]

const MX casadi::FunctionInternal::mx_in ( casadi_int  ind) const
virtualinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_l7

Reimplemented in casadi::MXFunction.

Definition at line 3344 of file function_internal.cpp.

3344  {
3345  return MX::sym(name_in_.at(ind), sparsity_in(ind));
3346  }
static MX sym(const std::string &name, casadi_int nrow=1, casadi_int ncol=1)
Create an nrow-by-ncol symbolic primitive.

References casadi::FunctionInternal::name_in_, casadi::FunctionInternal::sparsity_in(), and casadi::GenericMatrix< MX >::sym().

◆ mx_out() [1/2]

const std::vector< MX > casadi::FunctionInternal::mx_out ( ) const
virtualinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_l7

Definition at line 3360 of file function_internal.cpp.

3360  {
3361  std::vector<MX> ret(n_out_);
3362  for (casadi_int i=0; i<ret.size(); ++i) {
3363  ret[i] = mx_out(i);
3364  }
3365  return ret;
3366  }
virtual const std::vector< MX > mx_out() const
Get function input(s) and output(s)

References casadi::FunctionInternal::n_out_.

Referenced by casadi::Nlpsol::get_forward(), and casadi::Nlpsol::get_reverse().

◆ mx_out() [2/2]

const MX casadi::FunctionInternal::mx_out ( casadi_int  ind) const
virtualinherited

◆ n_instructions()

casadi_int casadi::SXFunction::n_instructions ( ) const
inlineoverridevirtual

Extra doc: https://github.com/casadi/casadi/wiki/L_uq

Reimplemented from casadi::FunctionInternal.

Definition at line 177 of file sx_function.hpp.

177 { return algorithm_.size();}

Referenced by SXFunction().

◆ n_nodes()

casadi_int casadi::SXFunction::n_nodes ( ) const
inlineoverridevirtual

Extra doc: https://github.com/casadi/casadi/wiki/L_uv

Reimplemented from casadi::FunctionInternal.

Definition at line 226 of file sx_function.hpp.

226 { return algorithm_.size() - nnz_out();}

◆ nnz_in() [1/2]

casadi_int casadi::FunctionInternal::nnz_in ( ) const
inherited

Extra doc: https://github.com/casadi/casadi/wiki/L_me

Definition at line 2301 of file function_internal.cpp.

2301  {
2302  casadi_int ret=0;
2303  for (casadi_int iind=0; iind<n_in_; ++iind) ret += nnz_in(iind);
2304  return ret;
2305  }

References casadi::FunctionInternal::n_in_.

Referenced by casadi::FunctionInternal::adjViaJac(), casadi::FunctionInternal::call_gen(), casadi::JitFunction::codegen_body(), casadi::FunctionInternal::codegen_meta(), casadi::FunctionInternal::eval_gen(), casadi::CallbackInternal::finalize(), casadi::FunctionInternal::from_compact(), casadi::FunctionInternal::fwdViaJac(), casadi::FunctionInternal::generate_in(), casadi::FunctionInternal::get_jac_sparsity(), casadi::Expm::get_jac_sparsity(), casadi::FmuFunction::get_jac_sparsity(), casadi::FunctionInternal::get_jac_sparsity_gen(), casadi::FunctionInternal::get_jac_sparsity_hierarchical(), casadi::FunctionInternal::get_jac_sparsity_hierarchical_symm(), casadi::JitFunction::init(), casadi::Nlpsol::init(), casadi::CbcInterface::init(), casadi::ClpInterface::init(), casadi::CplexInterface::init(), casadi::OoqpInterface::init(), casadi::ProxqpInterface::init(), casadi::QpoasesInterface::init(), casadi::ImplicitToNlp::init(), casadi::FunctionInternal::jac_sparsity(), casadi::FunctionInternal::nz_in(), casadi::ImplicitToNlp::set_work(), casadi::CbcInterface::solve(), casadi::ClpInterface::solve(), casadi::CplexInterface::solve(), casadi::OoqpInterface::solve(), casadi::ProxqpInterface::solve(), casadi::QpToNlp::solve(), casadi::KinsolInterface::solve(), casadi::FunctionInternal::sp_forward(), and casadi::FunctionInternal::sp_reverse().

◆ nnz_in() [2/2]

casadi_int casadi::FunctionInternal::nnz_in ( casadi_int  ind) const
inlineinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_me

Definition at line 974 of file function_internal.hpp.

974 { return sparsity_in(ind).nnz(); }
casadi_int nnz() const
Get the number of (structural) non-zeros.
Definition: sparsity.cpp:148

◆ nnz_out() [1/2]

casadi_int casadi::FunctionInternal::nnz_out ( ) const
inherited

◆ nnz_out() [2/2]

casadi_int casadi::FunctionInternal::nnz_out ( casadi_int  ind) const
inlineinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_me

Definition at line 976 of file function_internal.hpp.

976 { return sparsity_out(ind).nnz(); }

◆ numel_in() [1/2]

casadi_int casadi::FunctionInternal::numel_in ( ) const
inherited

Extra doc: https://github.com/casadi/casadi/wiki/L_mf

Definition at line 2313 of file function_internal.cpp.

2313  {
2314  casadi_int ret=0;
2315  for (casadi_int iind=0; iind<n_in_; ++iind) ret += numel_in(iind);
2316  return ret;
2317  }

References casadi::FunctionInternal::n_in_.

Referenced by casadi::FunctionInternal::from_compact(), and casadi::Integrator::get_reverse().

◆ numel_in() [2/2]

casadi_int casadi::FunctionInternal::numel_in ( casadi_int  ind) const
inlineinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_mf

Definition at line 984 of file function_internal.hpp.

984 { return sparsity_in(ind).numel(); }
casadi_int numel() const
The total number of elements, including structural zeros, i.e. size2()*size1()
Definition: sparsity.cpp:132

◆ numel_out() [1/2]

casadi_int casadi::FunctionInternal::numel_out ( ) const
inherited

Extra doc: https://github.com/casadi/casadi/wiki/L_mf

Definition at line 2319 of file function_internal.cpp.

2319  {
2320  casadi_int ret=0;
2321  for (casadi_int oind=0; oind<n_out_; ++oind) ret += numel_out(oind);
2322  return ret;
2323  }

References casadi::FunctionInternal::n_out_.

Referenced by casadi::FunctionInternal::from_compact(), and casadi::Integrator::get_reverse().

◆ numel_out() [2/2]

casadi_int casadi::FunctionInternal::numel_out ( casadi_int  ind) const
inlineinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_mf

Definition at line 985 of file function_internal.hpp.

985 { return sparsity_out(ind).numel(); }

◆ nz_in() [1/2]

std::vector< double > casadi::FunctionInternal::nz_in ( const std::vector< DM > &  arg) const
inherited

Extra doc: https://github.com/casadi/casadi/wiki/L_kt

Definition at line 3513 of file function_internal.cpp.

3513  {
3514  // Disallow parallel inputs
3515  casadi_int npar = -1;
3516  if (!matching_arg(arg, npar)) {
3517  return nz_in(replace_arg(arg, npar));
3518  }
3519 
3520  std::vector<DM> arg2 = project_arg(arg, 1);
3521  std::vector<double> ret(nnz_in());
3522  casadi_int offset = 0;
3523  for (casadi_int i=0;i<n_in_;++i) {
3524  const double* e = arg2.at(i).ptr();
3525  std::copy(e, e+nnz_in(i), ret.begin()+offset);
3526  offset+= nnz_in(i);
3527  }
3528  return ret;
3529  }

References casadi::FunctionInternal::matching_arg(), casadi::FunctionInternal::n_in_, casadi::FunctionInternal::nnz_in(), casadi::FunctionInternal::project_arg(), and casadi::FunctionInternal::replace_arg().

Referenced by call_fwd(), call_rev(), call_setup(), casadi::FunctionInternal::get_jac_sparsity(), casadi::FunctionInternal::get_jac_sparsity_gen(), and casadi::FunctionInternal::get_jac_sparsity_hierarchical().

◆ nz_in() [2/2]

std::vector< DM > casadi::FunctionInternal::nz_in ( const std::vector< double > &  arg) const
inherited

Extra doc: https://github.com/casadi/casadi/wiki/L_kt

Definition at line 3483 of file function_internal.cpp.

3483  {
3484  casadi_assert(nnz_in()==arg.size(),
3485  "Dimension mismatch. Expecting " + str(nnz_in()) +
3486  ", got " + str(arg.size()) + " instead.");
3487 
3488  std::vector<DM> ret = dm_in();
3489  casadi_int offset = 0;
3490  for (casadi_int i=0;i<n_in_;++i) {
3491  DM& r = ret.at(i);
3492  std::copy(arg.begin()+offset, arg.begin()+offset+nnz_in(i), r.ptr());
3493  offset+= nnz_in(i);
3494  }
3495  return ret;
3496  }
Matrix< double > DM
Definition: dm_fwd.hpp:33

References casadi::FunctionInternal::dm_in(), casadi::FunctionInternal::n_in_, casadi::FunctionInternal::nnz_in(), casadi::Matrix< Scalar >::ptr(), and casadi::str().

◆ nz_out() [1/2]

std::vector< double > casadi::FunctionInternal::nz_out ( const std::vector< DM > &  res) const
inherited

Extra doc: https://github.com/casadi/casadi/wiki/L_kt

Definition at line 3531 of file function_internal.cpp.

3531  {
3532  // Disallow parallel inputs
3533  casadi_int npar = -1;
3534  if (!matching_res(res, npar)) {
3535  return nz_out(replace_res(res, npar));
3536  }
3537 
3538  std::vector<DM> res2 = project_res(res, 1);
3539  std::vector<double> ret(nnz_out());
3540  casadi_int offset = 0;
3541  for (casadi_int i=0;i<n_out_;++i) {
3542  const double* e = res2.at(i).ptr();
3543  std::copy(e, e+nnz_out(i), ret.begin()+offset);
3544  offset+= nnz_out(i);
3545  }
3546  return ret;
3547  }
std::vector< M > project_res(const std::vector< M > &arg, casadi_int npar) const
Project sparsities.
std::vector< M > replace_res(const std::vector< M > &res, casadi_int npar) const
Replace 0-by-0 outputs.

References casadi::FunctionInternal::matching_res(), casadi::FunctionInternal::n_out_, casadi::FunctionInternal::nnz_out(), casadi::FunctionInternal::project_res(), and casadi::FunctionInternal::replace_res().

Referenced by call_fwd(), call_rev(), call_setup(), casadi::FunctionInternal::get_jac_sparsity(), casadi::FunctionInternal::get_jac_sparsity_gen(), and casadi::FunctionInternal::get_jac_sparsity_hierarchical().

◆ nz_out() [2/2]

std::vector< DM > casadi::FunctionInternal::nz_out ( const std::vector< double > &  res) const
inherited

Extra doc: https://github.com/casadi/casadi/wiki/L_kt

Definition at line 3498 of file function_internal.cpp.

3498  {
3499  casadi_assert(nnz_out()==res.size(),
3500  "Dimension mismatch. Expecting " + str(nnz_out()) +
3501  ", got " + str(res.size()) + " instead.");
3502 
3503  std::vector<DM> ret = dm_out();
3504  casadi_int offset = 0;
3505  for (casadi_int i=0;i<n_out_;++i) {
3506  DM& r = ret.at(i);
3507  std::copy(res.begin()+offset, res.begin()+offset+nnz_out(i), r.ptr());
3508  offset+= nnz_out(i);
3509  }
3510  return ret;
3511  }

References casadi::FunctionInternal::dm_out(), casadi::FunctionInternal::n_out_, casadi::FunctionInternal::nnz_out(), casadi::Matrix< Scalar >::ptr(), and casadi::str().

◆ oracle()

const Function & casadi::FunctionInternal::oracle ( ) const
virtualinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_l3

Reimplemented in casadi::OracleFunction.

Definition at line 3736 of file function_internal.cpp.

3736  {
3737  casadi_error("'oracle' not defined for " + class_name());
3738  static Function singleton;
3739  return singleton;
3740  }

References casadi::SharedObjectInternal::class_name().

Referenced by casadi::Function::oracle(), and casadi::DaeBuilder::oracle().

◆ order()

std::vector< SX > casadi::SXFunction::order ( const std::vector< SX > &  expr)
static

Definition at line 1955 of file sx_function.cpp.

1955  {
1956 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
1957  std::lock_guard<std::mutex> lock(SX::get_mutex_temp());
1958 #endif // CASADI_WITH_THREADSAFE_SYMBOLICS
1959  // Stack used to sort the computational graph
1960  std::stack<SXNode*> s;
1961 
1962  // All nodes
1963  std::vector<SXNode*> nodes;
1964 
1965  // Add the list of nodes
1966  casadi_int ind=0;
1967  for (auto it = expr.begin(); it != expr.end(); ++it, ++ind) {
1968  casadi_int nz=0;
1969  for (auto itc = (*it)->begin(); itc != (*it)->end(); ++itc, ++nz) {
1970  // Add outputs to the list
1971  s.push(itc->get());
1973  }
1974  }
1975 
1976  // Clear temporary markers
1977  for (casadi_int i=0; i<nodes.size(); ++i) {
1978  nodes[i]->temp = 0;
1979  }
1980 
1981  std::vector<SX> ret(nodes.size());
1982  for (casadi_int i=0; i<nodes.size(); ++i) {
1983  ret[i] = SXElem::create(nodes[i]);
1984  }
1985 
1986  return ret;
1987  }

References casadi::SXElem::create(), and casadi::XFunction< DerivedType, MatType, NodeType >::sort_depth_first().

Referenced by casadi::Function::order().

◆ print() [1/2]

void casadi::ProtoFunction::print ( const char *  fmt,
  ... 
) const
inherited

Extra doc: https://github.com/casadi/casadi/wiki/L_jr

Definition at line 3897 of file function_internal.cpp.

3897  {
3898  // Variable number of arguments
3899  va_list args;
3900  va_start(args, fmt);
3901  // Static & dynamic buffers
3902  char buf[256];
3903  size_t buf_sz = sizeof(buf);
3904  char* buf_dyn = nullptr;
3905  // Try to print with a small buffer
3906  casadi_int n = vsnprintf(buf, buf_sz, fmt, args);
3907  // Need a larger buffer?
3908  if (n>static_cast<casadi_int>(buf_sz)) {
3909  buf_sz = static_cast<size_t>(n+1);
3910  buf_dyn = new char[buf_sz];
3911  n = vsnprintf(buf_dyn, buf_sz, fmt, args);
3912  }
3913  // Print buffer content
3914  if (n>=0) uout() << (buf_dyn ? buf_dyn : buf) << std::flush;
3915  // Cleanup
3916  delete[] buf_dyn;
3917  va_end(args);
3918  // Throw error if failure
3919  casadi_assert(n>=0, "Print failure while processing '" + std::string(fmt) + "'");
3920  }

References casadi::uout().

Referenced by casadi::Feasiblesqpmethod::anderson_acc_step_update(), casadi::Nlpsol::callback(), casadi::Blocksqp::convertHessian(), casadi::FmuFunction::eval_task(), casadi::Feasiblesqpmethod::feasibility_iterations(), casadi::Blocksqp::feasibilityRestorationPhase(), casadi::Blocksqp::fullstep(), casadi::Blocksqp::init(), casadi::Feasiblesqpmethod::init(), casadi::Ipqp::init(), casadi::Qrqp::init(), casadi::Qrsqp::init(), casadi::Sqpmethod::init(), casadi::LinsolQr::nfact(), casadi::Feasiblesqpmethod::print_iteration(), casadi::Qrsqp::print_iteration(), casadi::Sqpmethod::print_iteration(), casadi::SundialsInterface::print_stats(), casadi::ProtoFunction::print_time(), casadi::Blocksqp::printInfo(), casadi::Blocksqp::printProgress(), casadi::Blocksqp::run(), casadi::Blocksqp::solve(), casadi::Feasiblesqpmethod::solve(), casadi::Qrsqp::solve(), casadi::Sqpmethod::solve(), casadi::Sqpmethod::solve_ela_QP(), casadi::Feasiblesqpmethod::solve_LP(), casadi::Feasiblesqpmethod::solve_QP(), casadi::Qrsqp::solve_QP(), casadi::Sqpmethod::solve_QP(), and casadi::Blocksqp::solveQP().

◆ print() [2/2]

std::string casadi::SXFunction::print ( const ScalarAtomic a) const

Definition at line 138 of file sx_function.cpp.

138  {
139  std::stringstream stream;
140  if (a.op==OP_OUTPUT) {
141  stream << "output[" << a.i0 << "][" << a.i2 << "] = @" << a.i1;
142  } else if (a.op==OP_CALL) {
143  const ExtendedAlgEl& m = call_.el.at(a.i1);
144  stream << "[";
145  casadi_int k = 0;
146  for (casadi_int i=0; i<m.f.n_out(); ++i) {
147  if (m.f.nnz_out(i)>1) stream << "[";
148  for (casadi_int j=0; j<m.f.nnz_out(i); ++j) {
149  int el = m.res[k++];
150  if (el>=0) {
151  stream << "@" << el;
152  } else {
153  stream << "NULL";
154  }
155  if (j<m.f.nnz_out(i)-1) stream << ",";
156  }
157  if (m.f.nnz_out(i)>1) stream << "]";
158  if (i<m.f.n_out()-1) stream << ",";
159  }
160  stream << "] = ";
161  stream << m.f.name() << "(";
162  k = 0;
163  for (casadi_int i=0; i<m.f.n_in(); ++i) {
164  if (m.f.nnz_in(i)==0) stream << "0x0";
165  if (m.f.nnz_in(i)>1) stream << "[";
166  for (casadi_int j=0; j<m.f.nnz_in(i); ++j) {
167  stream << "@" << m.dep[k++];
168  if (j<m.f.nnz_in(i)-1) stream << ",";
169  }
170  if (m.f.nnz_in(i)>1) stream << "]";
171  if (i<m.f.n_in()-1) stream << ",";
172  }
173  stream << ")";
174  } else {
175  stream << "@" << a.i0 << " = ";
176  if (a.op==OP_INPUT) {
177  stream << "input[" << a.i1 << "][" << a.i2 << "]";
178  } else {
179  if (a.op==OP_CONST) {
180  stream << a.d;
181  } else if (a.op==OP_PARAMETER) {
182  stream << free_vars_[a.i1];
183  } else {
184  casadi_int ndep = casadi_math<double>::ndeps(a.op);
185  stream << casadi_math<double>::pre(a.op);
186  for (casadi_int c=0; c<ndep; ++c) {
187  if (c==0) {
188  stream << "@" << a.i1;
189  } else {
190  stream << casadi_math<double>::sep(a.op);
191  stream << "@" << a.i2;
192  }
193 
194  }
195  stream << casadi_math<double>::post(a.op);
196  }
197  }
198  }
199  return stream.str();
200  }

References call_, casadi::ScalarAtomic::d, casadi::SXFunction::ExtendedAlgEl::dep, casadi::SXFunction::CallInfo::el, casadi::SXFunction::ExtendedAlgEl::f, free_vars_, casadi::ScalarAtomic::i0, casadi::ScalarAtomic::i1, casadi::ScalarAtomic::i2, casadi::Function::n_in(), casadi::Function::n_out(), casadi::Function::name(), casadi::casadi_math< T >::ndeps(), casadi::Function::nnz_in(), casadi::Function::nnz_out(), casadi::ScalarAtomic::op, casadi::OP_CALL, casadi::OP_CONST, casadi::OP_INPUT, casadi::OP_OUTPUT, casadi::OP_PARAMETER, and casadi::SXFunction::ExtendedAlgEl::res.

Referenced by disp_more(), print_arg(), and print_res().

◆ print_arg() [1/2]

void casadi::SXFunction::print_arg ( CodeGenerator g,
casadi_int  k,
const ScalarAtomic el 
) const

Definition at line 273 of file sx_function.cpp.

273  {
274  if (el.op==OP_INPUT || el.op==OP_OUTPUT || el.op==OP_CONST) return;
275  g << g.printf(name_ + ":" + str(k) + ": " + print(el) + " inputs:\\n") << "\n";
276  if (el.op==OP_CALL) {
277  const ExtendedAlgEl& m = call_.el[el.i1];
278  g << g.print_vector(m.f.nnz_in(), "arg[" + str(n_in_) + "]");
279  g << g.printf("\\n");
280  } else {
281  casadi_int ndeps = casadi_math<double>::ndeps(el.op);
282  if (ndeps==1) {
283  g << g.printf("0: %.16e\\n", g.sx_work(el.i1));
284  } else if (ndeps==2) {
285  g << g.printf("0: %.16e\\n1: %.16e\\n", g.sx_work(el.i1), g.sx_work(el.i2));
286  }
287  }
288  g << "\n";
289  }

References call_, casadi::SXFunction::CallInfo::el, casadi::SXFunction::ExtendedAlgEl::f, casadi::ScalarAtomic::i1, casadi::ScalarAtomic::i2, casadi::FunctionInternal::n_in_, casadi::ProtoFunction::name_, casadi::casadi_math< T >::ndeps(), casadi::Function::nnz_in(), casadi::ScalarAtomic::op, casadi::OP_CALL, casadi::OP_CONST, casadi::OP_INPUT, casadi::OP_OUTPUT, print(), casadi::CodeGenerator::print_vector(), casadi::CodeGenerator::printf(), casadi::str(), and casadi::CodeGenerator::sx_work().

◆ print_arg() [2/2]

void casadi::SXFunction::print_arg ( std::ostream &  stream,
casadi_int  k,
const ScalarAtomic el,
const double *  w 
) const

Definition at line 234 of file sx_function.cpp.

235  {
236  if (el.op==OP_INPUT || el.op==OP_OUTPUT || el.op==OP_CONST) return;
237  stream << name_ << ":" << k << ": " << print(el) << " inputs:" << std::endl;
238 
239  // Default dependencies
240  const int* dep = &el.i1;
241  casadi_int ndeps = casadi_math<double>::ndeps(el.op);
242 
243  // Call node overrides these defaults
244  if (el.op==OP_CALL) {
245  const ExtendedAlgEl& e = call_.el.at(el.i1);
246  ndeps = e.n_dep;
247  dep = get_ptr(e.dep);
248  stream << "[";
249  for (size_t i = 0; i < ndeps; ++i) {
250  if (i>0) stream << ", ";
251  if (print_canonical_) {
252  print_canonical(stream, w[dep[i]]);
253  } else {
254  DM::print_scalar(stream, w[dep[i]]);
255  }
256  }
257  stream << "]";
258  stream << std::endl;
259  return;
260  }
261 
262  for (size_t i = 0; i < ndeps; ++i) {
263  stream << i << ": ";
264  if (print_canonical_) {
265  print_canonical(stream, w[dep[i]]);
266  } else {
267  DM::print_scalar(stream, w[dep[i]]);
268  }
269  stream << std::endl;
270  }
271  }
static void print_canonical(std::ostream &stream, const Sparsity &sp, const double *nz)
Print canonical representation of a numeric matrix.
void print_scalar(std::ostream &stream) const
Print scalar.

References call_, casadi::SXFunction::ExtendedAlgEl::dep, casadi::SXFunction::CallInfo::el, casadi::get_ptr(), casadi::ScalarAtomic::i1, casadi::SXFunction::ExtendedAlgEl::n_dep, casadi::ProtoFunction::name_, casadi::casadi_math< T >::ndeps(), casadi::ScalarAtomic::op, casadi::OP_CALL, casadi::OP_CONST, casadi::OP_INPUT, casadi::OP_OUTPUT, print(), casadi::FunctionInternal::print_canonical(), casadi::FunctionInternal::print_canonical_, and casadi::Matrix< double >::print_scalar().

Referenced by codegen_body(), and eval().

◆ print_canonical() [1/3]

void casadi::FunctionInternal::print_canonical ( std::ostream &  stream,
casadi_int  sz,
const double *  nz 
)
staticinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_2di

Definition at line 858 of file function_internal.cpp.

858  {
859  StreamStateGuard backup(stream);
860  normalized_setup(stream);
861  if (nz) {
862  stream << "[";
863  for (casadi_int i=0; i<sz; ++i) {
864  if (i>0) stream << ", ";
865  normalized_out(stream, nz[i]);
866  }
867  stream << "]";
868  } else {
869  stream << "NULL";
870  }
871  }

References casadi::normalized_out(), and casadi::normalized_setup().

◆ print_canonical() [2/3]

void casadi::FunctionInternal::print_canonical ( std::ostream &  stream,
const Sparsity sp,
const double *  nz 
)
staticinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_2dh

Definition at line 873 of file function_internal.cpp.

874  {
875  StreamStateGuard backup(stream);
876  normalized_setup(stream);
877  if (nz) {
878  if (!sp.is_scalar(true)) {
879  stream << sp.dim(false) << ": ";
880  stream << "[";
881  }
882  for (casadi_int i=0; i<sp.nnz(); ++i) {
883  if (i>0) stream << ", ";
884  normalized_out(stream, nz[i]);
885  }
886  if (!sp.is_scalar(true)) {
887  stream << "]";
888  if (!sp.is_dense()) {
889  stream << ", colind: [";
890  for (casadi_int i=0; i<sp.size2(); ++i) {
891  if (i>0) stream << ", ";
892  stream << sp.colind()[i];
893  }
894  stream << "]";
895  stream << ", row: [";
896  for (casadi_int i=0; i<sp.nnz(); ++i) {
897  if (i>0) stream << ", ";
898  stream << sp.row()[i];
899  }
900  stream << "]";
901  }
902  }
903  } else {
904  stream << "NULL";
905  }
906  }

References casadi::Sparsity::colind(), casadi::Sparsity::dim(), casadi::Sparsity::is_dense(), casadi::Sparsity::is_scalar(), casadi::Sparsity::nnz(), casadi::normalized_out(), casadi::normalized_setup(), casadi::Sparsity::row(), and casadi::Sparsity::size2().

Referenced by casadi::Monitor::eval(), casadi::MXFunction::print_arg(), print_arg(), casadi::FunctionInternal::print_in(), casadi::FunctionInternal::print_out(), casadi::MXFunction::print_res(), and print_res().

◆ print_canonical() [3/3]

void casadi::FunctionInternal::print_canonical ( std::ostream &  stream,
double  a 
)
staticinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_2dj

Definition at line 908 of file function_internal.cpp.

908  {
909  StreamStateGuard backup(stream);
910  normalized_setup(stream);
911  normalized_out(stream, a);
912  }

References casadi::normalized_out(), and casadi::normalized_setup().

◆ print_dimensions()

void casadi::FunctionInternal::print_dimensions ( std::ostream &  stream) const
inherited

Extra doc: https://github.com/casadi/casadi/wiki/L_mb

Definition at line 983 of file function_internal.cpp.

983  {
984  stream << " Number of inputs: " << n_in_ << std::endl;
985  for (casadi_int i=0; i<n_in_; ++i) {
986  stream << " Input " << i << " (\"" << name_in_[i] << "\"): "
987  << sparsity_in_[i].dim() << std::endl;
988  }
989  stream << " Number of outputs: " << n_out_ << std::endl;
990  for (casadi_int i=0; i<n_out_; ++i) {
991  stream << " Output " << i << " (\"" << name_out_[i] << "\"): "
992  << sparsity_out_[i].dim() << std::endl;
993  }
994  }

References casadi::FunctionInternal::n_in_, casadi::FunctionInternal::n_out_, casadi::FunctionInternal::name_in_, casadi::FunctionInternal::name_out_, casadi::FunctionInternal::sparsity_in_, and casadi::FunctionInternal::sparsity_out_.

◆ print_in()

void casadi::FunctionInternal::print_in ( std::ostream &  stream,
const double **  arg,
bool  truncate 
) const
inherited

Extra doc: https://github.com/casadi/casadi/wiki/L_nv

Definition at line 824 of file function_internal.cpp.

824  {
825  stream << "Function " << name_ << " (" << this << ")" << std::endl;
826  for (casadi_int i=0; i<n_in_; ++i) {
827  stream << "Input " << i << " (" << name_in_[i] << "): ";
828  if (arg[i]) {
829  if (print_canonical_) {
830  print_canonical(stream, sparsity_in_[i], arg[i]);
831  } else {
832  DM::print_default(stream, sparsity_in_[i], arg[i], truncate);
833  }
834  stream << std::endl;
835  } else {
836  stream << "NULL" << std::endl;
837  }
838  }
839  }
static void print_default(std::ostream &stream, const Sparsity &sp, const double *nonzeros, bool truncate=true)
Print default style.

References casadi::FunctionInternal::n_in_, casadi::ProtoFunction::name_, casadi::FunctionInternal::name_in_, casadi::FunctionInternal::print_canonical(), casadi::FunctionInternal::print_canonical_, casadi::Matrix< double >::print_default(), and casadi::FunctionInternal::sparsity_in_.

Referenced by casadi::FunctionInternal::eval_gen().

◆ print_option()

void casadi::ProtoFunction::print_option ( const std::string &  name,
std::ostream &  stream 
) const
inherited

Extra doc: https://github.com/casadi/casadi/wiki/L_ji

Definition at line 1000 of file function_internal.cpp.

1000  {
1001  get_options().print_one(name, stream);
1002  }
void print_one(const std::string &name, std::ostream &stream) const
Print all information there is to know about a certain option.
Definition: options.cpp:274

References casadi::ProtoFunction::get_options(), and casadi::Options::print_one().

◆ print_options()

void casadi::ProtoFunction::print_options ( std::ostream &  stream) const
inherited

Extra doc: https://github.com/casadi/casadi/wiki/L_jh

Definition at line 996 of file function_internal.cpp.

996  {
997  get_options().print_all(stream);
998  }
void print_all(std::ostream &stream) const
Print list of options.
Definition: options.cpp:268

References casadi::ProtoFunction::get_options(), and casadi::Options::print_all().

◆ print_out()

void casadi::FunctionInternal::print_out ( std::ostream &  stream,
double **  res,
bool  truncate 
) const
inherited

Extra doc: https://github.com/casadi/casadi/wiki/L_nw

Definition at line 841 of file function_internal.cpp.

841  {
842  stream << "Function " << name_ << " (" << this << ")" << std::endl;
843  for (casadi_int i=0; i<n_out_; ++i) {
844  stream << "Output " << i << " (" << name_out_[i] << "): ";
845  if (res[i]) {
846  if (print_canonical_) {
847  print_canonical(stream, sparsity_out_[i], res[i]);
848  } else {
849  DM::print_default(stream, sparsity_out_[i], res[i], truncate);
850  }
851  stream << std::endl;
852  } else {
853  stream << "NULL" << std::endl;
854  }
855  }
856  }

References casadi::FunctionInternal::n_out_, casadi::ProtoFunction::name_, casadi::FunctionInternal::name_out_, casadi::FunctionInternal::print_canonical(), casadi::FunctionInternal::print_canonical_, casadi::Matrix< double >::print_default(), and casadi::FunctionInternal::sparsity_out_.

Referenced by casadi::FunctionInternal::eval_gen().

◆ print_res() [1/2]

void casadi::SXFunction::print_res ( CodeGenerator g,
casadi_int  k,
const ScalarAtomic el 
) const

Definition at line 291 of file sx_function.cpp.

291  {
292  if (el.op==OP_INPUT || el.op==OP_OUTPUT) return;
293  g << g.printf(name_ + ":" + str(k) + ": " + print(el) + " outputs:\\n") << "\n";
294  if (el.op==OP_CALL) {
295  const ExtendedAlgEl& m = call_.el[el.i1];
296  g << g.print_vector(m.f.nnz_out(), "w+" + str(m.f.nnz_in()));
297  g << g.printf("\\n");
298  } else {
299  g << g.printf("0: %.16e\\n", g.sx_work(el.i0));
300  }
301  g << "\n";
302  }

References call_, casadi::SXFunction::CallInfo::el, casadi::SXFunction::ExtendedAlgEl::f, casadi::ScalarAtomic::i0, casadi::ScalarAtomic::i1, casadi::ProtoFunction::name_, casadi::Function::nnz_in(), casadi::Function::nnz_out(), casadi::ScalarAtomic::op, casadi::OP_CALL, casadi::OP_INPUT, casadi::OP_OUTPUT, print(), casadi::CodeGenerator::print_vector(), casadi::CodeGenerator::printf(), casadi::str(), and casadi::CodeGenerator::sx_work().

◆ print_res() [2/2]

void casadi::SXFunction::print_res ( std::ostream &  stream,
casadi_int  k,
const ScalarAtomic el,
const double *  w 
) const

Definition at line 304 of file sx_function.cpp.

305  {
306  if (el.op==OP_INPUT || el.op==OP_OUTPUT) return;
307  stream << name_ << ":" << k << ": " << print(el) << " outputs:" << std::endl;
308 
309  // Default outputs
310  const int* res = &el.i0;
311  casadi_int nres = 1;
312 
313  // Call node overrides these defaults
314  if (el.op==OP_CALL) {
315  const ExtendedAlgEl& e = call_.el.at(el.i1);
316  nres = e.n_res;
317  res = get_ptr(e.res);
318  stream << "[";
319  for (size_t i = 0; i < nres; ++i) {
320  if (i>0) stream << ", ";
321  if (print_canonical_) {
322  print_canonical(stream, w[res[i]]);
323  } else {
324  DM::print_scalar(stream, w[res[i]]);
325  }
326  }
327  stream << "]";
328  stream << std::endl;
329  return;
330  }
331 
332  for (size_t i = 0; i < nres; ++i) {
333  stream << i << ": ";
334  if (print_canonical_) {
335  print_canonical(stream, w[res[i]]);
336  } else {
337  DM::print_scalar(stream, w[res[i]]);
338  }
339  stream << std::endl;
340  }
341 
342  }

References call_, casadi::SXFunction::CallInfo::el, casadi::get_ptr(), casadi::ScalarAtomic::i0, casadi::ScalarAtomic::i1, casadi::SXFunction::ExtendedAlgEl::n_res, casadi::ProtoFunction::name_, casadi::ScalarAtomic::op, casadi::OP_CALL, casadi::OP_INPUT, casadi::OP_OUTPUT, print(), casadi::FunctionInternal::print_canonical(), casadi::FunctionInternal::print_canonical_, casadi::Matrix< double >::print_scalar(), and casadi::SXFunction::ExtendedAlgEl::res.

Referenced by codegen_body(), and eval().

◆ print_time()

void casadi::ProtoFunction::print_time ( const std::map< std::string, FStats > &  fstats) const
inherited

Extra doc: https://github.com/casadi/casadi/wiki/L_ju

Definition at line 3817 of file function_internal.cpp.

3817  {
3818  if (!print_time_) return;
3819  // Length of the name being printed
3820  size_t name_len=0;
3821  for (auto &&s : fstats) {
3822  name_len = std::max(s.first.size(), name_len);
3823  }
3824  name_len = std::max(name_.size(), name_len);
3825 
3826  // Print name with a given length. Format: "%NNs "
3827  char namefmt[10];
3828  sprint(namefmt, sizeof(namefmt), "%%%ds ", static_cast<casadi_int>(name_len));
3829 
3830  // Print header
3831  print(namefmt, name_.c_str());
3832 
3833  print(" : %8s %10s %8s %10s %9s\n", "t_proc", "(avg)", "t_wall", "(avg)", "n_eval");
3834 
3835 
3836  char buffer_proc[10];
3837  char buffer_wall[10];
3838  char buffer_proc_avg[10];
3839  char buffer_wall_avg[10];
3840 
3841  // Print keys
3842  for (const auto &s : fstats) {
3843  if (s.second.n_call!=0) {
3844  print(namefmt, s.first.c_str());
3845  format_time(buffer_proc, s.second.t_proc);
3846  format_time(buffer_wall, s.second.t_wall);
3847  format_time(buffer_proc_avg, s.second.t_proc/s.second.n_call);
3848  format_time(buffer_wall_avg, s.second.t_wall/s.second.n_call);
3849  print(" | %s (%s) %s (%s) %9d\n",
3850  buffer_proc, buffer_proc_avg,
3851  buffer_wall, buffer_wall_avg, s.second.n_call);
3852  }
3853  }
3854  }
void print(const char *fmt,...) const
C-style formatted printing during evaluation.
void format_time(char *buffer, double time) const
Format time in a fixed width 8 format.

References casadi::ProtoFunction::format_time(), casadi::ProtoFunction::name_, casadi::ProtoFunction::print(), casadi::ProtoFunction::print_time_, and casadi::ProtoFunction::sprint().

Referenced by casadi::FunctionInternal::eval_gen().

◆ project_arg()

template<typename M >
std::vector< M > casadi::FunctionInternal::project_arg ( const std::vector< M > &  arg,
casadi_int  npar 
) const
inherited

Extra doc: https://github.com/casadi/casadi/wiki/L_kn

Definition at line 1617 of file function_internal.hpp.

1618  {
1619  casadi_assert_dev(arg.size()==n_in_);
1620 
1621  // Which arguments require mapped evaluation
1622  std::vector<bool> mapped(n_in_);
1623  for (casadi_int i=0; i<n_in_; ++i) {
1624  mapped[i] = arg[i].size2()!=size2_in(i);
1625  }
1626 
1627  // Check if matching input sparsity
1628  std::vector<bool> matching(n_in_);
1629  bool any_mismatch = false;
1630  for (casadi_int i=0; i<n_in_; ++i) {
1631  if (mapped[i]) {
1632  matching[i] = arg[i].sparsity().is_stacked(sparsity_in(i), npar);
1633  } else {
1634  matching[i] = arg[i].sparsity()==sparsity_in(i);
1635  }
1636  any_mismatch = any_mismatch || !matching[i];
1637  }
1638 
1639  // Correct input sparsity
1640  if (any_mismatch) {
1641  std::vector<M> arg2(arg);
1642  for (casadi_int i=0; i<n_in_; ++i) {
1643  if (!matching[i]) {
1644  if (mapped[i]) {
1645  arg2[i] = project(arg2[i], repmat(sparsity_in(i), 1, npar));
1646  } else {
1647  arg2[i] = project(arg2[i], sparsity_in(i));
1648  }
1649  }
1650  }
1651  return arg2;
1652  }
1653  return arg;
1654  }

References casadi::FunctionInternal::n_in_, casadi::FunctionInternal::size2_in(), and casadi::FunctionInternal::sparsity_in().

Referenced by casadi::FunctionInternal::call_gen(), and casadi::FunctionInternal::nz_in().

◆ project_res()

template<typename M >
std::vector< M > casadi::FunctionInternal::project_res ( const std::vector< M > &  arg,
casadi_int  npar 
) const
inherited

Extra doc: https://github.com/casadi/casadi/wiki/L_ko

Definition at line 1657 of file function_internal.hpp.

1658  {
1659  return arg;
1660  }

Referenced by casadi::FunctionInternal::nz_out().

◆ purgable()

template<typename MatType >
bool casadi::FunctionInternal::purgable ( const std::vector< MatType > &  seed)
staticinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_nq

Definition at line 1510 of file function_internal.hpp.

1510  {
1511  for (auto i=v.begin(); i!=v.end(); ++i) {
1512  if (!i->is_zero()) return false;
1513  }
1514  return true;
1515  }

Referenced by casadi::MXFunction::ad_forward(), and casadi::MXFunction::ad_reverse().

◆ release()

void casadi::ProtoFunction::release ( int  mem) const
inherited

Definition at line 3690 of file function_internal.cpp.

3690  {
3691 #ifdef CASADI_WITH_THREAD
3692  std::lock_guard<std::mutex> lock(mtx_);
3693 #endif //CASADI_WITH_THREAD
3694  unused_.push(mem);
3695  }

◆ replace_arg()

template<typename M >
std::vector< M > casadi::FunctionInternal::replace_arg ( const std::vector< M > &  arg,
casadi_int  npar 
) const
inherited

Extra doc: https://github.com/casadi/casadi/wiki/L_km

Definition at line 1790 of file function_internal.hpp.

1791  {
1792  std::vector<M> r(arg.size());
1793  for (casadi_int i=0; i<r.size(); ++i) r[i] = replace_mat(arg[i], sparsity_in(i), npar);
1794  return r;
1795  }

References casadi::replace_mat(), and casadi::FunctionInternal::sparsity_in().

Referenced by casadi::FunctionInternal::call(), casadi::FunctionInternal::nz_in(), and casadi::FunctionInternal::replace_fseed().

◆ replace_aseed() [1/2]

template<typename M >
std::vector<std::vector<M> > casadi::FunctionInternal::replace_aseed ( const std::vector< std::vector< M > > &  aseed,
casadi_int  npar 
) const
inherited

Definition at line 1814 of file function_internal.hpp.

1815  {
1816  std::vector<std::vector<M> > r(aseed.size());
1817  for (casadi_int d=0; d<r.size(); ++d) r[d] = replace_res(aseed[d], npar);
1818  return r;
1819  }

References casadi::FunctionInternal::replace_res().

◆ replace_aseed() [2/2]

template<typename M >
std::vector<std::vector<M> > casadi::FunctionInternal::replace_aseed ( const std::vector< std::vector< M >> &  aseed,
casadi_int  npar 
) const
inherited

◆ replace_fseed() [1/2]

template<typename M >
std::vector<std::vector<M> > casadi::FunctionInternal::replace_fseed ( const std::vector< std::vector< M > > &  fseed,
casadi_int  npar 
) const
inherited

Definition at line 1806 of file function_internal.hpp.

1807  {
1808  std::vector<std::vector<M> > r(fseed.size());
1809  for (casadi_int d=0; d<r.size(); ++d) r[d] = replace_arg(fseed[d], npar);
1810  return r;
1811  }

References casadi::FunctionInternal::replace_arg().

◆ replace_fseed() [2/2]

template<typename M >
std::vector<std::vector<M> > casadi::FunctionInternal::replace_fseed ( const std::vector< std::vector< M >> &  fseed,
casadi_int  npar 
) const
inherited

◆ replace_res()

template<typename M >
std::vector< M > casadi::FunctionInternal::replace_res ( const std::vector< M > &  res,
casadi_int  npar 
) const
inherited

Extra doc: https://github.com/casadi/casadi/wiki/L_kp

Definition at line 1798 of file function_internal.hpp.

1799  {
1800  std::vector<M> r(res.size());
1801  for (casadi_int i=0; i<r.size(); ++i) r[i] = replace_mat(res[i], sparsity_out(i), npar);
1802  return r;
1803  }

References casadi::replace_mat(), and casadi::FunctionInternal::sparsity_out().

Referenced by casadi::FunctionInternal::nz_out(), and casadi::FunctionInternal::replace_aseed().

◆ reset_dump_count()

void casadi::FunctionInternal::reset_dump_count ( )
inherited

Extra doc: https://github.com/casadi/casadi/wiki/L_2dx

Definition at line 461 of file function_internal.cpp.

461  {
462  dump_count_ = 0;
463  }

References casadi::FunctionInternal::dump_count_.

◆ reverse()

Function casadi::FunctionInternal::reverse ( casadi_int  nadj) const
inherited

reverse(nadj) returns a cached instance if available, and calls Function get_reverse(casadi_int nadj) if no cached version is available.

Extra doc: https://github.com/casadi/casadi/wiki/L_l1

Definition at line 2224 of file function_internal.cpp.

2224  {
2225  casadi_assert_dev(nadj>=0);
2226  // Used wrapped function if reverse not available
2227  if (!enable_reverse_) {
2228  // Derivative information must be available
2229  casadi_assert(has_derivative(), "Derivatives cannot be calculated for " + name_);
2230  return wrap().reverse(nadj);
2231  }
2232  // Retrieve/generate cached
2233  Function f;
2234  std::string fname = reverse_name(name_, nadj);
2235  if (!incache(fname, f)) {
2236  casadi_int i;
2237  // Prefix to be used for adjoint seeds, sensitivities
2238  std::string pref = diff_prefix("adj");
2239  // Names of inputs
2240  std::vector<std::string> inames;
2241  for (i=0; i<n_in_; ++i) inames.push_back(name_in_[i]);
2242  for (i=0; i<n_out_; ++i) inames.push_back("out_" + name_out_[i]);
2243  for (i=0; i<n_out_; ++i) inames.push_back(pref + name_out_[i]);
2244  // Names of outputs
2245  std::vector<std::string> onames;
2246  for (casadi_int i=0; i<n_in_; ++i) onames.push_back(pref + name_in_[i]);
2247  // Options
2249  opts = combine(opts, generate_options("reverse"));
2250  opts["derivative_of"] = self();
2251  // Generate derivative function
2252  casadi_assert_dev(enable_reverse_);
2253  f = get_reverse(nadj, fname, inames, onames, opts);
2254  // Consistency check for inputs
2255  casadi_assert_dev(f.n_in()==n_in_ + n_out_ + n_out_);
2256  casadi_int ind=0;
2257  for (i=0; i<n_in_; ++i) f.assert_size_in(ind++, size1_in(i), size2_in(i));
2258  for (i=0; i<n_out_; ++i) f.assert_size_in(ind++, size1_out(i), size2_out(i));
2259  for (i=0; i<n_out_; ++i) f.assert_size_in(ind++, size1_out(i), nadj*size2_out(i));
2260  // Consistency check for outputs
2261  casadi_assert_dev(f.n_out()==n_in_);
2262  for (i=0; i<n_in_; ++i) f.assert_sparsity_out(i, sparsity_in(i), nadj);
2263  // Save to cache
2264  tocache_if_missing(f);
2265  }
2266  return f;
2267  }
virtual Function get_reverse(casadi_int nadj, const std::string &name, const std::vector< std::string > &inames, const std::vector< std::string > &onames, const Dict &opts) const
Return function that calculates adjoint derivatives.
static std::string reverse_name(const std::string &fcn, casadi_int nadj)
Helper function: Get name of adjoint derivative function.
Function reverse(casadi_int nadj) const
Get a function that calculates nadj adjoint derivatives.
Definition: function.cpp:1143

References casadi::Function::assert_size_in(), casadi::Function::assert_sparsity_out(), casadi::combine(), casadi::FunctionInternal::der_options_, casadi::FunctionInternal::diff_prefix(), casadi::FunctionInternal::enable_reverse_, casadi::FunctionInternal::generate_options(), casadi::FunctionInternal::get_reverse(), casadi::FunctionInternal::has_derivative(), casadi::FunctionInternal::incache(), casadi::Function::n_in(), casadi::FunctionInternal::n_in_, casadi::Function::n_out(), casadi::FunctionInternal::n_out_, casadi::ProtoFunction::name_, casadi::FunctionInternal::name_in_, casadi::FunctionInternal::name_out_, casadi::Function::reverse(), casadi::FunctionInternal::reverse_name(), casadi::FunctionInternal::reverse_options_, casadi::FunctionInternal::size1_in(), casadi::FunctionInternal::size1_out(), casadi::FunctionInternal::size2_in(), casadi::FunctionInternal::size2_out(), casadi::FunctionInternal::sparsity_in(), casadi::FunctionInternal::tocache_if_missing(), and casadi::FunctionInternal::wrap().

Referenced by casadi::FunctionInternal::call_reverse(), and casadi::Function::reverse().

◆ reverse_name()

static std::string casadi::FunctionInternal::reverse_name ( const std::string &  fcn,
casadi_int  nadj 
)
inlinestaticinherited

Definition at line 662 of file function_internal.hpp.

662  {
663  return "adj" + str(nadj) + "_" + fcn;
664  }

References casadi::str().

Referenced by casadi::FunctionInternal::reverse(), and casadi::FixedStepIntegrator::stepB().

◆ self()

Function casadi::FunctionInternal::self ( ) const
inlineinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_k8

Definition at line 353 of file function_internal.hpp.

353 { return shared_from_this<Function>();}

◆ serialize()

void casadi::ProtoFunction::serialize ( SerializingStream s) const
inherited

Extra doc: https://github.com/casadi/casadi/wiki/L_jv

Definition at line 4181 of file function_internal.cpp.

4181  {
4182  serialize_type(s);
4183  serialize_body(s);
4184  }
virtual void serialize_type(SerializingStream &s) const
Serialize type information.
virtual void serialize_body(SerializingStream &s) const
Serialize an object without type information.

References casadi::ProtoFunction::serialize_body(), and casadi::ProtoFunction::serialize_type().

◆ serialize_base_function()

virtual std::string casadi::ProtoFunction::serialize_base_function ( ) const
inlinevirtualinherited

◆ serialize_body()

void casadi::SXFunction::serialize_body ( SerializingStream s) const
overridevirtual

Extra doc: https://github.com/casadi/casadi/wiki/L_v0

Reimplemented from casadi::FunctionInternal.

Definition at line 1897 of file sx_function.cpp.

1897  {
1899  s.version("SXFunction", 3);
1900  s.pack("SXFunction::n_instr", algorithm_.size());
1901 
1902  s.pack("SXFunction::worksize", worksize_);
1903  s.pack("SXFunction::free_vars", free_vars_);
1904  s.pack("SXFunction::operations", operations_);
1905  s.pack("SXFunction::constants", constants_);
1906  s.pack("SXFunction::default_in", default_in_);
1907 
1908  s.pack("SXFunction::call_sz_arg", call_.sz_arg);
1909  s.pack("SXFunction::call_sz_res", call_.sz_res);
1910  s.pack("SXFunction::call_sz_iw", call_.sz_iw);
1911  s.pack("SXFunction::call_sz_w", call_.sz_w);
1912  s.pack("SXFunction::call_sz_arg", call_.sz_w_arg);
1913  s.pack("SXFunction::call_sz_res", call_.sz_w_res);
1914 
1915  s.pack("SXFunction::call_el_size", call_.el.size());
1916  // Loop over ExtendedALgEl elements
1917  for (const auto& n : call_.el) {
1918  s.pack("SXFunction::call_el_f", n.f);
1919  s.pack("SXFunction::call_el_dep", n.dep);
1920  s.pack("SXFunction::call_el_res", n.res);
1921  s.pack("SXFunction::call_el_copy_elision_arg", n.copy_elision_arg);
1922  s.pack("SXFunction::call_el_copy_elision_offset", n.copy_elision_offset);
1923  }
1924 
1925  s.pack("SXFunction::copy_elision", copy_elision_);
1926 
1927  // Loop over algorithm
1928  for (const auto& e : algorithm_) {
1929  s.pack("SXFunction::ScalarAtomic::op", e.op);
1930  s.pack("SXFunction::ScalarAtomic::i0", e.i0);
1931  s.pack("SXFunction::ScalarAtomic::i1", e.i1);
1932  s.pack("SXFunction::ScalarAtomic::i2", e.i2);
1933  }
1934 
1935  s.pack("SXFunction::live_variables", live_variables_);
1936  s.pack("SXFunction::print_instructions", print_instructions_);
1937 
1939  }
void delayed_serialize_members(SerializingStream &s) const
Helper functions to avoid recursion limit.
Definition: x_function.hpp:305
void serialize_body(SerializingStream &s) const override
Serialize an object without type information.
Definition: x_function.hpp:311

References algorithm_, call_, constants_, copy_elision_, default_in_, casadi::XFunction< DerivedType, MatType, NodeType >::delayed_serialize_members(), casadi::SXFunction::CallInfo::el, free_vars_, live_variables_, operations_, casadi::SerializingStream::pack(), print_instructions_, casadi::XFunction< DerivedType, MatType, NodeType >::serialize_body(), casadi::SXFunction::CallInfo::sz_arg, casadi::SXFunction::CallInfo::sz_iw, casadi::SXFunction::CallInfo::sz_res, casadi::SXFunction::CallInfo::sz_w, casadi::SXFunction::CallInfo::sz_w_arg, casadi::SXFunction::CallInfo::sz_w_res, casadi::SerializingStream::version(), and worksize_.

◆ serialize_type()

void casadi::FunctionInternal::serialize_type ( SerializingStream s) const
overridevirtualinherited

◆ set_jac_sparsity()

void casadi::FunctionInternal::set_jac_sparsity ( casadi_int  oind,
casadi_int  iind,
const Sparsity sp 
)
protectedinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_nx

Definition at line 3761 of file function_internal.cpp.

3761  {
3762 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
3763  // Safe access to jac_sparsity_
3764  std::lock_guard<std::mutex> lock(jac_sparsity_mtx_);
3765 #endif // CASADI_WITH_THREADSAFE_SYMBOLICS
3766  casadi_int ind = iind + oind * n_in_;
3767  jac_sparsity_[false].resize(n_in_ * n_out_);
3768  jac_sparsity_[false].at(ind) = sp;
3769  jac_sparsity_[true].resize(n_in_ * n_out_);
3770  jac_sparsity_[true].at(ind) = to_compact(oind, iind, sp);
3771  }

References casadi::FunctionInternal::jac_sparsity_, casadi::FunctionInternal::n_in_, casadi::FunctionInternal::n_out_, and casadi::FunctionInternal::to_compact().

◆ set_temp()

virtual void casadi::FunctionInternal::set_temp ( void *  mem,
const double **  arg,
double **  res,
casadi_int *  iw,
double *  w 
) const
inlinevirtualinherited

◆ set_work()

virtual void casadi::FunctionInternal::set_work ( void *  mem,
const double **&  arg,
double **&  res,
casadi_int *&  iw,
double *&  w 
) const
inlinevirtualinherited

◆ setup()

void casadi::FunctionInternal::setup ( void *  mem,
const double **  arg,
double **  res,
casadi_int *  iw,
double *  w 
) const
inherited

Extra doc: https://github.com/casadi/casadi/wiki/L_nb

Definition at line 3549 of file function_internal.cpp.

3550  {
3551  set_work(mem, arg, res, iw, w);
3552  set_temp(mem, arg, res, iw, w);
3553  auto m = static_cast<FunctionMemory*>(mem);
3554  m->stats_available = true;
3555  }
virtual void set_work(void *mem, const double **&arg, double **&res, casadi_int *&iw, double *&w) const
Set the (persistent) work vectors.
virtual void set_temp(void *mem, const double **arg, double **res, casadi_int *iw, double *w) const
Set the (temporary) work vectors.

References casadi::FunctionInternal::set_temp(), casadi::FunctionInternal::set_work(), and casadi::FunctionMemory::stats_available.

Referenced by casadi::Conic::eval(), casadi::Nlpsol::eval(), casadi::CallbackInternal::eval(), casadi::FiniteDiff::eval(), casadi::FmuFunction::eval(), casadi::Integrator::eval(), casadi::Map::eval(), casadi::OmpMap::eval(), casadi::ThreadMap::eval(), casadi::MapSum::eval(), casadi::MXFunction::eval(), casadi::Rootfinder::eval(), casadi::Switch::eval(), eval(), casadi::SlicotDple::eval(), casadi::SlicotExpm::eval(), casadi::BSplineInterpolant::eval(), and casadi::LinearInterpolant::eval().

◆ shared_from_this() [1/2]

B casadi::GenericSharedInternal< SharedObject , SharedObjectInternal >::shared_from_this ( )
inlineprotectedinherited

Definition at line 83 of file generic_shared_internal.hpp.

83  {
84  casadi_assert_dev(B::test_cast(static_cast<Internal*>(this)));
85  B ret;
86  ret.own(static_cast<Internal*>(this));
87  return ret;
88  }

◆ shared_from_this() [2/2]

const B casadi::GenericSharedInternal< SharedObject , SharedObjectInternal >::shared_from_this ( ) const
inlineprotectedinherited

Definition at line 92 of file generic_shared_internal.hpp.

92  {
93  casadi_assert_dev(B::test_cast(static_cast<const Internal*>(this)));
94  B ret;
95  ret.own(const_cast<Internal*>(static_cast<const Internal*>(this)));
96  return ret;
97  }

◆ should_inline()

bool casadi::SXFunction::should_inline ( bool  with_sx,
bool  always_inline,
bool  never_inline 
) const
overridevirtual

Inline calls?

Implements casadi::XFunction< SXFunction, Matrix< SXElem >, SXNode >.

Definition at line 1178 of file sx_function.cpp.

1178  {
1179  // If inlining has been specified
1180  casadi_assert(!(always_inline && never_inline),
1181  "Inconsistent options for " + definition());
1182  casadi_assert(!(never_inline && has_free()),
1183  "Must inline " + definition());
1184  if (always_inline) return true;
1185  if (never_inline) return false;
1186  // Functions with free variables must be inlined
1187  if (has_free()) return true;
1188  // Inlining by default
1189  return true;
1190  }

References casadi::FunctionInternal::definition(), and has_free().

Referenced by eval_sx().

◆ signature()

std::string casadi::FunctionInternal::signature ( const std::string &  fname) const
inherited

Extra doc: https://github.com/casadi/casadi/wiki/L_ly

Definition at line 2413 of file function_internal.cpp.

2413  {
2414  return "int " + fname + "(const casadi_real** arg, casadi_real** res, "
2415  "casadi_int* iw, casadi_real* w, int mem)";
2416  }

Referenced by casadi::CodeGenerator::add(), casadi::FunctionInternal::codegen(), and casadi::External::codegen_declarations().

◆ signature_unrolled()

std::string casadi::FunctionInternal::signature_unrolled ( const std::string &  fname) const
inherited

Extra doc: https://github.com/casadi/casadi/wiki/L_27o

Definition at line 2418 of file function_internal.cpp.

2418  {
2419  std::vector<std::string> args;
2420  for (auto e : name_in_) {
2421  args.push_back("const casadi_real* " + str(e));
2422  }
2423  for (auto e : name_out_) {
2424  args.push_back("casadi_real* " + str(e));
2425  }
2426  args.push_back("const casadi_real** arg");
2427  args.push_back("casadi_real** res");
2428  args.push_back("casadi_int* iw");
2429  args.push_back("casadi_real* w");
2430  args.push_back("int mem");
2431  return "int " + fname + "_unrolled(" + join(args, ", ") + ")";
2432  }

References casadi::join(), casadi::FunctionInternal::name_in_, casadi::FunctionInternal::name_out_, and casadi::str().

Referenced by casadi::CodeGenerator::add().

◆ size1_in()

casadi_int casadi::FunctionInternal::size1_in ( casadi_int  ind) const
inlineinherited

◆ size1_out()

casadi_int casadi::FunctionInternal::size1_out ( casadi_int  ind) const
inlineinherited

◆ size2_in()

casadi_int casadi::FunctionInternal::size2_in ( casadi_int  ind) const
inlineinherited

◆ size2_out()

casadi_int casadi::FunctionInternal::size2_out ( casadi_int  ind) const
inlineinherited

◆ size_in()

std::pair<casadi_int, casadi_int> casadi::FunctionInternal::size_in ( casadi_int  ind) const
inlineinherited

◆ size_out()

std::pair<casadi_int, casadi_int> casadi::FunctionInternal::size_out ( casadi_int  ind) const
inlineinherited

◆ slice()

Function casadi::XFunction< SXFunction , Matrix< SXElem > , SXNode >::slice ( const std::string &  name,
const std::vector< casadi_int > &  order_in,
const std::vector< casadi_int > &  order_out,
const Dict opts 
) const
overridevirtualinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_xy

Reimplemented from casadi::FunctionInternal.

Definition at line 160 of file x_function.hpp.

976  {
977  // Return expressions
978  std::vector<MatType> ret_in, ret_out;
979  std::vector<std::string> ret_in_name, ret_out_name;
980 
981  // Reorder inputs
982  for (casadi_int k : order_in) {
983  ret_in.push_back(in_.at(k));
984  ret_in_name.push_back(name_in_.at(k));
985  }
986 
987  // Reorder outputs
988  for (casadi_int k : order_out) {
989  ret_out.push_back(out_.at(k));
990  ret_out_name.push_back(name_out_.at(k));
991  }
992 
993  // Assemble function
994  return Function(name, ret_in, ret_out,
995  ret_in_name, ret_out_name, opts);
996  }

◆ sort_depth_first()

void casadi::XFunction< SXFunction , Matrix< SXElem > , SXNode >::sort_depth_first ( std::stack< SXNode * > &  s,
std::vector< SXNode * > &  nodes 
)
staticinherited

This function modifies the temp member of the nodes, making it not thread-safe.

Extra doc: https://github.com/casadi/casadi/wiki/L_xr 

Definition at line 93 of file x_function.hpp.

396  {
397  while (!s.empty()) {
398  // Get the topmost element
399  NodeType* t = s.top();
400  // If the last element on the stack has not yet been added
401  if (t && t->temp>=0) {
402  // Get the index of the next dependency
403  casadi_int next_dep = t->temp++;
404  // If there is any dependency which has not yet been added
405  if (next_dep < t->n_dep()) {
406  // Add dependency to stack
407  s.push(static_cast<NodeType*>(t->dep(next_dep).get()));
408  } else {
409  // if no dependencies need to be added, we can add the node to the algorithm
410  nodes.push_back(t);
411  // Mark the node as found
412  t->temp = -1;
413  // Remove from stack
414  s.pop();
415  }
416  } else {
417  // If the last element on the stack has already been added
418  s.pop();
419  }
420  }
421  }

◆ sp_forward()

int casadi::SXFunction::sp_forward ( const bvec_t **  arg,
bvec_t **  res,
casadi_int *  iw,
bvec_t w,
void *  mem 
) const
overridevirtual

Extra doc: https://github.com/casadi/casadi/wiki/L_v6

Reimplemented from casadi::FunctionInternal.

Definition at line 1643 of file sx_function.cpp.

1644  {
1645  // Fall back when forward mode not allowed
1646  if (sp_weight()==1 || sp_weight()==-1)
1647  return FunctionInternal::sp_forward(arg, res, iw, w, mem);
1648  // Propagate sparsity forward
1649  for (auto&& e : algorithm_) {
1650  switch (e.op) {
1651  case OP_CONST:
1652  case OP_PARAMETER:
1653  w[e.i0] = 0; break;
1654  case OP_INPUT:
1655  w[e.i0] = arg[e.i1]==nullptr ? 0 : arg[e.i1][e.i2];
1656  break;
1657  case OP_OUTPUT:
1658  if (res[e.i0]!=nullptr) res[e.i0][e.i2] = w[e.i1];
1659  break;
1660  case OP_CALL:
1661  call_fwd(e, arg, res, iw, w);
1662  break;
1663  default: // Unary or binary operation
1664  w[e.i0] = w[e.i1] | w[e.i2]; break;
1665  }
1666  }
1667  return 0;
1668  }

References algorithm_, call_fwd(), casadi::OP_CALL, casadi::OP_CONST, casadi::OP_INPUT, casadi::OP_OUTPUT, casadi::OP_PARAMETER, casadi::FunctionInternal::sp_forward(), and casadi::FunctionInternal::sp_weight().

◆ sp_forward_block()

int casadi::FunctionInternal::sp_forward_block ( const bvec_t **  arg,
bvec_t **  res,
casadi_int *  iw,
bvec_t w,
void *  mem,
casadi_int  oind,
casadi_int  iind 
) const
virtualinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_mx

Definition at line 2857 of file function_internal.cpp.

2858  {
2859  // Get the sparsity of the Jacobian block
2860  Sparsity sp = jac_sparsity(oind, iind, true, false);
2861  if (sp.is_null() || sp.nnz() == 0) return 0; // Skip if zero
2862  // Carry out the sparse matrix-vector multiplication
2863  casadi_int d1 = sp.size2();
2864  const casadi_int *colind = sp.colind(), *row = sp.row();
2865  for (casadi_int cc=0; cc<d1; ++cc) {
2866  for (casadi_int el = colind[cc]; el < colind[cc+1]; ++el) {
2867  res[oind][row[el]] |= arg[iind][cc];
2868  }
2869  }
2870  return 0;
2871  }

References casadi::Sparsity::colind(), casadi::GenericShared< Shared, Internal >::is_null(), casadi::FunctionInternal::jac_sparsity(), casadi::Sparsity::nnz(), casadi::Sparsity::row(), and casadi::Sparsity::size2().

Referenced by casadi::FunctionInternal::sp_forward().

◆ sp_reverse()

int casadi::SXFunction::sp_reverse ( bvec_t **  arg,
bvec_t **  res,
casadi_int *  iw,
bvec_t w,
void *  mem 
) const
overridevirtual

Extra doc: https://github.com/casadi/casadi/wiki/L_v7

Reimplemented from casadi::FunctionInternal.

Definition at line 1670 of file sx_function.cpp.

1671  {
1672  // Fall back when reverse mode not allowed
1673  if (sp_weight()==0 || sp_weight()==-1)
1674  return FunctionInternal::sp_reverse(arg, res, iw, w, mem);
1675  std::fill_n(w, sz_w(), 0);
1676 
1677  // Propagate sparsity backward
1678  for (auto it=algorithm_.rbegin(); it!=algorithm_.rend(); ++it) {
1679  // Temp seed
1680  bvec_t seed;
1681 
1682  // Propagate seeds
1683  switch (it->op) {
1684  case OP_CONST:
1685  case OP_PARAMETER:
1686  w[it->i0] = 0;
1687  break;
1688  case OP_INPUT:
1689  if (arg[it->i1]!=nullptr) arg[it->i1][it->i2] |= w[it->i0];
1690  w[it->i0] = 0;
1691  break;
1692  case OP_OUTPUT:
1693  if (res[it->i0]!=nullptr) {
1694  w[it->i1] |= res[it->i0][it->i2];
1695  res[it->i0][it->i2] = 0;
1696  }
1697  break;
1698  case OP_CALL:
1699  call_rev(*it, arg, res, iw, w);
1700  break;
1701  default: // Unary or binary operation
1702  seed = w[it->i0];
1703  w[it->i0] = 0;
1704  w[it->i1] |= seed;
1705  w[it->i2] |= seed;
1706  }
1707  }
1708  return 0;
1709  }
virtual int sp_reverse(bvec_t **arg, bvec_t **res, casadi_int *iw, bvec_t *w, void *mem) const
Propagate sparsity backwards.
void call_rev(const AlgEl &e, T **arg, T **res, casadi_int *iw, T *w) const

References algorithm_, call_rev(), casadi::OP_CALL, casadi::OP_CONST, casadi::OP_INPUT, casadi::OP_OUTPUT, casadi::OP_PARAMETER, casadi::FunctionInternal::sp_reverse(), casadi::FunctionInternal::sp_weight(), and casadi::FunctionInternal::sz_w().

◆ sp_weight()

double casadi::FunctionInternal::sp_weight ( ) const
virtualinherited

sparsity propagation

Extra doc: https://github.com/casadi/casadi/wiki/L_l6

Definition at line 3285 of file function_internal.cpp.

3285  {
3286  // If reverse mode propagation unavailable, use forward
3287  if (!has_sprev()) return 0;
3288 
3289  // If forward mode propagation unavailable, use reverse
3290  if (!has_spfwd()) return 1;
3291 
3292  // Use the (potentially user set) option
3293  return ad_weight_sp_;
3294  }

References casadi::FunctionInternal::ad_weight_sp_, casadi::FunctionInternal::has_spfwd(), and casadi::FunctionInternal::has_sprev().

Referenced by casadi::FunctionInternal::get_jac_sparsity(), casadi::FunctionInternal::get_jac_sparsity_hierarchical(), casadi::MXFunction::sp_forward(), sp_forward(), casadi::MXFunction::sp_reverse(), sp_reverse(), casadi::FunctionInternal::wrap(), and casadi::FunctionInternal::wrap_as_needed().

◆ sparsity_in()

const Sparsity& casadi::FunctionInternal::sparsity_in ( casadi_int  ind) const
inlineinherited

◆ sparsity_out()

const Sparsity& casadi::FunctionInternal::sparsity_out ( casadi_int  ind) const
inlineinherited

◆ sprint()

void casadi::ProtoFunction::sprint ( char *  buf,
size_t  buf_sz,
const char *  fmt,
  ... 
) const
inherited

Extra doc: https://github.com/casadi/casadi/wiki/L_js

Definition at line 3885 of file function_internal.cpp.

3885  {
3886  // Variable number of arguments
3887  va_list args;
3888  va_start(args, fmt);
3889  // Print to buffer
3890  casadi_int n = vsnprintf(buf, buf_sz, fmt, args);
3891  // Cleanup
3892  va_end(args);
3893  // Throw error if failure
3894  casadi_assert(n>=0 && n<buf_sz, "Print failure while processing '" + std::string(fmt) + "'");
3895  }

Referenced by casadi::ProtoFunction::format_time(), and casadi::ProtoFunction::print_time().

◆ string_from_UnifiedReturnStatus()

std::string casadi::FunctionInternal::string_from_UnifiedReturnStatus ( UnifiedReturnStatus  status)
staticinherited

Definition at line 3953 of file function_internal.cpp.

3953  {
3954  switch (status) {
3955  case SOLVER_RET_LIMITED: return "SOLVER_RET_LIMITED";
3956  case SOLVER_RET_NAN: return "SOLVER_RET_NAN";
3957  case SOLVER_RET_SUCCESS: return "SOLVER_RET_SUCCESS";
3958  default: return "SOLVER_RET_UNKNOWN";
3959  }
3960  }
@ SOLVER_RET_NAN
@ SOLVER_RET_LIMITED
@ SOLVER_RET_SUCCESS

References casadi::SOLVER_RET_LIMITED, casadi::SOLVER_RET_NAN, and casadi::SOLVER_RET_SUCCESS.

Referenced by casadi::Conic::get_stats(), casadi::Nlpsol::get_stats(), and casadi::Rootfinder::get_stats().

◆ sx_in() [1/2]

const std::vector< SX > casadi::SXFunction::sx_in ( ) const
overridevirtual

Extra doc: https://github.com/casadi/casadi/wiki/L_um

Reimplemented from casadi::FunctionInternal.

Definition at line 1715 of file sx_function.cpp.

1715  {
1716  return in_;
1717  }

References casadi::XFunction< SXFunction, Matrix< SXElem >, SXNode >::in_.

◆ sx_in() [2/2]

const SX casadi::SXFunction::sx_in ( casadi_int  ind) const
overridevirtual

Extra doc: https://github.com/casadi/casadi/wiki/L_um

Reimplemented from casadi::FunctionInternal.

Definition at line 1711 of file sx_function.cpp.

1711  {
1712  return in_.at(ind);
1713  }

References casadi::XFunction< SXFunction, Matrix< SXElem >, SXNode >::in_.

◆ sx_out() [1/2]

const std::vector< SX > casadi::FunctionInternal::sx_out ( ) const
virtualinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_l7

Definition at line 3320 of file function_internal.cpp.

3320  {
3321  std::vector<SX> ret(n_out_);
3322  for (casadi_int i=0; i<ret.size(); ++i) {
3323  ret[i] = sx_out(i);
3324  }
3325  return ret;
3326  }
virtual const std::vector< SX > sx_out() const
Get function input(s) and output(s)

References casadi::FunctionInternal::n_out_.

◆ sx_out() [2/2]

const SX casadi::FunctionInternal::sx_out ( casadi_int  ind) const
virtualinherited

◆ symbolic_output()

std::vector< MX > casadi::FunctionInternal::symbolic_output ( const std::vector< MX > &  arg) const
virtualinherited

Reimplemented in casadi::MXFunction.

Definition at line 1150 of file function_internal.cpp.

1150  {
1151  return self()(arg);
1152  }

Referenced by casadi::MXFunction::symbolic_output().

◆ symbolicAdjSeed()

template<typename MatType >
std::vector< std::vector< MatType > > casadi::FunctionInternal::symbolicAdjSeed ( casadi_int  nadj,
const std::vector< MatType > &  v 
) const
inherited

Extra doc: https://github.com/casadi/casadi/wiki/L_ns

Definition at line 1535 of file function_internal.hpp.

1536  {
1537  std::vector<std::vector<MatType> > aseed(nadj, v);
1538  for (casadi_int dir=0; dir<nadj; ++dir) {
1539  // Replace symbolic inputs
1540  casadi_int oind=0;
1541  for (typename std::vector<MatType>::iterator i=aseed[dir].begin();
1542  i!=aseed[dir].end();
1543  ++i, ++oind) {
1544  // Name of the adjoint seed
1545  std::stringstream ss;
1546  ss << "a";
1547  if (nadj>1) ss << dir << "_";
1548  ss << oind;
1549 
1550  // Save to matrix
1551  *i = MatType::sym(ss.str(), is_diff_out_[oind] ? i->sparsity() : Sparsity(i->size()));
1552 
1553  }
1554  }
1555  return aseed;
1556  }

References casadi::FunctionInternal::is_diff_out_.

◆ sz_arg()

size_t casadi::FunctionInternal::sz_arg ( ) const
inlineinherited

◆ sz_iw()

size_t casadi::FunctionInternal::sz_iw ( ) const
inlineinherited

◆ sz_res()

size_t casadi::FunctionInternal::sz_res ( ) const
inlineinherited

◆ sz_w()

size_t casadi::FunctionInternal::sz_w ( ) const
inlineinherited

◆ sz_work()

void casadi::FunctionInternal::sz_work ( size_t &  sz_arg,
size_t &  sz_res,
size_t &  sz_iw,
size_t &  sz_w 
) const
inherited

Extra doc: https://github.com/casadi/casadi/wiki/L_mz

Definition at line 2905 of file function_internal.cpp.

2906  {
2907  sz_arg = this->sz_arg();
2908  sz_res = this->sz_res();
2909  sz_iw = this->sz_iw();
2910  sz_w = this->sz_w();
2911  }

References casadi::FunctionInternal::sz_arg(), casadi::FunctionInternal::sz_iw(), casadi::FunctionInternal::sz_res(), and casadi::FunctionInternal::sz_w().

◆ to_compact()

Sparsity casadi::FunctionInternal::to_compact ( casadi_int  oind,
casadi_int  iind,
const Sparsity sp 
) const
inherited

Definition at line 1921 of file function_internal.cpp.

1922  {
1923  // Strip rows and columns
1924  std::vector<casadi_int> mapping;
1925  return sp.sub(sparsity_out(oind).find(), sparsity_in(iind).find(), mapping);
1926  }

References casadi::FunctionInternal::find(), casadi::FunctionInternal::sparsity_in(), casadi::FunctionInternal::sparsity_out(), and casadi::Sparsity::sub().

Referenced by casadi::FunctionInternal::jac_sparsity(), and casadi::FunctionInternal::set_jac_sparsity().

◆ tocache()

void casadi::FunctionInternal::tocache ( const Function f,
const std::string &  suffix = "" 
) const
inherited

◆ tocache_if_missing()

void casadi::FunctionInternal::tocache_if_missing ( Function f,
const std::string &  suffix = "" 
) const
inherited

◆ uses_output()

virtual bool casadi::FunctionInternal::uses_output ( ) const
inlinevirtualinherited

◆ weak()

Extra doc: https://github.com/casadi/casadi/wiki/L_1ai

Definition at line 67 of file generic_shared_internal.hpp.

191  {
192  if (weak_ref_==nullptr) {
193  weak_ref_ = new GenericWeakRef<Shared, Internal>(static_cast<Internal*>(this));
194  }
195  return weak_ref_;
196  }

◆ which_depends()

std::vector< bool > casadi::XFunction< SXFunction , Matrix< SXElem > , SXNode >::which_depends ( const std::string &  s_in,
const std::vector< std::string > &  s_out,
casadi_int  order,
bool  tr = false 
) const
overridevirtualinherited
Parameters
[in]orderOnly 1 (linear) and 2 (nonlinear) allowed
[in]trFlip the relationship. Return which expressions contain the variables

Extra doc: https://github.com/casadi/casadi/wiki/L_xu

Reimplemented from casadi::FunctionInternal.

Definition at line 120 of file x_function.hpp.

1219  {
1220 
1221  // Input arguments
1222  auto it = std::find(name_in_.begin(), name_in_.end(), s_in);
1223  casadi_assert_dev(it!=name_in_.end());
1224  MatType arg = in_.at(it-name_in_.begin());
1225 
1226  // Output arguments
1227  std::vector<MatType> res;
1228  for (auto&& s : s_out) {
1229  it = std::find(name_out_.begin(), name_out_.end(), s);
1230  casadi_assert_dev(it!=name_out_.end());
1231  res.push_back(out_.at(it-name_out_.begin()));
1232  }
1233 
1234  // Extract variables entering nonlinearly
1235  return MatType::which_depends(veccat(res), arg, order, tr);
1236  }

◆ wrap()

Function casadi::FunctionInternal::wrap ( ) const
inherited

Extra doc: https://github.com/casadi/casadi/wiki/L_li

Definition at line 1128 of file function_internal.cpp.

1128  {
1129  Function f;
1130  std::string fname = "wrap_" + name_;
1131  if (!incache(fname, f)) {
1132  // Options
1133  Dict opts;
1134  opts["derivative_of"] = derivative_of_;
1135  opts["ad_weight"] = ad_weight();
1136  opts["ad_weight_sp"] = sp_weight();
1137  opts["max_num_dir"] = max_num_dir_;
1138  opts["is_diff_in"] = is_diff_in_;
1139  opts["is_diff_out"] = is_diff_out_;
1140  // Wrap the function
1141  std::vector<MX> arg = mx_in();
1142  std::vector<MX> res = self()(arg);
1143  f = Function(fname, arg, res, name_in_, name_out_, opts);
1144  // Save in cache
1145  tocache_if_missing(f);
1146  }
1147  return f;
1148  }

References casadi::FunctionInternal::ad_weight(), casadi::FunctionInternal::derivative_of_, casadi::FunctionInternal::Function, casadi::FunctionInternal::incache(), casadi::FunctionInternal::is_diff_in_, casadi::FunctionInternal::is_diff_out_, casadi::FunctionInternal::max_num_dir_, casadi::FunctionInternal::mx_in(), casadi::ProtoFunction::name_, casadi::FunctionInternal::name_in_, casadi::FunctionInternal::name_out_, casadi::FunctionInternal::sp_weight(), and casadi::FunctionInternal::tocache_if_missing().

Referenced by casadi::FunctionInternal::eval_mx(), casadi::FunctionInternal::factory(), casadi::FunctionInternal::forward(), casadi::FunctionInternal::jacobian(), casadi::FunctionInternal::reverse(), casadi::FunctionInternal::slice(), and casadi::Function::wrap().

◆ wrap_as_needed()

Function casadi::FunctionInternal::wrap_as_needed ( const Dict opts) const
inherited

Extra doc: https://github.com/casadi/casadi/wiki/L_lj

Definition at line 1110 of file function_internal.cpp.

1110  {
1111  if (opts.empty()) return shared_from_this<Function>();
1112  std::string fname = "wrap_" + name_;
1113  // Options
1114  Dict my_opts = opts;
1115  my_opts["derivative_of"] = derivative_of_;
1116  if (my_opts.find("ad_weight")==my_opts.end())
1117  my_opts["ad_weight"] = ad_weight();
1118  if (my_opts.find("ad_weight_sp")==my_opts.end())
1119  my_opts["ad_weight_sp"] = sp_weight();
1120  if (my_opts.find("max_num_dir")==my_opts.end())
1121  my_opts["max_num_dir"] = max_num_dir_;
1122  // Wrap the function
1123  std::vector<MX> arg = mx_in();
1124  std::vector<MX> res = self()(arg);
1125  return Function(fname, arg, res, name_in_, name_out_, my_opts);
1126  }

References casadi::FunctionInternal::ad_weight(), casadi::FunctionInternal::derivative_of_, casadi::FunctionInternal::Function, casadi::FunctionInternal::max_num_dir_, casadi::FunctionInternal::mx_in(), casadi::ProtoFunction::name_, casadi::FunctionInternal::name_in_, casadi::FunctionInternal::name_out_, and casadi::FunctionInternal::sp_weight().

Referenced by casadi::Function::wrap_as_needed().

Member Data Documentation

◆ ad_weight_

double casadi::FunctionInternal::ad_weight_
inherited

◆ ad_weight_sp_

double casadi::FunctionInternal::ad_weight_sp_
inherited

◆ algorithm_

std::vector<AlgEl> casadi::SXFunction::algorithm_

◆ always_inline_

bool casadi::FunctionInternal::always_inline_
inherited

◆ cache_

WeakCache<std::string, Function> casadi::FunctionInternal::cache_
mutableinherited

◆ cache_init_

Dict casadi::FunctionInternal::cache_init_
inherited

◆ call_

struct casadi::SXFunction::CallInfo casadi::SXFunction::call_

◆ checkout_

casadi_checkout_t casadi::FunctionInternal::checkout_
inherited

◆ compiler_

Importer casadi::FunctionInternal::compiler_
inherited

◆ compiler_plugin_

std::string casadi::FunctionInternal::compiler_plugin_
inherited

◆ constants_

std::vector<SXElem> casadi::SXFunction::constants_

Definition at line 260 of file sx_function.hpp.

Referenced by eval_mx(), eval_sx(), init(), instructions_sx(), serialize_body(), and SXFunction().

◆ copy_elision_

std::vector<bool> casadi::SXFunction::copy_elision_

Definition at line 266 of file sx_function.hpp.

Referenced by codegen_body(), init_copy_elision(), serialize_body(), and SXFunction().

◆ custom_jacobian_

Function casadi::FunctionInternal::custom_jacobian_
inherited

◆ default_in_

std::vector<double> casadi::SXFunction::default_in_

Definition at line 263 of file sx_function.hpp.

Referenced by init(), serialize_body(), and SXFunction().

◆ der_options_

Dict casadi::FunctionInternal::der_options_
inherited

◆ derivative_of_

Function casadi::FunctionInternal::derivative_of_
inherited

◆ deserialize_map

std::map< std::string, ProtoFunction *(*)(DeserializingStream &)> casadi::FunctionInternal::deserialize_map
staticinherited
Initial value:
= {
{"MXFunction", MXFunction::deserialize},
{"SXFunction", SXFunction::deserialize},
{"Interpolant", Interpolant::deserialize},
{"Switch", Switch::deserialize},
{"Map", Map::deserialize},
{"MapSum", MapSum::deserialize},
{"Nlpsol", Nlpsol::deserialize},
{"Rootfinder", Rootfinder::deserialize},
{"Integrator", Integrator::deserialize},
{"External", External::deserialize},
{"Conic", Conic::deserialize},
{"FmuFunction", FmuFunction::deserialize},
{"BlazingSplineFunction", BlazingSplineFunction::deserialize}
}
static ProtoFunction * deserialize(DeserializingStream &s)
Deserialize into MX.
void deserialize(DeserializingStream &s, SDPToSOCPMem &m)
Definition: conic.cpp:728
static ProtoFunction * deserialize(DeserializingStream &s)
Deserialize into MX.
Definition: external.cpp:512
static ProtoFunction * deserialize(DeserializingStream &s)
Deserialize without type information.
static ProtoFunction * deserialize(DeserializingStream &s)
Deserialize into MX.
static ProtoFunction * deserialize(DeserializingStream &s)
Deserialize with type disambiguation.
static ProtoFunction * deserialize(DeserializingStream &s)
Deserialize with type disambiguation.
static ProtoFunction * deserialize(DeserializingStream &s)
Deserialize with type disambiguation.
Definition: mapsum.cpp:85
static ProtoFunction * deserialize(DeserializingStream &s)
Deserialize with type disambiguation.
Definition: map.cpp:103
static ProtoFunction * deserialize(DeserializingStream &s)
Deserialize into MX.
Definition: nlpsol.cpp:1341
static ProtoFunction * deserialize(DeserializingStream &s)
Deserialize into MX.
Definition: rootfinder.cpp:592
static ProtoFunction * deserialize(DeserializingStream &s)
Deserialize without type information.
static ProtoFunction * deserialize(DeserializingStream &s)
Deserialize without type information.
Definition: switch.hpp:150

Definition at line 1455 of file function_internal.hpp.

Referenced by casadi::FunctionInternal::deserialize().

◆ dump_

bool casadi::FunctionInternal::dump_
inherited

◆ dump_count_

casadi_int casadi::FunctionInternal::dump_count_
mutableinherited

◆ dump_dir_

std::string casadi::FunctionInternal::dump_dir_
inherited

◆ dump_format_

std::string casadi::FunctionInternal::dump_format_
inherited

◆ dump_in_

bool casadi::FunctionInternal::dump_in_
inherited

◆ dump_out_

bool casadi::FunctionInternal::dump_out_
inherited

◆ enable_fd_

bool casadi::FunctionInternal::enable_fd_
inherited

◆ enable_fd_op_

bool casadi::FunctionInternal::enable_fd_op_
inherited

◆ enable_forward_

bool casadi::FunctionInternal::enable_forward_
inherited

◆ enable_forward_op_

bool casadi::FunctionInternal::enable_forward_op_
inherited

◆ enable_jacobian_

bool casadi::FunctionInternal::enable_jacobian_
inherited

◆ enable_jacobian_op_

bool casadi::FunctionInternal::enable_jacobian_op_
inherited

◆ enable_reverse_

bool casadi::FunctionInternal::enable_reverse_
inherited

◆ enable_reverse_op_

bool casadi::FunctionInternal::enable_reverse_op_
inherited

◆ error_on_fail_

bool casadi::ProtoFunction::error_on_fail_
inherited

◆ eval_

eval_t casadi::FunctionInternal::eval_
inherited

◆ fd_method_

std::string casadi::FunctionInternal::fd_method_
inherited

◆ fd_options_

Dict casadi::FunctionInternal::fd_options_
inherited

◆ fd_step_

double casadi::FunctionInternal::fd_step_
inherited

◆ forward_options_

Dict casadi::FunctionInternal::forward_options_
inherited

◆ free_vars_

std::vector<SXElem> casadi::SXFunction::free_vars_

◆ has_refcount_

bool casadi::FunctionInternal::has_refcount_
inherited

◆ in_

std::vector<Matrix< SXElem > > casadi::XFunction< SXFunction , Matrix< SXElem > , SXNode >::in_
inherited

Extra doc: https://github.com/casadi/casadi/wiki/L_yc

Definition at line 257 of file x_function.hpp.

◆ inputs_check_

bool casadi::FunctionInternal::inputs_check_
inherited

◆ is_diff_in_

std::vector<bool> casadi::FunctionInternal::is_diff_in_
inherited

◆ is_diff_out_

std::vector<bool> casadi::FunctionInternal::is_diff_out_
inherited

◆ jac_penalty_

double casadi::FunctionInternal::jac_penalty_
inherited

◆ jac_sparsity_

std::vector<Sparsity> casadi::FunctionInternal::jac_sparsity_[2]
mutableinherited

◆ jacobian_options_

Dict casadi::FunctionInternal::jacobian_options_
inherited

◆ jit_

bool casadi::FunctionInternal::jit_
inherited

◆ jit_base_name_

std::string casadi::FunctionInternal::jit_base_name_
inherited

◆ jit_cleanup_

bool casadi::FunctionInternal::jit_cleanup_
inherited

◆ jit_name_

std::string casadi::FunctionInternal::jit_name_
inherited

◆ jit_options_

Dict casadi::FunctionInternal::jit_options_
inherited

◆ jit_serialize_

std::string casadi::FunctionInternal::jit_serialize_
inherited

◆ jit_temp_suffix_

bool casadi::FunctionInternal::jit_temp_suffix_
inherited

◆ just_in_time_opencl_

bool casadi::SXFunction::just_in_time_opencl_

Definition at line 379 of file sx_function.hpp.

Referenced by generate_options(), init(), and SXFunction().

◆ just_in_time_sparsity_

bool casadi::SXFunction::just_in_time_sparsity_

Definition at line 382 of file sx_function.hpp.

Referenced by generate_options(), init(), and SXFunction().

◆ live_variables_

bool casadi::SXFunction::live_variables_

Definition at line 385 of file sx_function.hpp.

Referenced by generate_options(), init(), serialize_body(), and SXFunction().

◆ max_io_

casadi_int casadi::FunctionInternal::max_io_
inherited

◆ max_num_dir_

casadi_int casadi::FunctionInternal::max_num_dir_
inherited

◆ n_in_

size_t casadi::FunctionInternal::n_in_
inherited

Definition at line 1266 of file function_internal.hpp.

Referenced by ad_forward(), casadi::Rootfinder::ad_reverse(), casadi::MXFunction::ad_reverse(), ad_reverse(), casadi::FunctionInternal::all_scalar(), casadi::KinsolInterface::bjac(), casadi::FunctionInternal::call_forward(), casadi::FunctionInternal::call_gen(), casadi::FunctionInternal::call_reverse(), call_setup(), casadi::FunctionInternal::check_arg(), casadi::JitFunction::codegen_body(), casadi::Map::codegen_body(), casadi::OmpMap::codegen_body(), casadi::MapSum::codegen_body(), casadi::MXFunction::codegen_body(), casadi::Switch::codegen_body(), codegen_body(), casadi::FastNewton::codegen_body(), casadi::FunctionInternal::codegen_meta(), casadi::FunctionInternal::convert_arg(), casadi::FunctionInternal::definition(), casadi::KinsolInterface::djac(), casadi::FunctionInternal::dm_in(), casadi::FunctionInternal::eval(), casadi::OmpMap::eval(), casadi::MXFunction::eval(), casadi::Switch::eval(), casadi::FunctionInternal::eval_gen(), casadi::Map::eval_gen(), casadi::MapSum::eval_gen(), casadi::MXFunction::eval_mx(), eval_mx(), casadi::Switch::eval_sx(), export_code_body(), casadi::CallbackInternal::finalize(), casadi::FmuFunction::FmuFunction(), casadi::FunctionInternal::forward(), casadi::KinsolInterface::func(), casadi::FunctionInternal::FunctionInternal(), casadi::FunctionInternal::fwd_seed(), casadi::FunctionInternal::generate_in(), casadi::GenericExternal::get_jac_sparsity(), casadi::GenericExternal::has_jac_sparsity(), casadi::FunctionInternal::init(), casadi::MXFunction::init(), casadi::Switch::init(), init(), casadi::ImplicitToNlp::init(), casadi::FunctionInternal::jac_sparsity(), casadi::FunctionInternal::jacobian(), casadi::KinsolInterface::jtimes(), casadi::FunctionInternal::mapsum_mx(), casadi::FunctionInternal::matching_arg(), casadi::FunctionInternal::mx_in(), casadi::FunctionInternal::nnz_in(), casadi::FunctionInternal::numel_in(), casadi::FunctionInternal::nz_in(), print_arg(), casadi::FunctionInternal::print_dimensions(), casadi::FunctionInternal::print_in(), casadi::FunctionInternal::project_arg(), casadi::KinsolInterface::psetup(), casadi::FunctionInternal::reverse(), casadi::FmuFunction::serialize_body(), casadi::FunctionInternal::set_jac_sparsity(), casadi::Rootfinder::set_work(), casadi::QpToNlp::solve(), casadi::KinsolInterface::solve(), casadi::FastNewton::solve(), casadi::ImplicitToNlp::solve(), casadi::Newton::solve(), casadi::FunctionInternal::sp_forward(), casadi::Integrator::sp_forward(), casadi::MXFunction::sp_forward(), casadi::Rootfinder::sp_forward(), casadi::FunctionInternal::sp_reverse(), casadi::Integrator::sp_reverse(), casadi::Map::sp_reverse(), casadi::MapSum::sp_reverse(), casadi::MXFunction::sp_reverse(), casadi::Rootfinder::sp_reverse(), and casadi::FunctionInternal::sx_in().

◆ n_out_

size_t casadi::FunctionInternal::n_out_
inherited

Definition at line 1266 of file function_internal.hpp.

Referenced by casadi::Rootfinder::ad_forward(), casadi::MXFunction::ad_forward(), ad_forward(), casadi::Rootfinder::ad_reverse(), ad_reverse(), casadi::FunctionInternal::all_scalar(), casadi::KinsolInterface::bjac(), casadi::FunctionInternal::call(), casadi::FunctionInternal::call_forward(), casadi::FunctionInternal::call_gen(), casadi::FunctionInternal::call_reverse(), call_setup(), casadi::FunctionInternal::check_res(), casadi::JitFunction::codegen_body(), casadi::Map::codegen_body(), casadi::OmpMap::codegen_body(), casadi::MapSum::codegen_body(), casadi::MXFunction::codegen_body(), casadi::Switch::codegen_body(), codegen_body(), casadi::FastNewton::codegen_body(), casadi::FunctionInternal::codegen_meta(), casadi::FunctionInternal::convert_res(), casadi::FunctionInternal::definition(), casadi::KinsolInterface::djac(), casadi::FunctionInternal::dm_out(), casadi::FunctionInternal::eval(), casadi::OmpMap::eval(), casadi::MXFunction::eval(), casadi::Switch::eval(), casadi::FunctionInternal::eval_gen(), casadi::Map::eval_gen(), casadi::MapSum::eval_gen(), casadi::Switch::eval_sx(), casadi::CallbackInternal::finalize(), casadi::FmuFunction::FmuFunction(), casadi::FunctionInternal::forward(), casadi::KinsolInterface::func(), casadi::FunctionInternal::FunctionInternal(), casadi::FunctionInternal::generate_out(), casadi::LinearInterpolantJac::get_jacobian(), casadi::FunctionInternal::init(), casadi::MapSum::init(), casadi::Nlpsol::init(), casadi::Switch::init(), casadi::FunctionInternal::jac_sparsity(), casadi::FunctionInternal::jacobian(), casadi::FunctionInternal::mapsum_mx(), casadi::FunctionInternal::matching_res(), casadi::FunctionInternal::mx_out(), casadi::FunctionInternal::nnz_out(), casadi::FunctionInternal::numel_out(), casadi::FunctionInternal::nz_out(), casadi::FunctionInternal::print_dimensions(), casadi::FunctionInternal::print_out(), casadi::KinsolInterface::psetup(), casadi::FunctionInternal::reverse(), casadi::FmuFunction::serialize_body(), casadi::FunctionInternal::set_jac_sparsity(), casadi::Rootfinder::set_work(), casadi::QpToNlp::solve(), casadi::KinsolInterface::solve(), casadi::FastNewton::solve(), casadi::ImplicitToNlp::solve(), casadi::Newton::solve(), casadi::FunctionInternal::sp_forward(), casadi::Integrator::sp_forward(), casadi::MXFunction::sp_forward(), casadi::Rootfinder::sp_forward(), casadi::FunctionInternal::sp_reverse(), casadi::Integrator::sp_reverse(), casadi::Map::sp_reverse(), casadi::MapSum::sp_reverse(), casadi::MXFunction::sp_reverse(), casadi::Rootfinder::sp_reverse(), and casadi::FunctionInternal::sx_out().

◆ name_

std::string casadi::ProtoFunction::name_
inherited

Definition at line 246 of file function_internal.hpp.

Referenced by casadi::MXFunction::ad_forward(), ad_forward(), casadi::MXFunction::ad_reverse(), ad_reverse(), casadi::Integrator::augmented_dae(), casadi::OracleFunction::calc_function(), casadi::FunctionInternal::call_forward(), casadi::FunctionInternal::call_reverse(), casadi::FunctionInternal::codegen_body(), casadi::External::codegen_body(), casadi::External::codegen_checkout(), casadi::External::codegen_declarations(), casadi::MXFunction::codegen_declarations(), codegen_declarations(), casadi::External::codegen_decref(), casadi::External::codegen_incref(), casadi::FunctionInternal::codegen_meta(), casadi::FunctionInternal::codegen_name(), casadi::External::codegen_release(), casadi::FunctionInternal::codegen_sparsities(), casadi::ProtoFunction::construct(), casadi::OracleFunction::create_function(), casadi::FunctionInternal::definition(), casadi::FunctionInternal::eval(), casadi::MXFunction::eval(), eval(), casadi::FunctionInternal::eval_mx(), casadi::MXFunction::eval_mx(), eval_mx(), eval_sx(), casadi::FmuFunction::factory(), casadi::FunctionInternal::finalize(), casadi::FunctionInternal::forward(), casadi::FunctionInternal::FunctionInternal(), casadi::Integrator::get_forward(), casadi::Integrator::get_forward_dae(), casadi::Map::get_function(), casadi::MapSum::get_function(), casadi::OracleFunction::get_function(), casadi::GenericExternal::get_jac_sparsity(), casadi::BlazingSplineFunction::get_jacobian(), casadi::FunctionInternal::get_n_in(), casadi::External::get_n_in(), casadi::FunctionInternal::get_n_out(), casadi::External::get_n_out(), casadi::FunctionInternal::get_name_in(), casadi::External::get_name_in(), casadi::FunctionInternal::get_name_out(), casadi::External::get_name_out(), casadi::FunctionInternal::get_partition(), casadi::Integrator::get_reverse(), casadi::FunctionInternal::get_sparsity_in(), casadi::GenericExternal::get_sparsity_in(), casadi::FunctionInternal::get_sparsity_out(), casadi::GenericExternal::get_sparsity_out(), casadi::FunctionInternal::get_stats(), casadi::External::has_forward(), casadi::GenericExternal::has_jac_sparsity(), casadi::External::has_jacobian(), casadi::External::has_reverse(), casadi::External::init(), casadi::FunctionInternal::init(), casadi::MXFunction::init(), init(), casadi::CvodesInterface::init(), casadi::IdasInterface::init(), casadi::External::init_external(), casadi::GenericExternal::init_external(), casadi::FunctionInternal::jac_is_symm(), casadi::FunctionInternal::jacobian(), casadi::FunctionInternal::map(), casadi::OracleFunction::monitored(), casadi::MXFunction::print_arg(), print_arg(), casadi::FunctionInternal::print_in(), casadi::FunctionInternal::print_out(), casadi::MXFunction::print_res(), print_res(), casadi::ProtoFunction::print_time(), casadi::ProtoFunction::ProtoFunction(), casadi::CvodesInterface::reset(), casadi::IdasInterface::reset(), casadi::IdasInterface::resetB(), casadi::FunctionInternal::reverse(), casadi::ProtoFunction::serialize_body(), casadi::GurobiInterface::solve(), casadi::SnoptInterface::solve(), casadi::Integrator::sp_forward(), casadi::Integrator::sp_reverse(), casadi::FunctionInternal::wrap(), and casadi::FunctionInternal::wrap_as_needed().

◆ name_in_

std::vector<std::string> casadi::FunctionInternal::name_in_
inherited

◆ name_out_

std::vector<std::string> casadi::FunctionInternal::name_out_
inherited

◆ never_inline_

bool casadi::FunctionInternal::never_inline_
inherited

◆ operations_

std::vector<SXElem> casadi::SXFunction::operations_

◆ options_

const Options casadi::SXFunction::options_
static
Initial value:
{{"default_in",
"Default input values"}},
{"just_in_time_sparsity",
"Propagate sparsity patterns using just-in-time "
"compilation to a CPU or GPU using OpenCL"}},
{"just_in_time_opencl",
"Just-in-time compilation for numeric evaluation using OpenCL (experimental)"}},
{"live_variables",
"Reuse variables in the work vector"}},
{"cse",
"Perform common subexpression elimination (complexity is N*log(N) in graph size)"}},
{"allow_free",
"Allow construction with free variables (Default: false)"}},
{"allow_duplicate_io_names",
"Allow construction with duplicate io names (Default: false)"}},
{"print_instructions",
"Print each operation during evaluation. Influenced by print_canonical."}}
}
}
static const Options options_
Options.
@ OT_DOUBLEVECTOR

Extra doc: https://github.com/casadi/casadi/wiki/L_v2

Definition at line 316 of file sx_function.hpp.

◆ out_

std::vector<Matrix< SXElem > > casadi::XFunction< SXFunction , Matrix< SXElem > , SXNode >::out_
inherited

Extra doc: https://github.com/casadi/casadi/wiki/L_yd

Definition at line 262 of file x_function.hpp.

◆ print_canonical_

bool casadi::FunctionInternal::print_canonical_
inherited

◆ print_in_

bool casadi::FunctionInternal::print_in_
inherited

◆ print_instructions_

bool casadi::SXFunction::print_instructions_

Definition at line 269 of file sx_function.hpp.

Referenced by codegen_body(), eval(), init(), serialize_body(), and SXFunction().

◆ print_out_

bool casadi::FunctionInternal::print_out_
inherited

◆ print_time_

bool casadi::ProtoFunction::print_time_
inherited

◆ record_time_

bool casadi::ProtoFunction::record_time_
inherited

◆ regularity_check_

bool casadi::ProtoFunction::regularity_check_
inherited

◆ release_

casadi_release_t casadi::FunctionInternal::release_
inherited

◆ reverse_options_

Dict casadi::FunctionInternal::reverse_options_
inherited

◆ sparsity_in_

std::vector<Sparsity> casadi::FunctionInternal::sparsity_in_
inherited

◆ sparsity_out_

std::vector<Sparsity> casadi::FunctionInternal::sparsity_out_
inherited

◆ stats_

Dict casadi::FunctionInternal::stats_
inherited

◆ user_data_

void* casadi::FunctionInternal::user_data_
inherited

◆ verbose_

bool casadi::ProtoFunction::verbose_
inherited

Definition at line 249 of file function_internal.hpp.

Referenced by casadi::MXFunction::ad_forward(), ad_forward(), casadi::MXFunction::ad_reverse(), ad_reverse(), casadi::Integrator::advance(), casadi::ProtoFunction::change_option(), casadi::BSplineInterpolant::construct_graph(), casadi::OracleFunction::create_function(), casadi::FmuFunction::eval(), casadi::Integrator::eval(), casadi::MXFunction::eval(), eval(), casadi::MXFunction::eval_mx(), eval_mx(), eval_sx(), casadi::FmuFunction::factory(), casadi::FunctionInternal::finalize(), casadi::KinsolInterface::func(), casadi::ProtoFunction::generate_options(), casadi::FmuFunction::get_forward(), casadi::Integrator::get_forward(), casadi::Integrator::get_forward_dae(), casadi::FunctionInternal::get_jac_sparsity_gen(), casadi::FunctionInternal::get_jac_sparsity_hierarchical(), casadi::FunctionInternal::get_jac_sparsity_hierarchical_symm(), casadi::FmuFunction::get_jacobian(), casadi::FunctionInternal::get_partition(), casadi::FmuFunction::get_reverse(), casadi::Integrator::get_reverse(), casadi::ProtoFunction::init(), casadi::FiniteDiff::init(), casadi::FmuFunction::init(), casadi::FunctionInternal::init(), casadi::MXFunction::init(), init(), casadi::Blocksqp::init(), casadi::FatropConicInterface::init(), casadi::FatropInterface::init(), casadi::HpipmInterface::init(), casadi::HpmpcInterface::init(), casadi::IpoptInterface::init(), casadi::MadnlpInterface::init(), casadi::CvodesInterface::init(), casadi::IdasInterface::init(), casadi::Feasiblesqpmethod::init(), casadi::Scpgen::init(), casadi::Sqpmethod::init(), casadi::IpoptInterface::init_mem(), casadi::IdasInterface::init_mem(), instructions_sx(), casadi::BonminInterface::intermediate_callback(), casadi::OracleFunction::jit_dependencies(), casadi::CsparseInterface::nfact(), casadi::LapackLu::nfact(), casadi::LapackQr::nfact(), casadi::LinsolQr::nfact(), casadi::Integrator::predict_events(), casadi::ProtoFunction::ProtoFunction(), casadi::CvodesInterface::reset(), casadi::IdasInterface::reset(), casadi::IdasInterface::resetB(), casadi::ProtoFunction::serialize_body(), casadi::CbcInterface::solve(), casadi::ClpInterface::solve(), casadi::CplexInterface::solve(), casadi::GurobiInterface::solve(), casadi::HpipmInterface::solve(), casadi::QpoasesInterface::solve(), casadi::Ipqp::solve(), casadi::Qrqp::solve(), casadi::AlpaqaInterface::solve(), casadi::AmplInterface::solve(), casadi::SnoptInterface::solve(), casadi::KinsolInterface::solve(), casadi::WorhpInterface::solve(), casadi::Newton::solve(), casadi::Qrsqp::solve(), casadi::Scpgen::solve(), casadi::Sqpmethod::solve(), casadi::Sqpmethod::solve_ela_QP(), casadi::Feasiblesqpmethod::solve_LP(), casadi::Feasiblesqpmethod::solve_QP(), casadi::Qrsqp::solve_QP(), casadi::Sqpmethod::solve_QP(), casadi::Integrator::sp_forward(), casadi::Integrator::sp_reverse(), and casadi::Integrator::trigger_event().

◆ worksize_

size_t casadi::SXFunction::worksize_

The documentation for this class was generated from the following files: