List of all members | Classes | Public Types | Public Member Functions | Static Public Member Functions | Public Attributes | Static Public Attributes | Protected Member Functions | Static 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 and traces 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
dump_traceOT_BOOLDump interpreted instruction values to name.NNNNNN.trace.jsonl in dump_dir, using the dump_in/dump_out counter. [false]casadi::SXFunction
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
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
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...
 
void trace_instruction (std::ostream &trace, casadi_int k, const double *w, bool output) const
 
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< SX > free_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...
 
std::vector< std::string > get_function () const override
 Get list of dependency functions. More...
 
const Function & get_function (const std::string &name) const override
 Get a dependency function. 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 eval_activity (const bvec_t **arg, bvec_t **res, casadi_int *iw, bvec_t *w, void *mem) const override
 Propagate signal activity 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 *, std::pair< Function, size_t > > &all_fun, casadi_int max_depth) const override
 
void change_option (const std::string &option_name, const GenericType &option_value) override
 Change option after object creation for debugging. More...
 
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...
 
Function simplify_passes (const std::vector< std::pair< std::string, casadi_int > > &tasks) const override
 Apply an ordered list of simplify passes. More...
 
void apply_simplify_passes (const std::vector< std::pair< std::string, casadi_int > > &tasks, std::vector< Matrix< SXElem > > &new_in, std::vector< Matrix< SXElem > > &new_out) const
 Apply simplify passes in-place on a set of inputs/outputs. 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 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 bool has_function (const std::string &fname) const
 
void add_embedded (std::map< FunctionInternal *, std::pair< Function, size_t > > &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< MX > mapsum_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 Function & oracle () 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< MX > free_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...
 
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 bool codegen_needs_mem () const
 Is thread-local memory object needed? More...
 
virtual bool codegen_mem_is_opaque () const
 Is thread-local memory object managed by checkout/release. 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< SX > sx_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< DM > eval_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< DM > nz_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< DM > nz_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...
 
Sparsity & jac_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< SX > sx_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< MX > mx_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< MX > mx_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< DM > dm_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< DM > dm_out () const
 Get function input(s) and output(s) More...
 
Function wrap (const std::string &name) const
 Wrap in an Function instance consisting of only one MX call. More...
 
Function wrap () const
 Wrap in an Function instance consisting of only one MX call. More...
 
Function wrap_as_needed (const std::string &name, const Dict &opts) 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...
 
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 Sparsity & sparsity_in (casadi_int ind) const
 Input/output sparsity. More...
 
const Sparsity & sparsity_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< MX > symbolic_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 ProtoFunction * deserialize (DeserializingStream &s)
 Deserialize without type information. More...
 
static std::vector< SX > order (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...
 
static std::string get_jit_directory (const Dict &jit_options)
 Get JIT directory from options. 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< AlgEl > algorithm_
 all binary nodes of the tree in the order of execution More...
 
size_t worksize_
 
std::vector< SXElem > free_vars_
 Free variables. More...
 
std::vector< SXElem > operations_
 The expressions corresponding to each binary operation. More...
 
std::vector< SXElem > constants_
 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...
 
bool dump_trace_ = false
 
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< Sparsity > sparsity_in_
 Input and output sparsity. More...
 
std::vector< Sparsity > sparsity_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_directory_
 
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...
 
signal_t incref_
 Incref/decref redirected to C functions. More...
 
signal_t decref_
 
Dict stats_
 Dict of statistics (resulting from evaluate) More...
 
bool has_refcount_
 Reference counting in codegen? More...
 
bool has_refcount_in_deps_
 Reference counting in dependent functions. More...
 
Dict cache_init_
 Values to prepopulate the function cache with. More...
 
WeakCache< std::string, Function > cache_
 Function cache. More...
 
std::vector< Sparsity > jac_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_
 
std::vector< Function > registered_functions_
 
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
 
void call_activity (const AlgEl &e, const bvec_t **arg, bvec_t **res, casadi_int *iw, bvec_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...
 
std::unique_ptr< std::ostream > open_trace (const double **arg, casadi_int dump_id) const
 
void finish_trace (std::ostream &trace, double **res, int ret) const
 
void initSingleton ()
 
void destroySingleton ()
 
B 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 Protected Member Functions

static void trace_values (std::ostream &trace, const double *values, casadi_int nnz)
 
static const Options options_
 Options. More...
 
const Options & get_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 248 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 1976 of file sx_function.cpp.

1976  :
1977  XFunction<SXFunction, SX, SXNode>(s) {
1978  int version = s.version("SXFunction", 1, 4);
1979  size_t n_instructions;
1980  s.unpack("SXFunction::n_instr", n_instructions);
1981 
1982  s.unpack("SXFunction::worksize", worksize_);
1983  s.unpack("SXFunction::free_vars", free_vars_);
1984  s.unpack("SXFunction::operations", operations_);
1985  s.unpack("SXFunction::constants", constants_);
1986  s.unpack("SXFunction::default_in", default_in_);
1987 
1988  if (version>=2) {
1989 
1990  s.unpack("SXFunction::call_sz_arg", call_.sz_arg);
1991  s.unpack("SXFunction::call_sz_res", call_.sz_res);
1992  s.unpack("SXFunction::call_sz_iw", call_.sz_iw);
1993  s.unpack("SXFunction::call_sz_w", call_.sz_w);
1994  s.unpack("SXFunction::call_sz_arg", call_.sz_w_arg);
1995  s.unpack("SXFunction::call_sz_res", call_.sz_w_res);
1996 
1997  size_t el_size;
1998  s.unpack("SXFunction::call_el_size", el_size);
1999  call_.el.reserve(el_size);
2000 
2001  // Loop over nodes
2002  for (casadi_int k=0;k<el_size;++k) {
2003  Function f;
2004  s.unpack("SXFunction::call_el_f", f);
2005  call_.el.emplace_back(f);
2006  auto& e = call_.el[k];
2007  s.unpack("SXFunction::call_el_dep", e.dep);
2008  s.unpack("SXFunction::call_el_res", e.res);
2009  s.unpack("SXFunction::call_el_copy_elision_arg", e.copy_elision_arg);
2010  s.unpack("SXFunction::call_el_copy_elision_offset", e.copy_elision_offset);
2011  }
2012 
2013  s.unpack("SXFunction::copy_elision", copy_elision_);
2014 
2015  } else {
2016  call_.sz_arg = 0;
2017  call_.sz_res = 0;
2018  call_.sz_iw = 0;
2019  call_.sz_w = 0;
2020  call_.sz_w_arg = 0;
2021  call_.sz_w_res = 0;
2022  call_.el.clear();
2023  copy_elision_.resize(n_instructions, false);
2024  }
2025 
2026  algorithm_.resize(n_instructions);
2027  for (casadi_int k=0;k<n_instructions;++k) {
2028  AlgEl& e = algorithm_[k];
2029  s.unpack("SXFunction::ScalarAtomic::op", e.op);
2030  s.unpack("SXFunction::ScalarAtomic::i0", e.i0);
2031  s.unpack("SXFunction::ScalarAtomic::i1", e.i1);
2032  s.unpack("SXFunction::ScalarAtomic::i2", e.i2);
2033  }
2034 
2035  // Default (persistent) options
2036  just_in_time_opencl_ = false;
2037  just_in_time_sparsity_ = false;
2038 
2039  s.unpack("SXFunction::live_variables", live_variables_);
2040  if (version>=3) {
2041  s.unpack("SXFunction::print_instructions", print_instructions_);
2042  } else {
2043  print_instructions_ = false;
2044  }
2045 
2046  if (version >= 4) s.unpack("SXFunction::dump_trace", dump_trace_);
2047 
2049  }
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:316
std::vector< ExtendedAlgEl > el

References algorithm_, call_, constants_, copy_elision_, default_in_, casadi::XFunction< DerivedType, MatType, NodeType >::delayed_deserialize_members(), dump_trace_, 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 1236 of file sx_function.cpp.

1237  {
1238  if (verbose_) casadi_message(name_ + "::ad_forward");
1239 
1240  // Number of forward seeds
1241  casadi_int nfwd = fseed.size();
1242  fsens.resize(nfwd);
1243 
1244  // Quick return if possible
1245  if (nfwd==0) return;
1246 
1247  // Check if seeds need to have dimensions corrected
1248  casadi_int npar = 1;
1249  for (auto&& r : fseed) {
1250  if (!matching_arg(r, npar)) {
1251  casadi_assert_dev(npar==1);
1252  ad_forward(replace_fseed(fseed, npar), fsens);
1253  return;
1254  }
1255  }
1256 
1257  // Make sure seeds have matching sparsity patterns
1258  for (auto it=fseed.begin(); it!=fseed.end(); ++it) {
1259  casadi_assert_dev(it->size()==n_in_);
1260  for (casadi_int i=0; i<n_in_; ++i) {
1261  if (it->at(i).sparsity()!=sparsity_in_[i]) {
1262  // Correct sparsity
1263  std::vector<std::vector<SX> > fseed2(fseed);
1264  for (auto&& r : fseed2) {
1265  for (casadi_int i=0; i<n_in_; ++i) r[i] = project(r[i], sparsity_in_[i]);
1266  }
1267  ad_forward(fseed2, fsens);
1268  return;
1269  }
1270  }
1271  }
1272 
1273  // Allocate results
1274  for (casadi_int d=0; d<nfwd; ++d) {
1275  fsens[d].resize(n_out_);
1276  for (casadi_int i=0; i<fsens[d].size(); ++i)
1277  if (fsens[d][i].sparsity()!=sparsity_out_[i])
1278  fsens[d][i] = SX::zeros(sparsity_out_[i]);
1279  }
1280 
1281  // Iterator to the binary operations
1282  std::vector<SXElem>::const_iterator b_it=operations_.begin();
1283 
1284  // Tape
1285  std::vector<TapeEl<SXElem> > s_pdwork(operations_.size());
1286  std::vector<TapeEl<SXElem> >::iterator it1 = s_pdwork.begin();
1287 
1288  // Evaluate algorithm
1289  if (verbose_) casadi_message("Evaluating algorithm forward");
1290  for (auto&& e : algorithm_) {
1291  switch (e.op) {
1292  case OP_INPUT:
1293  case OP_OUTPUT:
1294  case OP_CONST:
1295  case OP_PARAMETER:
1296  break;
1297  default:
1298  {
1299  const SXElem& f=*b_it++;
1300  switch (e.op) {
1301  CASADI_MATH_DER_BUILTIN(f->dep(0), f->dep(1), f, it1++->d)
1302  case OP_CALL:
1303  it1++->d[0] = f;
1304  }
1305  }
1306  }
1307  }
1308 
1309  // Work vector
1310  std::vector<SXElem> w(worksize_);
1311 
1312  // Calculate forward sensitivities
1313  if (verbose_) casadi_message("Calculating forward derivatives");
1314  for (casadi_int dir=0; dir<nfwd; ++dir) {
1315  std::vector<TapeEl<SXElem> >::const_iterator it2 = s_pdwork.begin();
1316  for (auto&& a : algorithm_) {
1317  switch (a.op) {
1318  case OP_INPUT:
1319  w[a.i0] = fseed[dir][a.i1].nonzeros()[a.i2]; break;
1320  case OP_OUTPUT:
1321  fsens[dir][a.i0].nonzeros()[a.i2] = w[a.i1]; break;
1322  case OP_CONST:
1323  case OP_PARAMETER:
1324  w[a.i0] = 0;
1325  break;
1326  case OP_IF_ELSE_ZERO:
1327  w[a.i0] = if_else_zero(it2++->d[1], w[a.i2]);
1328  break;
1329  case OP_CALL:
1330  {
1331  const auto& m = call_.el.at(a.i1);
1332  CallSX* call_node = static_cast<CallSX*>(it2->d[0].get());
1333 
1334  // Construct forward sensitivity function
1335  Function ff = m.f.forward(1);
1336 
1337  // Symbolic inputs to forward sensitivity function
1338  std::vector<SXElem> deps;
1339  deps.reserve(2*m.n_dep);
1340 
1341  // Set nominal inputs from node
1342  casadi_int offset = 0;
1343  for (casadi_int i=0;i<m.f_n_in;++i) {
1344  casadi_int nnz = ff.nnz_in(i);
1345  casadi_assert(nnz==0 || nnz==m.f.nnz_in(i), "Not implemented");
1346  for (casadi_int j=0;j<nnz;++j) {
1347  deps.push_back(call_node->dep(offset+j));
1348  }
1349  offset += m.f_nnz_in[i];
1350  }
1351 
1352  // Collect the nominal outputs needed by the derivative function
1353  std::vector<casadi_int> oind;
1354  offset = 0;
1355  for (casadi_int i=0;i<m.f_n_out;++i) {
1356  casadi_int nnz = ff.nnz_in(i+m.f_n_in);
1357  casadi_assert(nnz==0 || nnz==m.f.nnz_out(i), "Not implemented");
1358  for (casadi_int j=0;j<nnz;++j) {
1359  oind.push_back(offset+j);
1360  }
1361  offset += m.f_nnz_out[i];
1362  }
1363 
1364  auto nominal_outputs = call_node->get_output(oind);
1365  deps.insert(deps.end(), nominal_outputs.begin(), nominal_outputs.end());
1366 
1367  // Read in forward seeds from work vector
1368  offset = 0;
1369  for (casadi_int i=0;i<m.f_n_in;++i) {
1370  casadi_int nnz = ff.nnz_in(i+m.f_n_in+m.f_n_out);
1371  // nnz=0 occurs for is_diff_in[i] false
1372  casadi_assert(nnz==0 || nnz==m.f.nnz_in(i), "Not implemented");
1373  if (nnz) {
1374  for (casadi_int j=0;j<nnz;++j) {
1375  deps.push_back(w[m.dep[offset+j]]);
1376  }
1377  }
1378  offset += m.f_nnz_in[i];
1379  }
1380 
1381  // Call forward sensitivity function
1382  std::vector<SXElem> ret = SXElem::call(ff, deps);
1383 
1384  // Retrieve sensitivities
1385  offset = 0;
1386  casadi_int k = 0;
1387  for (casadi_int i=0;i<m.f_n_out;++i) {
1388  casadi_int nnz = ff.nnz_out(i);
1389  // nnz=0 occurs for is_diff_out[i] false
1390  casadi_assert(nnz==0 || nnz==m.f_nnz_out[i], "Not implemented");
1391  if (nnz) {
1392  for (casadi_int j=0;j<nnz;++j) {
1393  if (m.res[offset+j]>=0) w[m.res[offset+j]] = ret[k];
1394  k++;
1395  }
1396  }
1397  offset += m.f_nnz_out[i];
1398  }
1399  }
1400  it2++;
1401  break;
1402  CASADI_MATH_BINARY_BUILTIN // Binary operation
1403  w[a.i0] = it2->d[0] * w[a.i1] + it2->d[1] * w[a.i2];
1404  it2++;
1405  break;
1406  default: // Unary operation
1407  w[a.i0] = it2->d[0] * w[a.i1];
1408  it2++;
1409  }
1410  }
1411  }
1412  }
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:232
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:295
@ 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
Definition: sx_elem.cpp:512

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 1414 of file sx_function.cpp.

1415  {
1416  if (verbose_) casadi_message(name_ + "::ad_reverse");
1417 
1418  // number of adjoint seeds
1419  casadi_int nadj = aseed.size();
1420  asens.resize(nadj);
1421 
1422  // Quick return if possible
1423  if (nadj==0) return;
1424 
1425  // Check if seeds need to have dimensions corrected
1426  casadi_int npar = 1;
1427  for (auto&& r : aseed) {
1428  if (!matching_res(r, npar)) {
1429  casadi_assert_dev(npar==1);
1430  ad_reverse(replace_aseed(aseed, npar), asens);
1431  return;
1432  }
1433  }
1434 
1435  // Make sure matching sparsity of fseed
1436  bool matching_sparsity = true;
1437  for (casadi_int d=0; d<nadj; ++d) {
1438  casadi_assert_dev(aseed[d].size()==n_out_);
1439  for (casadi_int i=0; matching_sparsity && i<n_out_; ++i)
1440  matching_sparsity = aseed[d][i].sparsity()==sparsity_out_[i];
1441  }
1442 
1443  // Correct sparsity if needed
1444  if (!matching_sparsity) {
1445  std::vector<std::vector<SX> > aseed2(aseed);
1446  for (casadi_int d=0; d<nadj; ++d)
1447  for (casadi_int i=0; i<n_out_; ++i)
1448  if (aseed2[d][i].sparsity()!=sparsity_out_[i])
1449  aseed2[d][i] = project(aseed2[d][i], sparsity_out_[i]);
1450  ad_reverse(aseed2, asens);
1451  return;
1452  }
1453 
1454  // Allocate results if needed
1455  for (casadi_int d=0; d<nadj; ++d) {
1456  asens[d].resize(n_in_);
1457  for (casadi_int i=0; i<asens[d].size(); ++i) {
1458  if (asens[d][i].sparsity()!=sparsity_in_[i]) {
1459  asens[d][i] = SX::zeros(sparsity_in_[i]);
1460  } else {
1461  std::fill(asens[d][i]->begin(), asens[d][i]->end(), 0);
1462  }
1463  }
1464  }
1465 
1466  // Iterator to the binary operations
1467  std::vector<SXElem>::const_iterator b_it=operations_.begin();
1468 
1469  // Tape
1470  std::vector<TapeEl<SXElem> > s_pdwork(operations_.size());
1471  std::vector<TapeEl<SXElem> >::iterator it1 = s_pdwork.begin();
1472 
1473  // Evaluate algorithm
1474  if (verbose_) casadi_message("Evaluating algorithm forward");
1475  for (auto&& a : algorithm_) {
1476  switch (a.op) {
1477  case OP_INPUT:
1478  case OP_OUTPUT:
1479  case OP_CONST:
1480  case OP_PARAMETER:
1481  break;
1482  default:
1483  {
1484  const SXElem& f=*b_it++;
1485  switch (a.op) {
1486  CASADI_MATH_DER_BUILTIN(f->dep(0), f->dep(1), f, it1++->d)
1487  case OP_CALL:
1488  it1++->d[0] = f;
1489  }
1490  }
1491  }
1492  }
1493 
1494  // Calculate adjoint sensitivities
1495  if (verbose_) casadi_message("Calculating adjoint derivatives");
1496 
1497  // Work vector
1498  std::vector<SXElem> w(worksize_, 0);
1499 
1500  for (casadi_int dir=0; dir<nadj; ++dir) {
1501  auto it2 = s_pdwork.rbegin();
1502  for (auto it = algorithm_.rbegin(); it!=algorithm_.rend(); ++it) {
1503  SXElem seed;
1504  switch (it->op) {
1505  case OP_INPUT:
1506  asens[dir][it->i1].nonzeros()[it->i2] = w[it->i0];
1507  w[it->i0] = 0;
1508  break;
1509  case OP_OUTPUT:
1510  w[it->i1] += aseed[dir][it->i0].nonzeros()[it->i2];
1511  break;
1512  case OP_CONST:
1513  case OP_PARAMETER:
1514  w[it->i0] = 0;
1515  break;
1516  case OP_IF_ELSE_ZERO:
1517  seed = w[it->i0];
1518  w[it->i0] = 0;
1519  w[it->i2] += if_else_zero(it2++->d[1], seed);
1520  break;
1521  case OP_CALL:
1522  {
1523  const auto& m = call_.el.at(it->i1);
1524  CallSX* call_node = static_cast<CallSX*>(it2->d[0].get());
1525 
1526  // Construct reverse sensitivity function
1527  Function fr = m.f.reverse(1);
1528 
1529  // Symbolic inputs to reverse sensitivity function
1530  std::vector<SXElem> deps;
1531  deps.reserve(m.n_dep+m.n_res);
1532 
1533  // Set nominal inputs from node
1534  casadi_int offset = 0;
1535  for (casadi_int i=0;i<m.f_n_in;++i) {
1536  casadi_int nnz = fr.nnz_in(i);
1537  casadi_assert(nnz==0 || nnz==m.f.nnz_in(i), "Not implemented");
1538  for (casadi_int j=0;j<nnz;++j) {
1539  deps.push_back(call_node->dep(offset+j));
1540  }
1541  offset += m.f_nnz_in[i];
1542  }
1543 
1544  // Collect the nominal outputs needed by the derivative function
1545  std::vector<casadi_int> oind;
1546  offset = 0;
1547  for (casadi_int i=0;i<m.f_n_out;++i) {
1548  casadi_int nnz = fr.nnz_in(i+m.f_n_in);
1549  casadi_assert(nnz==0 || nnz==m.f.nnz_out(i), "Not implemented");
1550  for (casadi_int j=0;j<nnz;++j) {
1551  oind.push_back(offset+j);
1552  }
1553  offset += m.f_nnz_out[i];
1554  }
1555 
1556  auto nominal_outputs = call_node->get_output(oind);
1557  deps.insert(deps.end(), nominal_outputs.begin(), nominal_outputs.end());
1558 
1559  // Read in reverse seeds from work vector
1560  offset = 0;
1561  for (casadi_int i=0;i<m.f_n_out;++i) {
1562  casadi_int nnz = fr.nnz_in(i+m.f_n_in+m.f_n_out);
1563  // nnz=0 occurs for is_diff_out[i] false
1564  casadi_assert(nnz==0 || nnz==m.f.nnz_out(i), "Not implemented");
1565  if (nnz) {
1566  for (casadi_int j=0;j<nnz;++j) {
1567  deps.push_back((m.res[offset+j]>=0) ? w[m.res[offset+j]] : 0);
1568  }
1569  }
1570  offset += m.f.nnz_out(i);
1571  }
1572 
1573  // Call reverse sensitivity function
1574  std::vector<SXElem> ret = SXElem::call(fr, deps);
1575 
1576  // Clear out reverse seeds
1577  for (casadi_int i=0;i<m.n_res;++i) {
1578  if (m.res[i]>=0) w[m.res[i]] = 0;
1579  }
1580 
1581  // Store reverse sensitivities into work vector
1582  offset = 0;
1583  casadi_int k = 0;
1584  for (casadi_int i=0;i<m.f_n_in;++i) {
1585  casadi_int nnz = fr.nnz_out(i);
1586  // nnz=0 occurs for is_diff_in[i] false
1587  casadi_assert(nnz==0 || nnz==m.f_nnz_in[i], "Not implemented");
1588  if (nnz) {
1589  for (casadi_int j=0;j<nnz;++j) {
1590  w[m.dep[offset+j]] += ret[k++];
1591  }
1592  }
1593  offset += m.f_nnz_in[i];
1594  }
1595  }
1596  it2++;
1597  break;
1598  CASADI_MATH_BINARY_BUILTIN // Binary operation
1599  seed = w[it->i0];
1600  w[it->i0] = 0;
1601  w[it->i1] += it2->d[0] * seed;
1602  w[it->i2] += it2++->d[1] * seed;
1603  break;
1604  default: // Unary operation
1605  seed = w[it->i0];
1606  w[it->i0] = 0;
1607  w[it->i1] += it2++->d[0] * seed;
1608  }
1609  }
1610  }
1611 
1612  // Drop sparsity of fully structurally-zero sensitivities, matching MXFunction (#4345)
1613  for (casadi_int d=0; d<nadj; ++d) {
1614  for (casadi_int i=0; i<n_in_; ++i) {
1615  SX& a = asens[d][i];
1616  if (a.is_zero()) a = SX(a.size1(), a.size2());
1617  }
1618  }
1619  }
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.
Matrix< SXElem > SX
Definition: sx_fwd.hpp:32

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::Matrix< Scalar >::is_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::GenericMatrix< MatType >::size1(), casadi::GenericMatrix< MatType >::size2(), 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 3522 of file function_internal.cpp.

3522  {
3523  // If reverse mode derivatives unavailable, use forward
3524  if (!enable_reverse_) return 0;
3525 
3526  // If forward mode derivatives unavailable, use reverse
3527  if (!enable_forward_ && !enable_fd_) return 1;
3528 
3529  // Use the (potentially user set) option
3530  return ad_weight_;
3531  }
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::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 *, std::pair< Function, size_t > > &  all_fun,
const Function &  dep,
casadi_int  max_depth 
) const
inherited

Definition at line 3964 of file function_internal.cpp.

3966  {
3967  // Add, if not already in graph and not null
3968  if (!dep.is_null() && all_fun.find(dep.get()) == all_fun.end()) {
3969  size_t index = all_fun.size();
3970  all_fun[dep.get()] = std::make_pair(dep, index);
3971  // Also add its dependencies
3972  if (max_depth > 0) dep->find(all_fun, max_depth - 1);
3973  }
3974  }

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

Referenced by casadi::FunctionInternal::find(), casadi::Map::find(), casadi::MapSum::find(), casadi::MXFunction::find(), casadi::OracleFunction::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 3255 of file function_internal.cpp.

3255  {
3256  if (!enable_reverse_) return true;
3257  if (jac_penalty_==-1) return false;
3258 
3259  // Heuristic 1: Jac calculated via reverse mode likely cheaper
3260  if (jac_penalty_*static_cast<double>(nnz_out())<nadj) return true;
3261 
3262  // Heuristic 2: Jac calculated via forward mode likely cheaper
3263  double w = ad_weight();
3264  if ((enable_forward_ || enable_fd_) &&
3265  jac_penalty_*w*static_cast<double>(nnz_in())<(1-w)*static_cast<double>(nadj))
3266  return true; // NOLINT
3267 
3268  return false;
3269  }
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 4009 of file function_internal.cpp.

4009  {
4010  // Check inputs
4011  for (casadi_int i=0; i<n_in_; ++i) {
4012  if (!sparsity_in_[i].is_scalar()) return false;
4013  }
4014  // Check outputs
4015  for (casadi_int i=0; i<n_out_; ++i) {
4016  if (!sparsity_out_[i].is_scalar()) return false;
4017  }
4018  // All are scalar
4019  return true;
4020  }

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 3203 of file function_internal.cpp.

3203  {
3204  if (f.is_null()) return;
3205  size_t sz_arg, sz_res, sz_iw, sz_w;
3206  f.sz_work(sz_arg, sz_res, sz_iw, sz_w);
3207  alloc_arg(sz_arg*num_threads, persistent);
3208  alloc_res(sz_res*num_threads, persistent);
3209  alloc_iw(sz_iw*num_threads, persistent);
3210  alloc_w(sz_w*num_threads, persistent);
3211  registered_functions_.push_back(f);
3212  }
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.
std::vector< Function > registered_functions_
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::registered_functions_, 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 3195 of file function_internal.cpp.

3195  {
3196  if (persistent) {
3197  sz_w_per_ += sz_w;
3198  } else {
3199  sz_w_tmp_ = std::max(sz_w_tmp_, sz_w);
3200  }
3201  }

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::MadmpecInterface::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::MosekInterface::init(), casadi::OoqpInterface::init(), casadi::OsqpInterface::init(), casadi::PiqpInterface::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::XpressInterface::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().

◆ apply_simplify_passes()

void casadi::XFunction< SXFunction , Matrix< SXElem > , SXNode >::apply_simplify_passes ( const std::vector< std::pair< std::string, casadi_int > > &  tasks,
std::vector< Matrix< SXElem > > &  new_in,
std::vector< Matrix< SXElem > > &  new_out 
) const
inherited

Each pass is a (task, count) pair; count>0 runs the task that many times, count==0 runs it until a fixed point.

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

Definition at line 175 of file x_function.hpp.

1051  {
1052  for (const auto& tc : tasks) {
1053  const std::string& task = tc.first;
1054  // count>0: run exactly that many times; count==0: run until a fixed point
1055  casadi_int count = tc.second;
1056  casadi_assert(count>=0,
1057  "simplify task '" + task + "': run count must be >= 0 (0 = until fixed point)");
1058  casadi_int prev_nodes = -1;
1059  casadi_int max_iter = count==0 ? 100 : count;
1060  for (casadi_int it=0; it<max_iter; ++it) {
1061  if (task=="empty_inputs") {
1062  // What symbols occur in the outputs?
1063  std::vector<MatType> syms = MatType::symvar(veccat(new_out));
1064  // Loop over inputs
1065  for (MatType& e : new_in) {
1066  // If current input symbols do not occur in outputs
1067  if (!contains_any(syms, MatType::symvar(e))) {
1068  // Replace input by an empty matrix
1069  e = MatType(e.size());
1070  }
1071  }
1072  } else if (task=="combine_terms") {
1073  MatType::simplify_combine_terms(new_in, new_out);
1074  } else if (task=="cse") {
1075  new_out = MatType::cse(new_out);
1076  } else if (task=="ref_count") {
1077  MatType::simplify_ref_count(new_in, new_out);
1078  } else if (task=="const_folding") {
1079  MatType::simplify_const_folding(new_in, new_out);
1080  } else {
1081  casadi_error("No such simplify task: '" + task + "'.\n");
1082  }
1083  if (count!=0) continue;
1084  // Stop once the graph size stops shrinking
1085  casadi_int nodes = MatType::n_nodes(veccat(new_out));
1086  if (prev_nodes != -1 && nodes >= prev_nodes) break;
1087  prev_nodes = nodes;
1088  }
1089  }
1090  }

◆ cache()

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

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

Definition at line 1163 of file function_internal.cpp.

1163  {
1164  // Return value
1165  Dict ret;
1166 
1167  // Retrieve all Function instances that haven't been deleted
1168  std::vector<std::string> keys;
1169  std::vector<Function> entries;
1170  cache_.cache(keys, entries);
1171 
1172  for (size_t i=0; i<keys.size(); ++i) {
1173  // Get the name of the key
1174  std::string s = keys[i];
1175  casadi_assert_dev(s.size() > 0);
1176  // Replace ':' with '_'
1177  std::replace(s.begin(), s.end(), ':', '_');
1178  // Remove trailing underscore, if any
1179  if (s.back() == '_') s.resize(s.size() - 1);
1180  // Add entry to function return
1181  ret[s] = entries[i];
1182  }
1183 
1184  return ret;
1185  }
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 1622 of file function_internal.hpp.

1623  {
1624  // If all inputs are scalar ...
1625  if (all_scalar()) {
1626  // ... and some arguments are matrix-valued with matching dimensions ...
1627  bool matrix_call = false;
1628  std::pair<casadi_int, casadi_int> sz;
1629  for (auto&& a : arg) {
1630  if (!a.is_scalar() && !a.is_empty()) {
1631  if (!matrix_call) {
1632  // Matrix call
1633  matrix_call = true;
1634  sz = a.size();
1635  } else if (a.size()!=sz) {
1636  // Not same dimensions
1637  matrix_call = false;
1638  break;
1639  }
1640  }
1641  }
1642 
1643  // ... then, call multiple times
1644  if (matrix_call) {
1645  // Start with zeros
1646  res.resize(n_out_);
1647  M z = M::zeros(sz);
1648  for (auto&& a : res) a = z;
1649  // Call multiple times
1650  std::vector<M> arg1 = arg, res1;
1651  for (casadi_int c=0; c<sz.second; ++c) {
1652  for (casadi_int r=0; r<sz.first; ++r) {
1653  // Get scalar arguments
1654  for (casadi_int i=0; i<arg.size(); ++i) {
1655  if (arg[i].size()==sz) arg1[i] = arg[i](r, c);
1656  }
1657  // Call recursively with scalar arguments
1658  call(arg1, res1, always_inline, never_inline);
1659  // Get results
1660  casadi_assert_dev(res.size() == res1.size());
1661  for (casadi_int i=0; i<res.size(); ++i) res[i](r, c) = res1[i];
1662  }
1663  }
1664  // All elements assigned
1665  return;
1666  }
1667  }
1668 
1669  // Check if inputs need to be replaced
1670  casadi_int npar = 1;
1671  if (!matching_arg(arg, npar)) {
1672  return call(replace_arg(arg, npar), res, always_inline, never_inline);
1673  }
1674 
1675  // Call the type-specific method
1676  call_gen(arg, res, npar, always_inline, never_inline);
1677  }
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().

Referenced by trace_instruction().

◆ call_activity()

void casadi::SXFunction::call_activity ( const AlgEl &  e,
const bvec_t **  arg,
bvec_t **  res,
casadi_int *  iw,
bvec_t *  w 
) const
protected

Definition at line 1770 of file sx_function.cpp.

1771  {
1772  const auto& m = call_.el[e.i1];
1773  const bvec_t** call_arg = arg;
1774  bvec_t** call_res = res;
1775  casadi_int* call_iw = iw;
1776  bvec_t* call_w = w;
1777  bvec_t* nz_in;
1778  bvec_t* nz_out;
1779 
1780  call_setup(m, &call_arg, &call_res, &call_iw, &call_w, &nz_in, &nz_out);
1781 
1782  // Populate nz_in from work vector
1783  for (casadi_int i=0; i<m.n_dep; ++i) nz_in[i] = w[m.dep[i]];
1784  // Recurse: activity through the callee
1785  m.f.eval_activity(call_arg, call_res, call_iw, call_w);
1786  // Store nz_out results back in work vector
1787  for (casadi_int i=0; i<m.n_res; ++i) {
1788  if (m.res[i]>=0) w[m.res[i]] = nz_out[i];
1789  }
1790  }
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
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 eval_activity().

◆ 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 218 of file x_function.hpp.

1193  {
1194  casadi_assert(!(always_inline && never_inline), "Inconsistent options");
1195  if (!should_inline(MatType::type_name()=="SX", always_inline, never_inline)) {
1196  // The non-inlining version is implemented in the base class
1197  return FunctionInternal::call_forward(arg, res, fseed, fsens,
1198  always_inline, never_inline);
1199  }
1200 
1201  // Quick return if no seeds
1202  if (fseed.empty()) {
1203  fsens.clear();
1204  return;
1205  }
1206 
1207  // Call inlining
1208  if (isInput(arg)) {
1209  // Argument agrees with in_, call ad_forward directly
1210  static_cast<const DerivedType*>(this)->ad_forward(fseed, fsens);
1211  } else {
1212  // Need to create a temporary function
1213  Function f("tmp_call_forward", arg, res);
1214  static_cast<DerivedType *>(f.get())->ad_forward(fseed, fsens);
1215  }
1216  }
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 3275 of file function_internal.cpp.

3279  {
3280  casadi_assert(!(always_inline && never_inline), "Inconsistent options");
3281  casadi_assert(!always_inline, "Class " + class_name() +
3282  " cannot be inlined in an MX expression");
3283 
3284  // Derivative information must be available
3285  casadi_assert(has_derivative(),
3286  "Derivatives cannot be calculated for " + name_);
3287 
3288  // Number of directional derivatives
3289  casadi_int nfwd = fseed.size();
3290  fsens.resize(nfwd);
3291 
3292  // Quick return if no seeds
3293  if (nfwd==0) return;
3294 
3295  // Check if seeds need to have dimensions corrected
3296  casadi_int npar = 1;
3297  for (auto&& r : fseed) {
3298  if (!matching_arg(r, npar)) {
3299  FunctionInternal::call_forward(arg, res, replace_fseed(fseed, npar),
3300  fsens, always_inline, never_inline);
3301  return;
3302  }
3303  }
3304 
3305  // Calculating full Jacobian and then multiplying
3306  if (fwdViaJac(nfwd)) {
3307  // Multiply the Jacobian from the right
3308  std::vector<MX> darg = arg;
3309  darg.insert(darg.end(), res.begin(), res.end());
3310  std::vector<MX> J = jacobian()(darg);
3311  // Join forward seeds
3312  std::vector<MX> v(nfwd), all_fseed(n_in_);
3313  for (size_t i = 0; i < n_in_; ++i) {
3314  for (size_t d = 0; d < nfwd; ++d) v[d] = vec(fseed.at(d).at(i));
3315  all_fseed[i] = horzcat(v);
3316  }
3317  // Calculate forward sensitivities
3318  std::vector<MX> all_fsens(n_out_);
3319  std::vector<MX>::const_iterator J_it = J.begin();
3320  for (size_t oind = 0; oind < n_out_; ++oind) {
3321  for (size_t iind = 0; iind < n_in_; ++iind) {
3322  // Add contribution
3323  MX a = mtimes(*J_it++, all_fseed[iind]);
3324  all_fsens[oind] = all_fsens[oind].is_empty(true) ? a : all_fsens[oind] + a;
3325  }
3326  }
3327  // Split forward sensitivities
3328  for (size_t d = 0; d < nfwd; ++d) fsens[d].resize(n_out_);
3329  for (size_t i = 0; i < n_out_; ++i) {
3330  v = horzsplit(all_fsens[i]);
3331  casadi_assert_dev(v.size() == nfwd);
3332  for (size_t d = 0; d < nfwd; ++d) fsens[d][i] = reshape(v[d], size_out(i));
3333  }
3334  } else {
3335  // Evaluate in batches
3336  casadi_assert_dev(enable_forward_ || enable_fd_);
3337  casadi_int max_nfwd = max_num_dir_;
3338  if (!enable_fd_) {
3339  while (!has_forward(max_nfwd)) max_nfwd/=2;
3340  }
3341  casadi_int offset = 0;
3342  while (offset<nfwd) {
3343  // Number of derivatives, in this batch
3344  casadi_int nfwd_batch = std::min(nfwd-offset, max_nfwd);
3345 
3346  // All inputs and seeds
3347  std::vector<MX> darg;
3348  darg.reserve(n_in_ + n_out_ + n_in_);
3349  darg.insert(darg.end(), arg.begin(), arg.end());
3350  darg.insert(darg.end(), res.begin(), res.end());
3351  std::vector<MX> v(nfwd_batch);
3352  for (casadi_int i=0; i<n_in_; ++i) {
3353  for (casadi_int d=0; d<nfwd_batch; ++d) v[d] = fseed[offset+d][i];
3354  darg.push_back(horzcat(v));
3355  }
3356 
3357  // Create the evaluation node
3358  Function dfcn = self().forward(nfwd_batch);
3359  std::vector<MX> x = dfcn(darg);
3360 
3361  casadi_assert_dev(x.size()==n_out_);
3362 
3363  // Retrieve sensitivities
3364  for (casadi_int d=0; d<nfwd_batch; ++d) fsens[offset+d].resize(n_out_);
3365  for (casadi_int i=0; i<n_out_; ++i) {
3366  if (size2_out(i)>0) {
3367  v = horzsplit(x[i], size2_out(i));
3368  casadi_assert_dev(v.size()==nfwd_batch);
3369  } else {
3370  v = std::vector<MX>(nfwd_batch, MX(size_out(i)));
3371  }
3372  for (casadi_int d=0; d<nfwd_batch; ++d) fsens[offset+d][i] = v[d];
3373  }
3374 
3375  // Update offset
3376  offset += nfwd_batch;
3377  }
3378  }
3379  }
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 3496 of file function_internal.cpp.

3500  {
3501  casadi_assert(!(always_inline && never_inline), "Inconsistent options");
3502  if (fseed.empty()) { // Quick return if no seeds
3503  fsens.clear();
3504  return;
3505  }
3506  casadi_error("'forward' (SX) not defined for " + class_name());
3507  }

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 1646 of file sx_function.cpp.

1646  {
1647  const auto& m = call_.el[e.i1];
1648  const T** call_arg = arg;
1649  T** call_res = res;
1650  casadi_int* call_iw = iw;
1651  T* call_w = w;
1652  T* nz_in;
1653  T* nz_out;
1654 
1655  call_setup(m, &call_arg, &call_res, &call_iw, &call_w, &nz_in, &nz_out);
1656 
1657  // Populate nz_in from work vector
1658  for (casadi_int i=0;i<m.n_dep;++i) {
1659  nz_in[i] = w[m.dep[i]];
1660  }
1661  // Perform call nz_in -> nz_out
1662  m.f(call_arg, call_res, call_iw, call_w);
1663 
1664  // Store nz_out results back in workvector
1665  for (casadi_int i=0;i<m.n_res;++i) {
1666  // Only if the result is actually needed
1667  if (m.res[i]>=0) {
1668  w[m.res[i]] = nz_out[i];
1669  }
1670  }
1671  }

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 4183 of file function_internal.cpp.

4185  {
4186  if (npar==1) {
4187  eval_mx(arg, res, always_inline, never_inline);
4188  } else {
4189  // Split it up arguments
4190  std::vector<std::vector<MX>> v(npar, arg);
4191  std::vector<MX> t;
4192  for (int i=0; i<n_in_; ++i) {
4193  if (arg[i].size2()!=size2_in(i)) {
4194  t = horzsplit(arg[i], size2_in(i));
4195  casadi_assert_dev(t.size()==npar);
4196  for (int p=0; p<npar; ++p) v[p][i] = t[p];
4197  }
4198  }
4199  // Unroll the loop
4200  for (int p=0; p<npar; ++p) {
4201  eval_mx(v[p], t, always_inline, never_inline);
4202  v[p] = t;
4203  }
4204  // Concatenate results
4205  t.resize(npar);
4206  res.resize(n_out_);
4207  for (int i=0; i<n_out_; ++i) {
4208  for (int p=0; p<npar; ++p) t[p] = v[p][i];
4209  res[i] = horzcat(t);
4210  }
4211  }
4212  }
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 1726 of file function_internal.hpp.

1728  {
1729  std::vector< Matrix<D> > arg2 = project_arg(arg, npar);
1730 
1731  // Which arguments require mapped evaluation
1732  std::vector<bool> mapped(n_in_);
1733  for (casadi_int i=0; i<n_in_; ++i) {
1734  mapped[i] = arg[i].size2()!=size2_in(i);
1735  }
1736 
1737  // Allocate results
1738  res.resize(n_out_);
1739  for (casadi_int i=0; i<n_out_; ++i) {
1740  if (!res[i].sparsity().is_stacked(sparsity_out(i), npar)) {
1741  res[i] = Matrix<D>::zeros(repmat(sparsity_out(i), 1, npar));
1742  }
1743  }
1744 
1745  // Allocate temporary memory if needed
1746  std::vector<casadi_int> iw_tmp(sz_iw());
1747  std::vector<D> w_tmp(sz_w());
1748 
1749  // Get pointers to input arguments
1750  std::vector<const D*> argp(sz_arg());
1751  for (casadi_int i=0; i<n_in_; ++i) argp[i]=get_ptr(arg2[i]);
1752 
1753  // Get pointers to output arguments
1754  std::vector<D*> resp(sz_res());
1755  for (casadi_int i=0; i<n_out_; ++i) resp[i]=get_ptr(res[i]);
1756 
1757  // For all parallel calls
1758  for (casadi_int p=0; p<npar; ++p) {
1759  // Call memory-less
1760  if (eval_gen(get_ptr(argp), get_ptr(resp),
1761  get_ptr(iw_tmp), get_ptr(w_tmp), memory(0),
1762  always_inline, never_inline)) {
1763  if (error_on_fail_) casadi_error("Evaluation failed");
1764  }
1765  // Update offsets
1766  if (p==npar-1) break;
1767  for (casadi_int i=0; i<n_in_; ++i) if (mapped[i]) argp[i] += nnz_in(i);
1768  for (casadi_int i=0; i<n_out_; ++i) resp[i] += nnz_out(i);
1769  }
1770  }
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 1675 of file sx_function.cpp.

1675  {
1676  const auto& m = call_.el[e.i1];
1677  bvec_t** call_arg = arg;
1678  bvec_t** call_res = res;
1679  casadi_int* call_iw = iw;
1680  bvec_t* call_w = w;
1681  bvec_t* nz_in;
1682  bvec_t* nz_out;
1683 
1684  call_setup(m, &call_arg, &call_res, &call_iw, &call_w, &nz_in, &nz_out);
1685 
1686  std::fill_n(nz_in, m.n_dep, 0);
1687 
1688  // Read in reverse seeds nz_out from work vector
1689  for (casadi_int i=0;i<m.n_res;++i) {
1690  nz_out[i] = (m.res[i]>=0) ? w[m.res[i]] : 0;
1691  }
1692 
1693  // Perform reverse mode call nz_out -> nz_in
1694  m.f.rev(call_arg, call_res, call_iw, call_w);
1695 
1696  // Clear out reverse seeds
1697  for (casadi_int i=0;i<m.n_res;++i) {
1698  if (m.res[i]>=0) w[m.res[i]] = 0;
1699  }
1700 
1701  // Store reverse sensitivities into work vector
1702  for (casadi_int i=0;i<m.n_dep;++i) {
1703  w[m.dep[i]] |= nz_in[i];
1704  }
1705  }

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 227 of file x_function.hpp.

1224  {
1225  casadi_assert(!(always_inline && never_inline), "Inconsistent options");
1226  if (!should_inline(MatType::type_name()=="SX", always_inline, never_inline)) {
1227  // The non-inlining version is implemented in the base class
1228  return FunctionInternal::call_reverse(arg, res, aseed, asens,
1229  always_inline, never_inline);
1230  }
1231 
1232  // Quick return if no seeds
1233  if (aseed.empty()) {
1234  asens.clear();
1235  return;
1236  }
1237 
1238  // Call inlining
1239  if (isInput(arg)) {
1240  // Argument agrees with in_, call ad_reverse directly
1241  static_cast<const DerivedType*>(this)->ad_reverse(aseed, asens);
1242  } else {
1243  // Need to create a temporary function
1244  Function f("tmp_call_reverse", arg, res);
1245  static_cast<DerivedType *>(f.get())->ad_reverse(aseed, asens);
1246  }
1247  }

◆ 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 3381 of file function_internal.cpp.

3385  {
3386  casadi_assert(!(always_inline && never_inline), "Inconsistent options");
3387  casadi_assert(!always_inline, "Class " + class_name() +
3388  " cannot be inlined in an MX expression");
3389 
3390  // Derivative information must be available
3391  casadi_assert(has_derivative(),
3392  "Derivatives cannot be calculated for " + name_);
3393 
3394  // Number of directional derivatives
3395  casadi_int nadj = aseed.size();
3396  asens.resize(nadj);
3397 
3398  // Quick return if no seeds
3399  if (nadj==0) return;
3400 
3401  // Check if seeds need to have dimensions corrected
3402  casadi_int npar = 1;
3403  for (auto&& r : aseed) {
3404  if (!matching_res(r, npar)) {
3405  FunctionInternal::call_reverse(arg, res, replace_aseed(aseed, npar),
3406  asens, always_inline, never_inline);
3407  return;
3408  }
3409  }
3410 
3411  // Calculating full Jacobian and then multiplying likely cheaper
3412  if (adjViaJac(nadj)) {
3413  // Multiply the transposed Jacobian from the right
3414  std::vector<MX> darg = arg;
3415  darg.insert(darg.end(), res.begin(), res.end());
3416  std::vector<MX> J = jacobian()(darg);
3417  // Join adjoint seeds
3418  std::vector<MX> v(nadj), all_aseed(n_out_);
3419  for (size_t i = 0; i < n_out_; ++i) {
3420  for (size_t d = 0; d < nadj; ++d) v[d] = vec(aseed.at(d).at(i));
3421  all_aseed[i] = horzcat(v);
3422  }
3423  // Calculate adjoint sensitivities
3424  std::vector<MX> all_asens(n_in_);
3425  std::vector<MX>::const_iterator J_it = J.begin();
3426  for (size_t oind = 0; oind < n_out_; ++oind) {
3427  for (size_t iind = 0; iind < n_in_; ++iind) {
3428  // Add contribution
3429  MX a = mtimes((*J_it++).T(), all_aseed[oind]);
3430  all_asens[iind] = all_asens[iind].is_empty(true) ? a : all_asens[iind] + a;
3431  }
3432  }
3433  // Split adjoint sensitivities
3434  for (size_t d = 0; d < nadj; ++d) asens[d].resize(n_in_);
3435  for (size_t i = 0; i < n_in_; ++i) {
3436  v = horzsplit(all_asens[i]);
3437  casadi_assert_dev(v.size() == nadj);
3438  for (size_t d = 0; d < nadj; ++d) {
3439  if (asens[d][i].is_empty(true)) {
3440  asens[d][i] = reshape(v[d], size_in(i));
3441  } else {
3442  asens[d][i] += reshape(v[d], size_in(i));
3443  }
3444  }
3445  }
3446  } else {
3447  // Evaluate in batches
3448  casadi_assert_dev(enable_reverse_);
3449  casadi_int max_nadj = max_num_dir_;
3450 
3451  while (!has_reverse(max_nadj)) max_nadj/=2;
3452  casadi_int offset = 0;
3453  while (offset<nadj) {
3454  // Number of derivatives, in this batch
3455  casadi_int nadj_batch = std::min(nadj-offset, max_nadj);
3456 
3457  // All inputs and seeds
3458  std::vector<MX> darg;
3459  darg.reserve(n_in_ + n_out_ + n_out_);
3460  darg.insert(darg.end(), arg.begin(), arg.end());
3461  darg.insert(darg.end(), res.begin(), res.end());
3462  std::vector<MX> v(nadj_batch);
3463  for (casadi_int i=0; i<n_out_; ++i) {
3464  for (casadi_int d=0; d<nadj_batch; ++d) v[d] = aseed[offset+d][i];
3465  darg.push_back(horzcat(v));
3466  }
3467 
3468  // Create the evaluation node
3469  Function dfcn = self().reverse(nadj_batch);
3470  std::vector<MX> x = dfcn(darg);
3471  casadi_assert_dev(x.size()==n_in_);
3472 
3473  // Retrieve sensitivities
3474  for (casadi_int d=0; d<nadj_batch; ++d) asens[offset+d].resize(n_in_);
3475  for (casadi_int i=0; i<n_in_; ++i) {
3476  if (size2_in(i)>0) {
3477  v = horzsplit(x[i], size2_in(i));
3478  casadi_assert_dev(v.size()==nadj_batch);
3479  } else {
3480  v = std::vector<MX>(nadj_batch, MX(size_in(i)));
3481  }
3482  for (casadi_int d=0; d<nadj_batch; ++d) {
3483  if (asens[offset+d][i].is_empty(true)) {
3484  asens[offset+d][i] = v[d];
3485  } else {
3486  asens[offset+d][i] += v[d];
3487  }
3488  }
3489  }
3490  // Update offset
3491  offset += nadj_batch;
3492  }
3493  }
3494  }
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 3509 of file function_internal.cpp.

3513  {
3514  casadi_assert(!(always_inline && never_inline), "Inconsistent options");
3515  if (aseed.empty()) { // Quick return if no seeds
3516  asens.clear();
3517  return;
3518  }
3519  casadi_error("'reverse' (SX) not defined for " + class_name());
3520  }

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 1622 of file sx_function.cpp.

1623  {
1624  *call_arg += n_in_;
1625  *call_res += n_out_;
1626  *nz_in = *call_w + worksize_;
1627  *nz_out = *call_w + worksize_ + call_.sz_w_arg;
1628  *call_w = *call_w + worksize_ + call_.sz_w_arg + call_.sz_w_res;
1629 
1630  // Set up call_arg to point to nz_in
1631  T* ptr_w = *nz_in;
1632  for (casadi_int i=0;i<m.f_n_in;++i) {
1633  (*call_arg)[i] = ptr_w;
1634  ptr_w+=m.f_nnz_in[i];
1635  }
1636 
1637  // Set up call_res to point to nz_out
1638  ptr_w = *nz_out;
1639  for (casadi_int i=0;i<m.f_n_out;++i) {
1640  (*call_res)[i] = ptr_w;
1641  ptr_w+=m.f_nnz_out[i];
1642  }
1643  }

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_activity(), call_fwd(), and call_rev().

◆ change_option()

void casadi::SXFunction::change_option ( const std::string &  option_name,
const GenericType &  option_value 
)
overridevirtual

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

Reimplemented from casadi::FunctionInternal.

Definition at line 2112 of file sx_function.cpp.

2113  {
2114  if (option_name == "print_instructions") {
2115  print_instructions_ = option_value;
2116  } else if (option_name == "dump_trace") {
2117  bool value = option_value;
2118  casadi_assert(!value || !jit_, "dump_trace is not supported for JIT evaluation");
2119  dump_trace_ = value;
2120  } else {
2121  // Option not found - continue to base classes
2122  XFunction<SXFunction, SX, SXNode>::change_option(option_name, option_value);
2123  }
2124  }
bool jit_
Use just-in-time compiler.
void change_option(const std::string &option_name, const GenericType &option_value) override
Change option after object creation for debugging.

References casadi::FunctionInternal::change_option(), dump_trace_, casadi::FunctionInternal::jit_, and print_instructions_.

◆ 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 1773 of file function_internal.hpp.

1773  {
1774  casadi_assert(arg.size()==n_in_, "Incorrect number of inputs: Expected "
1775  + str(n_in_) + ", got " + str(arg.size()));
1776  for (casadi_int i=0; i<n_in_; ++i) {
1777  if (!check_mat(arg[i].sparsity(), sparsity_in(i), npar)) {
1778  // Dimensions
1779  std::string d_arg = str(arg[i].size1()) + "-by-" + str(arg[i].size2());
1780  std::string d_in = str(size1_in(i)) + "-by-" + str(size2_in(i));
1781  std::string e = "Input " + str(i) + " (" + name_in_[i] + ") has mismatching shape. "
1782  "Got " + d_arg + ". Allowed dimensions, in general, are:\n"
1783  " - The input dimension N-by-M (here " + d_in + ")\n"
1784  " - A scalar, i.e. 1-by-1\n"
1785  " - M-by-N if N=1 or M=1 (i.e. a transposed vector)\n"
1786  " - N-by-M1 if K*M1=M for some K (argument repeated horizontally)\n";
1787  if (npar!=-1) {
1788  e += " - N-by-P*M, indicating evaluation with multiple arguments (P must be a "
1789  "multiple of " + str(npar) + " for consistency with previous inputs)";
1790  }
1791  casadi_error(e);
1792  }
1793  }
1794  }
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 3707 of file function_internal.cpp.

3707  {
3708  // Matching dimensions
3709  if (arg.size()==inp.size()) return true;
3710  // Calling with a scalar - set all
3711  if (arg.is_scalar()) return true;
3712  // Vectors that are transposes of each other
3713  if (arg.is_vector() && inp.size()==std::make_pair(arg.size2(), arg.size1())) return true;
3714  // Horizontal repmat
3715  if (arg.size1()==inp.size1() && arg.size2()>0 && inp.size2()>0
3716  && inp.size2()%arg.size2()==0) return true;
3717  // Evaluate with multiple arguments
3718  if (npar!=-1 && arg.size1()==inp.size1() && arg.size2()>0 && inp.size2()>0
3719  && arg.size2()%(npar*inp.size2())==0) {
3720  npar *= arg.size2()/(npar*inp.size2());
3721  return true;
3722  }
3723  // Calling with empty matrix - set all to zero (after the structured branches above,
3724  // so that a 0-by-N argument can still be recognised as a parallel/repmat call)
3725  if (arg.is_empty()) return true;
3726  // No match
3727  return false;
3728  }

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 181 of file function_internal.hpp.

181 { }

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 1797 of file function_internal.hpp.

1797  {
1798  casadi_assert(res.size()==n_out_, "Incorrect number of outputs: Expected "
1799  + str(n_out_) + ", got " + str(res.size()));
1800  for (casadi_int i=0; i<n_out_; ++i) {
1801  casadi_assert(check_mat(res[i].sparsity(), sparsity_out(i), npar),
1802  "Output " + str(i) + " (" + name_out_[i] + ") has mismatching shape. "
1803  "Expected " + str(size_out(i)) + ", got " + str(res[i].size()));
1804  }
1805  }
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 3916 of file function_internal.cpp.

3916  {
3917 #ifdef CASADI_WITH_THREAD
3918  std::lock_guard<std::mutex> lock(mtx_);
3919 #endif //CASADI_WITH_THREAD
3920  if (unused_.empty()) {
3921  check_mem_count(mem_.size()+1);
3922  // Allocate a new memory object
3923  void* m = alloc_mem();
3924  mem_.push_back(m);
3925  if (init_mem(m)) {
3926  casadi_error("Failed to create or initialize memory object");
3927  }
3928  return static_cast<int>(mem_.size()) - 1;
3929  } else {
3930  // Use an unused memory object
3931  int m = unused_.top();
3932  unused_.pop();
3933  return m;
3934  }
3935  }
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::FunctionInternal::codegen_meta(), casadi::ProtoFunction::finalize(), 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 136 of file sx_function.hpp.

136 {return "SXFunction";}

◆ clear_mem()

void casadi::ProtoFunction::clear_mem ( )
inherited

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

Definition at line 3804 of file function_internal.cpp.

3804  {
3805  for (auto&& i : mem_) {
3806  if (i!=nullptr) free_mem(i);
3807  }
3808  mem_.clear();
3809  }
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::ConoptInterface::~ConoptInterface(), 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::MadmpecInterface::~MadmpecInterface(), casadi::MadnlpInterface::~MadnlpInterface(), casadi::Map::~Map(), casadi::MapSum::~MapSum(), casadi::MosekInterface::~MosekInterface(), casadi::MumpsInterface::~MumpsInterface(), casadi::MXFunction::~MXFunction(), casadi::Newton::~Newton(), casadi::Nlpsol::~Nlpsol(), casadi::OmpMap::~OmpMap(), casadi::OnnxFunction::~OnnxFunction(), casadi::OnnxRuntimeInterface::~OnnxRuntimeInterface(), casadi::OoqpInterface::~OoqpInterface(), casadi::OsqpInterface::~OsqpInterface(), casadi::PiqpInterface::~PiqpInterface(), 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(), casadi::UnoInterface::~UnoInterface(), casadi::WorhpInterface::~WorhpInterface(), and casadi::XpressInterface::~XpressInterface().

◆ 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 2510 of file function_internal.cpp.

2510  {
2511  // Define function
2512  g << "/* " << definition() << " */\n";
2513  g << "static " << signature(fname) << " {\n";
2514 
2515  // Reset local variables, flush buffer
2516  g.flush(g.body);
2517 
2518  g.scope_enter();
2519 
2520  if (dump_in_ || dump_out_) {
2521  Function F = shared_from_this<Function>();
2522  std::string cg_name = codegen_name(g, false);
2523  std::string dump_counter = g.shorthand(cg_name + "_dump_counter");
2524  g.auxiliaries << "static int " << dump_counter << " = 0;\n";
2525  if (g.thread_safe()) {
2526  g.define_local_mutex(F, cg_name + "_dump_mutex");
2527  std::string dump_mutex = g.local_mutex(F, cg_name + "_dump_mutex");
2528  g << "CASADI_MUTEX_LOCK(&" << dump_mutex << ");\n";
2529  g << "int dump_id_local = " << dump_counter << "++;\n";
2530  g << "CASADI_MUTEX_UNLOCK(&" << dump_mutex << ");\n";
2531  } else {
2532  g << "int dump_id_local = " << dump_counter << "++;\n";
2533  }
2534  }
2535 
2536  if (dump_in_) g.generate_dump(shared_from_this<Function>(), "arg", true);
2537  if (print_in_) g.generate_print(shared_from_this<Function>(), "arg", true);
2538 
2539  // Generate function body (to buffer)
2540  codegen_body(g);
2541 
2542  if (dump_out_) g.generate_dump(shared_from_this<Function>(), "res", false);
2543  if (print_out_) g.generate_print(shared_from_this<Function>(), "res", false);
2544 
2545  g.scope_exit();
2546 
2547  // Finalize the function
2548  g << "return 0;\n";
2549  g << "}\n\n";
2550 
2551  // Flush to function body
2552  g.flush(g.body);
2553  }
std::string definition() const
Get function signature: name:(inputs)->(outputs)
virtual std::string codegen_name(const CodeGenerator &g, bool ns=true) const
Get name in codegen.
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::auxiliaries, casadi::CodeGenerator::body, casadi::FunctionInternal::codegen_body(), casadi::FunctionInternal::codegen_name(), casadi::CodeGenerator::define_local_mutex(), casadi::FunctionInternal::definition(), casadi::FunctionInternal::dump_in_, casadi::FunctionInternal::dump_out_, casadi::CodeGenerator::flush(), casadi::CodeGenerator::generate_dump(), casadi::CodeGenerator::generate_print(), casadi::CodeGenerator::local_mutex(), casadi::FunctionInternal::print_in_, casadi::FunctionInternal::print_out_, casadi::CodeGenerator::scope_enter(), casadi::CodeGenerator::scope_exit(), casadi::CodeGenerator::shorthand(), casadi::FunctionInternal::signature(), and casadi::CodeGenerator::thread_safe().

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 2654 of file function_internal.cpp.

2654  {
2655  bool needs_mem = codegen_needs_mem();
2656  if (needs_mem) {
2657  std::string name = codegen_name(g, false);
2658  std::string mem_counter = g.shorthand(name + "_mem_counter");
2659  g << "return " + mem_counter + "++;\n";
2660  }
2661  }
virtual bool codegen_needs_mem() const
Is thread-local memory object needed?

References casadi::FunctionInternal::codegen_name(), casadi::FunctionInternal::codegen_needs_mem(), 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 377 of file sx_function.cpp.

377  {
378  g.reserve_work(worksize_);
379 
380  casadi_int cnt = 0;
381  // Run the algorithm
382  for (auto&& a : algorithm_) {
383  if (a.op==OP_OUTPUT) {
384  g << "if (res[" << a.i0 << "]!=0) "
385  << g.res(a.i0) << "[" << a.i2 << "]=" << g.sx_work(a.i1) << ";\n";
386  } else if (a.op==OP_CALL) {
387  const ExtendedAlgEl& m = call_.el[a.i1];
388 
389  casadi_int worksize = g.avoid_stack() ? worksize_ : 0;
390 
391  // Collect input arguments
392  casadi_int offset = worksize;
393  for (casadi_int i=0; i<m.f_n_in; ++i) {
394  if (m.copy_elision_arg[i]>=0) {
395  g << "arg[" << n_in_+i << "] = "
396  << "arg[" + str(m.copy_elision_arg[i]) << "]? "
397  << "arg[" + str(m.copy_elision_arg[i]) << "] + "
398  << str(m.copy_elision_offset[i]) << " : 0;\n";
399  } else {
400  if (m.f_nnz_in[i]==0) {
401  g << "arg[" << n_in_+i << "]=" << 0 << ";\n";
402  } else {
403  g << "arg[" << n_in_+i << "]=" << "w+" + str(offset) << ";\n";
404  }
405  }
406  offset += m.f_nnz_in[i];
407  }
408 
409 
410  casadi_int out_offset = offset;
411 
412  // Collect output arguments
413  for (casadi_int i=0; i<m.f_n_out; ++i) {
414  g << "res[" << n_out_+i << "]=" << "w+" + str(offset) << ";\n";
415  offset += m.f_nnz_out[i];
416  }
417  casadi_int k=0;
418  for (casadi_int i=0; i<m.f_n_in; ++i) {
419  if (m.copy_elision_arg[i]==-1) {
420  for (casadi_int j=0; j<m.f_nnz_in[i]; ++j) {
421  g << "w["+str(k+worksize) + "] = " << g.sx_work(m.dep[k]) << ";\n";
422  k++;
423  }
424  } else {
425  k+=m.f_nnz_in[i];
426  }
427  }
428  if (print_instructions_) print_arg(g, cnt, a);
429  std::string flag =
430  g(m.f, "arg+"+str(n_in_), "res+"+str(n_out_), "iw", "w+" + str(offset));
431  // Call function
432  g << "if (" << flag << ") return 1;\n";
433  if (print_instructions_) print_res(g, cnt, a);
434  for (casadi_int i=0;i<m.n_res;++i) {
435  if (m.res[i]>=0) {
436  g << g.sx_work(m.res[i]) << " = ";
437  g << "w[" + str(i+out_offset) + "];\n";
438  }
439  }
440  } else if (a.op==OP_INPUT) {
441  if (!copy_elision_[cnt]) {
442  g << g.sx_work(a.i0) << "="
443  << g.arg(a.i1) << "? " << g.arg(a.i1) << "[" << a.i2 << "] : 0;\n";
444  }
445  } else {
446  if (print_instructions_) print_arg(g, cnt, a);
447 
448  // Where to store the result
449  g << g.sx_work(a.i0) << "=";
450 
451  // What to store
452  if (a.op==OP_CONST) {
453  g << g.constant(a.d);
454  } else {
455  casadi_int ndep = casadi_math<double>::ndeps(a.op);
456  casadi_assert_dev(ndep>0);
457  if (ndep==1) g << g.print_op(a.op, g.sx_work(a.i1));
458  if (ndep==2) g << g.print_op(a.op, g.sx_work(a.i1), g.sx_work(a.i2));
459  }
460 
461  g << ";\n";
462 
463  if (print_instructions_) print_res(g, cnt, a);
464  }
465  cnt++;
466  }
467  }
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:1633

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 2663 of file function_internal.cpp.

2663  {
2664  std::string name = codegen_name(g, false);
2665  std::string stack_counter = g.shorthand(name + "_unused_stack_counter");
2666  std::string stack = g.shorthand(name + "_unused_stack");
2667  std::string mem_counter = g.shorthand(name + "_mem_counter");
2668  std::string mem_array = g.shorthand(name + "_mem");
2669  std::string alloc_mem = g.shorthand(name + "_alloc_mem");
2670  std::string init_mem = g.shorthand(name + "_init_mem");
2671 
2672 
2673  g.auxiliaries << "static int " << mem_counter << " = 0;\n";
2674  g.auxiliaries << "static int " << stack_counter << " = -1;\n";
2675  g.auxiliaries << "static int " << stack << "[CASADI_MAX_NUM_THREADS];\n";
2676  g.auxiliaries << "static " << codegen_mem_type() <<
2677  " " << mem_array << "[CASADI_MAX_NUM_THREADS];\n\n";
2678 
2679  if (g.thread_safe()) {
2680  Function F = shared_from_this<Function>();
2681  g.define_local_mutex(F, name + "_mem_mutex");
2682  std::string mem_mutex = g.local_mutex(F, name + "_mem_mutex");
2683  g << "CASADI_MUTEX_LOCK(&" << mem_mutex << ");\n";
2684  g.scope_add_cleanup("CASADI_MUTEX_UNLOCK(&" + mem_mutex + ");\n");
2685  }
2686 
2687  g.local("mid", "int");
2688 
2689  g << "if (" << stack_counter << ">=0) {\n";
2690  g.scope_return(stack + "[" + stack_counter + "--]");
2691  g << "} else {\n";
2692  g << "if (" << mem_counter << "==CASADI_MAX_NUM_THREADS) {\n";
2693  g.scope_return("-1");
2694  g << "}\n";
2695  g << "mid = " << alloc_mem << "();\n";
2696  g << "if (mid<0) {\n";
2697  g.scope_return("-1");
2698  g << "}\n";
2699  g << "if (" << init_mem << "(mid)) {\n";
2700  g.scope_return("-1");
2701  g << "}\n";
2702  g.scope_return("mid");
2703  g << "}\n";
2704  }
virtual std::string codegen_mem_type() const
Thread-local memory object type.
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::CodeGenerator::define_local_mutex(), casadi::ProtoFunction::init_mem(), casadi::CodeGenerator::local(), casadi::CodeGenerator::local_mutex(), casadi::CodeGenerator::scope_add_cleanup(), casadi::CodeGenerator::scope_return(), casadi::CodeGenerator::shorthand(), and casadi::CodeGenerator::thread_safe().

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 252 of file sx_function.cpp.

252  {
253 
254  // Make sure that there are no free variables
255  if (!free_vars_.empty()) {
256  casadi_error("Code generation of '" + name_ + "' is not possible since variables "
257  + str(free_vars_) + " are free.");
258  }
259 
260  // Generate code for the call nodes
261  for (auto&& m : call_.el) {
262  g.add_dependency(m.f);
263  }
264  }

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

◆ codegen_decref()

void casadi::FunctionInternal::codegen_decref ( CodeGenerator &  g) const
virtualinherited

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

Reimplemented in casadi::MXFunction, and casadi::External.

Definition at line 2609 of file function_internal.cpp.

2609  {
2610 
2611  // Treat dependent functions
2612  std::set<void*> added;
2613  Function F = shared_from_this<Function>();
2614  for (const Function& f : F.find_functions(0)) {
2615  if (f->has_refcount_in_deps_) {
2616  std::string cg_name = f->codegen_name(g, false);
2617  auto i = added.insert(f.get());
2618  if (i.second) { // prevent duplicate calls
2619  std::string decref = g.shorthand(cg_name + "_decref");
2620  g << decref << "();\n";
2621  }
2622  }
2623  }
2624 
2625  if (has_refcount_) {
2626  std::string name = codegen_name(g, false);
2627  std::string ref_counter = g.shorthand(name + "_ref_counter");
2628  std::string mem_counter = g.shorthand(name + "_mem_counter");
2629  std::string free_mem = g.shorthand(name + "_free_mem");
2630  g << ref_counter << "--;\n";
2631  g << "if (" << ref_counter << "==0) {\n";
2632  if (codegen_needs_mem()) {
2633  g << "while (" << mem_counter << ">0) {\n";
2634  g << free_mem << "(--" << mem_counter << ");\n";
2635  g << "}\n";
2636  }
2637  if (g.thread_safe()) {
2638  Function F = shared_from_this<Function>();
2639  for (const auto& m : g.local_mutexes(F)) {
2640  std::string mtx = g.local_mutex(F, m);
2641  g << "#if CASADI_MUTEX_USE_STATIC_INIT == 0\n";
2642  g << "CASADI_MUTEX_DESTROY(&" << mtx << ");\n";
2643  g << "#endif\n";
2644  }
2645  }
2646  g << "}\n";
2647  }
2648  }
bool has_refcount_
Reference counting in codegen?
void free_mem(void *mem) const override
Free memory block.

References casadi::FunctionInternal::codegen_name(), casadi::FunctionInternal::codegen_needs_mem(), casadi::Function::find_functions(), casadi::FunctionInternal::free_mem(), casadi::FunctionInternal::has_refcount_, casadi::CodeGenerator::local_mutex(), casadi::CodeGenerator::local_mutexes(), casadi::CodeGenerator::shorthand(), and casadi::CodeGenerator::thread_safe().

Referenced by casadi::CodeGenerator::add_dependency(), and casadi::MXFunction::codegen_decref().

◆ codegen_free_mem()

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

◆ codegen_incref()

void casadi::FunctionInternal::codegen_incref ( CodeGenerator &  g) const
virtualinherited

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

Reimplemented in casadi::MXFunction, and casadi::External.

Definition at line 2576 of file function_internal.cpp.

2576  {
2577  if (has_refcount_) {
2578  std::string name = codegen_name(g, false);
2579  std::string ref_counter = g.shorthand(name + "_ref_counter");
2580  g.auxiliaries << "static int " << ref_counter << " = 0;\n";
2581 
2582  Function F = shared_from_this<Function>();
2583  if (g.thread_safe()) {
2584  for (const auto& m : g.local_mutexes(F)) {
2585  std::string mtx = g.local_mutex(F, m);
2586  g << "#if CASADI_MUTEX_USE_STATIC_INIT == 0\n";
2587  g << "if (" << ref_counter << "==0) CASADI_MUTEX_INIT(&" << mtx << ");\n";
2588  g << "#endif\n";
2589  }
2590  }
2591  g << ref_counter << "++;\n";
2592  }
2593 
2594  // Treat dependent functions
2595  std::set<void*> added;
2596  Function F = shared_from_this<Function>();
2597  for (const Function& f : F.find_functions(0)) {
2598  if (f->has_refcount_in_deps_) {
2599  std::string cg_name = f->codegen_name(g, false);
2600  auto i = added.insert(f.get());
2601  if (i.second) { // prevent duplicate calls
2602  std::string incref = g.shorthand(cg_name + "_incref");
2603  g << incref << "();\n";
2604  }
2605  }
2606  }
2607  }

References casadi::CodeGenerator::auxiliaries, casadi::FunctionInternal::codegen_name(), casadi::Function::find_functions(), casadi::FunctionInternal::has_refcount_, casadi::CodeGenerator::local_mutex(), casadi::CodeGenerator::local_mutexes(), casadi::CodeGenerator::shorthand(), and casadi::CodeGenerator::thread_safe().

Referenced by casadi::CodeGenerator::add_dependency(), and casadi::MXFunction::codegen_incref().

◆ 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

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

Definition at line 3051 of file function_internal.cpp.

3051  {
3052  std::string name = codegen_name(g, false);
3053  std::string mem_array = g.shorthand(name + "_mem");
3054  return mem_array+"[" + index + "]";
3055  }

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

Referenced by casadi::MadmpecInterface::codegen_body(), casadi::ClarabelInterface::codegen_body(), casadi::DaqpInterface::codegen_body(), casadi::FatropInterface::codegen_body(), casadi::HighsInterface::codegen_body(), casadi::IpoptInterface::codegen_body(), casadi::MadnlpInterface::codegen_body(), casadi::MosekInterface::codegen_body(), casadi::OsqpInterface::codegen_body(), casadi::UnoInterface::codegen_body(), casadi::XpressInterface::codegen_body(), casadi::Sqpmethod::codegen_body(), casadi::MadmpecInterface::codegen_free_mem(), casadi::ClarabelInterface::codegen_free_mem(), casadi::DaqpInterface::codegen_free_mem(), casadi::FatropInterface::codegen_free_mem(), casadi::HighsInterface::codegen_free_mem(), casadi::IpoptInterface::codegen_free_mem(), casadi::MadnlpInterface::codegen_free_mem(), casadi::MosekInterface::codegen_free_mem(), casadi::OsqpInterface::codegen_free_mem(), casadi::UnoInterface::codegen_free_mem(), casadi::XpressInterface::codegen_free_mem(), casadi::MadmpecInterface::codegen_init_mem(), casadi::ClarabelInterface::codegen_init_mem(), casadi::DaqpInterface::codegen_init_mem(), casadi::FatropInterface::codegen_init_mem(), casadi::HighsInterface::codegen_init_mem(), casadi::IpoptInterface::codegen_init_mem(), casadi::MadnlpInterface::codegen_init_mem(), casadi::MosekInterface::codegen_init_mem(), casadi::OsqpInterface::codegen_init_mem(), casadi::UnoInterface::codegen_init_mem(), casadi::XpressInterface::codegen_init_mem(), and casadi::MadmpecInterface::codegen_options().

◆ codegen_mem_is_opaque()

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

without a need for alloc_mem, init_mem, free_mem?

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

Reimplemented in casadi::External.

Definition at line 935 of file function_internal.hpp.

935 { return false; }

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

◆ 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 2726 of file function_internal.cpp.

2726  {
2727  bool needs_mem = codegen_needs_mem();
2728  std::string name = codegen_name(g, false);
2729 
2730  // Checkout/release routines
2731  g << g.declare("int " + name_ + "_checkout(void)") << " {\n";
2732  if (needs_mem) {
2733  std::string checkout = g.shorthand(name + "_checkout");
2734  g << "return " << checkout << "();\n";
2735  } else {
2736  g << "return 0;\n";
2737  }
2738  g << "}\n\n";
2739 
2740  if (needs_mem) {
2741  g << g.declare("void " + name_ + "_release(int mem)") << " {\n";
2742  std::string release = g.shorthand(name + "_release");
2743  g << release << "(mem);\n";
2744  } else {
2745  g << g.declare("void " + name_ + "_release(int mem)") << " {\n";
2746  }
2747  g << "}\n\n";
2748 
2749  // Reference counter routines
2750  g << g.declare("void " + name_ + "_incref(void)") << " {\n";
2751  if (has_refcount_in_deps_) {
2752  std::string incref = g.shorthand(name + "_incref");
2753  g << incref << "();\n";
2754  }
2755  g << "}\n\n"
2756  << g.declare("void " + name_ + "_decref(void)") << " {\n";
2757  if (has_refcount_in_deps_) {
2758  std::string decref = g.shorthand(name + "_decref");
2759  g << decref << "();\n";
2760  }
2761  g << "}\n\n";
2762 
2763  // Number of inputs and outptus
2764  g << g.declare("casadi_int " + name_ + "_n_in(void)")
2765  << " { return " << n_in_ << ";}\n\n"
2766  << g.declare("casadi_int " + name_ + "_n_out(void)")
2767  << " { return " << n_out_ << ";}\n\n";
2768 
2769  // Default inputs
2770  g << g.declare("casadi_real " + name_ + "_default_in(casadi_int i)") << " {\n"
2771  << "switch (i) {\n";
2772  for (casadi_int i=0; i<n_in_; ++i) {
2773  double def = get_default_in(i);
2774  if (def!=0) g << "case " << i << ": return " << g.constant(def) << ";\n";
2775  }
2776  g << "default: return 0;\n}\n"
2777  << "}\n\n";
2778 
2779  // Input names
2780  g << g.declare("const char* " + name_ + "_name_in(casadi_int i)") << " {\n"
2781  << "switch (i) {\n";
2782  for (casadi_int i=0; i<n_in_; ++i) {
2783  g << "case " << i << ": return \"" << name_in_[i] << "\";\n";
2784  }
2785  g << "default: return 0;\n}\n"
2786  << "}\n\n";
2787 
2788  // Output names
2789  g << g.declare("const char* " + name_ + "_name_out(casadi_int i)") << " {\n"
2790  << "switch (i) {\n";
2791  for (casadi_int i=0; i<n_out_; ++i) {
2792  g << "case " << i << ": return \"" << name_out_[i] << "\";\n";
2793  }
2794  g << "default: return 0;\n}\n"
2795  << "}\n\n";
2796 
2797  // Codegen sparsities
2798  codegen_sparsities(g);
2799 
2800  // Function that returns work vector lengths
2801  g << g.declare(
2802  "int " + name_ + "_work(casadi_int *sz_arg, casadi_int* sz_res, "
2803  "casadi_int *sz_iw, casadi_int *sz_w)")
2804  << " {\n"
2805  << "if (sz_arg) *sz_arg = " << codegen_sz_arg(g) << ";\n"
2806  << "if (sz_res) *sz_res = " << codegen_sz_res(g) << ";\n"
2807  << "if (sz_iw) *sz_iw = " << codegen_sz_iw(g) << ";\n"
2808  << "if (sz_w) *sz_w = " << codegen_sz_w(g) << ";\n"
2809  << "return 0;\n"
2810  << "}\n\n";
2811 
2812  // Function that returns work vector lengths in bytes
2813  g << g.declare(
2814  "int " + name_ + "_work_bytes(casadi_int *sz_arg, casadi_int* sz_res, "
2815  "casadi_int *sz_iw, casadi_int *sz_w)")
2816  << " {\n"
2817  << "if (sz_arg) *sz_arg = " << codegen_sz_arg(g) << "*sizeof(const casadi_real*);\n"
2818  << "if (sz_res) *sz_res = " << codegen_sz_res(g) << "*sizeof(casadi_real*);\n"
2819  << "if (sz_iw) *sz_iw = " << codegen_sz_iw(g) << "*sizeof(casadi_int);\n"
2820  << "if (sz_w) *sz_w = " << codegen_sz_w(g) << "*sizeof(casadi_real);\n"
2821  << "return 0;\n"
2822  << "}\n\n";
2823 
2824  // Also add to header file to allow getting
2825  if (g.with_header) {
2826  g.header
2827  << "#define " << name_ << "_SZ_ARG " << codegen_sz_arg(g) << "\n"
2828  << "#define " << name_ << "_SZ_RES " << codegen_sz_res(g) << "\n"
2829  << "#define " << name_ << "_SZ_IW " << codegen_sz_iw(g) << "\n"
2830  << "#define " << name_ << "_SZ_W " << codegen_sz_w(g) << "\n";
2831  }
2832 
2833  // Which inputs are differentiable
2834  if (!all(is_diff_in_)) {
2835  g << g.declare("int " + name_ + "_diff_in(casadi_int i)") << " {\n"
2836  << "switch (i) {\n";
2837  for (casadi_int i=0; i<n_in_; ++i) {
2838  g << "case " << i << ": return " << is_diff_in_[i] << ";\n";
2839  }
2840  g << "default: return -1;\n}\n"
2841  << "}\n\n";
2842  }
2843 
2844  // Which outputs are differentiable
2845  if (!all(is_diff_out_)) {
2846  g << g.declare("int " + name_ + "_diff_out(casadi_int i)") << " {\n"
2847  << "switch (i) {\n";
2848  for (casadi_int i=0; i<n_out_; ++i) {
2849  g << "case " << i << ": return " << is_diff_out_[i] << ";\n";
2850  }
2851  g << "default: return -1;\n}\n"
2852  << "}\n\n";
2853  }
2854 
2855  // Generate mex gateway for the function
2856  if (g.mex) {
2857  // Begin conditional compilation
2858  g << "#ifdef MATLAB_MEX_FILE\n";
2859 
2860  // Declare wrapper
2861  g << "void mex_" << name_
2862  << "(int resc, mxArray *resv[], int argc, const mxArray *argv[]) {\n"
2863  << "casadi_int i;\n";
2864  g << "int mem;\n";
2865  // Work vectors, including input and output buffers
2866  casadi_int i_nnz = nnz_in(), o_nnz = nnz_out();
2867  size_t sz_w = this->sz_w();
2868  for (casadi_int i=0; i<n_in_; ++i) {
2869  const Sparsity& s = sparsity_in_[i];
2870  sz_w = std::max(sz_w, static_cast<size_t>(s.size1())); // To be able to copy a column
2871  sz_w = std::max(sz_w, static_cast<size_t>(s.size2())); // To be able to copy a row
2872  }
2873  sz_w += i_nnz + o_nnz;
2874  g << CodeGenerator::array("casadi_real", "w", sz_w);
2875  g << CodeGenerator::array("casadi_int", "iw", sz_iw());
2876  std::string fw = "w+" + str(i_nnz + o_nnz);
2877 
2878  // Copy inputs to buffers
2879  casadi_int offset=0;
2880  g << CodeGenerator::array("const casadi_real*", "arg", sz_arg(), "{0}");
2881 
2882  // Allocate output buffers
2883  g << "casadi_real* res[" << sz_res() << "] = {0};\n";
2884 
2885  // Check arguments
2886  g << "if (argc>" << n_in_ << ") mexErrMsgIdAndTxt(\"Casadi:RuntimeError\","
2887  << "\"Evaluation of \\\"" << name_ << "\\\" failed. Too many input arguments "
2888  << "(%d, max " << n_in_ << ")\", argc);\n";
2889 
2890  g << "if (resc>" << n_out_ << ") mexErrMsgIdAndTxt(\"Casadi:RuntimeError\","
2891  << "\"Evaluation of \\\"" << name_ << "\\\" failed. "
2892  << "Too many output arguments (%d, max " << n_out_ << ")\", resc);\n";
2893 
2894  for (casadi_int i=0; i<n_in_; ++i) {
2895  std::string p = "argv[" + str(i) + "]";
2896  g << "if (--argc>=0) arg[" << i << "] = "
2897  << g.from_mex(p, "w", offset, sparsity_in_[i], fw) << "\n";
2898  offset += nnz_in(i);
2899  }
2900 
2901  for (casadi_int i=0; i<n_out_; ++i) {
2902  if (i==0) {
2903  // if i==0, always store output (possibly ans output)
2904  g << "--resc;\n";
2905  } else {
2906  // Store output, if it exists
2907  g << "if (--resc>=0) ";
2908  }
2909  // Create and get pointer
2910  g << g.res(i) << " = w+" << str(offset) << ";\n";
2911  offset += nnz_out(i);
2912  }
2913  g << name_ << "_incref();\n";
2914  g << "mem = " << name_ << "_checkout();\n";
2915 
2916  // Call the function
2917  g << "i = " << name_ << "(arg, res, iw, " << fw << ", mem);\n"
2918  << "if (i) mexErrMsgIdAndTxt(\"Casadi:RuntimeError\",\"Evaluation of \\\"" << name_
2919  << "\\\" failed.\");\n";
2920  g << name_ << "_release(mem);\n";
2921  g << name_ << "_decref();\n";
2922 
2923  // Save results
2924  for (casadi_int i=0; i<n_out_; ++i) {
2925  g << "if (" << g.res(i) << ") resv[" << i << "] = "
2926  << g.to_mex(sparsity_out_[i], g.res(i)) << "\n";
2927  }
2928 
2929  // End conditional compilation and function
2930  g << "}\n"
2931  << "#endif\n\n";
2932  }
2933 
2934  if (g.main) {
2935  // Declare wrapper
2936  g << "casadi_int main_" << name_ << "(casadi_int argc, char* argv[]) {\n";
2937 
2938  g << "casadi_int j;\n";
2939  g << "casadi_real* a;\n";
2940  g << "const casadi_real* r;\n";
2941  g << "casadi_int flag;\n";
2942  if (needs_mem) g << "int mem;\n";
2943 
2944 
2945 
2946  // Work vectors and input and output buffers
2947  size_t nr = sz_w() + nnz_in() + nnz_out();
2948  g << CodeGenerator::array("casadi_int", "iw", sz_iw())
2949  << CodeGenerator::array("casadi_real", "w", nr);
2950 
2951  // Input buffers
2952  g << "const casadi_real* arg[" << sz_arg() << "];\n";
2953 
2954  // Output buffers
2955  g << "casadi_real* res[" << sz_res() << "];\n";
2956 
2957  casadi_int off=0;
2958  for (casadi_int i=0; i<n_in_; ++i) {
2959  g << "arg[" << i << "] = w+" << off << ";\n";
2960  off += nnz_in(i);
2961  }
2962  for (casadi_int i=0; i<n_out_; ++i) {
2963  g << "res[" << i << "] = w+" << off << ";\n";
2964  off += nnz_out(i);
2965  }
2966 
2967  // TODO(@jaeandersson): Read inputs from file. For now; read from stdin
2968  g << "a = w;\n"
2969  << "for (j=0; j<" << nnz_in() << "; ++j) "
2970  << "if (scanf(\"%lg\", a++)<=0) return 2;\n";
2971 
2972  if (has_refcount_in_deps_) {
2973  g << name_ << "_incref();\n";
2974  }
2975 
2976  if (needs_mem) {
2977  g << "mem = " << name_ << "_checkout();\n";
2978  }
2979 
2980  // Call the function
2981  g << "flag = " << name_ << "(arg, res, iw, w+" << off << ", ";
2982  if (needs_mem) {
2983  g << "mem";
2984  } else {
2985  g << "0";
2986  }
2987  g << ");\n";
2988  if (needs_mem) {
2989  g << name_ << "_release(mem);\n";
2990  }
2991 
2992  if (has_refcount_in_deps_) {
2993  g << name_ << "_decref();\n";
2994  }
2995 
2996  g << "if (flag) return flag;\n";
2997 
2998  // TODO(@jaeandersson): Write outputs to file. For now: print to stdout
2999  g << "r = w+" << nnz_in() << ";\n"
3000  << "for (j=0; j<" << nnz_out() << "; ++j) "
3001  << g.printf("%.16e ", "*r++") << "\n";
3002 
3003  // End with newline
3004  g << g.printf("\\n") << "\n";
3005 
3006  // Finalize function
3007  g << "return 0;\n"
3008  << "}\n\n";
3009  }
3010 
3011  if (g.with_mem) {
3012  // Allocate memory
3013  g << g.declare("casadi_functions* " + name_ + "_functions(void)") << " {\n"
3014  << "static casadi_functions fun = {\n"
3015  << name_ << "_incref,\n"
3016  << name_ << "_decref,\n"
3017  << name_ << "_checkout,\n"
3018  << name_ << "_release,\n"
3019  << name_ << "_default_in,\n"
3020  << name_ << "_n_in,\n"
3021  << name_ << "_n_out,\n"
3022  << name_ << "_name_in,\n"
3023  << name_ << "_name_out,\n"
3024  << name_ << "_sparsity_in,\n"
3025  << name_ << "_sparsity_out,\n"
3026  << name_ << "_work,\n"
3027  << name_ << "\n"
3028  << "};\n"
3029  << "return &fun;\n"
3030  << "}\n";
3031  }
3032  // Flush
3033  g.flush(g.body);
3034  }
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 size_t codegen_sz_w(const CodeGenerator &g) const
Get required lengths, for codegen.
bool has_refcount_in_deps_
Reference counting in dependent functions.
std::vector< bool > is_diff_in_
Are inputs and outputs differentiable?
void codegen_sparsities(CodeGenerator &g) const
Codegen sparsities.
virtual double get_default_in(casadi_int ind) const
Get default input value.
int checkout() const
Checkout a memory object.
void release(int mem) const
Release a memory object.
bool all(const std::vector< bool > &v)
Check if all arguments are true.
Definition: casadi_misc.cpp:81

References casadi::all(), casadi::CodeGenerator::array(), casadi::CodeGenerator::body, casadi::ProtoFunction::checkout(), casadi::FunctionInternal::codegen_name(), casadi::FunctionInternal::codegen_needs_mem(), 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::FunctionInternal::has_refcount_in_deps_, 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::ProtoFunction::release(), casadi::CodeGenerator::res(), casadi::CodeGenerator::shorthand(), 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 3036 of file function_internal.cpp.

3036  {
3037  if (ns) {
3038  // Get the index of the function
3039  for (auto&& e : g.added_functions_) {
3040  if (e.f.get()==this) return e.codegen_name;
3041  }
3042  } else {
3043  for (casadi_int i=0;i<g.added_functions_.size();++i) {
3044  const auto & e = g.added_functions_[i];
3045  if (e.f.get()==this) return "f" + str(i);
3046  }
3047  }
3048  casadi_error("Function '" + name_ + "' not found");
3049  }

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

Referenced by casadi::FunctionInternal::codegen(), casadi::FunctionInternal::codegen_alloc_mem(), casadi::FatropInterface::codegen_body(), casadi::FunctionInternal::codegen_checkout(), casadi::FunctionInternal::codegen_decref(), casadi::FunctionInternal::codegen_incref(), casadi::FunctionInternal::codegen_mem(), casadi::FunctionInternal::codegen_meta(), casadi::FunctionInternal::codegen_release(), casadi::CodeGenerator::mem(), and casadi::CodeGenerator::operator()().

◆ codegen_needs_mem()

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

◆ 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 2706 of file function_internal.cpp.

2706  {
2707  std::string name = codegen_name(g, false);
2708  std::string stack_counter = g.shorthand(name + "_unused_stack_counter");
2709  std::string stack = g.shorthand(name + "_unused_stack");
2710 
2711  if (g.thread_safe()) {
2712  Function F = shared_from_this<Function>();
2713  std::string mem_mutex = g.local_mutex(F, name + "_mem_mutex");
2714  g << "CASADI_MUTEX_LOCK(&" << mem_mutex << ");\n";
2715  g.scope_add_cleanup("CASADI_MUTEX_UNLOCK(&" + mem_mutex + ");\n");
2716  }
2717 
2718  g << stack << "[++" << stack_counter << "] = mem;\n";
2719  g.scope_return();
2720  }

References casadi::FunctionInternal::codegen_name(), casadi::CodeGenerator::local_mutex(), casadi::CodeGenerator::scope_add_cleanup(), casadi::CodeGenerator::scope_return(), casadi::CodeGenerator::shorthand(), and casadi::CodeGenerator::thread_safe().

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 3158 of file function_internal.cpp.

3158  {
3159  return sz_arg();
3160  }

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 3164 of file function_internal.cpp.

3164  {
3165  return sz_iw();
3166  }

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 3161 of file function_internal.cpp.

3161  {
3162  return sz_res();
3163  }

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 141 of file function_internal.cpp.

141  {
142  // Sanitize dictionary is needed
143  if (!Options::is_sane(opts)) {
144  // Call recursively
146  return;
147  }
148 
149  // Make sure all options exist
150  get_options().check(opts);
151 
152  // Initialize the class hierarchy
153  try {
154  init(opts);
155  } catch(std::exception& e) {
156  casadi_error("Error calling " + class_name() + "::init for '" + name_ + "':\n"
157  + std::string(e.what()));
158  }
159 
160  // Revisit class hierarchy in reverse order
161  try {
162  finalize();
163  } catch(std::exception& e) {
164  casadi_error("Error calling " + class_name() + "::finalize for '" + name_ + "':\n"
165  + std::string(e.what()));
166  }
167  }
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 1899 of file function_internal.hpp.

1900  {
1901  // Get default inputs
1902  std::vector<M> arg_v(n_in_);
1903  for (casadi_int i=0; i<arg_v.size(); ++i) {
1904  arg_v[i] = get_default_in(i);
1905  }
1906 
1907  // Assign provided inputs
1908  for (auto&& e : arg) {
1909  arg_v.at(index_in(e.first)) = e.second;
1910  }
1911 
1912  return arg_v;
1913  }
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 1887 of file function_internal.hpp.

1888  {
1889  casadi_assert(arg.size()==n_in_, "Incorrect number of inputs: Expected "
1890  + str(n_in_) + ", got " + str(arg.size()));
1891  std::map<std::string, M> ret;
1892  for (casadi_int i=0;i<n_in_;++i) {
1893  ret[name_in_[i]] = arg[i];
1894  }
1895  return ret;
1896  }

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 1928 of file function_internal.hpp.

1929  {
1930  // Get default inputs
1931  std::vector<M> res_v(n_out_);
1932  for (casadi_int i=0; i<res_v.size(); ++i) {
1933  res_v[i] = std::numeric_limits<double>::quiet_NaN();
1934  }
1935 
1936  // Assign provided inputs
1937  for (auto&& e : res) {
1938  M a = e.second;
1939  res_v.at(index_out(e.first)) = a;
1940  }
1941  return res_v;
1942  }
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 1916 of file function_internal.hpp.

1917  {
1918  casadi_assert(res.size()==n_out_, "Incorrect number of outputs: Expected "
1919  + str(n_out_) + ", got " + str(res.size()));
1920  std::map<std::string, M> ret;
1921  for (casadi_int i=0;i<n_out_;++i) {
1922  ret[name_out_[i]] = res[i];
1923  }
1924  return ret;
1925  }

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.

180  {
181  // Note: i != this because of something something multiple inheritance
182  return str( (casadi_int)(i)) + "/" + static_cast<const Internal*>(this)->class_name();
183  }

◆ definition()

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

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

Definition at line 1134 of file function_internal.cpp.

1134  {
1135  std::stringstream s;
1136 
1137  // Print name
1138  s << name_ << ":(";
1139  // Print input arguments
1140  for (casadi_int i=0; i<n_in_; ++i) {
1141  if (!is_diff_in_.empty() && !is_diff_in_[i]) s << "#";
1142  s << name_in_[i] << sparsity_in_[i].postfix_dim() << (i==n_in_-1 ? "" : ",");
1143  }
1144  s << ")->(";
1145  // Print output arguments
1146  for (casadi_int i=0; i<n_out_; ++i) {
1147  if (!is_diff_out_.empty() && !is_diff_out_[i]) s << "#";
1148  s << name_out_[i] << sparsity_out_[i].postfix_dim() << (i==n_out_-1 ? "" : ",");
1149  }
1150  s << ")";
1151 
1152  return s.str();
1153  }

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 266 of file x_function.hpp.

316  {
317  s.unpack("XFunction::out", out_);
318  }
std::vector< Matrix< SXElem > > out_
Outputs of the function (needed for symbolic calculations)
Definition: x_function.hpp:279

◆ 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 265 of file x_function.hpp.

322  {
323  s.pack("XFunction::out", out_);
324  }

◆ deserialize()

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

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

Definition at line 2096 of file sx_function.cpp.

2096  {
2097  return new SXFunction(s);
2098  }
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 2242 of file function_internal.cpp.

2242  {
2243  // Highest index found in current inputs and outputs
2244  casadi_int highest_index = 0;
2245  // Loop over both input names and output names
2246  for (const std::vector<std::string>& name_io : {name_in_, name_out_}) {
2247  for (const std::string& n : name_io) {
2248  // Find end of prefix, skip if no prefix
2249  size_t end = n.find('_');
2250  if (end >= n.size()) continue;
2251  // Skip if too short
2252  if (end < prefix.size()) continue;
2253  // Skip if wrong prefix
2254  if (n.compare(0, prefix.size(), prefix) != 0) continue;
2255  // Beginning of index
2256  size_t begin = prefix.size();
2257  // Check if any index
2258  casadi_int this_index;
2259  if (begin == end) {
2260  // No prefix, implicitly 1
2261  this_index = 1;
2262  } else {
2263  // Read index from string
2264  this_index = std::stoi(n.substr(begin, end - begin));
2265  }
2266  // Find the highest index
2267  if (this_index > highest_index) highest_index = this_index;
2268  }
2269  }
2270  // Return one higher index
2271  if (highest_index == 0) {
2272  return prefix + "_";
2273  } else {
2274  return prefix + std::to_string(highest_index + 1) + "_";
2275  }
2276  }

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

Referenced by casadi::FunctionInternal::forward(), casadi::OnnxFunction::get_forward(), casadi::OnnxFunction::get_reverse(), casadi::OnnxFunction::has_derivative(), 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 1155 of file function_internal.cpp.

1155  {
1156  stream << definition() << " " << class_name();
1157  if (more) {
1158  stream << std::endl;
1159  disp_more(stream);
1160  }
1161  }
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 235 of file sx_function.cpp.

235  {
236  stream << "Algorithm:";
237 
238  // Normal, interpreted output
239  for (auto&& a : algorithm_) {
241  stream << std::endl;
242  stream << print(a);
243  stream << ";";
244  }
245  }
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 3576 of file function_internal.cpp.

3576  {
3577  std::vector<DM> ret(n_in_);
3578  for (casadi_int i=0; i<ret.size(); ++i) {
3579  ret[i] = dm_in(i);
3580  }
3581  return ret;
3582  }
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 3584 of file function_internal.cpp.

3584  {
3585  std::vector<DM> ret(n_out_);
3586  for (casadi_int i=0; i<ret.size(); ++i) {
3587  ret[i] = dm_out(i);
3588  }
3589  return ret;
3590  }
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 1945 of file function_internal.hpp.

1945  {
1946  // Check dimensions
1947  if (v.size1() == sp.size1() && v.size2() == n * sp.size2()) {
1948  // Ensure that sparsity is a horizontal multiple of original input, or has no entries
1949  if (v.nnz() != 0 && !v.sparsity().is_stacked(sp, n)) {
1950  return project(v, repmat(sp, 1, n));
1951  }
1952  } else {
1953  // Correct empty sparsity
1954  casadi_assert_dev(v.is_empty());
1955  return MatType(sp.size1(), sp.size2() * n);
1956  }
1957  // No correction needed
1958  return v;
1959  }

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  auto trace = dump_trace_ ? open_trace(arg, static_cast<FunctionMemory*>(mem)->dump_id)
75  : nullptr;
76  try {
77  if (verbose_) casadi_message(name_ + "::eval");
78  setup(mem, arg, res, iw, w);
79 
80  // Make sure no free parameters
81  if (!free_vars_.empty()) {
82  std::stringstream ss;
83  disp(ss, false);
84  casadi_error("Cannot evaluate \"" + ss.str() + "\" since variables "
85  + str(free_vars_) + " are free.");
86  }
87 
88  // NOTE: The implementation of this function is very delicate. Small changes in the
89  // class structure can cause large performance losses. For this reason,
90  // the preprocessor macros are used below
91 
92  if (print_instructions_ || trace) {
93  int k = 0;
94  // Evaluate the algorithm
95  for (auto&& e : algorithm_) {
96  if (trace) trace_instruction(*trace, k, w, false);
97  if (print_instructions_) print_arg(uout(), k, e, w);
98  switch (e.op) {
99  CASADI_MATH_FUN_BUILTIN(w[e.i1], w[e.i2], w[e.i0])
100 
101  case OP_CONST: w[e.i0] = e.d; break;
102  case OP_INPUT: w[e.i0] = arg[e.i1]==nullptr ? 0 : arg[e.i1][e.i2]; break;
103  case OP_OUTPUT: if (res[e.i0]!=nullptr) res[e.i0][e.i2] = w[e.i1]; break;
104  case OP_CALL:
105  call_fwd(e, arg, res, iw, w);
106  break;
107  default:
108  casadi_error("Unknown operation" + str(e.op));
109  }
110  if (print_instructions_) print_res(uout(), k, e, w);
111  if (trace) trace_instruction(*trace, k, w, true);
112  k++;
113  }
114  } else {
115  // Evaluate the algorithm
116  for (auto&& e : algorithm_) {
117  switch (e.op) {
118  CASADI_MATH_FUN_BUILTIN(w[e.i1], w[e.i2], w[e.i0])
119 
120  case OP_CONST: w[e.i0] = e.d; break;
121  case OP_INPUT: w[e.i0] = arg[e.i1]==nullptr ? 0 : arg[e.i1][e.i2]; break;
122  case OP_OUTPUT: if (res[e.i0]!=nullptr) res[e.i0][e.i2] = w[e.i1]; break;
123  case OP_CALL:
124  call_fwd(e, arg, res, iw, w);
125  break;
126  default:
127  casadi_error("Unknown operation" + str(e.op));
128  }
129  }
130  }
131  } catch (...) {
132  if (trace) *trace << "{\"event\":\"error\"}\n";
133  throw;
134  }
135  if (trace) finish_trace(*trace, res, 0);
136  return 0;
137  }
void finish_trace(std::ostream &trace, double **res, int ret) const
void disp(std::ostream &stream, bool more) const override
Display object.
std::unique_ptr< std::ostream > open_trace(const double **arg, casadi_int dump_id) const
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
void trace_instruction(std::ostream &trace, casadi_int k, const double *w, bool output) const
std::ostream & uout()

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

◆ eval_activity()

int casadi::SXFunction::eval_activity ( 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_2ie

Reimplemented from casadi::FunctionInternal.

Definition at line 1734 of file sx_function.cpp.

1735  {
1736  const bvec_t nz = ~static_cast<bvec_t>(0);
1737  // Propagate signal activity forward (bit set = active (possibly nonzero))
1738  for (auto&& e : algorithm_) {
1739  switch (e.op) {
1740  case OP_CONST:
1741  w[e.i0] = (e.d!=0) ? nz : 0; break;
1742  case OP_PARAMETER:
1743  w[e.i0] = nz; break; // free variable: assume nonzero
1744  case OP_INPUT:
1745  w[e.i0] = (arg[e.i1]!=nullptr) ? arg[e.i1][e.i2] : 0;
1746  break;
1747  case OP_OUTPUT:
1748  if (res[e.i0]!=nullptr) res[e.i0][e.i2] = w[e.i1];
1749  break;
1750  case OP_CALL:
1751  call_activity(e, arg, res, iw, w);
1752  break;
1753  default: // Unary or binary operation
1754  if (casadi_math<double>::ndeps(e.op)==1) {
1755  // Zero input yields zero only for zero-preserving ops (sin, sqrt; not cos/exp)
1756  w[e.i0] = w[e.i1] ? nz : (operation_checker<F0XChecker>(e.op) ? 0 : nz);
1757  } else {
1758  const bool z0 = w[e.i1]!=0, z1 = w[e.i2]!=0;
1759  if (!z0 && !z1) w[e.i0] = operation_checker<F00Checker>(e.op) ? 0 : nz;
1760  else if (!z0 && z1) w[e.i0] = operation_checker<F0XChecker>(e.op) ? 0 : nz;
1761  else if ( z0 && !z1) w[e.i0] = operation_checker<FX0Checker>(e.op) ? 0 : nz;
1762  else w[e.i0] = nz;
1763  }
1764  break;
1765  }
1766  }
1767  return 0;
1768  }
void call_activity(const AlgEl &e, const bvec_t **arg, bvec_t **res, casadi_int *iw, bvec_t *w) const

References algorithm_, call_activity(), casadi::OP_CALL, casadi::OP_CONST, casadi::OP_INPUT, casadi::OP_OUTPUT, and casadi::OP_PARAMETER.

◆ 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 2225 of file function_internal.cpp.

2225  {
2226  casadi_error("'eval_dm' not defined for " + class_name());
2227  }

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 448 of file function_internal.hpp.

449  {
450  return sp_forward(arg, res, iw, w, mem);
451  }
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 1022 of file function_internal.cpp.

1024  {
1025  casadi_int dump_id = (dump_in_ || dump_out_ || dump_) ? get_dump_id() : -1;
1026  if (dump_in_) dump_in(dump_id, arg);
1027  if (dump_ && dump_id==0) dump();
1028  if (print_in_) print_in(uout(), arg, false);
1029  auto *m = static_cast<FunctionMemory*>(mem);
1030 
1031  // Avoid memory corruption
1032  for (casadi_int i=0;i<n_in_;++i) {
1033  casadi_assert(arg[i]==nullptr || arg[i]+nnz_in(i)<=w || arg[i]>=w+sz_w(),
1034  "Memory corruption detected for input " + name_in_[i] + ".\n"+
1035  "arg[" + str(i) + "] " + str(arg[i]) + "-" + str(arg[i]+nnz_in(i)) +
1036  " intersects with w " + str(w)+"-"+str(w+sz_w())+".");
1037  }
1038  for (casadi_int i=0;i<n_out_;++i) {
1039  casadi_assert(res[i]==nullptr || res[i]+nnz_out(i)<=w || res[i]>=w+sz_w(),
1040  "Memory corruption detected for output " + name_out_[i]);
1041  }
1042  // Reset statistics
1043  for (auto&& s : m->fstats) s.second.reset();
1044  if (m->t_total) m->t_total->tic();
1045  m->dump_id = dump_id;
1046  int ret;
1047  if (eval_) {
1048  auto *m = static_cast<FunctionMemory*>(mem);
1049  m->stats_available = true;
1050  int mem_ = 0;
1051  if (checkout_) {
1052 #ifdef CASADI_WITH_THREAD
1053  std::lock_guard<std::mutex> lock(mtx_);
1054 #endif //CASADI_WITH_THREAD
1055  mem_ = checkout_();
1056  }
1057  ret = eval_(arg, res, iw, w, mem_);
1058  if (release_) {
1059 #ifdef CASADI_WITH_THREAD
1060  std::lock_guard<std::mutex> lock(mtx_);
1061 #endif //CASADI_WITH_THREAD
1062  release_(mem_);
1063  }
1064  } else {
1065  ret = eval(arg, res, iw, w, mem);
1066  }
1067  if (m->t_total) m->t_total->toc();
1068  // Show statistics
1069  print_time(m->fstats);
1070 
1071  if (dump_out_) dump_out(dump_id, res);
1072  if (print_out_) print_out(uout(), res, false);
1073  // Check all outputs for NaNs
1074  if (regularity_check_) {
1075  for (casadi_int i = 0; i < n_out_; ++i) {
1076  // Skip of not calculated
1077  if (!res[i]) continue;
1078  // Loop over nonzeros
1079  casadi_int nnz = this->nnz_out(i);
1080  for (casadi_int nz = 0; nz < nnz; ++nz) {
1081  if (isnan(res[i][nz]) || isinf(res[i][nz])) {
1082  // Throw readable error message
1083  casadi_error(str(res[i][nz]) + " detected for output " + name_out_[i] + " at "
1084  + sparsity_out(i).repr_el(nz));
1085  }
1086  }
1087  }
1088  }
1089  return ret;
1090  }
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 444 of file function_internal.hpp.

445  {
446  return eval_sx(arg, res, iw, w, mem, always_inline, never_inline);
447  }
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 1111 of file sx_function.cpp.

1112  {
1113  always_inline = always_inline || always_inline_;
1114  never_inline = never_inline || never_inline_;
1115 
1116  // non-inlining call is implemented in the base-class
1117  if (!always_inline) {
1118  FunctionInternal::eval_mx(arg, res, false, true);
1119  return;
1120  }
1121 
1122  if (verbose_) casadi_message(name_ + "::eval_mx");
1123 
1124  // Iterator to stack of constants
1125  std::vector<SXElem>::const_iterator c_it = constants_.begin();
1126 
1127  casadi_assert(!has_free(),
1128  "Free variables not supported in inlining call to SXFunction::eval_mx");
1129 
1130  // Resize the number of outputs
1131  casadi_assert(arg.size()==n_in_, "Wrong number of input arguments");
1132  res.resize(out_.size());
1133 
1134  // Symbolic work, non-differentiated
1135  std::vector<MX> w(sz_w());
1136  if (verbose_) casadi_message("Allocated work vector");
1137 
1138  // Split up inputs analogous to symbolic primitives
1139  std::vector<std::vector<MX> > arg_split(in_.size());
1140  for (casadi_int i=0; i<in_.size(); ++i) {
1141  // Get nonzeros of argument
1142  std::vector<MX> orig = arg[i].get_nonzeros();
1143 
1144  // Project to needed sparsity
1145  std::vector<MX> target(sparsity_in_[i].nnz(), 0);
1146  std::vector<MX> w(arg[i].size1());
1147  casadi_project(get_ptr(orig), arg[i].sparsity(),
1148  get_ptr(target), sparsity_in_[i], get_ptr(w));
1149 
1150  // Store
1151  arg_split[i] = target;
1152  }
1153 
1154  // Allocate storage for split outputs
1155  std::vector<std::vector<MX> > res_split(out_.size());
1156  for (casadi_int i=0; i<out_.size(); ++i) res_split[i].resize(nnz_out(i));
1157 
1158  // Evaluate algorithm
1159  if (verbose_) casadi_message("Evaluating algorithm forward");
1160  for (auto&& a : algorithm_) {
1161  switch (a.op) {
1162  case OP_INPUT:
1163  w[a.i0] = arg_split[a.i1][a.i2];
1164  break;
1165  case OP_OUTPUT:
1166  res_split[a.i0][a.i2] = w[a.i1];
1167  break;
1168  case OP_CONST:
1169  w[a.i0] = static_cast<double>(*c_it++);
1170  break;
1171  case OP_CALL:
1172  {
1173  const ExtendedAlgEl& m = call_.el.at(a.i1);
1174  std::vector<MX> deps(m.n_dep);
1175  std::vector<MX> args;
1176 
1177  casadi_int k = 0;
1178  // Construct matrix-valued function arguments
1179  for (casadi_int i=0;i<m.f_n_in;++i) {
1180  std::vector<MX> arg;
1181  for (casadi_int j=0;j<m.f_nnz_in[i];++j) {
1182  arg.push_back(w[m.dep[k++]]);
1183  }
1184  args.push_back(sparsity_cast(vertcat(arg), m.f.sparsity_in(i)));
1185  }
1186 
1187 
1188  std::vector<MX> ret = m.f(args);
1189  std::vector<MX> res;
1190 
1191  // Break apart matriv-valued outputs into scalar components
1192  for (casadi_int i=0;i<m.f_n_out;++i) {
1193  std::vector<MX> nz = ret[i].get_nonzeros();
1194  res.insert(res.end(), nz.begin(), nz.end());
1195  }
1196 
1197  // Store into work vector
1198  for (casadi_int i=0;i<m.n_res;++i) {
1199  if (m.res[i]>=0) w[m.res[i]] = res[i];
1200  }
1201  }
1202  break;
1203  default:
1204  // Evaluate the function to a temporary value
1205  // (as it might overwrite the children in the work vector)
1206  MX f;
1207  switch (a.op) {
1208  CASADI_MATH_FUN_BUILTIN(w[a.i1], w[a.i2], f)
1209  }
1210 
1211  // Finally save the function value
1212  w[a.i0] = f;
1213  }
1214  }
1215 
1216  // Join split outputs
1217  for (casadi_int i=0; i<res.size(); ++i) {
1218  res[i] = sparsity_cast(vertcat(res_split[i]), sparsity_out_[i]);
1219  }
1220  }
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:274
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 1029 of file sx_function.cpp.

1031  {
1032 
1033  always_inline = always_inline || always_inline_;
1034  never_inline = never_inline || never_inline_;
1035 
1036  // non-inlining call is implemented in the base-class
1037  if (!should_inline(true, always_inline, never_inline)) {
1038  return FunctionInternal::eval_sx(arg, res, iw, w, mem, false, true);
1039  }
1040 
1041  if (verbose_) casadi_message(name_ + "::eval_sx");
1042 
1043  // Iterator to the binary operations
1044  std::vector<SXElem>::const_iterator b_it=operations_.begin();
1045 
1046  // Iterator to stack of constants
1047  std::vector<SXElem>::const_iterator c_it = constants_.begin();
1048 
1049  // Iterator to free variables
1050  std::vector<SXElem>::const_iterator p_it = free_vars_.begin();
1051 
1052  // Evaluate algorithm
1053  if (verbose_) casadi_message("Evaluating algorithm forward");
1054  for (auto&& a : algorithm_) {
1055  switch (a.op) {
1056  case OP_INPUT:
1057  w[a.i0] = arg[a.i1]==nullptr ? 0 : arg[a.i1][a.i2];
1058  break;
1059  case OP_OUTPUT:
1060  if (res[a.i0]!=nullptr) res[a.i0][a.i2] = w[a.i1];
1061  break;
1062  case OP_CONST:
1063  w[a.i0] = *c_it++;
1064  break;
1065  case OP_PARAMETER:
1066  w[a.i0] = *p_it++; break;
1067  case OP_CALL:
1068  {
1069  const ExtendedAlgEl& m = call_.el.at(a.i1);
1070  const SXElem& orig = *b_it++;
1071  std::vector<SXElem> deps(m.n_dep);
1072  bool identical = true;
1073 
1074  std::vector<SXElem> ret;
1075  for (casadi_int i=0;i<m.n_dep;++i) {
1076  identical &= SXElem::is_equal(w[m.dep.at(i)], orig->dep(i), 2);
1077  }
1078  if (identical) {
1079  ret = OutputSX::split(orig, m.n_res);
1080  } else {
1081  for (casadi_int i=0;i<m.n_dep;++i) deps[i] = w[m.dep[i]];
1082  ret = SXElem::call(m.f, deps);
1083  }
1084  for (casadi_int i=0;i<m.n_res;++i) {
1085  if (m.res[i]>=0) w[m.res[i]] = ret[i];
1086  }
1087  }
1088  break;
1089  default:
1090  {
1091  // Evaluate the function to a temporary value
1092  // (as it might overwrite the children in the work vector)
1093  SXElem f;
1094  switch (a.op) {
1095  CASADI_MATH_FUN_BUILTIN(w[a.i1], w[a.i2], f)
1096  }
1097 
1098  // If this new expression is identical to the expression used
1099  // to define the algorithm, then reuse
1100  const casadi_int depth = 2; // NOTE: a higher depth could possibly give more savings
1101  f.assignIfDuplicate(*b_it++, depth);
1102 
1103  // Finally save the function value
1104  w[a.i0] = f;
1105  }
1106  }
1107  }
1108  return 0;
1109  }
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:355
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 193 of file x_function.hpp.

1107  {
1108 
1109  casadi_assert(!has_free(), "export_code needs a Function without free variables");
1110 
1111  casadi_assert(lang=="matlab", "Only matlab language supported for now.");
1112 
1113  // start function
1114  stream << "function [varargout] = " << name_ << "(varargin)" << std::endl;
1115 
1116  // Allocate space for output argument (segments)
1117  for (casadi_int i=0;i<n_out_;++i) {
1118  stream << " argout_" << i << " = cell(" << nnz_out(i) << ",1);" << std::endl;
1119  }
1120 
1121  Dict opts;
1122  opts["indent_level"] = 1;
1123  export_code_body(lang, stream, opts);
1124 
1125  // Process the outputs
1126  for (casadi_int i=0;i<n_out_;++i) {
1127  const Sparsity& out = sparsity_out_.at(i);
1128  if (out.is_dense()) {
1129  // Special case if dense
1130  stream << " varargout{" << i+1 << "} = reshape(vertcat(argout_" << i << "{:}), ";
1131  stream << out.size1() << ", " << out.size2() << ");" << std::endl;
1132  } else {
1133  // For sparse outputs, export sparsity and call 'sparse'
1134  Dict opts;
1135  opts["name"] = "sp";
1136  opts["indent_level"] = 1;
1137  opts["as_matrix"] = false;
1138  out.export_code("matlab", stream, opts);
1139  stream << " varargout{" << i+1 << "} = ";
1140  stream << "sparse(sp_i, sp_j, vertcat(argout_" << i << "{:}), sp_m, sp_n);" << std::endl;
1141  }
1142  }
1143 
1144  // end function
1145  stream << "end" << std::endl;
1146  stream << "function y=nonzeros_gen(x)" << std::endl;
1147  stream << " if isa(x,'casadi.SX') || isa(x,'casadi.MX') || isa(x,'casadi.DM')" << std::endl;
1148  stream << " y = x{:};" << std::endl;
1149  stream << " elseif isa(x,'sdpvar')" << std::endl;
1150  stream << " b = getbase(x);" << std::endl;
1151  stream << " f = find(sum(b~=0,2));" << std::endl;
1152  stream << " y = sdpvar(length(f),1,[],getvariables(x),b(f,:));" << std::endl;
1153  stream << " else" << std::endl;
1154  stream << " y = nonzeros(x);" << std::endl;
1155  stream << " end" << std::endl;
1156  stream << "end" << std::endl;
1157  stream << "function y=if_else_zero_gen(c,e)" << std::endl;
1158  stream << " if isa(c+e,'casadi.SX') || isa(c+e,'casadi.MX') "
1159  "|| isa(c+e,'casadi.DM')" << std::endl;
1160  stream << " y = if_else(c, e, 0);" << std::endl;
1161  stream << " else" << std::endl;
1162  stream << " if c" << std::endl;
1163  stream << " y = x;" << std::endl;
1164  stream << " else" << std::endl;
1165  stream << " y = 0;" << std::endl;
1166  stream << " end" << std::endl;
1167  stream << " end" << std::endl;
1168  stream << "end" << std::endl;
1169 
1170 
1171  }
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 1876 of file sx_function.cpp.

1877  {
1878 
1879  // Default values for options
1880  casadi_int indent_level = 0;
1881 
1882  // Read options
1883  for (auto&& op : options) {
1884  if (op.first=="indent_level") {
1885  indent_level = op.second;
1886  } else {
1887  casadi_error("Unknown option '" + op.first + "'.");
1888  }
1889  }
1890 
1891  // Construct indent string
1892  std::string indent;
1893  for (casadi_int i=0;i<indent_level;++i) {
1894  indent += " ";
1895  }
1896 
1897  // Non-cell aliases for inputs
1898  for (casadi_int i=0;i<n_in_;++i) {
1899  ss << indent << "argin_" << i << " = nonzeros_gen(varargin{" << i+1 << "});" << std::endl;
1900  }
1901 
1902  Function f = shared_from_this<Function>();
1903 
1904  for (casadi_int k=0;k<f.n_instructions();++k) {
1905  // Get operation
1906  casadi_int op = static_cast<casadi_int>(f.instruction_id(k));
1907  // Get input positions into workvector
1908  std::vector<casadi_int> o = f.instruction_output(k);
1909  // Get output positions into workvector
1910  std::vector<casadi_int> i = f.instruction_input(k);
1911  switch (op) {
1912  case OP_INPUT:
1913  {
1914  ss << indent << "w" << o[0] << " = " << "argin_" << i[0] << "(" << i[1]+1 << ");";
1915  ss << std::endl;
1916  }
1917  break;
1918  case OP_OUTPUT:
1919  {
1920  ss << indent << "argout_" << o[0] << "{" << o[1]+1 << "} = w" << i[0] << ";";
1921  ss << std::endl;
1922  }
1923  break;
1924  case OP_CONST:
1925  {
1926  std::ios_base::fmtflags fmtfl = ss.flags();
1927  ss << indent << "w" << o[0] << " = ";
1928  ss << std::scientific << std::setprecision(std::numeric_limits<double>::digits10 + 1);
1929  ss << f.instruction_constant(k) << ";" << std::endl;
1930  ss.flags(fmtfl);
1931  }
1932  break;
1933  case OP_SQ:
1934  {
1935  ss << indent << "w" << o[0] << " = " << "w" << i[0] << "^2;" << std::endl;
1936  }
1937  break;
1938  case OP_FABS:
1939  {
1940  ss << indent << "w" << o[0] << " = abs(" << "w" << i[0] << ");" << std::endl;
1941  }
1942  break;
1943  case OP_POW:
1944  case OP_CONSTPOW:
1945  ss << indent << "w" << o[0] << " = " << "w" << i[0] << ".^w" << i[1] << ";" << std::endl;
1946  break;
1947  case OP_NOT:
1948  ss << indent << "w" << o[0] << " = ~" << "w" << i[0] << ";" << std::endl;
1949  break;
1950  case OP_OR:
1951  ss << indent << "w" << o[0] << " = w" << i[0] << " | w" << i[1] << ";" << std::endl;
1952  break;
1953  case OP_AND:
1954  ss << indent << "w" << o[0] << " = w" << i[0] << " & w" << i[1] << ";" << std::endl;
1955  break;
1956  case OP_NE:
1957  ss << indent << "w" << o[0] << " = w" << i[0] << " ~= w" << i[1] << ";" << std::endl;
1958  break;
1959  case OP_IF_ELSE_ZERO:
1960  ss << indent << "w" << o[0] << " = ";
1961  ss << "if_else_zero_gen(w" << i[0] << ", w" << i[1] << ");" << std::endl;
1962  break;
1963  default:
1965  ss << indent << "w" << o[0] << " = " << casadi::casadi_math<double>::print(op,
1966  "w"+std::to_string(i[0]), "w"+std::to_string(i[1])) << ";" << std::endl;
1967  } else {
1968  ss << indent << "w" << o[0] << " = " << casadi::casadi_math<double>::print(op,
1969  "w"+std::to_string(i[0])) << ";" << std::endl;
1970  }
1971  }
1972  }
1973 
1974  }
@ 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:1135
static std::string print(unsigned char op, const std::string &x, const std::string &y)
Print.
Definition: calculus.hpp:1651

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.

1255  {
1256 
1257  Dict g_ops = generate_options("tmp");
1258  Dict f_options;
1259  f_options["helper_options"] = g_ops;
1260  f_options["final_options"] = g_ops;
1261  update_dict(f_options, opts, true);
1262 
1263  Dict final_options;
1264  extract_from_dict_inplace(f_options, "final_options", final_options);
1265  final_options["allow_duplicate_io_names"] = true;
1266 
1267  // Create an expression factory
1268  Factory<MatType> f;
1269  for (casadi_int i=0; i<in_.size(); ++i) f.add_input(name_in_[i], in_[i], is_diff_in_[i]);
1270  for (casadi_int i=0; i<out_.size(); ++i) f.add_output(name_out_[i], out_[i], is_diff_out_[i]);
1271  f.add_dual(aux);
1272 
1273  // Specify input expressions to be calculated
1274  std::vector<std::string> ret_iname;
1275  for (const std::string& s : s_in) {
1276  try {
1277  ret_iname.push_back(f.request_input(s));
1278  } catch (CasadiException& ex) {
1279  casadi_error("Cannot process factory input \"" + s + "\":" + ex.what());
1280  }
1281  }
1282 
1283  // Specify output expressions to be calculated
1284  std::vector<std::string> ret_oname;
1285  for (const std::string& s : s_out) {
1286  try {
1287  ret_oname.push_back(f.request_output(s));
1288  } catch (CasadiException& ex) {
1289  casadi_error("Cannot process factory output \"" + s + "\":" + ex.what());
1290  }
1291  }
1292 
1293  // Calculate expressions
1294  f.calculate(f_options);
1295 
1296  // Get input expressions
1297  std::vector<MatType> ret_in;
1298  ret_in.reserve(s_in.size());
1299  for (const std::string& s : s_in) ret_in.push_back(f.get_input(s));
1300 
1301  // Get output expressions
1302  std::vector<MatType> ret_out;
1303  ret_out.reserve(s_out.size());
1304  for (const std::string& s : s_out) ret_out.push_back(f.get_output(s));
1305 
1306  // Create function and return
1307  Dict final_options_allow_free = final_options;
1308  final_options_allow_free["allow_free"] = true;
1309  final_options_allow_free["allow_duplicate_io_names"] = true;
1310  Function ret(name, ret_in, ret_out, ret_iname, ret_oname, final_options_allow_free);
1311  if (ret.has_free()) {
1312  // Substitute free variables with zeros
1313  // We assume that the free variables are caused by false positive dependencies
1314  std::vector<MatType> free_in = MatType::get_free(ret);
1315  std::vector<MatType> free_sub = free_in;
1316  for (auto&& e : free_sub) e = MatType::zeros(e.sparsity());
1317  ret_out = substitute(ret_out, free_in, free_sub);
1318  ret = Function(name, ret_in, ret_out, ret_iname, ret_oname, final_options);
1319  }
1320  return ret;
1321  }
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::PiqpInterface, and casadi::OracleFunction.

Definition at line 732 of file function_internal.cpp.

732  {
733  if (codegen_needs_mem()) has_refcount_ = true;
734  if (dump_in_ || dump_out_) has_refcount_ = true;
735 
737 
738  // Does any embedded function have reference counting for codegen?
739  for (const Function& f : shared_from_this<Function>().find_functions(0)) {
740  if (f->has_refcount_in_deps_) {
741  has_refcount_in_deps_ = true;
742  break;
743  }
744  }
745 
746  if (jit_) {
749  if (jit_temp_suffix_) {
751  jit_name_ = std::string(jit_name_.begin()+jit_directory_.size(),
752  jit_name_.begin()+jit_name_.size()-2);
753  }
754  if (has_codegen()) {
755  if (compiler_.is_null()) {
756  if (verbose_) casadi_message("Codegenerating function '" + name_ + "'.");
757  // JIT everything
758  Dict opts;
759  // Override the default to avoid random strings in the generated code
760  opts["prefix"] = "jit";
761  CodeGenerator gen(jit_name_, opts);
762  gen.add(self());
763  if (verbose_) casadi_message("Compiling function '" + name_ + "'..");
764  compiler_ = Importer(gen.generate(jit_directory_), compiler_plugin_, jit_options_);
765  if (verbose_) casadi_message("Compiling function '" + name_ + "' done.");
766  }
767  // Try to load
771  incref_ = (signal_t) compiler_.get_function(name_ + "_incref");
772  decref_ = (signal_t) compiler_.get_function(name_ + "_decref");
773  casadi_assert(eval_!=nullptr, "Cannot load JIT'ed function.");
774  if (incref_) incref_();
775  } else {
776  // Just jit dependencies
778  }
779  }
780 
781  // Finalize base classes
783 
784  // Dump if requested
785  if (dump_) dump();
786  }
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.
static std::string get_jit_directory(const Dict &jit_options)
Get JIT directory from options.
bool jit_temp_suffix_
Use a temporary name.
signal_t incref_
Incref/decref redirected to C functions.
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:84
int(* casadi_checkout_t)(void)
Function pointer types for the C API.
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.
void(* signal_t)(void)
Function pointer types for the C API.
std::string temporary_file(const std::string &prefix, const std::string &suffix, const std::string &directory)

References casadi::CodeGenerator::add(), casadi::FunctionInternal::checkout_, casadi::FunctionInternal::codegen_needs_mem(), casadi::FunctionInternal::compiler_, casadi::FunctionInternal::compiler_plugin_, casadi::FunctionInternal::decref_, casadi::FunctionInternal::dump_, casadi::FunctionInternal::dump_in_, casadi::FunctionInternal::dump_out_, casadi::FunctionInternal::eval_, casadi::ProtoFunction::finalize(), casadi::CodeGenerator::generate(), casadi::Importer::get_function(), casadi::FunctionInternal::get_jit_directory(), casadi::FunctionInternal::has_codegen(), casadi::FunctionInternal::has_refcount_, casadi::FunctionInternal::has_refcount_in_deps_, casadi::FunctionInternal::incref_, casadi::GenericShared< Shared, Internal >::is_null(), casadi::FunctionInternal::jit_, casadi::FunctionInternal::jit_base_name_, casadi::FunctionInternal::jit_dependencies(), casadi::FunctionInternal::jit_directory_, 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(), casadi::Conic::finalize(), and casadi::OracleFunction::finalize().

◆ find()

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

Reimplemented from casadi::FunctionInternal.

Definition at line 2100 of file sx_function.cpp.

2101  {
2102  // Call to base class
2103  FunctionInternal::find(all_fun, max_depth);
2104  for (auto&& e : algorithm_) {
2105  if (e.op == OP_CALL) {
2106  const ExtendedAlgEl& m = call_.el.at(e.i1);
2107  add_embedded(all_fun, m.f, max_depth);
2108  }
2109  }
2110  }
void add_embedded(std::map< FunctionInternal *, std::pair< Function, size_t > > &all_fun, const Function &dep, casadi_int max_depth) const
virtual void find(std::map< FunctionInternal *, std::pair< Function, size_t > > &all_fun, casadi_int max_depth) const

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

◆ finish_trace()

void casadi::FunctionInternal::finish_trace ( std::ostream &  trace,
double **  res,
int  ret 
) const
protectedinherited

Definition at line 868 of file function_internal.cpp.

869  {
870  if (ret == 0) {
871  trace << "{\"event\":\"outputs\",\"values\":[";
872  for (casadi_int i = 0; i < n_out_; ++i) {
873  if (i) trace << ",";
874  trace_values(trace, res[i], nnz_out(i));
875  }
876  trace << "]}\n";
877  }
878  trace << "{\"event\":\"end\",\"status\":" << ret << "}\n";
879  trace.flush();
880  casadi_assert(trace.good(), "Failed to write dump_trace for '" + name_ + "'");
881  }
static void trace_values(std::ostream &trace, const double *values, casadi_int nnz)

References casadi::FunctionInternal::n_out_, casadi::ProtoFunction::name_, casadi::FunctionInternal::nnz_out(), and casadi::FunctionInternal::trace_values().

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

◆ 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 4117 of file function_internal.cpp.

4117  {
4118  // Always of width 8
4119  casadi_assert_dev(time>=0);
4120  double log_time = log10(time);
4121  int magn = static_cast<int>(floor(log_time));
4122  int iprefix = static_cast<int>(floor(log_time/3));
4123  if (iprefix<-4) {
4124  sprint(buffer, 10, " 0");
4125  return;
4126  }
4127  if (iprefix>=5) {
4128  sprint(buffer, 10, " inf");
4129  return;
4130  }
4131  char prefixes[] = "TGMk munp";
4132  char prefix = prefixes[4-iprefix];
4133 
4134  int rem = magn-3*iprefix;
4135  double time_normalized = time/pow(10, 3*iprefix);
4136 
4137  if (rem==0) {
4138  sprint(buffer, 10, " %1.2f%cs", time_normalized, prefix);
4139  } else if (rem==1) {
4140  sprint(buffer, 10, " %2.2f%cs", time_normalized, prefix);
4141  } else {
4142  sprint(buffer, 10, "%3.2f%cs", time_normalized, prefix);
4143  }
4144  }
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 2278 of file function_internal.cpp.

2278  {
2279  casadi_assert_dev(nfwd>=0);
2280  // Used wrapped function if forward not available
2281  if (!enable_forward_ && !enable_fd_) {
2282  // Derivative information must be available
2283  casadi_assert(has_derivative(), "Derivatives cannot be calculated for " + name_);
2284  return wrap().forward(nfwd);
2285  }
2286  // Retrieve/generate cached
2287  Function f;
2288  std::string fname = forward_name(name_, nfwd);
2289  if (!incache(fname, f)) {
2290  casadi_int i;
2291  // Prefix to be used for forward seeds, sensitivities
2292  std::string pref = diff_prefix("fwd");
2293  // Names of inputs
2294  std::vector<std::string> inames;
2295  for (i=0; i<n_in_; ++i) inames.push_back(name_in_[i]);
2296  for (i=0; i<n_out_; ++i) inames.push_back("out_" + name_out_[i]);
2297  for (i=0; i<n_in_; ++i) inames.push_back(pref + name_in_[i]);
2298  // Names of outputs
2299  std::vector<std::string> onames;
2300  for (i=0; i<n_out_; ++i) onames.push_back(pref + name_out_[i]);
2301  // Options
2303  if (enable_forward_) {
2304  opts = combine(opts, generate_options("forward"));
2305  } else {
2306  opts = combine(opts, FunctionInternal::generate_options("forward"));
2307  }
2308  opts["derivative_of"] = self();
2309  // Generate derivative function
2310  casadi_assert_dev(enable_forward_ || enable_fd_);
2311  if (enable_forward_) {
2312  f = get_forward(nfwd, fname, inames, onames, opts);
2313  } else {
2314  opts = combine(opts, fd_options_);
2315  // Get FD method
2316  if (fd_method_.empty() || fd_method_=="central") {
2317  f = Function::create(new CentralDiff(fname, nfwd), opts);
2318  } else if (fd_method_=="forward") {
2319  f = Function::create(new ForwardDiff(fname, nfwd), opts);
2320  } else if (fd_method_=="backward") {
2321  f = Function::create(new BackwardDiff(fname, nfwd), opts);
2322  } else if (fd_method_=="smoothing") {
2323  f = Function::create(new Smoothing(fname, nfwd), opts);
2324  } else {
2325  casadi_error("Unknown 'fd_method': " + fd_method_);
2326  }
2327  }
2328  // Consistency check for inputs
2329  casadi_assert_dev(f.n_in()==n_in_ + n_out_ + n_in_);
2330  casadi_int ind=0;
2331  for (i=0; i<n_in_; ++i) f.assert_size_in(ind++, size1_in(i), size2_in(i));
2332  for (i=0; i<n_out_; ++i) f.assert_size_in(ind++, size1_out(i), size2_out(i));
2333  for (i=0; i<n_in_; ++i) f.assert_size_in(ind++, size1_in(i), nfwd*size2_in(i));
2334  // Consistency check for outputs
2335  casadi_assert_dev(f.n_out()==n_out_);
2336  for (i=0; i<n_out_; ++i) f.assert_sparsity_out(i, sparsity_out(i), nfwd);
2337  // Save to cache
2338  tocache_if_missing(f);
2339  }
2340  return f;
2341  }
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:1324
static Function create(FunctionInternal *node)
Create from node.
Definition: function.cpp:488
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 3624 of file function_internal.cpp.

3624  {
3625  casadi_error("'free_mx' only defined for 'MXFunction'");
3626  }

◆ free_sx()

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

Reimplemented from casadi::FunctionInternal.

Definition at line 152 of file sx_function.hpp.

152  {
153  std::vector<SX> ret(free_vars_.size());
154  std::copy(free_vars_.begin(), free_vars_.end(), ret.begin());
155  return ret;
156  }

◆ from_compact()

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

Definition at line 2043 of file function_internal.cpp.

2044  {
2045  // Return value
2046  Sparsity r = sp;
2047  // Insert rows if sparse output
2048  if (numel_out(oind) != r.size1()) {
2049  casadi_assert_dev(r.size1() == nnz_out(oind));
2050  r.enlargeRows(numel_out(oind), sparsity_out(oind).find());
2051  }
2052  // Insert columns if sparse input
2053  if (numel_in(iind) != r.size2()) {
2054  casadi_assert_dev(r.size2() == nnz_in(iind));
2055  r.enlargeColumns(numel_in(iind), sparsity_in(iind).find());
2056  }
2057  // Return non-compact pattern
2058  return r;
2059  }
casadi_int numel_out() const
Number of input/output elements.
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 1582 of file function_internal.hpp.

1583  {
1584  std::vector<std::vector<MatType>> fseed(nfwd);
1585  for (casadi_int dir=0; dir<nfwd; ++dir) {
1586  fseed[dir].resize(n_in_);
1587  for (casadi_int iind=0; iind<n_in_; ++iind) {
1588  std::string n = "f" + str(dir) + "_" + name_in_[iind];
1589  Sparsity sp = is_diff_in_[iind] ? sparsity_in(iind) : Sparsity(size_in(iind));
1590  fseed[dir][iind] = MatType::sym(n, sp);
1591  }
1592  }
1593  return fseed;
1594  }

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 3239 of file function_internal.cpp.

3239  {
3240  if (!enable_forward_ && !enable_fd_) return true;
3241  if (jac_penalty_==-1) return false;
3242 
3243  // Heuristic 1: Jac calculated via forward mode likely cheaper
3244  if (jac_penalty_*static_cast<double>(nnz_in())<nfwd) return true;
3245 
3246  // Heuristic 2: Jac calculated via reverse mode likely cheaper
3247  double w = ad_weight();
3248  if (enable_reverse_ &&
3249  jac_penalty_*(1-w)*static_cast<double>(nnz_out())<w*static_cast<double>(nfwd))
3250  return true; // NOLINT
3251 
3252  return false;
3253  }

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 3068 of file function_internal.cpp.

3069  {
3070  casadi_error("'generate_dependencies' not defined for " + class_name());
3071  }

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 794 of file function_internal.cpp.

794  {
795  // Set up output stream
796  auto of_ptr = Filesystem::ofstream_ptr(fname);
797  std::ostream& of = *of_ptr;
798  normalized_setup(of);
799 
800  // Encode each input
801  for (casadi_int i=0; i<n_in_; ++i) {
802  const double* v = arg[i];
803  for (casadi_int k=0;k<nnz_in(i);++k) {
804  normalized_out(of, v ? v[k] : 0);
805  of << std::endl;
806  }
807  }
808  }
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 3632 of file function_internal.cpp.

3633  {
3634  casadi_error("'generate_lifted' only defined for 'MXFunction'");
3635  }

◆ generate_options()

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

Reimplemented from casadi::FunctionInternal.

Definition at line 503 of file sx_function.cpp.

503  {
505  opts["dump_trace"] = dump_trace_;
506  if (target=="clone") opts["default_in"] = default_in_;
507  opts["live_variables"] = live_variables_;
508  opts["just_in_time_sparsity"] = just_in_time_sparsity_;
509  opts["just_in_time_opencl"] = just_in_time_opencl_;
510  opts["print_instructions"] = print_instructions_;
511  return opts;
512  }

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

◆ generate_out()

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

Definition at line 810 of file function_internal.cpp.

810  {
811  // Set up output stream
812  auto of_ptr = Filesystem::ofstream_ptr(fname);
813  std::ostream& of = *of_ptr;
814  normalized_setup(of);
815 
816  // Encode each input
817  for (casadi_int i=0; i<n_out_; ++i) {
818  const double* v = res[i];
819  for (casadi_int k=0;k<nnz_out(i);++k) {
820  normalized_out(of, v ? v[k] : std::numeric_limits<double>::quiet_NaN());
821  of << std::endl;
822  }
823  }
824  }

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 1135 of file function_internal.hpp.

1135  {
1136  return eps;
1137  }
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 396 of file sx_function.hpp.

396 { 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.

847  {
848  try {
849  // Seeds
850  std::vector<std::vector<MatType> > fseed = fwd_seed<MatType>(nfwd), fsens;
851 
852  // Evaluate symbolically
853  static_cast<const DerivedType*>(this)->ad_forward(fseed, fsens);
854  casadi_assert_dev(fsens.size()==fseed.size());
855 
856  // All inputs of the return function
857  std::vector<MatType> ret_in(inames.size());
858  std::copy(in_.begin(), in_.end(), ret_in.begin());
859  for (casadi_int i=0; i<n_out_; ++i) {
860  ret_in.at(n_in_+i) = MatType::sym(inames[n_in_+i], Sparsity(out_.at(i).size()));
861  }
862  std::vector<MatType> v(nfwd);
863  for (casadi_int i=0; i<n_in_; ++i) {
864  for (casadi_int d=0; d<nfwd; ++d) v[d] = fseed[d][i];
865  ret_in.at(n_in_ + n_out_ + i) = horzcat(v);
866  }
867 
868  // All outputs of the return function
869  std::vector<MatType> ret_out(onames.size());
870  for (casadi_int i=0; i<n_out_; ++i) {
871  if (is_diff_out_[i]) {
872  // Concatenate sensitivities, correct sparsity pattern if needed
873  for (casadi_int d=0; d<nfwd; ++d) v[d] = fsens[d][i];
874  ret_out.at(i) = ensure_stacked(horzcat(v), sparsity_out(i), nfwd);
875  } else {
876  // Output is non-differentable
877  ret_out.at(i) = MatType(size1_out(i), size2_out(i) * nfwd);
878  }
879  }
880 
881  Dict options = opts;
882  options["allow_duplicate_io_names"] = true;
883  // Assemble function and return
884  return Function(name, ret_in, ret_out, inames, onames, options);
885  } catch (std::exception& e) {
886  CASADI_THROW_ERROR("get_forward", e.what());
887  }
888  }
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.

◆ 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 166 of file sx_function.hpp.

166  {
167  std::vector<std::string> ret;
168  for (auto&& e : free_vars_) ret.push_back(e.name());
169  return ret;
170  }

Referenced by init().

◆ get_function() [1/2]

std::vector< std::string > casadi::SXFunction::get_function ( ) const
overridevirtual

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

Reimplemented from casadi::FunctionInternal.

Definition at line 1842 of file sx_function.cpp.

1842  {
1843  std::map<std::string, bool> flagged;
1844  for (auto&& a : algorithm_) {
1845  if (a.op==OP_CALL) {
1846  const auto& m = call_.el.at(a.i1);
1847  const Function &f = m.f;
1848  if (flagged.find(f.name())==flagged.end()) {
1849  flagged[f.name()] = true;
1850  }
1851  }
1852  }
1853  std::vector<std::string> ret;
1854  for (auto it : flagged) {
1855  ret.push_back(it.first);
1856  }
1857  return ret;
1858  }

References algorithm_, call_, casadi::SXFunction::CallInfo::el, casadi::Function::name(), and casadi::OP_CALL.

◆ get_function() [2/2]

const Function & casadi::SXFunction::get_function ( const std::string &  name) const
overridevirtual

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

Reimplemented from casadi::FunctionInternal.

Definition at line 1860 of file sx_function.cpp.

1860  {
1861  for (auto&& a : algorithm_) {
1862  if (a.op==OP_CALL) {
1863  const auto& m = call_.el.at(a.i1);
1864  const Function &f = m.f;
1865  if (name==f.name()) return f;
1866  }
1867  }
1868  casadi_error("No such function '" + name + "'.");
1869  }

References algorithm_, call_, casadi::SXFunction::CallInfo::el, casadi::Function::name(), and casadi::OP_CALL.

◆ 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 1986 of file function_internal.cpp.

1987  {
1988  if (symmetric) {
1989  casadi_assert(sparsity_out_[oind].is_dense(),
1990  "Symmetry exploitation in Jacobian assumes dense expression. "
1991  "A potential workaround is to apply densify().");
1992  }
1993  // Check if we are able to propagate dependencies through the function
1994  if (has_spfwd() || has_sprev()) {
1995  // Get weighting factor
1996  double w = sp_weight();
1997 
1998  // Skip generation, assume dense
1999  if (w == -1) return Sparsity();
2000 
2001  Sparsity sp;
2002  if (nnz_in(iind) > 3*bvec_size && nnz_out(oind) > 3*bvec_size &&
2004  if (symmetric) {
2005  sp = get_jac_sparsity_hierarchical_symm(oind, iind);
2006  } else {
2007  sp = get_jac_sparsity_hierarchical(oind, iind);
2008  }
2009  } else {
2010  // Number of nonzero inputs and outputs
2011  casadi_int nz_in = nnz_in(iind);
2012  casadi_int nz_out = nnz_out(oind);
2013 
2014  // Number of forward sweeps we must make
2015  casadi_int nsweep_fwd = nz_in/bvec_size;
2016  if (nz_in%bvec_size) nsweep_fwd++;
2017 
2018  // Number of adjoint sweeps we must make
2019  casadi_int nsweep_adj = nz_out/bvec_size;
2020  if (nz_out%bvec_size) nsweep_adj++;
2021 
2022  // Use forward mode?
2023  if (w*static_cast<double>(nsweep_fwd) <= (1-w)*static_cast<double>(nsweep_adj)) {
2024  sp = get_jac_sparsity_gen<true>(oind, iind);
2025  } else {
2026  sp = get_jac_sparsity_gen<false>(oind, iind);
2027  }
2028  }
2029  return sp;
2030  } else {
2031  // Not calculated
2032  return Sparsity();
2033  }
2034  }
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 1331 of file function_internal.cpp.

1331  {
1332  // Number of nonzero inputs and outputs
1333  casadi_int nz_in = nnz_in(iind);
1334  casadi_int nz_out = nnz_out(oind);
1335 
1336  // Evaluation buffers
1337  std::vector<typename JacSparsityTraits<fwd>::arg_t> arg(sz_arg(), nullptr);
1338  std::vector<bvec_t*> res(sz_res(), nullptr);
1339  std::vector<casadi_int> iw(sz_iw());
1340  std::vector<bvec_t> w(sz_w(), 0);
1341 
1342  // Seeds and sensitivities
1343  std::vector<bvec_t> seed(nz_in, 0);
1344  arg[iind] = get_ptr(seed);
1345  std::vector<bvec_t> sens(nz_out, 0);
1346  res[oind] = get_ptr(sens);
1347  if (!fwd) std::swap(seed, sens);
1348 
1349  // Number of forward sweeps we must make
1350  casadi_int nsweep = seed.size() / bvec_size;
1351  if (seed.size() % bvec_size) nsweep++;
1352 
1353  // Print
1354  if (verbose_) {
1355  casadi_message(str(nsweep) + std::string(fwd ? " forward" : " reverse") + " sweeps "
1356  "needed for " + str(seed.size()) + " directions");
1357  }
1358 
1359  // Progress
1360  casadi_int progress = -10;
1361 
1362  // Temporary vectors
1363  std::vector<casadi_int> jcol, jrow;
1364 
1365  // Loop over the variables, bvec_size variables at a time
1366  for (casadi_int s=0; s<nsweep; ++s) {
1367 
1368  // Print progress
1369  if (verbose_) {
1370  casadi_int progress_new = (s*100)/nsweep;
1371  // Print when entering a new decade
1372  if (progress_new / 10 > progress / 10) {
1373  progress = progress_new;
1374  casadi_message(str(progress) + " %");
1375  }
1376  }
1377 
1378  // Nonzero offset
1379  casadi_int offset = s*bvec_size;
1380 
1381  // Number of local seed directions
1382  casadi_int ndir_local = seed.size()-offset;
1383  ndir_local = std::min(static_cast<casadi_int>(bvec_size), ndir_local);
1384 
1385  for (casadi_int i=0; i<ndir_local; ++i) {
1386  seed[offset+i] |= bvec_t(1)<<i;
1387  }
1388 
1389  // Propagate the dependencies
1390  JacSparsityTraits<fwd>::sp(this, get_ptr(arg), get_ptr(res),
1391  get_ptr(iw), get_ptr(w), memory(0));
1392 
1393  // Loop over the nonzeros of the output
1394  for (casadi_int el=0; el<sens.size(); ++el) {
1395 
1396  // Get the sparsity sensitivity
1397  bvec_t spsens = sens[el];
1398 
1399  if (!fwd) {
1400  // Clear the sensitivities for the next sweep
1401  sens[el] = 0;
1402  }
1403 
1404  // If there is a dependency in any of the directions
1405  if (spsens!=0) {
1406 
1407  // Loop over seed directions
1408  for (casadi_int i=0; i<ndir_local; ++i) {
1409 
1410  // If dependents on the variable
1411  if ((bvec_t(1) << i) & spsens) {
1412  // Add to pattern
1413  jcol.push_back(el);
1414  jrow.push_back(i+offset);
1415  }
1416  }
1417  }
1418  }
1419 
1420  // Remove the seeds
1421  for (casadi_int i=0; i<ndir_local; ++i) {
1422  seed[offset+i] = 0;
1423  }
1424  }
1425 
1426  // Construct sparsity pattern and return
1427  if (!fwd) swap(jrow, jcol);
1428  Sparsity ret = Sparsity::triplet(nz_out, nz_in, jcol, jrow);
1429  if (verbose_) {
1430  casadi_message("Formed Jacobian sparsity pattern (dimension " + str(ret.size()) + ", "
1431  + str(ret.nnz()) + " (" + str(ret.density()) + " %) nonzeros.");
1432  }
1433  return ret;
1434  }
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:1143

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 1671 of file function_internal.cpp.

1671  {
1672  // Number of nonzero inputs
1673  casadi_int nz_in = nnz_in(iind);
1674 
1675  // Number of nonzero outputs
1676  casadi_int nz_out = nnz_out(oind);
1677 
1678  // Seeds and sensitivities
1679  std::vector<bvec_t> s_in(nz_in, 0);
1680  std::vector<bvec_t> s_out(nz_out, 0);
1681 
1682  // Evaluation buffers
1683  std::vector<const bvec_t*> arg_fwd(sz_arg(), nullptr);
1684  std::vector<bvec_t*> arg_adj(sz_arg(), nullptr);
1685  arg_fwd[iind] = arg_adj[iind] = get_ptr(s_in);
1686  std::vector<bvec_t*> res(sz_res(), nullptr);
1687  res[oind] = get_ptr(s_out);
1688  std::vector<casadi_int> iw(sz_iw());
1689  std::vector<bvec_t> w(sz_w());
1690 
1691  // Sparsity triplet accumulator
1692  std::vector<casadi_int> jcol, jrow;
1693 
1694  // Cols of the coarse blocks
1695  std::vector<casadi_int> coarse_col(2, 0); coarse_col[1] = nz_out;
1696  // Rows of the coarse blocks
1697  std::vector<casadi_int> coarse_row(2, 0); coarse_row[1] = nz_in;
1698 
1699  // Cols of the fine blocks
1700  std::vector<casadi_int> fine_col;
1701 
1702  // Rows of the fine blocks
1703  std::vector<casadi_int> fine_row;
1704 
1705  // In each iteration, subdivide each coarse block in this many fine blocks
1706  casadi_int subdivision = bvec_size;
1707 
1708  Sparsity r = Sparsity::dense(1, 1);
1709 
1710  // The size of a block
1711  casadi_int granularity_row = nz_in;
1712  casadi_int granularity_col = nz_out;
1713 
1714  bool use_fwd = true;
1715 
1716  casadi_int nsweeps = 0;
1717 
1718  bool hasrun = false;
1719 
1720  // Get weighting factor
1721  double sp_w = sp_weight();
1722 
1723  // Lookup table for bvec_t
1724  std::vector<bvec_t> bvec_lookup;
1725  bvec_lookup.reserve(bvec_size);
1726  for (casadi_int i=0;i<bvec_size;++i) {
1727  bvec_lookup.push_back(bvec_t(1) << i);
1728  }
1729 
1730  while (!hasrun || coarse_col.size()!=nz_out+1 || coarse_row.size()!=nz_in+1) {
1731  if (verbose_) {
1732  casadi_message("Block size: " + str(granularity_col) + " x " + str(granularity_row));
1733  }
1734 
1735  // Clear the sparsity triplet acccumulator
1736  jcol.clear();
1737  jrow.clear();
1738 
1739  // Clear the fine block structure
1740  fine_row.clear();
1741  fine_col.clear();
1742 
1743  // r transpose will be needed in the algorithm
1744  Sparsity rT = r.T();
1745 
1748  // Forward mode
1749  Sparsity D1 = rT.uni_coloring(r);
1750  // Adjoint mode
1751  Sparsity D2 = r.uni_coloring(rT);
1752  if (verbose_) {
1753  casadi_message("Coloring on " + str(r.dim()) + " (fwd seeps: " + str(D1.size2()) +
1754  " , adj sweeps: " + str(D2.size1()) + ")");
1755  }
1756 
1757  // Use whatever required less colors if we tried both (with preference to forward mode)
1758  double fwd_cost = static_cast<double>(use_fwd ? granularity_row : granularity_col) *
1759  sp_w*static_cast<double>(D1.size2());
1760  double adj_cost = static_cast<double>(use_fwd ? granularity_col : granularity_row) *
1761  (1-sp_w)*static_cast<double>(D2.size2());
1762  use_fwd = fwd_cost <= adj_cost;
1763  if (verbose_) {
1764  casadi_message(std::string(use_fwd ? "Forward" : "Reverse") + " mode chosen "
1765  "(fwd cost: " + str(fwd_cost) + ", adj cost: " + str(adj_cost) + ")");
1766  }
1767 
1768  // Get seeds and sensitivities
1769  bvec_t* seed_v = use_fwd ? get_ptr(s_in) : get_ptr(s_out);
1770  bvec_t* sens_v = use_fwd ? get_ptr(s_out) : get_ptr(s_in);
1771 
1772  // The number of zeros in the seed and sensitivity directions
1773  casadi_int nz_seed = use_fwd ? nz_in : nz_out;
1774  casadi_int nz_sens = use_fwd ? nz_out : nz_in;
1775 
1776  // Clear the seeds
1777  for (casadi_int i=0; i<nz_seed; ++i) seed_v[i]=0;
1778 
1779  // Choose the active jacobian coloring scheme
1780  Sparsity D = use_fwd ? D1 : D2;
1781 
1782  // Adjoint mode amounts to swapping
1783  if (!use_fwd) {
1784  std::swap(coarse_col, coarse_row);
1785  std::swap(granularity_col, granularity_row);
1786  std::swap(r, rT);
1787  }
1788 
1789  // Subdivide the coarse block cols
1790  for (casadi_int k=0;k<coarse_col.size()-1;++k) {
1791  casadi_int diff = coarse_col[k+1]-coarse_col[k];
1792  casadi_int new_diff = diff/subdivision;
1793  if (diff%subdivision>0) new_diff++;
1794  std::vector<casadi_int> temp = range(coarse_col[k], coarse_col[k+1], new_diff);
1795  fine_col.insert(fine_col.end(), temp.begin(), temp.end());
1796  }
1797  // Subdivide the coarse block rows
1798  for (casadi_int k=0;k<coarse_row.size()-1;++k) {
1799  casadi_int diff = coarse_row[k+1]-coarse_row[k];
1800  casadi_int new_diff = diff/subdivision;
1801  if (diff%subdivision>0) new_diff++;
1802  std::vector<casadi_int> temp = range(coarse_row[k], coarse_row[k+1], new_diff);
1803  fine_row.insert(fine_row.end(), temp.begin(), temp.end());
1804  }
1805  if (fine_row.back()!=coarse_row.back()) fine_row.push_back(coarse_row.back());
1806  if (fine_col.back()!=coarse_col.back()) fine_col.push_back(coarse_col.back());
1807 
1808  granularity_col = fine_col[1] - fine_col[0];
1809  granularity_row = fine_row[1] - fine_row[0];
1810 
1811  // The index into the bvec bit vector
1812  casadi_int bvec_i = 0;
1813 
1814  // Create lookup tables for the fine blocks
1815  std::vector<casadi_int> fine_col_lookup = lookupvector(fine_col, nz_sens+1);
1816  std::vector<casadi_int> fine_row_lookup = lookupvector(fine_row, nz_seed+1);
1817 
1818  // Triplet data used as a lookup table
1819  std::vector<casadi_int> lookup_col;
1820  std::vector<casadi_int> lookup_row;
1821  std::vector<casadi_int> lookup_value;
1822 
1823 
1824  // The maximum number of fine blocks contained in one coarse block
1825  casadi_int n_fine_blocks_max = 0;
1826  for (casadi_int i=0;i<coarse_row.size()-1;++i) {
1827  casadi_int del = fine_row_lookup[coarse_row[i+1]]-fine_row_lookup[coarse_row[i]];
1828  n_fine_blocks_max = std::max(n_fine_blocks_max, del);
1829  }
1830 
1831  // Loop over all coarse seed directions from the coloring
1832  for (casadi_int csd=0; csd<D.size2(); ++csd) {
1833 
1834  casadi_int fci_offset = 0;
1835  casadi_int fci_cap = bvec_size-bvec_i;
1836 
1837  // Flag to indicate if all fine blocks have been handled
1838  bool f_finished = false;
1839 
1840  // Loop while not finished
1841  while (!f_finished) {
1842 
1843  // Loop over all coarse rows that are found in the coloring for this coarse seed direction
1844  for (casadi_int k=D.colind(csd); k<D.colind(csd+1); ++k) {
1845  casadi_int cci = D.row(k);
1846 
1847  // The first and last rows of the fine block
1848  casadi_int fci_start = fine_row_lookup[coarse_row[cci]];
1849  casadi_int fci_end = fine_row_lookup[coarse_row[cci+1]];
1850 
1851  // Local counter that modifies index into bvec
1852  casadi_int bvec_i_mod = 0;
1853 
1854  casadi_int value = -bvec_i + fci_offset + fci_start;
1855 
1856  // Loop over the rows of the fine block
1857  for (casadi_int fci = fci_offset; fci < std::min(fci_end-fci_start, fci_cap); ++fci) {
1858 
1859  // Loop over the coarse block cols that appear in the coloring
1860  // for the current coarse seed direction
1861  for (casadi_int cri=rT.colind(cci);cri<rT.colind(cci+1);++cri) {
1862  lookup_col.push_back(rT.row(cri));
1863  lookup_row.push_back(bvec_i+bvec_i_mod);
1864  lookup_value.push_back(value);
1865  }
1866 
1867  // Toggle on seeds
1868  bvec_toggle(seed_v, fine_row[fci+fci_start], fine_row[fci+fci_start+1],
1869  bvec_i+bvec_i_mod);
1870  bvec_i_mod++;
1871  }
1872  }
1873 
1874  // Bump bvec_i for next major coarse direction
1875  bvec_i+= std::min(n_fine_blocks_max, fci_cap);
1876 
1877  // Check if bvec buffer is full
1878  if (bvec_i==bvec_size || csd==D.size2()-1) {
1879  // Calculate sparsity for bvec_size directions at once
1880 
1881  // Statistics
1882  nsweeps+=1;
1883 
1884  // Construct lookup table
1885  IM lookup = IM::triplet(lookup_row, lookup_col, lookup_value, bvec_size,
1886  coarse_col.size());
1887 
1888  // Propagate the dependencies
1889  if (use_fwd) {
1890  JacSparsityTraits<true>::sp(this, get_ptr(arg_fwd), get_ptr(res),
1891  get_ptr(iw), get_ptr(w), memory(0));
1892  } else {
1893  std::fill(w.begin(), w.end(), 0);
1894  JacSparsityTraits<false>::sp(this, get_ptr(arg_adj), get_ptr(res),
1895  get_ptr(iw), get_ptr(w), memory(0));
1896  }
1897 
1898  // Temporary bit work vector
1899  bvec_t spsens;
1900 
1901  // Loop over the cols of coarse blocks
1902  for (casadi_int cri=0;cri<coarse_col.size()-1;++cri) {
1903 
1904  // Loop over the cols of fine blocks within the current coarse block
1905  for (casadi_int fri=fine_col_lookup[coarse_col[cri]];
1906  fri<fine_col_lookup[coarse_col[cri+1]];++fri) {
1907  // Lump individual sensitivities together into fine block
1908  bvec_or(sens_v, spsens, fine_col[fri], fine_col[fri+1]);
1909 
1910  // Next iteration if no sparsity
1911  if (!spsens) continue;
1912 
1913  // Loop over all bvec_bits
1914  for (casadi_int bvec_i=0;bvec_i<bvec_size;++bvec_i) {
1915  if (spsens & bvec_lookup[bvec_i]) {
1916  // if dependency is found, add it to the new sparsity pattern
1917  casadi_int ind = lookup.sparsity().get_nz(bvec_i, cri);
1918  if (ind==-1) continue;
1919  jrow.push_back(bvec_i+lookup->at(ind));
1920  jcol.push_back(fri);
1921  }
1922  }
1923  }
1924  }
1925 
1926  // Clear the forward seeds/adjoint sensitivities, ready for next bvec sweep
1927  std::fill(s_in.begin(), s_in.end(), 0);
1928 
1929  // Clear the adjoint seeds/forward sensitivities, ready for next bvec sweep
1930  std::fill(s_out.begin(), s_out.end(), 0);
1931 
1932  // Clean lookup table
1933  lookup_col.clear();
1934  lookup_row.clear();
1935  lookup_value.clear();
1936  }
1937 
1938  if (n_fine_blocks_max>fci_cap) {
1939  fci_offset += std::min(n_fine_blocks_max, fci_cap);
1940  bvec_i = 0;
1941  fci_cap = bvec_size;
1942  } else {
1943  f_finished = true;
1944  }
1945 
1946  }
1947 
1948  }
1949 
1950  // Swap results if adjoint mode was used
1951  if (use_fwd) {
1952  // Construct fine sparsity pattern
1953  r = Sparsity::triplet(fine_row.size()-1, fine_col.size()-1, jrow, jcol);
1954  coarse_col = fine_col;
1955  coarse_row = fine_row;
1956  } else {
1957  // Construct fine sparsity pattern
1958  r = Sparsity::triplet(fine_col.size()-1, fine_row.size()-1, jcol, jrow);
1959  coarse_col = fine_row;
1960  coarse_row = fine_col;
1961  }
1962  hasrun = true;
1963  }
1964  if (verbose_) {
1965  casadi_message("Number of sweeps: " + str(nsweeps));
1966  casadi_message("Formed Jacobian sparsity pattern (dimension " + str(r.size()) + ", " +
1967  str(r.nnz()) + " (" + str(r.density()) + " %) nonzeros.");
1968  }
1969 
1970  return r.T();
1971  }
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:1028
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 1436 of file function_internal.cpp.

1437  {
1438  casadi_assert_dev(has_spfwd());
1439 
1440  // Number of nonzero inputs
1441  casadi_int nz = nnz_in(iind);
1442  casadi_assert_dev(nz==nnz_out(oind));
1443 
1444  // Evaluation buffers
1445  std::vector<const bvec_t*> arg(sz_arg(), nullptr);
1446  std::vector<bvec_t*> res(sz_res(), nullptr);
1447  std::vector<casadi_int> iw(sz_iw());
1448  std::vector<bvec_t> w(sz_w());
1449 
1450  // Seeds
1451  std::vector<bvec_t> seed(nz, 0);
1452  arg[iind] = get_ptr(seed);
1453 
1454  // Sensitivities
1455  std::vector<bvec_t> sens(nz, 0);
1456  res[oind] = get_ptr(sens);
1457 
1458  // Sparsity triplet accumulator
1459  std::vector<casadi_int> jcol, jrow;
1460 
1461  // Cols/rows of the coarse blocks
1462  std::vector<casadi_int> coarse(2, 0); coarse[1] = nz;
1463 
1464  // Cols/rows of the fine blocks
1465  std::vector<casadi_int> fine;
1466 
1467  // In each iteration, subdivide each coarse block in this many fine blocks
1468  casadi_int subdivision = bvec_size;
1469 
1470  Sparsity r = Sparsity::dense(1, 1);
1471 
1472  // The size of a block
1473  casadi_int granularity = nz;
1474 
1475  casadi_int nsweeps = 0;
1476 
1477  bool hasrun = false;
1478 
1479  while (!hasrun || coarse.size()!=nz+1) {
1480  if (verbose_) casadi_message("Block size: " + str(granularity));
1481 
1482  // Clear the sparsity triplet acccumulator
1483  jcol.clear();
1484  jrow.clear();
1485 
1486  // Clear the fine block structure
1487  fine.clear();
1488 
1489  Sparsity D = r.star_coloring();
1490 
1491  if (verbose_) {
1492  casadi_message("Star coloring on " + str(r.dim()) + ": "
1493  + str(D.size2()) + " <-> " + str(D.size1()));
1494  }
1495 
1496  // Clear the seeds
1497  std::fill(seed.begin(), seed.end(), 0);
1498 
1499  // Subdivide the coarse block
1500  for (casadi_int k=0; k<coarse.size()-1; ++k) {
1501  casadi_int diff = coarse[k+1]-coarse[k];
1502  casadi_int new_diff = diff/subdivision;
1503  if (diff%subdivision>0) new_diff++;
1504  std::vector<casadi_int> temp = range(coarse[k], coarse[k+1], new_diff);
1505  fine.insert(fine.end(), temp.begin(), temp.end());
1506  }
1507  if (fine.back()!=coarse.back()) fine.push_back(coarse.back());
1508 
1509  granularity = fine[1] - fine[0];
1510 
1511  // The index into the bvec bit vector
1512  casadi_int bvec_i = 0;
1513 
1514  // Create lookup tables for the fine blocks
1515  std::vector<casadi_int> fine_lookup = lookupvector(fine, nz+1);
1516 
1517  // Triplet data used as a lookup table
1518  std::vector<casadi_int> lookup_col;
1519  std::vector<casadi_int> lookup_row;
1520  std::vector<casadi_int> lookup_value;
1521 
1522  // The maximum number of fine blocks contained in one coarse block
1523  casadi_int n_fine_blocks_max = 0;
1524  for (casadi_int i=0;i<coarse.size()-1;++i) {
1525  casadi_int del = fine_lookup[coarse[i+1]]-fine_lookup[coarse[i]];
1526  n_fine_blocks_max = std::max(n_fine_blocks_max, del);
1527  }
1528 
1529  // Loop over all coarse seed directions from the coloring
1530  for (casadi_int csd=0; csd<D.size2(); ++csd) {
1531 
1532 
1533  casadi_int fci_offset = 0;
1534  casadi_int fci_cap = bvec_size-bvec_i;
1535 
1536  // Flag to indicate if all fine blocks have been handled
1537  bool f_finished = false;
1538 
1539  // Loop while not finished
1540  while (!f_finished) {
1541 
1542  // Loop over all coarse rows that are found in the coloring for this coarse seed direction
1543  for (casadi_int k=D.colind(csd); k<D.colind(csd+1); ++k) {
1544  casadi_int cci = D.row(k);
1545 
1546  // The first and last rows of the fine block
1547  casadi_int fci_start = fine_lookup[coarse[cci]];
1548  casadi_int fci_end = fine_lookup[coarse[cci+1]];
1549 
1550  // Local counter that modifies index into bvec
1551  casadi_int bvec_i_mod = 0;
1552 
1553  casadi_int value = -bvec_i + fci_offset + fci_start;
1554 
1555  //casadi_assert_dev(value>=0);
1556 
1557  // Loop over the rows of the fine block
1558  for (casadi_int fci = fci_offset; fci<std::min(fci_end-fci_start, fci_cap); ++fci) {
1559 
1560  // Loop over the coarse block cols that appear in the
1561  // coloring for the current coarse seed direction
1562  for (casadi_int cri=r.colind(cci);cri<r.colind(cci+1);++cri) {
1563  lookup_col.push_back(r.row(cri));
1564  lookup_row.push_back(bvec_i+bvec_i_mod);
1565  lookup_value.push_back(value);
1566  }
1567 
1568  // Toggle on seeds
1569  bvec_toggle(get_ptr(seed), fine[fci+fci_start], fine[fci+fci_start+1],
1570  bvec_i+bvec_i_mod);
1571  bvec_i_mod++;
1572  }
1573  }
1574 
1575  // Bump bvec_i for next major coarse direction
1576  bvec_i += std::min(n_fine_blocks_max, fci_cap);
1577 
1578  // Check if bvec buffer is full
1579  if (bvec_i==bvec_size || csd==D.size2()-1) {
1580  // Calculate sparsity for bvec_size directions at once
1581 
1582  // Statistics
1583  nsweeps+=1;
1584 
1585  // Construct lookup table
1586  IM lookup = IM::triplet(lookup_row, lookup_col, lookup_value,
1587  bvec_size, coarse.size());
1588 
1589  std::reverse(lookup_col.begin(), lookup_col.end());
1590  std::reverse(lookup_row.begin(), lookup_row.end());
1591  std::reverse(lookup_value.begin(), lookup_value.end());
1592  IM duplicates =
1593  IM::triplet(lookup_row, lookup_col, lookup_value, bvec_size, coarse.size())
1594  - lookup;
1595  duplicates = sparsify(duplicates);
1596  lookup(duplicates.sparsity()) = -bvec_size;
1597 
1598  // Propagate the dependencies
1599  JacSparsityTraits<true>::sp(this, get_ptr(arg), get_ptr(res),
1600  get_ptr(iw), get_ptr(w), nullptr);
1601 
1602  // Temporary bit work vector
1603  bvec_t spsens;
1604 
1605  // Loop over the cols of coarse blocks
1606  for (casadi_int cri=0; cri<coarse.size()-1; ++cri) {
1607 
1608  // Loop over the cols of fine blocks within the current coarse block
1609  for (casadi_int fri=fine_lookup[coarse[cri]];fri<fine_lookup[coarse[cri+1]];++fri) {
1610  // Lump individual sensitivities together into fine block
1611  bvec_or(get_ptr(sens), spsens, fine[fri], fine[fri+1]);
1612 
1613  // Loop over all bvec_bits
1614  for (casadi_int bvec_i=0;bvec_i<bvec_size;++bvec_i) {
1615  if (spsens & (bvec_t(1) << bvec_i)) {
1616  // if dependency is found, add it to the new sparsity pattern
1617  casadi_int ind = lookup.sparsity().get_nz(bvec_i, cri);
1618  if (ind==-1) continue;
1619  casadi_int lk = lookup->at(ind);
1620  if (lk>-bvec_size) {
1621  jrow.push_back(bvec_i+lk);
1622  jcol.push_back(fri);
1623  jrow.push_back(fri);
1624  jcol.push_back(bvec_i+lk);
1625  }
1626  }
1627  }
1628  }
1629  }
1630 
1631  // Clear the forward seeds/adjoint sensitivities, ready for next bvec sweep
1632  std::fill(seed.begin(), seed.end(), 0);
1633 
1634  // Clean lookup table
1635  lookup_col.clear();
1636  lookup_row.clear();
1637  lookup_value.clear();
1638  }
1639 
1640  if (n_fine_blocks_max>fci_cap) {
1641  fci_offset += std::min(n_fine_blocks_max, fci_cap);
1642  bvec_i = 0;
1643  fci_cap = bvec_size;
1644  } else {
1645  f_finished = true;
1646  }
1647  }
1648  }
1649 
1650  // Construct fine sparsity pattern
1651  r = Sparsity::triplet(fine.size()-1, fine.size()-1, jrow, jcol);
1652 
1653  // There may be false positives here that are not present
1654  // in the reverse mode that precedes it.
1655  // This can lead to an assymetrical result
1656  // cf. #1522
1657  r=r*r.T();
1658 
1659  coarse = fine;
1660  hasrun = true;
1661  }
1662  if (verbose_) {
1663  casadi_message("Number of sweeps: " + str(nsweeps));
1664  casadi_message("Formed Jacobian sparsity pattern (dimension " + str(r.size()) +
1665  ", " + str(r.nnz()) + " (" + str(r.density()) + " %) nonzeros.");
1666  }
1667 
1668  return r.T();
1669  }

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.

942  {
943  try {
944  // Select only differentiable inputs and outputs
945  std::vector<MatType> diff_in = vector_select(in_, is_diff_in_);
946  std::vector<MatType> diff_out = vector_select(out_, is_diff_out_);
947 
948  std::vector<MatType> non_diff_in = vector_select(in_, is_diff_in_, true);
949 
950  // Create flattened function with only differentiable inputs/outputs
951  Dict tmp_options = generate_options("tmp");
952  tmp_options["allow_free"] = true;
953  tmp_options["allow_duplicate_io_names"] = true;
954  std::vector<bool> tmp_is_diff = {true};
955  if (!non_diff_in.empty()) tmp_is_diff.push_back(false);
956 
957  tmp_options["is_diff_in"] = tmp_is_diff;
958  std::vector<MatType> tmp_args = {veccat(diff_in)};
959  if (!non_diff_in.empty()) tmp_args.push_back(veccat(non_diff_in));
960 
961  Function tmp("flattened_" + name_, tmp_args, {veccat(diff_out)}, tmp_options);
962  // Expression for the Jacobian of differentiable inputs/outputs only
963  MatType J = tmp.get<DerivedType>()->jac(Dict()).at(0);
964 
965  // Split up Jacobian into blocks (only for differentiable inputs/outputs)
966  std::vector<casadi_int> r_offset = {0}, c_offset = {0};
967  for (auto& e : diff_out) r_offset.push_back(r_offset.back() + e.numel());
968  for (auto& e : diff_in) c_offset.push_back(c_offset.back() + e.numel());
969  auto Jblocks = MatType::blocksplit(J, r_offset, c_offset);
970 
971  // Assemble full Jacobian output, inserting zeros for non-differentiable blocks
972  std::vector<MatType> ret_out;
973  ret_out.reserve(onames.size());
974  casadi_int diff_i = 0;
975  for (casadi_int i=0; i<n_out_; ++i) {
976  casadi_int diff_j = 0;
977  for (casadi_int j=0; j<n_in_; ++j) {
978  if (is_diff_out_.at(i) && is_diff_in_.at(j)) {
979  ret_out.push_back(Jblocks.at(diff_i).at(diff_j));
980  diff_j++;
981  } else {
982  ret_out.push_back(MatType(out_.at(i).numel(), in_.at(j).numel()));
983  }
984  }
985  if (is_diff_out_.at(i)) diff_i++;
986  }
987 
988  // All inputs of the return function
989  std::vector<MatType> ret_in(inames.size());
990  std::copy(in_.begin(), in_.end(), ret_in.begin());
991  for (casadi_int i=0; i<n_out_; ++i) {
992  ret_in.at(n_in_+i) = MatType::sym(inames[n_in_+i], Sparsity(out_.at(i).size()));
993  }
994 
995  Dict options = opts;
996  options["allow_free"] = true;
997  options["allow_duplicate_io_names"] = true;
998 
999  if (opts.find("is_diff_in")==opts.end()) {
1000  std::vector<bool> is_diff_in = join(is_diff_in_, is_diff_out_);
1001  options["is_diff_in"] = is_diff_in;
1002  }
1003 
1004  if (opts.find("is_diff_out")==opts.end()) {
1005  std::vector<bool> is_diff_out;
1006  for (casadi_int i=0; i<n_out_; ++i) {
1007  for (casadi_int j=0; j<n_in_; ++j) {
1008  is_diff_out.push_back(is_diff_in_[j] && is_diff_out_[i]);
1009  }
1010  }
1011  options["is_diff_out"] = is_diff_out;
1012  }
1013 
1014  // Assemble function and return
1015  return Function(name, ret_in, ret_out, inames, onames, options);
1016  } catch (std::exception& e) {
1017  CASADI_THROW_ERROR("get_jacobian", e.what());
1018  }
1019  }
std::vector< Matrix< SXElem > > jac(const Dict &opts) const
Construct a complete Jacobian by compression.
Definition: x_function.hpp:442
std::string join(const std::vector< std::string > &l, const std::string &delim)
std::vector< T > vector_select(const std::vector< T > &v, const std::vector< bool > &s, bool invert=false)
Select subset of vector.

◆ get_jit_directory()

std::string casadi::FunctionInternal::get_jit_directory ( const Dict &  jit_options)
staticinherited

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

Definition at line 710 of file function_internal.cpp.

710  {
711  // Start with default temp work dir
712  std::string jit_directory = GlobalOptions::getTempWorkDir();
713 
714  // Get user-specified directory
715  std::string directory;
716  directory = get_from_dict(jit_options, "directory", std::string(""));
717 
718  // What if directory itself is absolute?
719  if (Filesystem::is_absolute(directory)) {
720  // Override
721  jit_directory = directory;
722  } else {
723  jit_directory = jit_directory + directory;
724  if (Filesystem::is_enabled()) {
725  jit_directory = Filesystem::absolute(jit_directory);
726  }
727  }
728 
729  return Filesystem::ensure_trailing_slash(jit_directory);
730  }
static std::string absolute(const std::string &path)
Definition: filesystem.cpp:78
static bool is_absolute(const std::string &path)
Definition: filesystem.cpp:162
static std::string ensure_trailing_slash(const std::string &path)
Definition: filesystem.cpp:155
static bool is_enabled()
Definition: filesystem.cpp:83
static std::string getTempWorkDir()
T get_from_dict(const std::map< std::string, T > &d, const std::string &key, const T &default_value)

References casadi::Filesystem::absolute(), casadi::Filesystem::ensure_trailing_slash(), casadi::get_from_dict(), casadi::GlobalOptions::getTempWorkDir(), casadi::Filesystem::is_absolute(), and casadi::Filesystem::is_enabled().

Referenced by casadi::FunctionInternal::finalize(), and casadi::ShellCompiler::init().

◆ 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 1106 of file function_internal.hpp.

1106  {
1107  return inf;
1108  }
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 1113 of file function_internal.hpp.

1113  {
1114  return -inf;
1115  }

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 237 of file x_function.hpp.

237 { 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 238 of file x_function.hpp.

238 { 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::OnnxFunction, 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 673 of file function_internal.cpp.

673  {
674  if (!derivative_of_.is_null()) {
675  std::string n = derivative_of_.name();
676  if (name_ == "jac_" + n || name_ == "adj1_" + n) {
677  if (i < derivative_of_.n_in()) {
678  // Same as nondifferentiated function
679  return derivative_of_.name_in(i);
680  } else if (i < derivative_of_.n_in() + derivative_of_.n_out()) {
681  // Nondifferentiated output
682  return "out_" + derivative_of_.name_out(i - derivative_of_.n_in());
683  } else {
684  // Adjoint seed
685  return "adj_" + derivative_of_.name_out(i - derivative_of_.n_in()
686  - derivative_of_.n_out());
687  }
688  }
689  }
690  // Default name
691  return "i" + str(i);
692  }
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:1113
const std::string & name() const
Name of the function.
Definition: function.cpp:1504
casadi_int n_out() const
Get the number of function outputs.
Definition: function.cpp:975
casadi_int n_in() const
Get the number of function inputs.
Definition: function.cpp:971
const std::vector< std::string > & name_out() const
Get output scheme.
Definition: function.cpp:1117

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::OnnxFunction, 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 694 of file function_internal.cpp.

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

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 1117 of file function_internal.hpp.

1117  {
1118  return std::vector<double>(nnz_in(ind), 1.);
1119  }

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 1121 of file function_internal.hpp.

1121  {
1122  return std::vector<double>(nnz_out(ind), 1.);
1123  }

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 331 of file sx_function.hpp.

331 { 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 2126 of file function_internal.cpp.

2128  {
2129  if (verbose_) casadi_message(name_ + "::get_partition");
2130  casadi_assert(allow_forward || allow_reverse, "Inconsistent options");
2131 
2132  // Sparsity pattern with transpose
2133  Sparsity &AT = jac_sparsity(oind, iind, compact, symmetric);
2134  Sparsity A = symmetric ? AT : AT.T();
2135 
2136  // Get seed matrices by graph coloring
2137  if (symmetric) {
2138  casadi_assert_dev(enable_forward_ || enable_fd_);
2139  casadi_assert_dev(allow_forward);
2140 
2141  // Star coloring if symmetric
2142  if (verbose_) casadi_message("FunctionInternal::getPartition star_coloring");
2143  D1 = A.star_coloring();
2144  if (verbose_) {
2145  casadi_message("Star coloring completed: " + str(D1.size2())
2146  + " directional derivatives needed ("
2147  + str(A.size1()) + " without coloring).");
2148  }
2149 
2150  } else {
2151  casadi_assert_dev(enable_forward_ || enable_fd_ || enable_reverse_);
2152  // Get weighting factor
2153  double w = ad_weight();
2154 
2155  // Which AD mode?
2156  if (w==1) allow_forward = false;
2157  if (w==0) allow_reverse = false;
2158  casadi_assert(allow_forward || allow_reverse, "Conflicting ad weights");
2159 
2160  // Best coloring encountered so far (relatively tight upper bound)
2161  double best_coloring = std::numeric_limits<double>::infinity();
2162 
2163  // Test forward mode first?
2164  bool test_fwd_first = allow_forward && w*static_cast<double>(A.size1()) <=
2165  (1-w)*static_cast<double>(A.size2());
2166  casadi_int mode_fwd = test_fwd_first ? 0 : 1;
2167 
2168  // Test both coloring modes
2169  for (casadi_int mode=0; mode<2; ++mode) {
2170  // Is this the forward mode?
2171  bool fwd = mode==mode_fwd;
2172 
2173  // Skip?
2174  if (!allow_forward && fwd) continue;
2175  if (!allow_reverse && !fwd) continue;
2176 
2177  // Perform the coloring
2178  if (fwd) {
2179  if (verbose_) casadi_message("Unidirectional coloring (forward mode)");
2180  bool d = best_coloring>=w*static_cast<double>(A.size1());
2181  casadi_int max_colorings_to_test =
2182  d ? A.size1() : static_cast<casadi_int>(floor(best_coloring/w));
2183  D1 = AT.uni_coloring(A, max_colorings_to_test);
2184  if (D1.is_null()) {
2185  if (verbose_) {
2186  casadi_message("Forward mode coloring interrupted (more than "
2187  + str(max_colorings_to_test) + " needed).");
2188  }
2189  } else {
2190  if (verbose_) {
2191  casadi_message("Forward mode coloring completed: "
2192  + str(D1.size2()) + " directional derivatives needed ("
2193  + str(A.size1()) + " without coloring).");
2194  }
2195  D2 = Sparsity();
2196  best_coloring = w*static_cast<double>(D1.size2());
2197  }
2198  } else {
2199  if (verbose_) casadi_message("Unidirectional coloring (adjoint mode)");
2200  bool d = best_coloring>=(1-w)*static_cast<double>(A.size2());
2201  casadi_int max_colorings_to_test =
2202  d ? A.size2() : static_cast<casadi_int>(floor(best_coloring/(1-w)));
2203 
2204  D2 = A.uni_coloring(AT, max_colorings_to_test);
2205  if (D2.is_null()) {
2206  if (verbose_) {
2207  casadi_message("Adjoint mode coloring interrupted (more than "
2208  + str(max_colorings_to_test) + " needed).");
2209  }
2210  } else {
2211  if (verbose_) {
2212  casadi_message("Adjoint mode coloring completed: "
2213  + str(D2.size2()) + " directional derivatives needed ("
2214  + str(A.size2()) + " without coloring).");
2215  }
2216  D1 = Sparsity();
2217  best_coloring = (1-w)*static_cast<double>(D2.size2());
2218  }
2219  }
2220  }
2221 
2222  }
2223  }
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 1128 of file function_internal.hpp.

1128  {
1129  return eps;
1130  }

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.

895  {
896  try {
897  // Seeds
898  std::vector<std::vector<MatType> > aseed = symbolicAdjSeed(nadj, out_), asens;
899 
900  // Evaluate symbolically
901  static_cast<const DerivedType*>(this)->ad_reverse(aseed, asens);
902 
903  // All inputs of the return function
904  std::vector<MatType> ret_in(inames.size());
905  std::copy(in_.begin(), in_.end(), ret_in.begin());
906  for (casadi_int i=0; i<n_out_; ++i) {
907  ret_in.at(n_in_ + i) = MatType::sym(inames[n_in_+i], Sparsity(out_.at(i).size()));
908  }
909  std::vector<MatType> v(nadj);
910  for (casadi_int i=0; i<n_out_; ++i) {
911  for (casadi_int d=0; d<nadj; ++d) v[d] = aseed[d][i];
912  ret_in.at(n_in_ + n_out_ + i) = horzcat(v);
913  }
914 
915  // All outputs of the return function
916  std::vector<MatType> ret_out(onames.size());
917  for (casadi_int i=0; i<n_in_; ++i) {
918  if (is_diff_in_[i]) {
919  // Concatenate sensitivities, correct sparsity pattern if needed
920  for (casadi_int d=0; d<nadj; ++d) v[d] = asens[d][i];
921  ret_out.at(i) = ensure_stacked(horzcat(v), sparsity_in(i), nadj);
922  } else {
923  // Input is non-differentable
924  ret_out.at(i) = MatType(size1_in(i), size2_in(i) * nadj);
925  }
926  }
927 
928  Dict options = opts;
929  options["allow_duplicate_io_names"] = true;
930  // Assemble function and return
931  return Function(name, ret_in, ret_out, inames, onames, options);
932  } catch (std::exception& e) {
933  CASADI_THROW_ERROR("get_reverse", e.what());
934  }
935  }
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 245 of file x_function.hpp.

245 { 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 246 of file x_function.hpp.

246 { 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::XpressInterface, casadi::WorhpInterface, casadi::UnoInterface, casadi::SuperscsInterface, casadi::SundialsInterface, casadi::SnoptInterface, casadi::SLEQPInterface, casadi::QpoasesInterface, casadi::ProxqpInterface, casadi::PiqpInterface, casadi::OsqpInterface, casadi::OoqpInterface, casadi::MosekInterface, casadi::MadnlpInterface, casadi::KnitroInterface, casadi::IpoptInterface, casadi::HpmpcInterface, casadi::HpipmInterface, casadi::HighsInterface, casadi::GurobiInterface, casadi::FatropInterface, casadi::FatropConicInterface, casadi::DaqpInterface, casadi::CplexInterface, casadi::ConoptInterface, casadi::ClpInterface, casadi::ClarabelInterface, casadi::MadmpecInterface, casadi::CbcInterface, casadi::BonminInterface, casadi::AlpaqaInterface, casadi::Rootfinder, casadi::OracleFunction, casadi::Nlpsol, and casadi::MXFunction.

Definition at line 3226 of file function_internal.cpp.

3226  {
3227  Dict stats = ProtoFunction::get_stats(mem);
3228  auto *m = static_cast<FunctionMemory*>(mem);
3229  casadi_assert(m->stats_available,
3230  "No stats available: Function '" + name_ + "' not set up. "
3231  "To get statistics, first evaluate it numerically.");
3232  return stats;
3233  }
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 306 of file function_internal.hpp.

306 { return ""; }

◆ getCount()

Definition at line 60 of file generic_shared_internal.hpp.

210  {
211  return static_cast<const Internal*>(this)->count;
212  }

◆ 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 205 of file x_function.hpp.

205 { 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 437 of file function_internal.hpp.

437 { 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 161 of file sx_function.hpp.

161 { 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 371 of file function_internal.hpp.

371 {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 3912 of file function_internal.cpp.

3912  {
3913  return ind<mem_.size();
3914  }

◆ 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 1113 of file function_internal.cpp.

1113  {
1114  return get_options().find(option_name) != nullptr;
1115  }
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 1162 of file function_internal.hpp.

1162  {
1163  for (casadi_int i=0; i<name_in_.size(); ++i) {
1164  if (name_in_[i]==name) return i;
1165  }
1166  casadi_error("FunctionInternal::index_in: could not find entry \""
1167  + name + "\". Available names are: " + str(name_in_) + ".");
1168  return -1;
1169  }

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 1174 of file function_internal.hpp.

1174  {
1175  for (casadi_int i=0; i<name_out_.size(); ++i) {
1176  if (name_out_[i]==name) return i;
1177  }
1178  casadi_error("FunctionInternal::index_out: could not find entry \""
1179  + name + "\". Available names are: " + str(name_out_) + ".");
1180  return -1;
1181  }

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 514 of file sx_function.cpp.

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

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(), dump_trace_, 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::FunctionInternal::jit_, 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 885 of file sx_function.cpp.

885  {
887  copy_elision_.resize(algorithm_.size(), false);
888  return;
889  }
890  // Perform copy elision (codegen-only)
891  // Remove nodes that only serve to compose CALL inputs
892 
893  // For work vector elements, store the arg source (-1 for no trivial source)
894  std::vector<int> arg_i(worksize_, -1);
895  std::vector<int> nz_i(worksize_, -1);
896 
897  // Which algel corresponds to this source?
898  std::vector<casadi_int> alg_i(worksize_, -1);
899 
900  // Is this algel to be elided?
901  copy_elision_.resize(algorithm_.size(), false);
902 
903  casadi_int k=0;
904  for (auto&& e : algorithm_) {
905  switch (e.op) {
906  case OP_INPUT:
907  // Make source association
908  arg_i[e.i0] = e.i1;
909  nz_i[e.i0] = e.i2;
910  alg_i[e.i0] = k;
911  copy_elision_[k] = true;
912  break;
913  case OP_OUTPUT:
914  if (arg_i[e.i1]>=0) {
915  copy_elision_[alg_i[e.i1]] = false;
916  }
917  break;
918  case OP_CALL:
919  {
920  auto& m = call_.el[e.i1];
921 
922  // Inspect input arguments
923  casadi_int offset_input = 0;
924  for (casadi_int i=0; i<m.f_n_in; ++i) {
925  // Pattern match results
926  casadi_int arg = -1;
927  casadi_int offset = -1;
928  for (casadi_int j=0; j<m.f_nnz_in[i]; ++j) {
929  casadi_int k = offset_input+j;
930  if (j==0) {
931  arg = arg_i[m.dep[k]];
932  offset = nz_i[m.dep[k]];
933  }
934  if (arg_i[m.dep[k]]==-1) {
935  arg = -1;
936  // Pattern match failed
937  break;
938  }
939  if (nz_i[m.dep[k]]!=offset+j) {
940  arg = -1;
941  // Pattern match failed
942  break;
943  }
944  }
945 
946  // If we cannot perform elision
947  if (arg==-1) {
948  // We need copies for all nonzeros of input i
949  for (casadi_int j=0; j<m.f_nnz_in[i]; ++j) {
950  casadi_int k = offset_input+j;
951  if (arg_i[m.dep[k]]>=0) {
952  copy_elision_[alg_i[m.dep[k]]] = false;
953  }
954  }
955  }
956  // Store pattern match results
957  m.copy_elision_arg[i] = arg;
958  m.copy_elision_offset[i] = offset;
959 
960  offset += m.f_nnz_in[i];
961  offset_input += m.f_nnz_in[i];
962  }
963 
964  // Remove source association of all outputs
965  for (casadi_int i=0; i<m.n_res; ++i) {
966  if (m.res[i]>=0) {
967  arg_i[m.res[i]] = -1;
968  }
969  }
970  }
971  break;
972  case OP_CONST:
973  case OP_PARAMETER:
974  // Remove source association
975  arg_i[e.i0] = -1;
976  break;
977  default:
978  if (arg_i[e.i1]>=0) {
979  copy_elision_[alg_i[e.i1]] = false;
980  }
981  if (!casadi_math<double>::is_unary(e.op)) {
982  if (arg_i[e.i2]>=0) {
983  copy_elision_[alg_i[e.i2]] = false;
984  }
985  }
986  // Remove source association
987  arg_i[e.i0] = -1;
988  }
989  k++;
990  }
991  }
static casadi_int copy_elision_min_size
static bool is_unary(unsigned char op)
Is unary operation?
Definition: calculus.hpp:1623

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::XpressInterface, casadi::WorhpInterface, casadi::UnoInterface, casadi::SuperscsInterface, casadi::SundialsInterface, casadi::KinsolInterface, casadi::IdasInterface, casadi::CvodesInterface, casadi::SnoptInterface, casadi::SlicotExpm, casadi::SlicotDple, casadi::SLEQPInterface, casadi::QpoasesInterface, casadi::ProxqpInterface, casadi::PiqpInterface, casadi::OsqpInterface, casadi::OnnxRuntimeInterface, casadi::MumpsInterface, casadi::MosekInterface, 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::ConoptInterface, casadi::ClpInterface, casadi::ClarabelInterface, casadi::MadmpecInterface, 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 921 of file function_internal.cpp.

921  {
922  auto *m = static_cast<ProtoFunctionMemory*>(mem);
923  if (record_time_) {
924  m->add_stat("total");
925  m->t_total = &m->fstats.at("total");
926  } else {
927  m->t_total = nullptr;
928  }
929  return 0;
930  }

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::OnnxRuntimeInterface::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 217 of file sx_function.hpp.

217  {
218  return algorithm_.at(k).d;
219  }

◆ 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 195 of file sx_function.hpp.

195 { 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 200 of file sx_function.hpp.

200  {
201  auto e = algorithm_.at(k);
202  if (e.op==OP_CALL) {
203  const ExtendedAlgEl& m = call_.el[e.i1];
204  return vector_static_cast<casadi_int>(m.dep);
205  } else if (casadi_math<double>::ndeps(e.op)==2 || e.op==OP_INPUT) {
206  return {e.i1, e.i2};
207  } else if (casadi_math<double>::ndeps(e.op)==1) {
208  return {e.i1};
209  } else {
210  return {};
211  }
212  }

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 3657 of file function_internal.cpp.

3657  {
3658  casadi_error("'instruction_MX' not defined for " + class_name());
3659  }

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 224 of file sx_function.hpp.

224  {
225  auto e = algorithm_.at(k);
226  if (e.op==OP_CALL) {
227  const ExtendedAlgEl& m = call_.el[e.i1];
228  return vector_static_cast<casadi_int>(m.res);
229  } else if (e.op==OP_OUTPUT) {
230  return {e.i0, e.i2};
231  } else {
232  return {e.i0};
233  }
234  }

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 993 of file sx_function.cpp.

993  {
994  std::vector<SXElem> ret(algorithm_.size(), casadi_limits<SXElem>::nan);
995 
996  std::vector<SXElem>::iterator it=ret.begin();
997 
998  // Iterator to the binary operations
999  std::vector<SXElem>::const_iterator b_it = operations_.begin();
1000 
1001  // Iterator to stack of constants
1002  std::vector<SXElem>::const_iterator c_it = constants_.begin();
1003 
1004  // Iterator to free variables
1005  std::vector<SXElem>::const_iterator p_it = free_vars_.begin();
1006 
1007  // Evaluate algorithm
1008  if (verbose_) casadi_message("Evaluating algorithm forward");
1009  for (auto&& a : algorithm_) {
1010  switch (a.op) {
1011  case OP_INPUT:
1012  case OP_OUTPUT:
1013  it++;
1014  break;
1015  case OP_CONST:
1016  *it++ = *c_it++;
1017  break;
1018  case OP_PARAMETER:
1019  *it++ = *p_it++;
1020  break;
1021  default:
1022  *it++ = *b_it++;
1023  }
1024  }
1025  casadi_assert(it==ret.end(), "Dimension mismatch");
1026  return ret;
1027  }
static const SXElem nan
Definition: sx_elem.hpp:332

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 1871 of file sx_function.cpp.

1871  {
1872  return type=="SXFunction" || (recursive && XFunction<SXFunction,
1873  SX, SXNode>::is_a(type, recursive));
1874  }
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:286

References SXFunction().

◆ is_smooth()

bool casadi::SXFunction::is_smooth ( ) const

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

Definition at line 162 of file sx_function.cpp.

162  {
163  // Go through all nodes and check if any node is non-smooth
164  for (auto&& a : algorithm_) {
165  if (!operation_checker<SmoothChecker>(a.op)) {
166  return false;
167  }
168  }
169  return true;
170  }

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 210 of file x_function.hpp.

1175  {
1176  // Check if arguments matches the input expressions, in which case
1177  // the output is known to be the output expressions
1178  const casadi_int checking_depth = 2;
1179  for (casadi_int i=0; i<arg.size(); ++i) {
1180  if (!is_equal(arg[i], in_[i], checking_depth)) {
1181  return false;
1182  }
1183  }
1184  return true;
1185  }
bool is_equal(double x, double y, casadi_int depth=0)
Definition: calculus.hpp:287

◆ 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.

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

◆ jac_is_symm()

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

Definition at line 1973 of file function_internal.cpp.

1973  {
1974  // If derivative expression
1975  if (!derivative_of_.is_null()) {
1976  std::string n = derivative_of_.name();
1977  // Reverse move
1978  if (name_ == "adj1_" + n) {
1979  if (iind == oind) return true;
1980  }
1981  }
1982  // Not symmetric by default
1983  return false;
1984  }

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 2061 of file function_internal.cpp.

2062  {
2063 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
2064  // Safe access to jac_sparsity_
2065  std::lock_guard<std::mutex> lock(jac_sparsity_mtx_);
2066 #endif // CASADI_WITH_THREADSAFE_SYMBOLICS
2067  // If first call, allocate cache
2068  for (bool c : {false, true}) {
2069  if (jac_sparsity_[c].empty()) jac_sparsity_[c].resize(n_in_ * n_out_);
2070  }
2071  // Flat index
2072  casadi_int ind = iind + oind * n_in_;
2073  // Reference to the block
2074  Sparsity& jsp = jac_sparsity_[compact].at(ind);
2075  // If null, generate
2076  if (jsp.is_null()) {
2077  // Use (non)-compact pattern, if given
2078  Sparsity& jsp_other = jac_sparsity_[!compact].at(ind);
2079  if (!jsp_other.is_null()) {
2080  jsp = compact ? to_compact(oind, iind, jsp_other) : from_compact(oind, iind, jsp_other);
2081  } else {
2082  // Generate pattern
2083  Sparsity sp;
2084  bool sp_is_compact;
2085  if (!is_diff_out_.at(oind) || !is_diff_in_.at(iind)) {
2086  // All-zero sparse
2087  sp = Sparsity(nnz_out(oind), nnz_in(iind));
2088  sp_is_compact = true;
2089  } else {
2090  // Use internal routine to determine sparsity
2091  if (has_spfwd() || has_sprev() || has_jac_sparsity(oind, iind)) {
2092  sp = get_jac_sparsity(oind, iind, symmetric);
2093  }
2094  // If null, dense
2095  if (sp.is_null()) sp = Sparsity::dense(nnz_out(oind), nnz_in(iind));
2096  // Is the return the compact pattern?
2097  sp_is_compact = sp.size1() == nnz_out(oind) && sp.size2() == nnz_in(iind);
2098  }
2099  // Save to cache and convert if needed
2100  if (sp_is_compact == compact) {
2101  jsp = sp;
2102  } else {
2103  jsp_other = sp;
2104  jsp = compact ? to_compact(oind, iind, sp) : from_compact(oind, iind, sp);
2105  }
2106  }
2107  }
2108 
2109  // Make sure the Jacobian is symmetric if requested, cf. #1522, #3074, #3134
2110  if (symmetric) {
2111  if (compact) {
2112  Sparsity sp = from_compact(oind, iind, jsp);
2113  if (!sp.is_symmetric()) {
2114  sp = sp * sp.T();
2115  jsp = to_compact(oind, iind, sp);
2116  }
2117  } else {
2118  if (!jsp.is_symmetric()) jsp = jsp * jsp.T();
2119  }
2120  }
2121 
2122  // Return a reference to the block
2123  return jsp;
2124  }
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 2461 of file function_internal.cpp.

2461  {
2462  // Used wrapped function if jacobian not available
2463  if (!has_jacobian()) {
2464  // Derivative information must be available
2465  casadi_assert(has_derivative(),
2466  "Derivatives cannot be calculated for " + name_);
2467  return wrap().jacobian();
2468  }
2469  // Retrieve/generate cached
2470  Function f;
2471  std::string fname = "jac_" + name_;
2472  if (!incache(fname, f)) {
2473  // Names of inputs
2474  std::vector<std::string> inames;
2475  for (casadi_int i=0; i<n_in_; ++i) inames.push_back(name_in_[i]);
2476  for (casadi_int i=0; i<n_out_; ++i) inames.push_back("out_" + name_out_[i]);
2477  // Names of outputs
2478  std::vector<std::string> onames;
2479  onames.reserve(n_in_ * n_out_);
2480  for (size_t oind = 0; oind < n_out_; ++oind) {
2481  for (size_t iind = 0; iind < n_in_; ++iind) {
2482  onames.push_back("jac_" + name_out_[oind] + "_" + name_in_[iind]);
2483  }
2484  }
2485  // Options
2487  opts["derivative_of"] = self();
2488  // Generate derivative function
2489  casadi_assert_dev(enable_jacobian_);
2490  f = get_jacobian(fname, inames, onames, opts);
2491  // Consistency checks
2492  casadi_assert(f.n_in() == inames.size(),
2493  "Mismatching input signature, expected " + str(inames));
2494  casadi_assert(f.n_out() == onames.size(),
2495  "Mismatching output signature, expected " + str(onames));
2496  // Save to cache
2497  tocache_if_missing(f);
2498  }
2499  return f;
2500  }
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:1068

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 950 of file function_internal.hpp.

950 {}

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 1200 of file function_internal.cpp.

1200  {
1201  Function f;
1202  if (parallelization=="serial") {
1203  // Serial maps are cached
1204  std::string fname = "map" + str(n) + "_" + name_;
1205  if (!incache(fname, f)) {
1206  // Create new serial map
1207  f = Map::create(parallelization, self(), n);
1208  casadi_assert_dev(f.name()==fname);
1209  // Save in cache
1210  tocache_if_missing(f);
1211  }
1212  } else {
1213  // Non-serial maps are not cached
1214  f = Map::create(parallelization, self(), n);
1215  }
1216  return f;
1217  }
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 3670 of file function_internal.cpp.

3671  {
3672  if (x.empty()) return x;
3673  // Check number of arguments
3674  casadi_assert(x.size()==n_in_, "mapsum_mx: Wrong number_i of arguments");
3675  // Number of parallel calls
3676  casadi_int npar = 1;
3677  // Check/replace arguments
3678  std::vector<MX> x_mod(x.size());
3679  for (casadi_int i=0; i<n_in_; ++i) {
3680  if (check_mat(x[i].sparsity(), sparsity_in_[i], npar)) {
3681  x_mod[i] = replace_mat(x[i], sparsity_in_[i], npar);
3682  } else {
3683  // Mismatching sparsity: The following will throw an error message
3684  npar = 0;
3685  check_arg(x, npar);
3686  }
3687  }
3688 
3689  casadi_int n = 1;
3690  for (casadi_int i=0; i<x_mod.size(); ++i) {
3691  n = std::max(x_mod[i].size2() / size2_in(i), n);
3692  }
3693 
3694  std::vector<casadi_int> reduce_in;
3695  for (casadi_int i=0; i<x_mod.size(); ++i) {
3696  if (x_mod[i].size2()/size2_in(i)!=n) {
3697  reduce_in.push_back(i);
3698  }
3699  }
3700 
3701  Function ms = self().map("mapsum", parallelization, n, reduce_in, range(n_out_));
3702 
3703  // Call the internal function
3704  return ms(x_mod);
3705  }
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 1808 of file function_internal.hpp.

1808  {
1809  check_arg(arg, npar);
1810  for (casadi_int i=0; i<n_in_; ++i) {
1811  if (arg.at(i).size1()!=size1_in(i)) return false;
1812  if (arg.at(i).size2()!=size2_in(i) && arg.at(i).size2()!=npar*size2_in(i)) return false;
1813  }
1814  return true;
1815  }

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 1818 of file function_internal.hpp.

1818  {
1819  check_res(res, npar);
1820  for (casadi_int i=0; i<n_out_; ++i) {
1821  if (res.at(i).size1()!=size1_out(i)) return false;
1822  if (res.at(i).size2()!=size2_out(i) && res.at(i).size2()!=npar*size2_out(i)) return false;
1823  }
1824  return true;
1825  }
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 3905 of file function_internal.cpp.

3905  {
3906 #ifdef CASADI_WITH_THREAD
3907  std::lock_guard<std::mutex> lock(mtx_);
3908 #endif //CASADI_WITH_THREAD
3909  return mem_.at(ind);
3910  }

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 3620 of file function_internal.cpp.

3621  {
3622  }

◆ 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 3600 of file function_internal.cpp.

3600  {
3601  std::vector<MX> ret(n_in_);
3602  for (casadi_int i=0; i<ret.size(); ++i) {
3603  ret[i] = mx_in(i);
3604  }
3605  return ret;
3606  }
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 3592 of file function_internal.cpp.

3592  {
3593  return MX::sym(name_in_.at(ind), sparsity_in(ind));
3594  }
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 3608 of file function_internal.cpp.

3608  {
3609  std::vector<MX> ret(n_out_);
3610  for (casadi_int i=0; i<ret.size(); ++i) {
3611  ret[i] = mx_out(i);
3612  }
3613  return ret;
3614  }
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 190 of file sx_function.hpp.

190 { 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 239 of file sx_function.hpp.

239 { 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 2420 of file function_internal.cpp.

2420  {
2421  casadi_int ret=0;
2422  for (casadi_int iind=0; iind<n_in_; ++iind) ret += nnz_in(iind);
2423  return ret;
2424  }

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::FunctionInternal::open_trace(), casadi::ImplicitToNlp::set_work(), casadi::CbcInterface::solve(), casadi::ClpInterface::solve(), casadi::CplexInterface::solve(), casadi::OoqpInterface::solve(), casadi::PiqpInterface::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 1010 of file function_internal.hpp.

1010 { 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 1012 of file function_internal.hpp.

1012 { 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 2432 of file function_internal.cpp.

2432  {
2433  casadi_int ret=0;
2434  for (casadi_int iind=0; iind<n_in_; ++iind) ret += numel_in(iind);
2435  return ret;
2436  }

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 1020 of file function_internal.hpp.

1020 { 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 2438 of file function_internal.cpp.

2438  {
2439  casadi_int ret=0;
2440  for (casadi_int oind=0; oind<n_out_; ++oind) ret += numel_out(oind);
2441  return ret;
2442  }

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 1021 of file function_internal.hpp.

1021 { 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 3760 of file function_internal.cpp.

3760  {
3761  // Disallow parallel inputs
3762  casadi_int npar = -1;
3763  if (!matching_arg(arg, npar)) {
3764  return nz_in(replace_arg(arg, npar));
3765  }
3766 
3767  std::vector<DM> arg2 = project_arg(arg, 1);
3768  std::vector<double> ret(nnz_in());
3769  casadi_int offset = 0;
3770  for (casadi_int i=0;i<n_in_;++i) {
3771  const double* e = arg2.at(i).ptr();
3772  std::copy(e, e+nnz_in(i), ret.begin()+offset);
3773  offset+= nnz_in(i);
3774  }
3775  return ret;
3776  }

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_activity(), 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 3730 of file function_internal.cpp.

3730  {
3731  casadi_assert(nnz_in()==arg.size(),
3732  "Dimension mismatch. Expecting " + str(nnz_in()) +
3733  ", got " + str(arg.size()) + " instead.");
3734 
3735  std::vector<DM> ret = dm_in();
3736  casadi_int offset = 0;
3737  for (casadi_int i=0;i<n_in_;++i) {
3738  DM& r = ret.at(i);
3739  std::copy(arg.begin()+offset, arg.begin()+offset+nnz_in(i), r.ptr());
3740  offset+= nnz_in(i);
3741  }
3742  return ret;
3743  }
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 3778 of file function_internal.cpp.

3778  {
3779  // Disallow parallel inputs
3780  casadi_int npar = -1;
3781  if (!matching_res(res, npar)) {
3782  return nz_out(replace_res(res, npar));
3783  }
3784 
3785  std::vector<DM> res2 = project_res(res, 1);
3786  std::vector<double> ret(nnz_out());
3787  casadi_int offset = 0;
3788  for (casadi_int i=0;i<n_out_;++i) {
3789  const double* e = res2.at(i).ptr();
3790  std::copy(e, e+nnz_out(i), ret.begin()+offset);
3791  offset+= nnz_out(i);
3792  }
3793  return ret;
3794  }
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_activity(), 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 3745 of file function_internal.cpp.

3745  {
3746  casadi_assert(nnz_out()==res.size(),
3747  "Dimension mismatch. Expecting " + str(nnz_out()) +
3748  ", got " + str(res.size()) + " instead.");
3749 
3750  std::vector<DM> ret = dm_out();
3751  casadi_int offset = 0;
3752  for (casadi_int i=0;i<n_out_;++i) {
3753  DM& r = ret.at(i);
3754  std::copy(res.begin()+offset, res.begin()+offset+nnz_out(i), r.ptr());
3755  offset+= nnz_out(i);
3756  }
3757  return ret;
3758  }

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

◆ open_trace()

std::unique_ptr< std::ostream > casadi::FunctionInternal::open_trace ( const double **  arg,
casadi_int  dump_id 
) const
protectedinherited

Definition at line 847 of file function_internal.cpp.

848  {
849  if (dump_id < 0) dump_id = get_dump_id();
850  std::stringstream filename;
851  filename << dump_dir_ << filesep() << name_ << "." << std::setfill('0')
852  << std::setw(6) << dump_id << ".trace.jsonl";
853  auto output = Filesystem::ofstream_ptr(filename.str());
854  std::ostream& trace = *output;
855  normalized_setup(trace);
856  trace << "{\"event\":\"header\",\"format\":\"casadi_trace\",\"version\":1,"
857  << "\"function\":\"" << name_ << "\",\"type\":\"" << class_name()
858  << "\",\"dump_id\":" << dump_id << "}\n";
859  trace << "{\"event\":\"inputs\",\"values\":[";
860  for (casadi_int i = 0; i < n_in_; ++i) {
861  if (i) trace << ",";
862  trace_values(trace, arg[i], nnz_in(i));
863  }
864  trace << "]}\n";
865  return output;
866  }
std::string filesep()
Definition: casadi_os.cpp:71
std::string filename(const std::string &path)
Definition: ghc.cpp:55

References casadi::SharedObjectInternal::class_name(), casadi::FunctionInternal::dump_dir_, casadi::filename(), casadi::filesep(), casadi::FunctionInternal::n_in_, casadi::ProtoFunction::name_, casadi::FunctionInternal::nnz_in(), casadi::normalized_setup(), casadi::Filesystem::ofstream_ptr(), and casadi::FunctionInternal::trace_values().

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

◆ 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 3997 of file function_internal.cpp.

3997  {
3998  casadi_error("'oracle' not defined for " + class_name());
3999  static Function singleton;
4000  return singleton;
4001  }

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 2126 of file sx_function.cpp.

2126  {
2127 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
2128  std::lock_guard<std::mutex> lock(SX::get_mutex_temp());
2129 #endif // CASADI_WITH_THREADSAFE_SYMBOLICS
2130  // Stack used to sort the computational graph
2131  std::stack<SXNode*> s;
2132 
2133  // All nodes
2134  std::vector<SXNode*> nodes;
2135 
2136  // Add the list of nodes
2137  casadi_int ind=0;
2138  for (auto it = expr.begin(); it != expr.end(); ++it, ++ind) {
2139  casadi_int nz=0;
2140  for (auto itc = (*it)->begin(); itc != (*it)->end(); ++itc, ++nz) {
2141  // Add outputs to the list
2142  s.push(itc->get());
2144  }
2145  }
2146 
2147  // Clear temporary markers
2148  for (casadi_int i=0; i<nodes.size(); ++i) {
2149  nodes[i]->temp = 0;
2150  }
2151 
2152  std::vector<SX> ret(nodes.size());
2153  for (casadi_int i=0; i<nodes.size(); ++i) {
2154  ret[i] = SXElem::create(nodes[i]);
2155  }
2156 
2157  return ret;
2158  }

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 4158 of file function_internal.cpp.

4158  {
4159  // Variable number of arguments
4160  va_list args;
4161  va_start(args, fmt);
4162  // Static & dynamic buffers
4163  char buf[256];
4164  size_t buf_sz = sizeof(buf);
4165  char* buf_dyn = nullptr;
4166  // Try to print with a small buffer
4167  casadi_int n = vsnprintf(buf, buf_sz, fmt, args);
4168  // Need a larger buffer?
4169  if (n>static_cast<casadi_int>(buf_sz)) {
4170  buf_sz = static_cast<size_t>(n+1);
4171  buf_dyn = new char[buf_sz];
4172  n = vsnprintf(buf_dyn, buf_sz, fmt, args);
4173  }
4174  // Print buffer content
4175  if (n>=0) uout() << (buf_dyn ? buf_dyn : buf) << std::flush;
4176  // Cleanup
4177  delete[] buf_dyn;
4178  va_end(args);
4179  // Throw error if failure
4180  casadi_assert(n>=0, "Print failure while processing '" + std::string(fmt) + "'");
4181  }

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 171 of file sx_function.cpp.

171  {
172  std::stringstream stream;
173  if (a.op==OP_OUTPUT) {
174  stream << "output[" << a.i0 << "][" << a.i2 << "] = @" << a.i1;
175  } else if (a.op==OP_CALL) {
176  const ExtendedAlgEl& m = call_.el.at(a.i1);
177  stream << "[";
178  casadi_int k = 0;
179  for (casadi_int i=0; i<m.f.n_out(); ++i) {
180  if (m.f.nnz_out(i)>1) stream << "[";
181  for (casadi_int j=0; j<m.f.nnz_out(i); ++j) {
182  int el = m.res[k++];
183  if (el>=0) {
184  stream << "@" << el;
185  } else {
186  stream << "NULL";
187  }
188  if (j<m.f.nnz_out(i)-1) stream << ",";
189  }
190  if (m.f.nnz_out(i)>1) stream << "]";
191  if (i<m.f.n_out()-1) stream << ",";
192  }
193  stream << "] = ";
194  stream << m.f.name() << "(";
195  k = 0;
196  for (casadi_int i=0; i<m.f.n_in(); ++i) {
197  if (m.f.nnz_in(i)==0) stream << "0x0";
198  if (m.f.nnz_in(i)>1) stream << "[";
199  for (casadi_int j=0; j<m.f.nnz_in(i); ++j) {
200  stream << "@" << m.dep[k++];
201  if (j<m.f.nnz_in(i)-1) stream << ",";
202  }
203  if (m.f.nnz_in(i)>1) stream << "]";
204  if (i<m.f.n_in()-1) stream << ",";
205  }
206  stream << ")";
207  } else {
208  stream << "@" << a.i0 << " = ";
209  if (a.op==OP_INPUT) {
210  stream << "input[" << a.i1 << "][" << a.i2 << "]";
211  } else {
212  if (a.op==OP_CONST) {
213  stream << a.d;
214  } else if (a.op==OP_PARAMETER) {
215  stream << free_vars_[a.i1];
216  } else {
217  casadi_int ndep = casadi_math<double>::ndeps(a.op);
218  stream << casadi_math<double>::pre(a.op);
219  for (casadi_int c=0; c<ndep; ++c) {
220  if (c==0) {
221  stream << "@" << a.i1;
222  } else {
223  stream << casadi_math<double>::sep(a.op);
224  stream << "@" << a.i2;
225  }
226 
227  }
228  stream << casadi_math<double>::post(a.op);
229  }
230  }
231  }
232  return stream.str();
233  }

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 306 of file sx_function.cpp.

306  {
307  if (el.op==OP_INPUT || el.op==OP_OUTPUT || el.op==OP_CONST) return;
308  g << g.printf(name_ + ":" + str(k) + ": " + print(el) + " inputs:\\n") << "\n";
309  if (el.op==OP_CALL) {
310  const ExtendedAlgEl& m = call_.el[el.i1];
311  g << g.print_vector(m.f.nnz_in(), "arg[" + str(n_in_) + "]");
312  g << g.printf("\\n");
313  } else {
314  casadi_int ndeps = casadi_math<double>::ndeps(el.op);
315  if (ndeps==1) {
316  g << g.printf("0: %.16e\\n", g.sx_work(el.i1));
317  } else if (ndeps==2) {
318  g << g.printf("0: %.16e\\n1: %.16e\\n", g.sx_work(el.i1), g.sx_work(el.i2));
319  }
320  }
321  g << "\n";
322  }

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 267 of file sx_function.cpp.

268  {
269  if (el.op==OP_INPUT || el.op==OP_OUTPUT || el.op==OP_CONST) return;
270  stream << name_ << ":" << k << ": " << print(el) << " inputs:" << std::endl;
271 
272  // Default dependencies
273  const int* dep = &el.i1;
274  casadi_int ndeps = casadi_math<double>::ndeps(el.op);
275 
276  // Call node overrides these defaults
277  if (el.op==OP_CALL) {
278  const ExtendedAlgEl& e = call_.el.at(el.i1);
279  ndeps = e.n_dep;
280  dep = get_ptr(e.dep);
281  stream << "[";
282  for (size_t i = 0; i < ndeps; ++i) {
283  if (i>0) stream << ", ";
284  if (print_canonical_) {
285  print_canonical(stream, w[dep[i]]);
286  } else {
287  DM::print_scalar(stream, w[dep[i]]);
288  }
289  }
290  stream << "]";
291  stream << std::endl;
292  return;
293  }
294 
295  for (size_t i = 0; i < ndeps; ++i) {
296  stream << i << ": ";
297  if (print_canonical_) {
298  print_canonical(stream, w[dep[i]]);
299  } else {
300  DM::print_scalar(stream, w[dep[i]]);
301  }
302  stream << std::endl;
303  }
304  }
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 966 of file function_internal.cpp.

966  {
967  StreamStateGuard backup(stream);
968  normalized_setup(stream);
969  if (nz) {
970  stream << "[";
971  for (casadi_int i=0; i<sz; ++i) {
972  if (i>0) stream << ", ";
973  normalized_out(stream, nz[i]);
974  }
975  stream << "]";
976  } else {
977  stream << "NULL";
978  }
979  }

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 981 of file function_internal.cpp.

982  {
983  StreamStateGuard backup(stream);
984  normalized_setup(stream);
985  if (nz) {
986  if (!sp.is_scalar(true)) {
987  stream << sp.dim(false) << ": ";
988  stream << "[";
989  }
990  for (casadi_int i=0; i<sp.nnz(); ++i) {
991  if (i>0) stream << ", ";
992  normalized_out(stream, nz[i]);
993  }
994  if (!sp.is_scalar(true)) {
995  stream << "]";
996  if (!sp.is_dense()) {
997  stream << ", colind: [";
998  for (casadi_int i=0; i<sp.size2()+1; ++i) {
999  if (i>0) stream << ", ";
1000  stream << sp.colind()[i];
1001  }
1002  stream << "]";
1003  stream << ", row: [";
1004  for (casadi_int i=0; i<sp.nnz(); ++i) {
1005  if (i>0) stream << ", ";
1006  stream << sp.row()[i];
1007  }
1008  stream << "]";
1009  }
1010  }
1011  } else {
1012  stream << "NULL";
1013  }
1014  }

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 1016 of file function_internal.cpp.

1016  {
1017  StreamStateGuard backup(stream);
1018  normalized_setup(stream);
1019  normalized_out(stream, a);
1020  }

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 1092 of file function_internal.cpp.

1092  {
1093  stream << " Number of inputs: " << n_in_ << std::endl;
1094  for (casadi_int i=0; i<n_in_; ++i) {
1095  stream << " Input " << i << " (\"" << name_in_[i] << "\"): "
1096  << sparsity_in_[i].dim() << std::endl;
1097  }
1098  stream << " Number of outputs: " << n_out_ << std::endl;
1099  for (casadi_int i=0; i<n_out_; ++i) {
1100  stream << " Output " << i << " (\"" << name_out_[i] << "\"): "
1101  << sparsity_out_[i].dim() << std::endl;
1102  }
1103  }

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 932 of file function_internal.cpp.

932  {
933  stream << "Function " << name_ << " (" << this << ")" << std::endl;
934  for (casadi_int i=0; i<n_in_; ++i) {
935  stream << "Input " << i << " (" << name_in_[i] << "): ";
936  if (arg[i]) {
937  if (print_canonical_) {
938  print_canonical(stream, sparsity_in_[i], arg[i]);
939  } else {
940  DM::print_default(stream, sparsity_in_[i], arg[i], truncate);
941  }
942  stream << std::endl;
943  } else {
944  stream << "NULL" << std::endl;
945  }
946  }
947  }
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 1109 of file function_internal.cpp.

1109  {
1110  get_options().print_one(name, stream);
1111  }
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 1105 of file function_internal.cpp.

1105  {
1106  get_options().print_all(stream);
1107  }
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 949 of file function_internal.cpp.

949  {
950  stream << "Function " << name_ << " (" << this << ")" << std::endl;
951  for (casadi_int i=0; i<n_out_; ++i) {
952  stream << "Output " << i << " (" << name_out_[i] << "): ";
953  if (res[i]) {
954  if (print_canonical_) {
955  print_canonical(stream, sparsity_out_[i], res[i]);
956  } else {
957  DM::print_default(stream, sparsity_out_[i], res[i], truncate);
958  }
959  stream << std::endl;
960  } else {
961  stream << "NULL" << std::endl;
962  }
963  }
964  }

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 324 of file sx_function.cpp.

324  {
325  if (el.op==OP_INPUT || el.op==OP_OUTPUT) return;
326  g << g.printf(name_ + ":" + str(k) + ": " + print(el) + " outputs:\\n") << "\n";
327  if (el.op==OP_CALL) {
328  const ExtendedAlgEl& m = call_.el[el.i1];
329  g << g.print_vector(m.f.nnz_out(), "w+" + str(m.f.nnz_in()));
330  g << g.printf("\\n");
331  } else {
332  g << g.printf("0: %.16e\\n", g.sx_work(el.i0));
333  }
334  g << "\n";
335  }

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 337 of file sx_function.cpp.

338  {
339  if (el.op==OP_INPUT || el.op==OP_OUTPUT) return;
340  stream << name_ << ":" << k << ": " << print(el) << " outputs:" << std::endl;
341 
342  // Default outputs
343  const int* res = &el.i0;
344  casadi_int nres = 1;
345 
346  // Call node overrides these defaults
347  if (el.op==OP_CALL) {
348  const ExtendedAlgEl& e = call_.el.at(el.i1);
349  nres = e.n_res;
350  res = get_ptr(e.res);
351  stream << "[";
352  for (size_t i = 0; i < nres; ++i) {
353  if (i>0) stream << ", ";
354  if (print_canonical_) {
355  print_canonical(stream, w[res[i]]);
356  } else {
357  DM::print_scalar(stream, w[res[i]]);
358  }
359  }
360  stream << "]";
361  stream << std::endl;
362  return;
363  }
364 
365  for (size_t i = 0; i < nres; ++i) {
366  stream << i << ": ";
367  if (print_canonical_) {
368  print_canonical(stream, w[res[i]]);
369  } else {
370  DM::print_scalar(stream, w[res[i]]);
371  }
372  stream << std::endl;
373  }
374 
375  }

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 4078 of file function_internal.cpp.

4078  {
4079  if (!print_time_) return;
4080  // Length of the name being printed
4081  size_t name_len=0;
4082  for (auto &&s : fstats) {
4083  name_len = std::max(s.first.size(), name_len);
4084  }
4085  name_len = std::max(name_.size(), name_len);
4086 
4087  // Print name with a given length. Format: "%NNs "
4088  char namefmt[10];
4089  sprint(namefmt, sizeof(namefmt), "%%%ds ", static_cast<casadi_int>(name_len));
4090 
4091  // Print header
4092  print(namefmt, name_.c_str());
4093 
4094  print(" : %8s %10s %8s %10s %9s\n", "t_proc", "(avg)", "t_wall", "(avg)", "n_eval");
4095 
4096 
4097  char buffer_proc[10];
4098  char buffer_wall[10];
4099  char buffer_proc_avg[10];
4100  char buffer_wall_avg[10];
4101 
4102  // Print keys
4103  for (const auto &s : fstats) {
4104  if (s.second.n_call!=0) {
4105  print(namefmt, s.first.c_str());
4106  format_time(buffer_proc, s.second.t_proc);
4107  format_time(buffer_wall, s.second.t_wall);
4108  format_time(buffer_proc_avg, s.second.t_proc/s.second.n_call);
4109  format_time(buffer_wall_avg, s.second.t_wall/s.second.n_call);
4110  print(" | %s (%s) %s (%s) %9d\n",
4111  buffer_proc, buffer_proc_avg,
4112  buffer_wall, buffer_wall_avg, s.second.n_call);
4113  }
4114  }
4115  }
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 1680 of file function_internal.hpp.

1681  {
1682  casadi_assert_dev(arg.size()==n_in_);
1683 
1684  // Which arguments require mapped evaluation
1685  std::vector<bool> mapped(n_in_);
1686  for (casadi_int i=0; i<n_in_; ++i) {
1687  mapped[i] = arg[i].size2()!=size2_in(i);
1688  }
1689 
1690  // Check if matching input sparsity
1691  std::vector<bool> matching(n_in_);
1692  bool any_mismatch = false;
1693  for (casadi_int i=0; i<n_in_; ++i) {
1694  if (mapped[i]) {
1695  matching[i] = arg[i].sparsity().is_stacked(sparsity_in(i), npar);
1696  } else {
1697  matching[i] = arg[i].sparsity()==sparsity_in(i);
1698  }
1699  any_mismatch = any_mismatch || !matching[i];
1700  }
1701 
1702  // Correct input sparsity
1703  if (any_mismatch) {
1704  std::vector<M> arg2(arg);
1705  for (casadi_int i=0; i<n_in_; ++i) {
1706  if (!matching[i]) {
1707  if (mapped[i]) {
1708  arg2[i] = project(arg2[i], repmat(sparsity_in(i), 1, npar));
1709  } else {
1710  arg2[i] = project(arg2[i], sparsity_in(i));
1711  }
1712  }
1713  }
1714  return arg2;
1715  }
1716  return arg;
1717  }

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 1720 of file function_internal.hpp.

1721  {
1722  return arg;
1723  }

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 1573 of file function_internal.hpp.

1573  {
1574  for (auto i=v.begin(); i!=v.end(); ++i) {
1575  if (!i->is_zero()) return false;
1576  }
1577  return true;
1578  }

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

◆ release()

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

Definition at line 3937 of file function_internal.cpp.

3937  {
3938 #ifdef CASADI_WITH_THREAD
3939  std::lock_guard<std::mutex> lock(mtx_);
3940 #endif //CASADI_WITH_THREAD
3941  unused_.push(mem);
3942  }

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

◆ 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 1855 of file function_internal.hpp.

1856  {
1857  std::vector<M> r(arg.size());
1858  for (casadi_int i=0; i<r.size(); ++i) r[i] = replace_mat(arg[i], sparsity_in(i), npar);
1859  return r;
1860  }

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 1879 of file function_internal.hpp.

1880  {
1881  std::vector<std::vector<M> > r(aseed.size());
1882  for (casadi_int d=0; d<r.size(); ++d) r[d] = replace_res(aseed[d], npar);
1883  return r;
1884  }

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 1871 of file function_internal.hpp.

1872  {
1873  std::vector<std::vector<M> > r(fseed.size());
1874  for (casadi_int d=0; d<r.size(); ++d) r[d] = replace_arg(fseed[d], npar);
1875  return r;
1876  }

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 1863 of file function_internal.hpp.

1864  {
1865  std::vector<M> r(res.size());
1866  for (casadi_int i=0; i<r.size(); ++i) r[i] = replace_mat(res[i], sparsity_out(i), npar);
1867  return r;
1868  }

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 471 of file function_internal.cpp.

471  {
472  dump_count_ = 0;
473  }

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 2343 of file function_internal.cpp.

2343  {
2344  casadi_assert_dev(nadj>=0);
2345  // Used wrapped function if reverse not available
2346  if (!enable_reverse_) {
2347  // Derivative information must be available
2348  casadi_assert(has_derivative(), "Derivatives cannot be calculated for " + name_);
2349  return wrap().reverse(nadj);
2350  }
2351  // Retrieve/generate cached
2352  Function f;
2353  std::string fname = reverse_name(name_, nadj);
2354  if (!incache(fname, f)) {
2355  casadi_int i;
2356  // Prefix to be used for adjoint seeds, sensitivities
2357  std::string pref = diff_prefix("adj");
2358  // Names of inputs
2359  std::vector<std::string> inames;
2360  for (i=0; i<n_in_; ++i) inames.push_back(name_in_[i]);
2361  for (i=0; i<n_out_; ++i) inames.push_back("out_" + name_out_[i]);
2362  for (i=0; i<n_out_; ++i) inames.push_back(pref + name_out_[i]);
2363  // Names of outputs
2364  std::vector<std::string> onames;
2365  for (casadi_int i=0; i<n_in_; ++i) onames.push_back(pref + name_in_[i]);
2366  // Options
2368  opts = combine(opts, generate_options("reverse"));
2369  opts["derivative_of"] = self();
2370  // Generate derivative function
2371  casadi_assert_dev(enable_reverse_);
2372  f = get_reverse(nadj, fname, inames, onames, opts);
2373  // Consistency check for inputs
2374  casadi_assert_dev(f.n_in()==n_in_ + n_out_ + n_out_);
2375  casadi_int ind=0;
2376  for (i=0; i<n_in_; ++i) f.assert_size_in(ind++, size1_in(i), size2_in(i));
2377  for (i=0; i<n_out_; ++i) f.assert_size_in(ind++, size1_out(i), size2_out(i));
2378  for (i=0; i<n_out_; ++i) f.assert_size_in(ind++, size1_out(i), nadj*size2_out(i));
2379  // Consistency check for outputs
2380  casadi_assert_dev(f.n_out()==n_in_);
2381  for (i=0; i<n_in_; ++i) f.assert_sparsity_out(i, sparsity_in(i), nadj);
2382  // Save to cache
2383  tocache_if_missing(f);
2384  }
2385  return f;
2386  }
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:1332

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 675 of file function_internal.hpp.

675  {
676  return "adj" + str(nadj) + "_" + fcn;
677  }

References casadi::str().

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

◆ self()

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

◆ serialize()

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

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

Definition at line 4451 of file function_internal.cpp.

4451  {
4452  serialize_type(s);
4453  serialize_body(s);
4454  }
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 2051 of file sx_function.cpp.

2051  {
2053  s.version("SXFunction", 4);
2054  s.pack("SXFunction::n_instr", algorithm_.size());
2055 
2056  s.pack("SXFunction::worksize", worksize_);
2057  s.pack("SXFunction::free_vars", free_vars_);
2058  s.pack("SXFunction::operations", operations_);
2059  s.pack("SXFunction::constants", constants_);
2060  s.pack("SXFunction::default_in", default_in_);
2061 
2062  s.pack("SXFunction::call_sz_arg", call_.sz_arg);
2063  s.pack("SXFunction::call_sz_res", call_.sz_res);
2064  s.pack("SXFunction::call_sz_iw", call_.sz_iw);
2065  s.pack("SXFunction::call_sz_w", call_.sz_w);
2066  s.pack("SXFunction::call_sz_arg", call_.sz_w_arg);
2067  s.pack("SXFunction::call_sz_res", call_.sz_w_res);
2068 
2069  s.pack("SXFunction::call_el_size", call_.el.size());
2070  // Loop over ExtendedALgEl elements
2071  for (const auto& n : call_.el) {
2072  s.pack("SXFunction::call_el_f", n.f);
2073  s.pack("SXFunction::call_el_dep", n.dep);
2074  s.pack("SXFunction::call_el_res", n.res);
2075  s.pack("SXFunction::call_el_copy_elision_arg", n.copy_elision_arg);
2076  s.pack("SXFunction::call_el_copy_elision_offset", n.copy_elision_offset);
2077  }
2078 
2079  s.pack("SXFunction::copy_elision", copy_elision_);
2080 
2081  // Loop over algorithm
2082  for (const auto& e : algorithm_) {
2083  s.pack("SXFunction::ScalarAtomic::op", e.op);
2084  s.pack("SXFunction::ScalarAtomic::i0", e.i0);
2085  s.pack("SXFunction::ScalarAtomic::i1", e.i1);
2086  s.pack("SXFunction::ScalarAtomic::i2", e.i2);
2087  }
2088 
2089  s.pack("SXFunction::live_variables", live_variables_);
2090  s.pack("SXFunction::print_instructions", print_instructions_);
2091  s.pack("SXFunction::dump_trace", dump_trace_);
2092 
2094  }
void delayed_serialize_members(SerializingStream &s) const
Helper functions to avoid recursion limit.
Definition: x_function.hpp:322
void serialize_body(SerializingStream &s) const override
Serialize an object without type information.
Definition: x_function.hpp:328

References algorithm_, call_, constants_, copy_elision_, default_in_, casadi::XFunction< DerivedType, MatType, NodeType >::delayed_serialize_members(), dump_trace_, 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 4022 of file function_internal.cpp.

4022  {
4023 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
4024  // Safe access to jac_sparsity_
4025  std::lock_guard<std::mutex> lock(jac_sparsity_mtx_);
4026 #endif // CASADI_WITH_THREADSAFE_SYMBOLICS
4027  casadi_int ind = iind + oind * n_in_;
4028  jac_sparsity_[false].resize(n_in_ * n_out_);
4029  jac_sparsity_[false].at(ind) = sp;
4030  jac_sparsity_[true].resize(n_in_ * n_out_);
4031  jac_sparsity_[true].at(ind) = to_compact(oind, iind, sp);
4032  }

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 3796 of file function_internal.cpp.

3797  {
3798  set_work(mem, arg, res, iw, w);
3799  set_temp(mem, arg, res, iw, w);
3800  auto *m = static_cast<FunctionMemory*>(mem);
3801  m->stats_available = true;
3802  }
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 1222 of file sx_function.cpp.

1222  {
1223  // If inlining has been specified
1224  casadi_assert(!(always_inline && never_inline),
1225  "Inconsistent options for " + definition());
1226  casadi_assert(!(never_inline && has_free()),
1227  "Must inline " + definition());
1228  if (always_inline) return true;
1229  if (never_inline) return false;
1230  // Functions with free variables must be inlined
1231  if (has_free()) return true;
1232  // Inlining by default
1233  return true;
1234  }

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 2555 of file function_internal.cpp.

2555  {
2556  return "int " + fname + "(const casadi_real** arg, casadi_real** res, "
2557  "casadi_int* iw, casadi_real* w, int mem)";
2558  }

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

◆ 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 2560 of file function_internal.cpp.

2560  {
2561  std::vector<std::string> args;
2562  for (auto e : name_in_) {
2563  args.push_back("const casadi_real* " + str(e));
2564  }
2565  for (auto e : name_out_) {
2566  args.push_back("casadi_real* " + str(e));
2567  }
2568  args.push_back("const casadi_real** arg");
2569  args.push_back("casadi_real** res");
2570  args.push_back("casadi_int* iw");
2571  args.push_back("casadi_real* w");
2572  args.push_back("int mem");
2573  return "int " + fname + "_unrolled(" + join(args, ", ") + ")";
2574  }

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

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

◆ simplify_passes()

Function casadi::XFunction< SXFunction , Matrix< SXElem > , SXNode >::simplify_passes ( const std::vector< std::pair< std::string, casadi_int > > &  tasks) const
overridevirtualinherited

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

Reimplemented from casadi::FunctionInternal.

Definition at line 166 of file x_function.hpp.

1095  {
1096  std::vector<MatType> new_in = in_;
1097  std::vector<MatType> new_out = out_;
1098  Dict final_options = generate_options("clone");
1099  final_options["allow_duplicate_io_names"] = true;
1100  final_options["allow_free"] = true;
1101  apply_simplify_passes(tasks, new_in, new_out);
1102  return Function(name_, new_in, new_out, name_in_, name_out_, final_options);
1103  }
void apply_simplify_passes(const std::vector< std::pair< std::string, casadi_int > > &tasks, std::vector< Matrix< SXElem > > &new_in, std::vector< Matrix< SXElem > > &new_out) const
Apply simplify passes in-place on a set of inputs/outputs.

◆ 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.

1024  {
1025  // Return expressions
1026  std::vector<MatType> ret_in, ret_out;
1027  std::vector<std::string> ret_in_name, ret_out_name;
1028 
1029  // Reorder inputs
1030  for (casadi_int k : order_in) {
1031  ret_in.push_back(in_.at(k));
1032  ret_in_name.push_back(name_in_.at(k));
1033  }
1034 
1035  // Reorder outputs
1036  for (casadi_int k : order_out) {
1037  ret_out.push_back(out_.at(k));
1038  ret_out_name.push_back(name_out_.at(k));
1039  }
1040 
1041  // Assemble function
1042  return Function(name, ret_in, ret_out,
1043  ret_in_name, ret_out_name, opts);
1044  }

◆ 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.

413  {
414  while (!s.empty()) {
415  // Get the topmost element
416  NodeType* t = s.top();
417  // If the last element on the stack has not yet been added
418  if (t && t->temp>=0) {
419  // Get the index of the next dependency
420  casadi_int next_dep = t->temp++;
421  // If there is any dependency which has not yet been added
422  if (next_dep < t->n_dep()) {
423  // Add dependency to stack
424  s.push(static_cast<NodeType*>(t->dep(next_dep).get()));
425  } else {
426  // if no dependencies need to be added, we can add the node to the algorithm
427  nodes.push_back(t);
428  // Mark the node as found
429  t->temp = -1;
430  // Remove from stack
431  s.pop();
432  }
433  } else {
434  // If the last element on the stack has already been added
435  s.pop();
436  }
437  }
438  }

◆ 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 1707 of file sx_function.cpp.

1708  {
1709  // Fall back when forward mode not allowed
1710  if (sp_weight()==1 || sp_weight()==-1)
1711  return FunctionInternal::sp_forward(arg, res, iw, w, mem);
1712  // Propagate sparsity forward
1713  for (auto&& e : algorithm_) {
1714  switch (e.op) {
1715  case OP_CONST:
1716  case OP_PARAMETER:
1717  w[e.i0] = 0; break;
1718  case OP_INPUT:
1719  w[e.i0] = (arg[e.i1]!=nullptr && is_diff_in_[e.i1]) ? arg[e.i1][e.i2] : 0;
1720  break;
1721  case OP_OUTPUT:
1722  if (res[e.i0]!=nullptr) res[e.i0][e.i2] = is_diff_out_[e.i0] ? w[e.i1] : 0;
1723  break;
1724  case OP_CALL:
1725  call_fwd(e, arg, res, iw, w);
1726  break;
1727  default: // Unary or binary operation
1728  w[e.i0] = w[e.i1] | w[e.i2]; break;
1729  }
1730  }
1731  return 0;
1732  }

References algorithm_, call_fwd(), casadi::FunctionInternal::is_diff_in_, casadi::FunctionInternal::is_diff_out_, 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 3102 of file function_internal.cpp.

3103  {
3104  // Get the sparsity of the Jacobian block
3105  Sparsity sp = jac_sparsity(oind, iind, true, false);
3106  if (sp.is_null() || sp.nnz() == 0) return 0; // Skip if zero
3107  // Carry out the sparse matrix-vector multiplication
3108  casadi_int d1 = sp.size2();
3109  const casadi_int *colind = sp.colind(), *row = sp.row();
3110  for (casadi_int cc=0; cc<d1; ++cc) {
3111  for (casadi_int el = colind[cc]; el < colind[cc+1]; ++el) {
3112  res[oind][row[el]] |= arg[iind][cc];
3113  }
3114  }
3115  return 0;
3116  }

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 1792 of file sx_function.cpp.

1793  {
1794  // Fall back when reverse mode not allowed
1795  if (sp_weight()==0 || sp_weight()==-1)
1796  return FunctionInternal::sp_reverse(arg, res, iw, w, mem);
1797  std::fill_n(w, sz_w(), 0);
1798 
1799  // Propagate sparsity backward
1800  for (auto it=algorithm_.rbegin(); it!=algorithm_.rend(); ++it) {
1801  // Temp seed
1802  bvec_t seed;
1803 
1804  // Propagate seeds
1805  switch (it->op) {
1806  case OP_CONST:
1807  case OP_PARAMETER:
1808  w[it->i0] = 0;
1809  break;
1810  case OP_INPUT:
1811  if (arg[it->i1]!=nullptr && is_diff_in_[it->i1])
1812  arg[it->i1][it->i2] |= w[it->i0];
1813  w[it->i0] = 0;
1814  break;
1815  case OP_OUTPUT:
1816  if (res[it->i0]!=nullptr && is_diff_out_[it->i0]) {
1817  w[it->i1] |= res[it->i0][it->i2];
1818  res[it->i0][it->i2] = 0;
1819  }
1820  break;
1821  case OP_CALL:
1822  call_rev(*it, arg, res, iw, w);
1823  break;
1824  default: // Unary or binary operation
1825  seed = w[it->i0];
1826  w[it->i0] = 0;
1827  w[it->i1] |= seed;
1828  w[it->i2] |= seed;
1829  }
1830  }
1831  return 0;
1832  }
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::FunctionInternal::is_diff_in_, casadi::FunctionInternal::is_diff_out_, 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 3533 of file function_internal.cpp.

3533  {
3534  // If reverse mode propagation unavailable, use forward
3535  if (!has_sprev()) return 0;
3536 
3537  // If forward mode propagation unavailable, use reverse
3538  if (!has_spfwd()) return 1;
3539 
3540  // Use the (potentially user set) option
3541  return ad_weight_sp_;
3542  }

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 4146 of file function_internal.cpp.

4146  {
4147  // Variable number of arguments
4148  va_list args;
4149  va_start(args, fmt);
4150  // Print to buffer
4151  casadi_int n = vsnprintf(buf, buf_sz, fmt, args);
4152  // Cleanup
4153  va_end(args);
4154  // Throw error if failure
4155  casadi_assert(n>=0 && n<buf_sz, "Print failure while processing '" + std::string(fmt) + "'");
4156  }

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 4214 of file function_internal.cpp.

4214  {
4215  switch (status) {
4216  case SOLVER_RET_LIMITED: return "SOLVER_RET_LIMITED";
4217  case SOLVER_RET_NAN: return "SOLVER_RET_NAN";
4218  case SOLVER_RET_SUCCESS: return "SOLVER_RET_SUCCESS";
4219  default: return "SOLVER_RET_UNKNOWN";
4220  }
4221  }
@ 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 1838 of file sx_function.cpp.

1838  {
1839  return in_;
1840  }

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 1834 of file sx_function.cpp.

1834  {
1835  return in_.at(ind);
1836  }

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 3568 of file function_internal.cpp.

3568  {
3569  std::vector<SX> ret(n_out_);
3570  for (casadi_int i=0; i<ret.size(); ++i) {
3571  ret[i] = sx_out(i);
3572  }
3573  return ret;
3574  }
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 1265 of file function_internal.cpp.

1265  {
1266  return self()(arg);
1267  }

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 1598 of file function_internal.hpp.

1599  {
1600  std::vector<std::vector<MatType> > aseed(nadj, v);
1601  for (casadi_int dir=0; dir<nadj; ++dir) {
1602  // Replace symbolic inputs
1603  casadi_int oind=0;
1604  for (typename std::vector<MatType>::iterator i=aseed[dir].begin();
1605  i!=aseed[dir].end();
1606  ++i, ++oind) {
1607  // Name of the adjoint seed
1608  std::stringstream ss;
1609  ss << "a";
1610  if (nadj>1) ss << dir << "_";
1611  ss << oind;
1612 
1613  // Save to matrix
1614  *i = MatType::sym(ss.str(), is_diff_out_[oind] ? i->sparsity() : Sparsity(i->size()));
1615 
1616  }
1617  }
1618  return aseed;
1619  }

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 3150 of file function_internal.cpp.

3151  {
3152  sz_arg = this->sz_arg();
3153  sz_res = this->sz_res();
3154  sz_iw = this->sz_iw();
3155  sz_w = this->sz_w();
3156  }

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 2036 of file function_internal.cpp.

2037  {
2038  // Strip rows and columns
2039  std::vector<casadi_int> mapping;
2040  return sp.sub(sparsity_out(oind).find(), sparsity_in(iind).find(), mapping);
2041  }

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

◆ trace_instruction()

void casadi::SXFunction::trace_instruction ( std::ostream &  trace,
casadi_int  k,
const double *  w,
bool  output 
) const

Definition at line 139 of file sx_function.cpp.

140  {
141  const auto& e = algorithm_.at(k);
142  const int* slots = output ? &e.i0 : &e.i1;
143  casadi_int n = output ? 1 : casadi_math<double>::ndeps(e.op);
144  if (e.op == OP_CALL) {
145  const auto& call = call_.el.at(e.i1);
146  slots = get_ptr(output ? call.res : call.dep);
147  n = output ? call.n_res : call.n_dep;
148  } else if (e.op == OP_INPUT || e.op == OP_CONST) {
149  n = output ? 1 : 0;
150  } else if (e.op == OP_OUTPUT) {
151  n = output ? 0 : 1;
152  }
153  trace << "{\"instruction\":" << k << ",\"op\":" << e.op
154  << ",\"phase\":\"" << (output ? "outputs" : "inputs") << "\",\"values\":[";
155  for (casadi_int i = 0; i < n; ++i) {
156  if (i) trace << ",";
157  trace_values(trace, slots[i] < 0 ? nullptr : w + slots[i], 1);
158  }
159  trace << "]}\n";
160  }

References algorithm_, casadi::FunctionInternal::call(), call_, casadi::SXFunction::CallInfo::el, casadi::get_ptr(), casadi::casadi_math< T >::ndeps(), casadi::OP_CALL, casadi::OP_CONST, casadi::OP_INPUT, casadi::OP_OUTPUT, and casadi::FunctionInternal::trace_values().

Referenced by eval().

◆ trace_values()

void casadi::FunctionInternal::trace_values ( std::ostream &  trace,
const double *  values,
casadi_int  nnz 
)
staticprotectedinherited

Definition at line 826 of file function_internal.cpp.

827  {
828  if (!values) {
829  trace << "null";
830  return;
831  }
832  trace << "[";
833  for (casadi_int i = 0; i < nnz; ++i) {
834  if (i) trace << ",";
835  double v = values[i];
836  if (isnan(v)) {
837  trace << "\"nan\"";
838  } else if (isinf(v)) {
839  trace << (v < 0 ? "\"-inf\"" : "\"inf\"");
840  } else {
841  normalized_out(trace, v);
842  }
843  }
844  trace << "]";
845  }

References casadi::normalized_out().

Referenced by casadi::FunctionInternal::finish_trace(), casadi::FunctionInternal::open_trace(), casadi::MXFunction::trace_instruction(), and trace_instruction().

◆ 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.

215  {
216 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
217  auto* w = weak_ref_.load(std::memory_order_acquire);
218  if (!w) {
219  auto* nw = new GenericWeakRef<Shared, Internal>(static_cast<Internal*>(this));
220  GenericWeakRef<Shared, Internal>* expected = nullptr;
221  if (weak_ref_.compare_exchange_strong(
222  expected, nw, std::memory_order_release, std::memory_order_acquire)) {
223  w = nw;
224  } else {
225  delete nw; // lost the race; another thread published first
226  w = expected;
227  }
228  }
229  return w;
230 #else
231  if (weak_ref_==nullptr) {
232  weak_ref_ = new GenericWeakRef<Shared, Internal>(static_cast<Internal*>(this));
233  }
234  return weak_ref_;
235 #endif // CASADI_WITH_THREADSAFE_SYMBOLICS
236  }

◆ 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.

1326  {
1327 
1328  // Input arguments
1329  auto it = std::find(name_in_.begin(), name_in_.end(), s_in);
1330  casadi_assert_dev(it!=name_in_.end());
1331  MatType arg = in_.at(it-name_in_.begin());
1332 
1333  // Output arguments
1334  std::vector<MatType> res;
1335  for (auto&& s : s_out) {
1336  it = std::find(name_out_.begin(), name_out_.end(), s);
1337  casadi_assert_dev(it!=name_out_.end());
1338  res.push_back(out_.at(it-name_out_.begin()));
1339  }
1340 
1341  // Extract variables entering nonlinearly
1342  return MatType::which_depends(veccat(res), arg, order, tr);
1343  }

◆ wrap() [1/2]

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

◆ wrap() [2/2]

Function casadi::FunctionInternal::wrap ( const std::string &  name) const
inherited

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

Definition at line 1244 of file function_internal.cpp.

1244  {
1245  Function f;
1246  if (!incache(name, f)) {
1247  // Options
1248  Dict opts;
1249  opts["derivative_of"] = derivative_of_;
1250  opts["ad_weight"] = ad_weight();
1251  opts["ad_weight_sp"] = sp_weight();
1252  opts["max_num_dir"] = max_num_dir_;
1253  opts["is_diff_in"] = is_diff_in_;
1254  opts["is_diff_out"] = is_diff_out_;
1255  // Wrap the function
1256  std::vector<MX> arg = mx_in();
1257  std::vector<MX> res = self()(arg);
1258  f = Function(name, arg, res, name_in_, name_out_, opts);
1259  // Save in cache
1260  tocache_if_missing(f);
1261  }
1262  return f;
1263  }

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::FunctionInternal::name_in_, casadi::FunctionInternal::name_out_, casadi::FunctionInternal::sp_weight(), and casadi::FunctionInternal::tocache_if_missing().

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

◆ wrap_as_needed() [1/2]

Function casadi::FunctionInternal::wrap_as_needed ( const Dict &  opts) const
inherited

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

Definition at line 1219 of file function_internal.cpp.

1219  {
1220  return wrap_as_needed("wrap_" + name_, opts);
1221  }
Function wrap_as_needed(const std::string &name, const Dict &opts) const
Wrap in an Function instance consisting of only one MX call.

References casadi::ProtoFunction::name_, and casadi::FunctionInternal::wrap_as_needed().

◆ wrap_as_needed() [2/2]

Function casadi::FunctionInternal::wrap_as_needed ( const std::string &  name,
const Dict &  opts 
) const
inherited

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

Definition at line 1223 of file function_internal.cpp.

1223  {
1224  if (opts.empty() && name==name_) return shared_from_this<Function>();
1225  // Options
1226  Dict my_opts = opts;
1227  my_opts["derivative_of"] = derivative_of_;
1228  if (my_opts.find("ad_weight")==my_opts.end())
1229  my_opts["ad_weight"] = ad_weight();
1230  if (my_opts.find("ad_weight_sp")==my_opts.end())
1231  my_opts["ad_weight_sp"] = sp_weight();
1232  if (my_opts.find("max_num_dir")==my_opts.end())
1233  my_opts["max_num_dir"] = max_num_dir_;
1234  // Wrap the function
1235  std::vector<MX> arg = mx_in();
1236  std::vector<MX> res = self()(arg);
1237  return Function(name, arg, res, name_in_, name_out_, my_opts);
1238  }

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(), and casadi::FunctionInternal::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 273 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 279 of file sx_function.hpp.

Referenced by codegen_body(), init_copy_elision(), serialize_body(), and SXFunction().

◆ custom_jacobian_

Function casadi::FunctionInternal::custom_jacobian_
inherited

◆ decref_

signal_t casadi::FunctionInternal::decref_
inherited

◆ default_in_

std::vector<double> casadi::SXFunction::default_in_

Definition at line 276 of file sx_function.hpp.

Referenced by generate_options(), 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},
{"ForwardDiff", ForwardDiff::deserialize},
{"BackwardDiff", BackwardDiff::deserialize},
{"CentralDiff", CentralDiff::deserialize},
{"Smoothing", Smoothing::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)
static ProtoFunction * deserialize(DeserializingStream &s)
Deserialize into MX.
static ProtoFunction * deserialize(DeserializingStream &s)
void deserialize(DeserializingStream &s, SDPToSOCPMem &m)
Definition: conic.cpp:744
static ProtoFunction * deserialize(DeserializingStream &s)
Deserialize into MX.
Definition: external.cpp:508
static ProtoFunction * deserialize(DeserializingStream &s)
Deserialize without type information.
static ProtoFunction * deserialize(DeserializingStream &s)
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:110
static ProtoFunction * deserialize(DeserializingStream &s)
Deserialize into MX.
Definition: nlpsol.cpp:1444
static ProtoFunction * deserialize(DeserializingStream &s)
Deserialize into a plugin instance (dispatches on the plugin name)
static ProtoFunction * deserialize(DeserializingStream &s)
Deserialize into MX.
Definition: rootfinder.cpp:595
static ProtoFunction * deserialize(DeserializingStream &s)
Deserialize without type information.
static ProtoFunction * deserialize(DeserializingStream &s)
static ProtoFunction * deserialize(DeserializingStream &s)
Deserialize without type information.
Definition: switch.hpp:150

Definition at line 1514 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

◆ dump_trace_

bool casadi::SXFunction::dump_trace_ = false

Definition at line 283 of file sx_function.hpp.

Referenced by change_option(), eval(), generate_options(), init(), serialize_body(), and SXFunction().

◆ 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

◆ has_refcount_in_deps_

bool casadi::FunctionInternal::has_refcount_in_deps_
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 274 of file x_function.hpp.

◆ incref_

signal_t casadi::FunctionInternal::incref_
inherited

◆ 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_directory_

std::string casadi::FunctionInternal::jit_directory_
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 405 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 408 of file sx_function.hpp.

Referenced by generate_options(), init(), and SXFunction().

◆ live_variables_

bool casadi::SXFunction::live_variables_

Definition at line 411 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 1312 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::ThreadMap::codegen_body(), casadi::MapSum::codegen_body(), casadi::MXFunction::codegen_body(), casadi::Switch::codegen_body(), codegen_body(), casadi::FastNewton::codegen_body(), casadi::ThreadMap::codegen_declarations(), 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::MXFunction::eval_activity(), 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(), casadi::FunctionInternal::open_trace(), 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 1312 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::ThreadMap::codegen_body(), casadi::MapSum::codegen_body(), casadi::MXFunction::codegen_body(), casadi::Switch::codegen_body(), codegen_body(), casadi::FastNewton::codegen_body(), casadi::ThreadMap::codegen_declarations(), 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_activity(), casadi::MXFunction::eval_activity(), casadi::FunctionInternal::eval_gen(), casadi::Map::eval_gen(), casadi::MapSum::eval_gen(), casadi::Switch::eval_sx(), casadi::CallbackInternal::finalize(), casadi::FunctionInternal::finish_trace(), 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 248 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::finish_trace(), 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::BlazingSplineFunction::init(), 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::OnnxRuntimeInterface::init_mem(), casadi::FunctionInternal::jac_is_symm(), casadi::FunctionInternal::jacobian(), casadi::FunctionInternal::map(), casadi::OracleFunction::monitored(), casadi::FunctionInternal::open_trace(), 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

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

Definition at line 330 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 279 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_

◆ print_out_

bool casadi::FunctionInternal::print_out_
inherited

◆ print_time_

bool casadi::ProtoFunction::print_time_
inherited

◆ record_time_

bool casadi::ProtoFunction::record_time_
inherited

◆ registered_functions_

std::vector<Function> casadi::FunctionInternal::registered_functions_
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 251 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::Integrator::eval(), casadi::MXFunction::eval(), eval(), casadi::MXFunction::eval_mx(), eval_mx(), eval_sx(), casadi::FmuFunction::factory(), casadi::FunctionInternal::finalize(), casadi::KinsolInterface::func(), casadi::CodeGenerator::generate_dump(), 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::MadmpecInterface::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::MosekInterface::init_mem(), casadi::IdasInterface::init_mem(), casadi::UnoInterface::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: