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

Internal node class for SXFunction. More...

#include <sx_function.hpp>

Detailed Description

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

Author
Joel Andersson
Date
2010-2015

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


List of available options
IdTypeDescriptionUsed in
ad_weightOT_DOUBLEWeighting factor for derivative calculation.When there is an option of either using forward or reverse mode directional derivatives, the condition ad_weight*nf<=(1-ad_weight)*na is used where nf and na are estimates of the number of forward/reverse mode directional derivatives needed. By default, ad_weight is calculated automatically, but this can be overridden by setting this option. In particular, 0 means forcing forward mode and 1 forcing reverse mode. Leave unset for (class specific) heuristics.casadi::FunctionInternal
ad_weight_spOT_DOUBLEWeighting factor for sparsity pattern calculation calculation.Overrides default behavior. Set to 0 and 1 to force forward and reverse mode respectively. Cf. option "ad_weight". When set to -1, sparsity is completely ignored and dense matrices are used.casadi::FunctionInternal
allow_duplicate_io_namesOT_BOOLAllow construction with duplicate io names (Default: false)casadi::SXFunction
allow_freeOT_BOOLAllow construction with free variables (Default: false)casadi::SXFunction
always_inlineOT_BOOLForce inlining.casadi::FunctionInternal
cacheOT_DICTPrepopulate the function cache. Default: emptycasadi::FunctionInternal
compilerOT_STRINGJust-in-time compiler plugin to be used.casadi::FunctionInternal
cseOT_BOOLPerform common subexpression elimination (complexity is N*log(N) in graph size)casadi::SXFunction
custom_jacobianOT_FUNCTIONOverride CasADi's AD. Use together with 'jac_penalty': 0. Note: Highly experimental. Syntax may break often.casadi::FunctionInternal
default_inOT_DOUBLEVECTORDefault input valuescasadi::SXFunction
der_optionsOT_DICTDefault options to be used to populate forward_options, reverse_options, and jacobian_options before those options are merged in.casadi::FunctionInternal
derivative_ofOT_FUNCTIONThe function is a derivative of another function. The type of derivative (directional derivative, Jacobian) is inferred from the function name.casadi::FunctionInternal
dumpOT_BOOLDump function to file upon first evaluation. [false]casadi::FunctionInternal
dump_dirOT_STRINGDirectory to dump inputs/outputs to. Make sure the directory exists [.]casadi::FunctionInternal
dump_formatOT_STRINGChoose file format to dump matrices. See DM.from_file [mtx]casadi::FunctionInternal
dump_inOT_BOOLDump numerical values of inputs to file (readable with DM.from_file) [default: false] A counter is used to generate unique names. The counter may be reset using reset_dump_count.casadi::FunctionInternal
dump_outOT_BOOLDump numerical values of outputs to file (readable with DM.from_file) [default: false] A counter is used to generate unique names. The counter may be reset using reset_dump_count.casadi::FunctionInternal
enable_fdOT_BOOLEnable derivative calculation by finite differencing. [default: false]]casadi::FunctionInternal
enable_forwardOT_BOOLEnable derivative calculation using generated functions for Jacobian-times-vector products - typically using forward mode AD - if available. [default: true]casadi::FunctionInternal
enable_jacobianOT_BOOLEnable derivative calculation using generated functions for Jacobians of all differentiable outputs with respect to all differentiable inputs - if available. [default: true]casadi::FunctionInternal
enable_reverseOT_BOOLEnable derivative calculation using generated functions for transposed Jacobian-times-vector products - typically using reverse mode AD - if available. [default: true]casadi::FunctionInternal
error_on_failOT_BOOLThrow exceptions when function evaluation fails (default true).casadi::ProtoFunction
external_transformOT_VECTORVECTORList of external_transform instruction arguments. Default: emptycasadi::FunctionInternal
fd_methodOT_STRINGMethod for finite differencing [default 'central']casadi::FunctionInternal
fd_optionsOT_DICTOptions to be passed to the finite difference instancecasadi::FunctionInternal
forward_optionsOT_DICTOptions to be passed to a forward mode constructorcasadi::FunctionInternal
gather_statsOT_BOOLDeprecated option (ignored): Statistics are now always collected.casadi::FunctionInternal
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...
 
int eval_sx (const SXElem **arg, SXElem **res, casadi_int *iw, SXElem *w, void *mem, bool always_inline, bool never_inline) const override
 evaluate symbolically while also propagating directional derivatives More...
 
void eval_mx (const MXVector &arg, MXVector &res, bool always_inline, bool never_inline) const override
 Evaluate symbolically, MX type. More...
 
bool should_inline (bool with_sx, bool always_inline, bool never_inline) const override
 
void ad_forward (const std::vector< std::vector< SX > > &fseed, std::vector< std::vector< SX > > &fsens) const
 Calculate forward mode directional derivatives. More...
 
void ad_reverse (const std::vector< std::vector< SX > > &aseed, std::vector< std::vector< SX > > &asens) const
 Calculate reverse mode directional derivatives. More...
 
bool is_smooth () const
 Check if smooth. More...
 
std::string print (const ScalarAtomic &a) const
 
void print_arg (std::ostream &stream, casadi_int k, const ScalarAtomic &el, const double *w) const
 
void print_arg (CodeGenerator &g, casadi_int k, const ScalarAtomic &el) const
 
void print_res (std::ostream &stream, casadi_int k, const ScalarAtomic &el, const double *w) const
 
void print_res (CodeGenerator &g, casadi_int k, const ScalarAtomic &el) const
 
void disp_more (std::ostream &stream) const override
 Print the algorithm. More...
 
std::string class_name () const override
 Get type name. More...
 
bool is_a (const std::string &type, bool recursive) const override
 Check if the function is of a particular type. More...
 
std::vector< SXfree_sx () const override
 Get free variables (SX) More...
 
bool has_free () const override
 Does the function have free variables. More...
 
std::vector< std::string > get_free () const override
 Print free variables. More...
 
std::vector< std::string > get_function () const override
 Get list of dependency functions. More...
 
const Functionget_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< MXmapsum_mx (const std::vector< MX > &arg, const std::string &parallelization)
 Parallel evaluation. More...
 
virtual bool uses_output () const
 Do the derivative functions need nondifferentiated outputs? More...
 
std::string diff_prefix (const std::string &prefix) const
 Determine prefix for differentiated functions. More...
 
virtual const Functionoracle () const
 Get oracle. More...
 
bool has_derivative () const
 Can derivatives be calculated in any way? More...
 
virtual double ad_weight () const
 Weighting factor for chosing forward/reverse mode. More...
 
virtual double sp_weight () const
 Weighting factor for chosing forward/reverse mode,. More...
 
virtual std::vector< MXfree_mx () const
 Get free variables (MX) More...
 
virtual void generate_lifted (Function &vdef_fcn, Function &vinit_fcn) const
 Extract the functions needed for the Lifted Newton method. More...
 
virtual MX instruction_MX (casadi_int k) const
 get MX expression associated with instruction More...
 
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< SXsx_in () const override
 Get function input(s) and output(s) More...
 
bool has_spfwd () const override
 
bool has_sprev () const override
 
bool has_forward (casadi_int nfwd) const override
 Generate a function that calculates nfwd forward derivatives. More...
 
Function get_forward (casadi_int nfwd, const std::string &name, const std::vector< std::string > &inames, const std::vector< std::string > &onames, const Dict &opts) const override
 Generate a function that calculates nfwd forward derivatives. More...
 
bool has_reverse (casadi_int nadj) const override
 Generate a function that calculates nadj adjoint derivatives. More...
 
Function get_reverse (casadi_int nadj, const std::string &name, const std::vector< std::string > &inames, const std::vector< std::string > &onames, const Dict &opts) const override
 Generate a function that calculates nadj adjoint derivatives. More...
 
bool has_jacobian () const override
 Return Jacobian of all input elements with respect to all output elements. More...
 
Function get_jacobian (const std::string &name, const std::vector< std::string > &inames, const std::vector< std::string > &onames, const Dict &opts) const override
 Return Jacobian of all input elements with respect to all output elements. More...
 
virtual void call_forward (const std::vector< MX > &arg, const std::vector< MX > &res, const std::vector< std::vector< MX > > &fseed, std::vector< std::vector< MX > > &fsens, bool always_inline, bool never_inline) const
 Forward mode AD, virtual functions overloaded in derived classes. More...
 
virtual void call_forward (const std::vector< SX > &arg, const std::vector< SX > &res, const std::vector< std::vector< SX > > &fseed, std::vector< std::vector< SX > > &fsens, bool always_inline, bool never_inline) const
 Forward mode AD, virtual functions overloaded in derived classes. More...
 
virtual void call_reverse (const std::vector< MX > &arg, const std::vector< MX > &res, const std::vector< std::vector< MX > > &aseed, std::vector< std::vector< MX > > &asens, bool always_inline, bool never_inline) const
 Reverse mode, virtual functions overloaded in derived classes. More...
 
virtual void call_reverse (const std::vector< SX > &arg, const std::vector< SX > &res, const std::vector< std::vector< SX > > &aseed, std::vector< std::vector< SX > > &asens, bool always_inline, bool never_inline) const
 Reverse mode, virtual functions overloaded in derived classes. More...
 
size_t get_n_in () override
 Number of function inputs and outputs. More...
 
size_t get_n_out () override
 Number of function inputs and outputs. More...
 
Sparsity get_sparsity_in (casadi_int i) override
 Sparsities of function inputs and outputs. More...
 
Sparsity get_sparsity_out (casadi_int i) override
 Sparsities of function inputs and outputs. More...
 
int eval_gen (const double **arg, double **res, casadi_int *iw, double *w, void *mem, bool always_inline, bool never_inline) const
 Evaluate numerically. More...
 
int eval_gen (const SXElem **arg, SXElem **res, casadi_int *iw, SXElem *w, void *mem, bool always_inline, bool never_inline) const
 Evaluate a function, overloaded. More...
 
int eval_gen (const bvec_t **arg, bvec_t **res, casadi_int *iw, bvec_t *w, void *mem, bool always_inline, bool never_inline) const
 Evaluate a function, overloaded. More...
 
virtual std::vector< DMeval_dm (const std::vector< DM > &arg) const
 Evaluate with DM matrices. More...
 
virtual bool has_eval_dm () const
 Evaluate with DM matrices. More...
 
void call_gen (const MXVector &arg, MXVector &res, casadi_int npar, bool always_inline, bool never_inline) const
 Call a function, overloaded. More...
 
template<typename D >
void call_gen (const std::vector< Matrix< D > > &arg, std::vector< Matrix< D > > &res, casadi_int npar, bool always_inline, bool never_inline) const
 Call a function, overloaded. More...
 
template<typename M >
void check_arg (const std::vector< M > &arg, casadi_int &npar) const
 Check if input arguments have correct length and dimensions. More...
 
template<typename M >
void check_res (const std::vector< M > &res, casadi_int &npar) const
 Check if output arguments have correct length and dimensions. More...
 
template<typename M >
std::map< std::string, M > convert_arg (const std::vector< M > &arg) const
 Convert from/to input/output lists/map. More...
 
template<typename M >
std::vector< M > convert_arg (const std::map< std::string, M > &arg) const
 Convert from/to input/output lists/map. More...
 
template<typename M >
std::map< std::string, M > convert_res (const std::vector< M > &res) const
 Convert from/to input/output lists/map. More...
 
template<typename M >
std::vector< M > convert_res (const std::map< std::string, M > &res) const
 Convert from/to input/output lists/map. More...
 
std::vector< double > nz_in (const std::vector< DM > &arg) const
 Convert from/to flat vector of input/output nonzeros. More...
 
std::vector< DMnz_in (const std::vector< double > &arg) const
 Convert from/to flat vector of input/output nonzeros. More...
 
std::vector< double > nz_out (const std::vector< DM > &res) const
 Convert from/to flat vector of input/output nonzeros. More...
 
std::vector< DMnz_out (const std::vector< double > &res) const
 Convert from/to flat vector of input/output nonzeros. More...
 
Function jacobian () const
 Return Jacobian of all input elements with respect to all output elements. More...
 
Sparsityjac_sparsity (casadi_int oind, casadi_int iind, bool compact, bool symmetric) const
 Get Jacobian sparsity. More...
 
virtual bool has_jac_sparsity (casadi_int oind, casadi_int iind) const
 Get Jacobian sparsity. More...
 
virtual Sparsity get_jac_sparsity (casadi_int oind, casadi_int iind, bool symmetric) const
 Get Jacobian sparsity. More...
 
Function forward (casadi_int nfwd) const
 Return function that calculates forward derivatives. More...
 
Function reverse (casadi_int nadj) const
 Return function that calculates adjoint derivatives. More...
 
virtual const SX sx_out (casadi_int ind) const
 Get function input(s) and output(s) More...
 
virtual const std::vector< SXsx_out () const
 Get function input(s) and output(s) More...
 
virtual const MX mx_in (casadi_int ind) const
 Get function input(s) and output(s) More...
 
virtual const std::vector< MXmx_in () const
 Get function input(s) and output(s) More...
 
virtual const MX mx_out (casadi_int ind) const
 Get function input(s) and output(s) More...
 
virtual const std::vector< MXmx_out () const
 Get function input(s) and output(s) More...
 
const DM dm_in (casadi_int ind) const
 Get function input(s) and output(s) More...
 
const std::vector< DMdm_in () const
 Get function input(s) and output(s) More...
 
const DM dm_out (casadi_int ind) const
 Get function input(s) and output(s) More...
 
const std::vector< DMdm_out () const
 Get function input(s) and output(s) More...
 
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 Sparsitysparsity_in (casadi_int ind) const
 Input/output sparsity. More...
 
const Sparsitysparsity_out (casadi_int ind) const
 Input/output sparsity. More...
 
bool all_scalar () const
 Are all inputs and outputs scalar. More...
 
virtual bool jac_is_symm (casadi_int oind, casadi_int iind) const
 Is a Jacobian block known to be symmetric a priori? More...
 
Sparsity to_compact (casadi_int oind, casadi_int iind, const Sparsity &sp) const
 Convert to compact Jacobian sparsity pattern. More...
 
Sparsity from_compact (casadi_int oind, casadi_int iind, const Sparsity &sp) const
 Convert from compact Jacobian sparsity pattern. More...
 
template<bool fwd>
Sparsity get_jac_sparsity_gen (casadi_int oind, casadi_int iind) const
 Get the sparsity pattern via sparsity seed propagation. More...
 
Sparsity get_jac_sparsity_hierarchical (casadi_int oind, casadi_int iind) const
 A flavor of get_jac_sparsity_gen that does hierarchical block structure recognition. More...
 
Sparsity get_jac_sparsity_hierarchical_symm (casadi_int oind, casadi_int iind) const
 
virtual std::vector< MXsymbolic_output (const std::vector< MX > &arg) const
 Get a vector of symbolic variables corresponding to the outputs. More...
 
virtual std::string get_name_in (casadi_int i)
 Names of function input and outputs. More...
 
virtual std::string get_name_out (casadi_int i)
 Names of function input and outputs. More...
 
virtual size_t codegen_sz_arg (const CodeGenerator &g) const
 Get required lengths, for codegen. More...
 
virtual size_t codegen_sz_res (const CodeGenerator &g) const
 Get required lengths, for codegen. More...
 
virtual size_t codegen_sz_iw (const CodeGenerator &g) const
 Get required lengths, for codegen. More...
 
virtual bool fwdViaJac (casadi_int nfwd) const
 Calculate derivatives by multiplying the full Jacobian and multiplying. More...
 
virtual bool adjViaJac (casadi_int nadj) const
 Calculate derivatives by multiplying the full Jacobian and multiplying. More...
 

Static Public Member Functions

static ProtoFunctiondeserialize (DeserializingStream &s)
 Deserialize without type information. More...
 
static std::vector< SXorder (const std::vector< SX > &expr)
 
static void sort_depth_first (std::stack< SXNode * > &s, std::vector< SXNode * > &nodes)
 Topological sorting of the nodes based on Depth-First Search (DFS) More...
 
static std::string forward_name (const std::string &fcn, casadi_int nfwd)
 Helper function: Get name of forward derivative function. More...
 
static std::string reverse_name (const std::string &fcn, casadi_int nadj)
 Helper function: Get name of adjoint derivative function. More...
 
template<typename MatType >
static MatType ensure_stacked (const MatType &v, const Sparsity &sp, casadi_int n)
 Ensure that a matrix's sparsity is a horizontal multiple of another, or empty. More...
 
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< AlgElalgorithm_
 all binary nodes of the tree in the order of execution More...
 
size_t worksize_
 
std::vector< SXElemfree_vars_
 Free variables. More...
 
std::vector< SXElemoperations_
 The expressions corresponding to each binary operation. More...
 
std::vector< SXElemconstants_
 The expressions corresponding to each constant. More...
 
std::vector< double > default_in_
 Default input values. More...
 
std::vector< bool > copy_elision_
 Copy elision per algel. More...
 
bool print_instructions_
 Print each operation during evaluation. More...
 
struct casadi::SXFunction::CallInfo call_
 
bool just_in_time_opencl_
 With just-in-time compilation using OpenCL. More...
 
bool just_in_time_sparsity_
 With just-in-time compilation for the sparsity propagation. More...
 
bool live_variables_
 Live variables? More...
 
std::vector< Matrix< SXElem > > in_
 Inputs of the function (needed for symbolic calculations) More...
 
std::vector< Matrix< SXElem > > out_
 Outputs of the function (needed for symbolic calculations) More...
 
bool always_inline_
 
bool never_inline_
 
size_t n_in_
 Number of inputs and outputs. More...
 
size_t n_out_
 
std::vector< bool > is_diff_in_
 Are inputs and outputs differentiable? More...
 
std::vector< bool > is_diff_out_
 
std::vector< Sparsitysparsity_in_
 Input and output sparsity. More...
 
std::vector< Sparsitysparsity_out_
 
std::vector< std::string > name_in_
 Input and output scheme. More...
 
std::vector< std::string > name_out_
 
bool jit_
 Use just-in-time compiler. More...
 
bool jit_cleanup_
 Cleanup jit source file. More...
 
std::string jit_serialize_
 Serialize behaviour. More...
 
std::string jit_name_
 Name if jit source file. More...
 
std::string jit_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, Functioncache_
 Function cache. More...
 
std::vector< Sparsityjac_sparsity_ [2]
 Cache for sparsities of the Jacobian blocks. More...
 
Function derivative_of_
 If the function is the derivative of another function. More...
 
void * user_data_
 User-set field. More...
 
std::string compiler_plugin_
 Just-in-time compiler. More...
 
Importer compiler_
 
Dict jit_options_
 
double jac_penalty_
 Penalty factor for using a complete Jacobian to calculate directional derivatives. More...
 
bool enable_forward_
 
bool enable_reverse_
 
bool enable_jacobian_
 
bool enable_fd_
 
bool enable_forward_op_
 
bool enable_reverse_op_
 
bool enable_jacobian_op_
 
bool enable_fd_op_
 
double ad_weight_
 Weighting factor for derivative calculation and sparsity pattern calculation. More...
 
double ad_weight_sp_
 
casadi_int max_num_dir_
 Maximum number of sensitivity directions. More...
 
bool inputs_check_
 Errors are thrown if numerical values of inputs look bad. More...
 
Dict fd_options_
 
double fd_step_
 
std::string fd_method_
 
bool print_in_
 
bool print_out_
 
bool print_canonical_
 
casadi_int max_io_
 
bool dump_in_
 
bool dump_out_
 
bool dump_
 
std::string dump_dir_
 
std::string dump_format_
 
Dict forward_options_
 
Dict reverse_options_
 
Dict jacobian_options_
 
Dict der_options_
 
Function custom_jacobian_
 
std::vector< Functionregistered_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...
 
void initSingleton ()
 
void destroySingleton ()
 
shared_from_this ()
 Get a shared object from the current internal object. More...
 
const B shared_from_this () const
 Get a shared object from the current internal object. More...
 
static const Options options_
 Options. More...
 
const Optionsget_options () const override
 Options. More...
 

Member Typedef Documentation

◆ AlgEl

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

An element of the algorithm, namely a binary operation

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

Definition at line 245 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 1926 of file sx_function.cpp.

1926  :
1927  XFunction<SXFunction, SX, SXNode>(s) {
1928  int version = s.version("SXFunction", 1, 3);
1929  size_t n_instructions;
1930  s.unpack("SXFunction::n_instr", n_instructions);
1931 
1932  s.unpack("SXFunction::worksize", worksize_);
1933  s.unpack("SXFunction::free_vars", free_vars_);
1934  s.unpack("SXFunction::operations", operations_);
1935  s.unpack("SXFunction::constants", constants_);
1936  s.unpack("SXFunction::default_in", default_in_);
1937 
1938  if (version>=2) {
1939 
1940  s.unpack("SXFunction::call_sz_arg", call_.sz_arg);
1941  s.unpack("SXFunction::call_sz_res", call_.sz_res);
1942  s.unpack("SXFunction::call_sz_iw", call_.sz_iw);
1943  s.unpack("SXFunction::call_sz_w", call_.sz_w);
1944  s.unpack("SXFunction::call_sz_arg", call_.sz_w_arg);
1945  s.unpack("SXFunction::call_sz_res", call_.sz_w_res);
1946 
1947  size_t el_size;
1948  s.unpack("SXFunction::call_el_size", el_size);
1949  call_.el.reserve(el_size);
1950 
1951  // Loop over nodes
1952  for (casadi_int k=0;k<el_size;++k) {
1953  Function f;
1954  s.unpack("SXFunction::call_el_f", f);
1955  call_.el.emplace_back(f);
1956  auto& e = call_.el[k];
1957  s.unpack("SXFunction::call_el_dep", e.dep);
1958  s.unpack("SXFunction::call_el_res", e.res);
1959  s.unpack("SXFunction::call_el_copy_elision_arg", e.copy_elision_arg);
1960  s.unpack("SXFunction::call_el_copy_elision_offset", e.copy_elision_offset);
1961  }
1962 
1963  s.unpack("SXFunction::copy_elision", copy_elision_);
1964 
1965  } else {
1966  call_.sz_arg = 0;
1967  call_.sz_res = 0;
1968  call_.sz_iw = 0;
1969  call_.sz_w = 0;
1970  call_.sz_w_arg = 0;
1971  call_.sz_w_res = 0;
1972  call_.el.clear();
1973  copy_elision_.resize(n_instructions, false);
1974  }
1975 
1976  algorithm_.resize(n_instructions);
1977  for (casadi_int k=0;k<n_instructions;++k) {
1978  AlgEl& e = algorithm_[k];
1979  s.unpack("SXFunction::ScalarAtomic::op", e.op);
1980  s.unpack("SXFunction::ScalarAtomic::i0", e.i0);
1981  s.unpack("SXFunction::ScalarAtomic::i1", e.i1);
1982  s.unpack("SXFunction::ScalarAtomic::i2", e.i2);
1983  }
1984 
1985  // Default (persistent) options
1986  just_in_time_opencl_ = false;
1987  just_in_time_sparsity_ = false;
1988 
1989  s.unpack("SXFunction::live_variables", live_variables_);
1990  if (version>=3) {
1991  s.unpack("SXFunction::print_instructions", print_instructions_);
1992  } else {
1993  print_instructions_ = false;
1994  }
1995 
1997  }
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(), 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 1194 of file sx_function.cpp.

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

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

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

3464  {
3465  // If reverse mode derivatives unavailable, use forward
3466  if (!enable_reverse_) return 0;
3467 
3468  // If forward mode derivatives unavailable, use reverse
3469  if (!enable_forward_ && !enable_fd_) return 1;
3470 
3471  // Use the (potentially user set) option
3472  return ad_weight_;
3473  }
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 3906 of file function_internal.cpp.

3908  {
3909  // Add, if not already in graph and not null
3910  if (!dep.is_null() && all_fun.find(dep.get()) == all_fun.end()) {
3911  // Add to map
3912  all_fun[dep.get()] = std::make_pair(dep, all_fun.size());
3913  // Also add its dependencies
3914  if (max_depth > 0) dep->find(all_fun, max_depth - 1);
3915  }
3916  }

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

3197  {
3198  if (!enable_reverse_) return true;
3199  if (jac_penalty_==-1) return false;
3200 
3201  // Heuristic 1: Jac calculated via reverse mode likely cheaper
3202  if (jac_penalty_*static_cast<double>(nnz_out())<nadj) return true;
3203 
3204  // Heuristic 2: Jac calculated via forward mode likely cheaper
3205  double w = ad_weight();
3206  if ((enable_forward_ || enable_fd_) &&
3207  jac_penalty_*w*static_cast<double>(nnz_in())<(1-w)*static_cast<double>(nadj))
3208  return true; // NOLINT
3209 
3210  return false;
3211  }
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 3951 of file function_internal.cpp.

3951  {
3952  // Check inputs
3953  for (casadi_int i=0; i<n_in_; ++i) {
3954  if (!sparsity_in_[i].is_scalar()) return false;
3955  }
3956  // Check outputs
3957  for (casadi_int i=0; i<n_out_; ++i) {
3958  if (!sparsity_out_[i].is_scalar()) return false;
3959  }
3960  // All are scalar
3961  return true;
3962  }

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

3145  {
3146  if (f.is_null()) return;
3147  size_t sz_arg, sz_res, sz_iw, sz_w;
3148  f.sz_work(sz_arg, sz_res, sz_iw, sz_w);
3149  alloc_arg(sz_arg*num_threads, persistent);
3150  alloc_res(sz_res*num_threads, persistent);
3151  alloc_iw(sz_iw*num_threads, persistent);
3152  alloc_w(sz_w*num_threads, persistent);
3153  registered_functions_.push_back(f);
3154  }
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 3137 of file function_internal.cpp.

3137  {
3138  if (persistent) {
3139  sz_w_per_ += sz_w;
3140  } else {
3141  sz_w_tmp_ = std::max(sz_w_tmp_, sz_w);
3142  }
3143  }

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

1105  {
1106  // Return value
1107  Dict ret;
1108 
1109  // Retrieve all Function instances that haven't been deleted
1110  std::vector<std::string> keys;
1111  std::vector<Function> entries;
1112  cache_.cache(keys, entries);
1113 
1114  for (size_t i=0; i<keys.size(); ++i) {
1115  // Get the name of the key
1116  std::string s = keys[i];
1117  casadi_assert_dev(s.size() > 0);
1118  // Replace ':' with '_'
1119  std::replace(s.begin(), s.end(), ':', '_');
1120  // Remove trailing underscore, if any
1121  if (s.back() == '_') s.resize(s.size() - 1);
1122  // Add entry to function return
1123  ret[s] = entries[i];
1124  }
1125 
1126  return ret;
1127  }
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 1615 of file function_internal.hpp.

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

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

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

1721  {
1722  const auto& m = call_.el[e.i1];
1723  const bvec_t** call_arg = arg;
1724  bvec_t** call_res = res;
1725  casadi_int* call_iw = iw;
1726  bvec_t* call_w = w;
1727  bvec_t* nz_in;
1728  bvec_t* nz_out;
1729 
1730  call_setup(m, &call_arg, &call_res, &call_iw, &call_w, &nz_in, &nz_out);
1731 
1732  // Populate nz_in from work vector
1733  for (casadi_int i=0; i<m.n_dep; ++i) nz_in[i] = w[m.dep[i]];
1734  // Recurse: activity through the callee
1735  m.f.eval_activity(call_arg, call_res, call_iw, call_w);
1736  // Store nz_out results back in work vector
1737  for (casadi_int i=0; i<m.n_res; ++i) {
1738  if (m.res[i]>=0) w[m.res[i]] = nz_out[i];
1739  }
1740  }
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 3217 of file function_internal.cpp.

3221  {
3222  casadi_assert(!(always_inline && never_inline), "Inconsistent options");
3223  casadi_assert(!always_inline, "Class " + class_name() +
3224  " cannot be inlined in an MX expression");
3225 
3226  // Derivative information must be available
3227  casadi_assert(has_derivative(),
3228  "Derivatives cannot be calculated for " + name_);
3229 
3230  // Number of directional derivatives
3231  casadi_int nfwd = fseed.size();
3232  fsens.resize(nfwd);
3233 
3234  // Quick return if no seeds
3235  if (nfwd==0) return;
3236 
3237  // Check if seeds need to have dimensions corrected
3238  casadi_int npar = 1;
3239  for (auto&& r : fseed) {
3240  if (!matching_arg(r, npar)) {
3241  FunctionInternal::call_forward(arg, res, replace_fseed(fseed, npar),
3242  fsens, always_inline, never_inline);
3243  return;
3244  }
3245  }
3246 
3247  // Calculating full Jacobian and then multiplying
3248  if (fwdViaJac(nfwd)) {
3249  // Multiply the Jacobian from the right
3250  std::vector<MX> darg = arg;
3251  darg.insert(darg.end(), res.begin(), res.end());
3252  std::vector<MX> J = jacobian()(darg);
3253  // Join forward seeds
3254  std::vector<MX> v(nfwd), all_fseed(n_in_);
3255  for (size_t i = 0; i < n_in_; ++i) {
3256  for (size_t d = 0; d < nfwd; ++d) v[d] = vec(fseed.at(d).at(i));
3257  all_fseed[i] = horzcat(v);
3258  }
3259  // Calculate forward sensitivities
3260  std::vector<MX> all_fsens(n_out_);
3261  std::vector<MX>::const_iterator J_it = J.begin();
3262  for (size_t oind = 0; oind < n_out_; ++oind) {
3263  for (size_t iind = 0; iind < n_in_; ++iind) {
3264  // Add contribution
3265  MX a = mtimes(*J_it++, all_fseed[iind]);
3266  all_fsens[oind] = all_fsens[oind].is_empty(true) ? a : all_fsens[oind] + a;
3267  }
3268  }
3269  // Split forward sensitivities
3270  for (size_t d = 0; d < nfwd; ++d) fsens[d].resize(n_out_);
3271  for (size_t i = 0; i < n_out_; ++i) {
3272  v = horzsplit(all_fsens[i]);
3273  casadi_assert_dev(v.size() == nfwd);
3274  for (size_t d = 0; d < nfwd; ++d) fsens[d][i] = reshape(v[d], size_out(i));
3275  }
3276  } else {
3277  // Evaluate in batches
3278  casadi_assert_dev(enable_forward_ || enable_fd_);
3279  casadi_int max_nfwd = max_num_dir_;
3280  if (!enable_fd_) {
3281  while (!has_forward(max_nfwd)) max_nfwd/=2;
3282  }
3283  casadi_int offset = 0;
3284  while (offset<nfwd) {
3285  // Number of derivatives, in this batch
3286  casadi_int nfwd_batch = std::min(nfwd-offset, max_nfwd);
3287 
3288  // All inputs and seeds
3289  std::vector<MX> darg;
3290  darg.reserve(n_in_ + n_out_ + n_in_);
3291  darg.insert(darg.end(), arg.begin(), arg.end());
3292  darg.insert(darg.end(), res.begin(), res.end());
3293  std::vector<MX> v(nfwd_batch);
3294  for (casadi_int i=0; i<n_in_; ++i) {
3295  for (casadi_int d=0; d<nfwd_batch; ++d) v[d] = fseed[offset+d][i];
3296  darg.push_back(horzcat(v));
3297  }
3298 
3299  // Create the evaluation node
3300  Function dfcn = self().forward(nfwd_batch);
3301  std::vector<MX> x = dfcn(darg);
3302 
3303  casadi_assert_dev(x.size()==n_out_);
3304 
3305  // Retrieve sensitivities
3306  for (casadi_int d=0; d<nfwd_batch; ++d) fsens[offset+d].resize(n_out_);
3307  for (casadi_int i=0; i<n_out_; ++i) {
3308  if (size2_out(i)>0) {
3309  v = horzsplit(x[i], size2_out(i));
3310  casadi_assert_dev(v.size()==nfwd_batch);
3311  } else {
3312  v = std::vector<MX>(nfwd_batch, MX(size_out(i)));
3313  }
3314  for (casadi_int d=0; d<nfwd_batch; ++d) fsens[offset+d][i] = v[d];
3315  }
3316 
3317  // Update offset
3318  offset += nfwd_batch;
3319  }
3320  }
3321  }
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 3438 of file function_internal.cpp.

3442  {
3443  casadi_assert(!(always_inline && never_inline), "Inconsistent options");
3444  if (fseed.empty()) { // Quick return if no seeds
3445  fsens.clear();
3446  return;
3447  }
3448  casadi_error("'forward' (SX) not defined for " + class_name());
3449  }

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

1596  {
1597  const auto& m = call_.el[e.i1];
1598  const T** call_arg = arg;
1599  T** call_res = res;
1600  casadi_int* call_iw = iw;
1601  T* call_w = w;
1602  T* nz_in;
1603  T* nz_out;
1604 
1605  call_setup(m, &call_arg, &call_res, &call_iw, &call_w, &nz_in, &nz_out);
1606 
1607  // Populate nz_in from work vector
1608  for (casadi_int i=0;i<m.n_dep;++i) {
1609  nz_in[i] = w[m.dep[i]];
1610  }
1611  // Perform call nz_in -> nz_out
1612  m.f(call_arg, call_res, call_iw, call_w);
1613 
1614  // Store nz_out results back in workvector
1615  for (casadi_int i=0;i<m.n_res;++i) {
1616  // Only if the result is actually needed
1617  if (m.res[i]>=0) {
1618  w[m.res[i]] = nz_out[i];
1619  }
1620  }
1621  }

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

4127  {
4128  if (npar==1) {
4129  eval_mx(arg, res, always_inline, never_inline);
4130  } else {
4131  // Split it up arguments
4132  std::vector<std::vector<MX>> v(npar, arg);
4133  std::vector<MX> t;
4134  for (int i=0; i<n_in_; ++i) {
4135  if (arg[i].size2()!=size2_in(i)) {
4136  t = horzsplit(arg[i], size2_in(i));
4137  casadi_assert_dev(t.size()==npar);
4138  for (int p=0; p<npar; ++p) v[p][i] = t[p];
4139  }
4140  }
4141  // Unroll the loop
4142  for (int p=0; p<npar; ++p) {
4143  eval_mx(v[p], t, always_inline, never_inline);
4144  v[p] = t;
4145  }
4146  // Concatenate results
4147  t.resize(npar);
4148  res.resize(n_out_);
4149  for (int i=0; i<n_out_; ++i) {
4150  for (int p=0; p<npar; ++p) t[p] = v[p][i];
4151  res[i] = horzcat(t);
4152  }
4153  }
4154  }
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 1719 of file function_internal.hpp.

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

1625  {
1626  const auto& m = call_.el[e.i1];
1627  bvec_t** call_arg = arg;
1628  bvec_t** call_res = res;
1629  casadi_int* call_iw = iw;
1630  bvec_t* call_w = w;
1631  bvec_t* nz_in;
1632  bvec_t* nz_out;
1633 
1634  call_setup(m, &call_arg, &call_res, &call_iw, &call_w, &nz_in, &nz_out);
1635 
1636  std::fill_n(nz_in, m.n_dep, 0);
1637 
1638  // Read in reverse seeds nz_out from work vector
1639  for (casadi_int i=0;i<m.n_res;++i) {
1640  nz_out[i] = (m.res[i]>=0) ? w[m.res[i]] : 0;
1641  }
1642 
1643  // Perform reverse mode call nz_out -> nz_in
1644  m.f.rev(call_arg, call_res, call_iw, call_w);
1645 
1646  // Clear out reverse seeds
1647  for (casadi_int i=0;i<m.n_res;++i) {
1648  if (m.res[i]>=0) w[m.res[i]] = 0;
1649  }
1650 
1651  // Store reverse sensitivities into work vector
1652  for (casadi_int i=0;i<m.n_dep;++i) {
1653  w[m.dep[i]] |= nz_in[i];
1654  }
1655  }

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

3327  {
3328  casadi_assert(!(always_inline && never_inline), "Inconsistent options");
3329  casadi_assert(!always_inline, "Class " + class_name() +
3330  " cannot be inlined in an MX expression");
3331 
3332  // Derivative information must be available
3333  casadi_assert(has_derivative(),
3334  "Derivatives cannot be calculated for " + name_);
3335 
3336  // Number of directional derivatives
3337  casadi_int nadj = aseed.size();
3338  asens.resize(nadj);
3339 
3340  // Quick return if no seeds
3341  if (nadj==0) return;
3342 
3343  // Check if seeds need to have dimensions corrected
3344  casadi_int npar = 1;
3345  for (auto&& r : aseed) {
3346  if (!matching_res(r, npar)) {
3347  FunctionInternal::call_reverse(arg, res, replace_aseed(aseed, npar),
3348  asens, always_inline, never_inline);
3349  return;
3350  }
3351  }
3352 
3353  // Calculating full Jacobian and then multiplying likely cheaper
3354  if (adjViaJac(nadj)) {
3355  // Multiply the transposed Jacobian from the right
3356  std::vector<MX> darg = arg;
3357  darg.insert(darg.end(), res.begin(), res.end());
3358  std::vector<MX> J = jacobian()(darg);
3359  // Join adjoint seeds
3360  std::vector<MX> v(nadj), all_aseed(n_out_);
3361  for (size_t i = 0; i < n_out_; ++i) {
3362  for (size_t d = 0; d < nadj; ++d) v[d] = vec(aseed.at(d).at(i));
3363  all_aseed[i] = horzcat(v);
3364  }
3365  // Calculate adjoint sensitivities
3366  std::vector<MX> all_asens(n_in_);
3367  std::vector<MX>::const_iterator J_it = J.begin();
3368  for (size_t oind = 0; oind < n_out_; ++oind) {
3369  for (size_t iind = 0; iind < n_in_; ++iind) {
3370  // Add contribution
3371  MX a = mtimes((*J_it++).T(), all_aseed[oind]);
3372  all_asens[iind] = all_asens[iind].is_empty(true) ? a : all_asens[iind] + a;
3373  }
3374  }
3375  // Split adjoint sensitivities
3376  for (size_t d = 0; d < nadj; ++d) asens[d].resize(n_in_);
3377  for (size_t i = 0; i < n_in_; ++i) {
3378  v = horzsplit(all_asens[i]);
3379  casadi_assert_dev(v.size() == nadj);
3380  for (size_t d = 0; d < nadj; ++d) {
3381  if (asens[d][i].is_empty(true)) {
3382  asens[d][i] = reshape(v[d], size_in(i));
3383  } else {
3384  asens[d][i] += reshape(v[d], size_in(i));
3385  }
3386  }
3387  }
3388  } else {
3389  // Evaluate in batches
3390  casadi_assert_dev(enable_reverse_);
3391  casadi_int max_nadj = max_num_dir_;
3392 
3393  while (!has_reverse(max_nadj)) max_nadj/=2;
3394  casadi_int offset = 0;
3395  while (offset<nadj) {
3396  // Number of derivatives, in this batch
3397  casadi_int nadj_batch = std::min(nadj-offset, max_nadj);
3398 
3399  // All inputs and seeds
3400  std::vector<MX> darg;
3401  darg.reserve(n_in_ + n_out_ + n_out_);
3402  darg.insert(darg.end(), arg.begin(), arg.end());
3403  darg.insert(darg.end(), res.begin(), res.end());
3404  std::vector<MX> v(nadj_batch);
3405  for (casadi_int i=0; i<n_out_; ++i) {
3406  for (casadi_int d=0; d<nadj_batch; ++d) v[d] = aseed[offset+d][i];
3407  darg.push_back(horzcat(v));
3408  }
3409 
3410  // Create the evaluation node
3411  Function dfcn = self().reverse(nadj_batch);
3412  std::vector<MX> x = dfcn(darg);
3413  casadi_assert_dev(x.size()==n_in_);
3414 
3415  // Retrieve sensitivities
3416  for (casadi_int d=0; d<nadj_batch; ++d) asens[offset+d].resize(n_in_);
3417  for (casadi_int i=0; i<n_in_; ++i) {
3418  if (size2_in(i)>0) {
3419  v = horzsplit(x[i], size2_in(i));
3420  casadi_assert_dev(v.size()==nadj_batch);
3421  } else {
3422  v = std::vector<MX>(nadj_batch, MX(size_in(i)));
3423  }
3424  for (casadi_int d=0; d<nadj_batch; ++d) {
3425  if (asens[offset+d][i].is_empty(true)) {
3426  asens[offset+d][i] = v[d];
3427  } else {
3428  asens[offset+d][i] += v[d];
3429  }
3430  }
3431  }
3432  // Update offset
3433  offset += nadj_batch;
3434  }
3435  }
3436  }
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 3451 of file function_internal.cpp.

3455  {
3456  casadi_assert(!(always_inline && never_inline), "Inconsistent options");
3457  if (aseed.empty()) { // Quick return if no seeds
3458  asens.clear();
3459  return;
3460  }
3461  casadi_error("'reverse' (SX) not defined for " + class_name());
3462  }

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

1573  {
1574  *call_arg += n_in_;
1575  *call_res += n_out_;
1576  *nz_in = *call_w + worksize_;
1577  *nz_out = *call_w + worksize_ + call_.sz_w_arg;
1578  *call_w = *call_w + worksize_ + call_.sz_w_arg + call_.sz_w_res;
1579 
1580  // Set up call_arg to point to nz_in
1581  T* ptr_w = *nz_in;
1582  for (casadi_int i=0;i<m.f_n_in;++i) {
1583  (*call_arg)[i] = ptr_w;
1584  ptr_w+=m.f_nnz_in[i];
1585  }
1586 
1587  // Set up call_res to point to nz_out
1588  ptr_w = *nz_out;
1589  for (casadi_int i=0;i<m.f_n_out;++i) {
1590  (*call_res)[i] = ptr_w;
1591  ptr_w+=m.f_nnz_out[i];
1592  }
1593  }

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

2060  {
2061  if (option_name == "print_instructions") {
2062  print_instructions_ = option_value;
2063  } else {
2064  // Option not found - continue to base classes
2065  XFunction<SXFunction, SX, SXNode>::change_option(option_name, option_value);
2066  }
2067  }
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(), 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 1766 of file function_internal.hpp.

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

3649  {
3650  // Matching dimensions
3651  if (arg.size()==inp.size()) return true;
3652  // Calling with a scalar - set all
3653  if (arg.is_scalar()) return true;
3654  // Vectors that are transposes of each other
3655  if (arg.is_vector() && inp.size()==std::make_pair(arg.size2(), arg.size1())) return true;
3656  // Horizontal repmat
3657  if (arg.size1()==inp.size1() && arg.size2()>0 && inp.size2()>0
3658  && inp.size2()%arg.size2()==0) return true;
3659  // Evaluate with multiple arguments
3660  if (npar!=-1 && arg.size1()==inp.size1() && arg.size2()>0 && inp.size2()>0
3661  && arg.size2()%(npar*inp.size2())==0) {
3662  npar *= arg.size2()/(npar*inp.size2());
3663  return true;
3664  }
3665  // Calling with empty matrix - set all to zero (after the structured branches above,
3666  // so that a 0-by-N argument can still be recognised as a parallel/repmat call)
3667  if (arg.is_empty()) return true;
3668  // No match
3669  return false;
3670  }

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

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

◆ check_mem_count()

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

Purpose if to allow more helpful error messages

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

Reimplemented in casadi::FmuFunction.

Definition at line 179 of file function_internal.hpp.

179 { }

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

◆ check_res()

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

Raises errors.

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

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

Definition at line 1790 of file function_internal.hpp.

1790  {
1791  casadi_assert(res.size()==n_out_, "Incorrect number of outputs: Expected "
1792  + str(n_out_) + ", got " + str(res.size()));
1793  for (casadi_int i=0; i<n_out_; ++i) {
1794  casadi_assert(check_mat(res[i].sparsity(), sparsity_out(i), npar),
1795  "Output " + str(i) + " (" + name_out_[i] + ") has mismatching shape. "
1796  "Expected " + str(size_out(i)) + ", got " + str(res[i].size()));
1797  }
1798  }
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 3858 of file function_internal.cpp.

3858  {
3859 #ifdef CASADI_WITH_THREAD
3860  std::lock_guard<std::mutex> lock(mtx_);
3861 #endif //CASADI_WITH_THREAD
3862  if (unused_.empty()) {
3863  check_mem_count(mem_.size()+1);
3864  // Allocate a new memory object
3865  void* m = alloc_mem();
3866  mem_.push_back(m);
3867  if (init_mem(m)) {
3868  casadi_error("Failed to create or initialize memory object");
3869  }
3870  return static_cast<int>(mem_.size()) - 1;
3871  } else {
3872  // Use an unused memory object
3873  int m = unused_.top();
3874  unused_.pop();
3875  return m;
3876  }
3877  }
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 133 of file sx_function.hpp.

133 {return "SXFunction";}

◆ clear_mem()

void casadi::ProtoFunction::clear_mem ( )
inherited

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

Definition at line 3746 of file function_internal.cpp.

3746  {
3747  for (auto&& i : mem_) {
3748  if (i!=nullptr) free_mem(i);
3749  }
3750  mem_.clear();
3751  }
virtual void free_mem(void *mem) const
Free memory block.

References casadi::ProtoFunction::free_mem().

Referenced by casadi::AlpaqaInterface::~AlpaqaInterface(), casadi::AmplInterface::~AmplInterface(), casadi::BlazingSplineFunction::~BlazingSplineFunction(), casadi::Blocksqp::~Blocksqp(), casadi::BonminInterface::~BonminInterface(), casadi::BSplineInterpolant::~BSplineInterpolant(), casadi::CallbackInternal::~CallbackInternal(), casadi::CbcInterface::~CbcInterface(), casadi::ClarabelInterface::~ClarabelInterface(), casadi::ClpInterface::~ClpInterface(), casadi::CplexInterface::~CplexInterface(), casadi::CsparseInterface::~CsparseInterface(), casadi::CvodesInterface::~CvodesInterface(), casadi::DaqpInterface::~DaqpInterface(), casadi::External::~External(), casadi::FastNewton::~FastNewton(), casadi::FatropConicInterface::~FatropConicInterface(), casadi::FatropInterface::~FatropInterface(), casadi::Feasiblesqpmethod::~Feasiblesqpmethod(), casadi::FiniteDiff::~FiniteDiff(), casadi::FixedStepIntegrator::~FixedStepIntegrator(), casadi::FmuFunction::~FmuFunction(), casadi::GurobiInterface::~GurobiInterface(), casadi::HighsInterface::~HighsInterface(), casadi::HpipmInterface::~HpipmInterface(), casadi::HpmpcInterface::~HpmpcInterface(), casadi::IdasInterface::~IdasInterface(), casadi::ImplicitToNlp::~ImplicitToNlp(), casadi::IpoptInterface::~IpoptInterface(), casadi::Ipqp::~Ipqp(), casadi::JitFunction::~JitFunction(), casadi::KinsolInterface::~KinsolInterface(), casadi::KnitroInterface::~KnitroInterface(), casadi::LapackLu::~LapackLu(), casadi::LapackQr::~LapackQr(), casadi::LinearInterpolant::~LinearInterpolant(), casadi::LinearInterpolantJac::~LinearInterpolantJac(), casadi::LinsolLdl::~LinsolLdl(), casadi::LinsolQr::~LinsolQr(), casadi::LinsolTridiag::~LinsolTridiag(), casadi::Lsqr::~Lsqr(), casadi::Ma27Interface::~Ma27Interface(), casadi::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 2452 of file function_internal.cpp.

2452  {
2453  // Define function
2454  g << "/* " << definition() << " */\n";
2455  g << "static " << signature(fname) << " {\n";
2456 
2457  // Reset local variables, flush buffer
2458  g.flush(g.body);
2459 
2460  g.scope_enter();
2461 
2462  if (dump_in_ || dump_out_) {
2463  Function F = shared_from_this<Function>();
2464  std::string cg_name = codegen_name(g, false);
2465  std::string dump_counter = g.shorthand(cg_name + "_dump_counter");
2466  g.auxiliaries << "static int " << dump_counter << " = 0;\n";
2467  if (g.thread_safe()) {
2468  g.define_local_mutex(F, cg_name + "_dump_mutex");
2469  std::string dump_mutex = g.local_mutex(F, cg_name + "_dump_mutex");
2470  g << "CASADI_MUTEX_LOCK(&" << dump_mutex << ");\n";
2471  g << "int dump_id_local = " << dump_counter << "++;\n";
2472  g << "CASADI_MUTEX_UNLOCK(&" << dump_mutex << ");\n";
2473  } else {
2474  g << "int dump_id_local = " << dump_counter << "++;\n";
2475  }
2476  }
2477 
2478  if (dump_in_) g.generate_dump(shared_from_this<Function>(), "arg", true);
2479  if (print_in_) g.generate_print(shared_from_this<Function>(), "arg", true);
2480 
2481  // Generate function body (to buffer)
2482  codegen_body(g);
2483 
2484  if (dump_out_) g.generate_dump(shared_from_this<Function>(), "res", false);
2485  if (print_out_) g.generate_print(shared_from_this<Function>(), "res", false);
2486 
2487  g.scope_exit();
2488 
2489  // Finalize the function
2490  g << "return 0;\n";
2491  g << "}\n\n";
2492 
2493  // Flush to function body
2494  g.flush(g.body);
2495  }
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 2596 of file function_internal.cpp.

2596  {
2597  bool needs_mem = codegen_needs_mem();
2598  if (needs_mem) {
2599  std::string name = codegen_name(g, false);
2600  std::string mem_counter = g.shorthand(name + "_mem_counter");
2601  g << "return " + mem_counter + "++;\n";
2602  }
2603  }
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 344 of file sx_function.cpp.

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

2605  {
2606  std::string name = codegen_name(g, false);
2607  std::string stack_counter = g.shorthand(name + "_unused_stack_counter");
2608  std::string stack = g.shorthand(name + "_unused_stack");
2609  std::string mem_counter = g.shorthand(name + "_mem_counter");
2610  std::string mem_array = g.shorthand(name + "_mem");
2611  std::string alloc_mem = g.shorthand(name + "_alloc_mem");
2612  std::string init_mem = g.shorthand(name + "_init_mem");
2613 
2614 
2615  g.auxiliaries << "static int " << mem_counter << " = 0;\n";
2616  g.auxiliaries << "static int " << stack_counter << " = -1;\n";
2617  g.auxiliaries << "static int " << stack << "[CASADI_MAX_NUM_THREADS];\n";
2618  g.auxiliaries << "static " << codegen_mem_type() <<
2619  " " << mem_array << "[CASADI_MAX_NUM_THREADS];\n\n";
2620 
2621  if (g.thread_safe()) {
2622  Function F = shared_from_this<Function>();
2623  g.define_local_mutex(F, name + "_mem_mutex");
2624  std::string mem_mutex = g.local_mutex(F, name + "_mem_mutex");
2625  g << "CASADI_MUTEX_LOCK(&" << mem_mutex << ");\n";
2626  g.scope_add_cleanup("CASADI_MUTEX_UNLOCK(&" + mem_mutex + ");\n");
2627  }
2628 
2629  g.local("mid", "int");
2630 
2631  g << "if (" << stack_counter << ">=0) {\n";
2632  g.scope_return(stack + "[" + stack_counter + "--]");
2633  g << "} else {\n";
2634  g << "if (" << mem_counter << "==CASADI_MAX_NUM_THREADS) {\n";
2635  g.scope_return("-1");
2636  g << "}\n";
2637  g << "mid = " << alloc_mem << "();\n";
2638  g << "if (mid<0) {\n";
2639  g.scope_return("-1");
2640  g << "}\n";
2641  g << "if (" << init_mem << "(mid)) {\n";
2642  g.scope_return("-1");
2643  g << "}\n";
2644  g.scope_return("mid");
2645  g << "}\n";
2646  }
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 219 of file sx_function.cpp.

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

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

◆ codegen_decref()

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

2551  {
2552 
2553  // Treat dependent functions
2554  std::set<void*> added;
2555  Function F = shared_from_this<Function>();
2556  for (const Function& f : F.find_functions(0)) {
2557  if (f->has_refcount_in_deps_) {
2558  std::string cg_name = f->codegen_name(g, false);
2559  auto i = added.insert(f.get());
2560  if (i.second) { // prevent duplicate calls
2561  std::string decref = g.shorthand(cg_name + "_decref");
2562  g << decref << "();\n";
2563  }
2564  }
2565  }
2566 
2567  if (has_refcount_) {
2568  std::string name = codegen_name(g, false);
2569  std::string ref_counter = g.shorthand(name + "_ref_counter");
2570  std::string mem_counter = g.shorthand(name + "_mem_counter");
2571  std::string free_mem = g.shorthand(name + "_free_mem");
2572  g << ref_counter << "--;\n";
2573  g << "if (" << ref_counter << "==0) {\n";
2574  if (codegen_needs_mem()) {
2575  g << "while (" << mem_counter << ">0) {\n";
2576  g << free_mem << "(--" << mem_counter << ");\n";
2577  g << "}\n";
2578  }
2579  if (g.thread_safe()) {
2580  Function F = shared_from_this<Function>();
2581  for (const auto& m : g.local_mutexes(F)) {
2582  std::string mtx = g.local_mutex(F, m);
2583  g << "#if CASADI_MUTEX_USE_STATIC_INIT == 0\n";
2584  g << "CASADI_MUTEX_DESTROY(&" << mtx << ");\n";
2585  g << "#endif\n";
2586  }
2587  }
2588  g << "}\n";
2589  }
2590  }
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 2518 of file function_internal.cpp.

2518  {
2519  if (has_refcount_) {
2520  std::string name = codegen_name(g, false);
2521  std::string ref_counter = g.shorthand(name + "_ref_counter");
2522  g.auxiliaries << "static int " << ref_counter << " = 0;\n";
2523 
2524  Function F = shared_from_this<Function>();
2525  if (g.thread_safe()) {
2526  for (const auto& m : g.local_mutexes(F)) {
2527  std::string mtx = g.local_mutex(F, m);
2528  g << "#if CASADI_MUTEX_USE_STATIC_INIT == 0\n";
2529  g << "if (" << ref_counter << "==0) CASADI_MUTEX_INIT(&" << mtx << ");\n";
2530  g << "#endif\n";
2531  }
2532  }
2533  g << ref_counter << "++;\n";
2534  }
2535 
2536  // Treat dependent functions
2537  std::set<void*> added;
2538  Function F = shared_from_this<Function>();
2539  for (const Function& f : F.find_functions(0)) {
2540  if (f->has_refcount_in_deps_) {
2541  std::string cg_name = f->codegen_name(g, false);
2542  auto i = added.insert(f.get());
2543  if (i.second) { // prevent duplicate calls
2544  std::string incref = g.shorthand(cg_name + "_incref");
2545  g << incref << "();\n";
2546  }
2547  }
2548  }
2549  }

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

2993  {
2994  std::string name = codegen_name(g, false);
2995  std::string mem_array = g.shorthand(name + "_mem");
2996  return mem_array+"[" + index + "]";
2997  }

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

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

2668  {
2669  bool needs_mem = codegen_needs_mem();
2670  std::string name = codegen_name(g, false);
2671 
2672  // Checkout/release routines
2673  g << g.declare("int " + name_ + "_checkout(void)") << " {\n";
2674  if (needs_mem) {
2675  std::string checkout = g.shorthand(name + "_checkout");
2676  g << "return " << checkout << "();\n";
2677  } else {
2678  g << "return 0;\n";
2679  }
2680  g << "}\n\n";
2681 
2682  if (needs_mem) {
2683  g << g.declare("void " + name_ + "_release(int mem)") << " {\n";
2684  std::string release = g.shorthand(name + "_release");
2685  g << release << "(mem);\n";
2686  } else {
2687  g << g.declare("void " + name_ + "_release(int mem)") << " {\n";
2688  }
2689  g << "}\n\n";
2690 
2691  // Reference counter routines
2692  g << g.declare("void " + name_ + "_incref(void)") << " {\n";
2693  if (has_refcount_in_deps_) {
2694  std::string incref = g.shorthand(name + "_incref");
2695  g << incref << "();\n";
2696  }
2697  g << "}\n\n"
2698  << g.declare("void " + name_ + "_decref(void)") << " {\n";
2699  if (has_refcount_in_deps_) {
2700  std::string decref = g.shorthand(name + "_decref");
2701  g << decref << "();\n";
2702  }
2703  g << "}\n\n";
2704 
2705  // Number of inputs and outptus
2706  g << g.declare("casadi_int " + name_ + "_n_in(void)")
2707  << " { return " << n_in_ << ";}\n\n"
2708  << g.declare("casadi_int " + name_ + "_n_out(void)")
2709  << " { return " << n_out_ << ";}\n\n";
2710 
2711  // Default inputs
2712  g << g.declare("casadi_real " + name_ + "_default_in(casadi_int i)") << " {\n"
2713  << "switch (i) {\n";
2714  for (casadi_int i=0; i<n_in_; ++i) {
2715  double def = get_default_in(i);
2716  if (def!=0) g << "case " << i << ": return " << g.constant(def) << ";\n";
2717  }
2718  g << "default: return 0;\n}\n"
2719  << "}\n\n";
2720 
2721  // Input names
2722  g << g.declare("const char* " + name_ + "_name_in(casadi_int i)") << " {\n"
2723  << "switch (i) {\n";
2724  for (casadi_int i=0; i<n_in_; ++i) {
2725  g << "case " << i << ": return \"" << name_in_[i] << "\";\n";
2726  }
2727  g << "default: return 0;\n}\n"
2728  << "}\n\n";
2729 
2730  // Output names
2731  g << g.declare("const char* " + name_ + "_name_out(casadi_int i)") << " {\n"
2732  << "switch (i) {\n";
2733  for (casadi_int i=0; i<n_out_; ++i) {
2734  g << "case " << i << ": return \"" << name_out_[i] << "\";\n";
2735  }
2736  g << "default: return 0;\n}\n"
2737  << "}\n\n";
2738 
2739  // Codegen sparsities
2740  codegen_sparsities(g);
2741 
2742  // Function that returns work vector lengths
2743  g << g.declare(
2744  "int " + name_ + "_work(casadi_int *sz_arg, casadi_int* sz_res, "
2745  "casadi_int *sz_iw, casadi_int *sz_w)")
2746  << " {\n"
2747  << "if (sz_arg) *sz_arg = " << codegen_sz_arg(g) << ";\n"
2748  << "if (sz_res) *sz_res = " << codegen_sz_res(g) << ";\n"
2749  << "if (sz_iw) *sz_iw = " << codegen_sz_iw(g) << ";\n"
2750  << "if (sz_w) *sz_w = " << codegen_sz_w(g) << ";\n"
2751  << "return 0;\n"
2752  << "}\n\n";
2753 
2754  // Function that returns work vector lengths in bytes
2755  g << g.declare(
2756  "int " + name_ + "_work_bytes(casadi_int *sz_arg, casadi_int* sz_res, "
2757  "casadi_int *sz_iw, casadi_int *sz_w)")
2758  << " {\n"
2759  << "if (sz_arg) *sz_arg = " << codegen_sz_arg(g) << "*sizeof(const casadi_real*);\n"
2760  << "if (sz_res) *sz_res = " << codegen_sz_res(g) << "*sizeof(casadi_real*);\n"
2761  << "if (sz_iw) *sz_iw = " << codegen_sz_iw(g) << "*sizeof(casadi_int);\n"
2762  << "if (sz_w) *sz_w = " << codegen_sz_w(g) << "*sizeof(casadi_real);\n"
2763  << "return 0;\n"
2764  << "}\n\n";
2765 
2766  // Also add to header file to allow getting
2767  if (g.with_header) {
2768  g.header
2769  << "#define " << name_ << "_SZ_ARG " << codegen_sz_arg(g) << "\n"
2770  << "#define " << name_ << "_SZ_RES " << codegen_sz_res(g) << "\n"
2771  << "#define " << name_ << "_SZ_IW " << codegen_sz_iw(g) << "\n"
2772  << "#define " << name_ << "_SZ_W " << codegen_sz_w(g) << "\n";
2773  }
2774 
2775  // Which inputs are differentiable
2776  if (!all(is_diff_in_)) {
2777  g << g.declare("int " + name_ + "_diff_in(casadi_int i)") << " {\n"
2778  << "switch (i) {\n";
2779  for (casadi_int i=0; i<n_in_; ++i) {
2780  g << "case " << i << ": return " << is_diff_in_[i] << ";\n";
2781  }
2782  g << "default: return -1;\n}\n"
2783  << "}\n\n";
2784  }
2785 
2786  // Which outputs are differentiable
2787  if (!all(is_diff_out_)) {
2788  g << g.declare("int " + name_ + "_diff_out(casadi_int i)") << " {\n"
2789  << "switch (i) {\n";
2790  for (casadi_int i=0; i<n_out_; ++i) {
2791  g << "case " << i << ": return " << is_diff_out_[i] << ";\n";
2792  }
2793  g << "default: return -1;\n}\n"
2794  << "}\n\n";
2795  }
2796 
2797  // Generate mex gateway for the function
2798  if (g.mex) {
2799  // Begin conditional compilation
2800  g << "#ifdef MATLAB_MEX_FILE\n";
2801 
2802  // Declare wrapper
2803  g << "void mex_" << name_
2804  << "(int resc, mxArray *resv[], int argc, const mxArray *argv[]) {\n"
2805  << "casadi_int i;\n";
2806  g << "int mem;\n";
2807  // Work vectors, including input and output buffers
2808  casadi_int i_nnz = nnz_in(), o_nnz = nnz_out();
2809  size_t sz_w = this->sz_w();
2810  for (casadi_int i=0; i<n_in_; ++i) {
2811  const Sparsity& s = sparsity_in_[i];
2812  sz_w = std::max(sz_w, static_cast<size_t>(s.size1())); // To be able to copy a column
2813  sz_w = std::max(sz_w, static_cast<size_t>(s.size2())); // To be able to copy a row
2814  }
2815  sz_w += i_nnz + o_nnz;
2816  g << CodeGenerator::array("casadi_real", "w", sz_w);
2817  g << CodeGenerator::array("casadi_int", "iw", sz_iw());
2818  std::string fw = "w+" + str(i_nnz + o_nnz);
2819 
2820  // Copy inputs to buffers
2821  casadi_int offset=0;
2822  g << CodeGenerator::array("const casadi_real*", "arg", sz_arg(), "{0}");
2823 
2824  // Allocate output buffers
2825  g << "casadi_real* res[" << sz_res() << "] = {0};\n";
2826 
2827  // Check arguments
2828  g << "if (argc>" << n_in_ << ") mexErrMsgIdAndTxt(\"Casadi:RuntimeError\","
2829  << "\"Evaluation of \\\"" << name_ << "\\\" failed. Too many input arguments "
2830  << "(%d, max " << n_in_ << ")\", argc);\n";
2831 
2832  g << "if (resc>" << n_out_ << ") mexErrMsgIdAndTxt(\"Casadi:RuntimeError\","
2833  << "\"Evaluation of \\\"" << name_ << "\\\" failed. "
2834  << "Too many output arguments (%d, max " << n_out_ << ")\", resc);\n";
2835 
2836  for (casadi_int i=0; i<n_in_; ++i) {
2837  std::string p = "argv[" + str(i) + "]";
2838  g << "if (--argc>=0) arg[" << i << "] = "
2839  << g.from_mex(p, "w", offset, sparsity_in_[i], fw) << "\n";
2840  offset += nnz_in(i);
2841  }
2842 
2843  for (casadi_int i=0; i<n_out_; ++i) {
2844  if (i==0) {
2845  // if i==0, always store output (possibly ans output)
2846  g << "--resc;\n";
2847  } else {
2848  // Store output, if it exists
2849  g << "if (--resc>=0) ";
2850  }
2851  // Create and get pointer
2852  g << g.res(i) << " = w+" << str(offset) << ";\n";
2853  offset += nnz_out(i);
2854  }
2855  g << name_ << "_incref();\n";
2856  g << "mem = " << name_ << "_checkout();\n";
2857 
2858  // Call the function
2859  g << "i = " << name_ << "(arg, res, iw, " << fw << ", mem);\n"
2860  << "if (i) mexErrMsgIdAndTxt(\"Casadi:RuntimeError\",\"Evaluation of \\\"" << name_
2861  << "\\\" failed.\");\n";
2862  g << name_ << "_release(mem);\n";
2863  g << name_ << "_decref();\n";
2864 
2865  // Save results
2866  for (casadi_int i=0; i<n_out_; ++i) {
2867  g << "if (" << g.res(i) << ") resv[" << i << "] = "
2868  << g.to_mex(sparsity_out_[i], g.res(i)) << "\n";
2869  }
2870 
2871  // End conditional compilation and function
2872  g << "}\n"
2873  << "#endif\n\n";
2874  }
2875 
2876  if (g.main) {
2877  // Declare wrapper
2878  g << "casadi_int main_" << name_ << "(casadi_int argc, char* argv[]) {\n";
2879 
2880  g << "casadi_int j;\n";
2881  g << "casadi_real* a;\n";
2882  g << "const casadi_real* r;\n";
2883  g << "casadi_int flag;\n";
2884  if (needs_mem) g << "int mem;\n";
2885 
2886 
2887 
2888  // Work vectors and input and output buffers
2889  size_t nr = sz_w() + nnz_in() + nnz_out();
2890  g << CodeGenerator::array("casadi_int", "iw", sz_iw())
2891  << CodeGenerator::array("casadi_real", "w", nr);
2892 
2893  // Input buffers
2894  g << "const casadi_real* arg[" << sz_arg() << "];\n";
2895 
2896  // Output buffers
2897  g << "casadi_real* res[" << sz_res() << "];\n";
2898 
2899  casadi_int off=0;
2900  for (casadi_int i=0; i<n_in_; ++i) {
2901  g << "arg[" << i << "] = w+" << off << ";\n";
2902  off += nnz_in(i);
2903  }
2904  for (casadi_int i=0; i<n_out_; ++i) {
2905  g << "res[" << i << "] = w+" << off << ";\n";
2906  off += nnz_out(i);
2907  }
2908 
2909  // TODO(@jaeandersson): Read inputs from file. For now; read from stdin
2910  g << "a = w;\n"
2911  << "for (j=0; j<" << nnz_in() << "; ++j) "
2912  << "if (scanf(\"%lg\", a++)<=0) return 2;\n";
2913 
2914  if (has_refcount_in_deps_) {
2915  g << name_ << "_incref();\n";
2916  }
2917 
2918  if (needs_mem) {
2919  g << "mem = " << name_ << "_checkout();\n";
2920  }
2921 
2922  // Call the function
2923  g << "flag = " << name_ << "(arg, res, iw, w+" << off << ", ";
2924  if (needs_mem) {
2925  g << "mem";
2926  } else {
2927  g << "0";
2928  }
2929  g << ");\n";
2930  if (needs_mem) {
2931  g << name_ << "_release(mem);\n";
2932  }
2933 
2934  if (has_refcount_in_deps_) {
2935  g << name_ << "_decref();\n";
2936  }
2937 
2938  g << "if (flag) return flag;\n";
2939 
2940  // TODO(@jaeandersson): Write outputs to file. For now: print to stdout
2941  g << "r = w+" << nnz_in() << ";\n"
2942  << "for (j=0; j<" << nnz_out() << "; ++j) "
2943  << g.printf("%.16e ", "*r++") << "\n";
2944 
2945  // End with newline
2946  g << g.printf("\\n") << "\n";
2947 
2948  // Finalize function
2949  g << "return 0;\n"
2950  << "}\n\n";
2951  }
2952 
2953  if (g.with_mem) {
2954  // Allocate memory
2955  g << g.declare("casadi_functions* " + name_ + "_functions(void)") << " {\n"
2956  << "static casadi_functions fun = {\n"
2957  << name_ << "_incref,\n"
2958  << name_ << "_decref,\n"
2959  << name_ << "_checkout,\n"
2960  << name_ << "_release,\n"
2961  << name_ << "_default_in,\n"
2962  << name_ << "_n_in,\n"
2963  << name_ << "_n_out,\n"
2964  << name_ << "_name_in,\n"
2965  << name_ << "_name_out,\n"
2966  << name_ << "_sparsity_in,\n"
2967  << name_ << "_sparsity_out,\n"
2968  << name_ << "_work,\n"
2969  << name_ << "\n"
2970  << "};\n"
2971  << "return &fun;\n"
2972  << "}\n";
2973  }
2974  // Flush
2975  g.flush(g.body);
2976  }
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 2978 of file function_internal.cpp.

2978  {
2979  if (ns) {
2980  // Get the index of the function
2981  for (auto&& e : g.added_functions_) {
2982  if (e.f.get()==this) return e.codegen_name;
2983  }
2984  } else {
2985  for (casadi_int i=0;i<g.added_functions_.size();++i) {
2986  const auto & e = g.added_functions_[i];
2987  if (e.f.get()==this) return "f" + str(i);
2988  }
2989  }
2990  casadi_error("Function '" + name_ + "' not found");
2991  }

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

2648  {
2649  std::string name = codegen_name(g, false);
2650  std::string stack_counter = g.shorthand(name + "_unused_stack_counter");
2651  std::string stack = g.shorthand(name + "_unused_stack");
2652 
2653  if (g.thread_safe()) {
2654  Function F = shared_from_this<Function>();
2655  std::string mem_mutex = g.local_mutex(F, name + "_mem_mutex");
2656  g << "CASADI_MUTEX_LOCK(&" << mem_mutex << ");\n";
2657  g.scope_add_cleanup("CASADI_MUTEX_UNLOCK(&" + mem_mutex + ");\n");
2658  }
2659 
2660  g << stack << "[++" << stack_counter << "] = mem;\n";
2661  g.scope_return();
2662  }

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

3100  {
3101  return sz_arg();
3102  }

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

3106  {
3107  return sz_iw();
3108  }

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

3103  {
3104  return sz_res();
3105  }

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

1893  {
1894  // Get default inputs
1895  std::vector<M> arg_v(n_in_);
1896  for (casadi_int i=0; i<arg_v.size(); ++i) {
1897  arg_v[i] = get_default_in(i);
1898  }
1899 
1900  // Assign provided inputs
1901  for (auto&& e : arg) {
1902  arg_v.at(index_in(e.first)) = e.second;
1903  }
1904 
1905  return arg_v;
1906  }
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 1880 of file function_internal.hpp.

1881  {
1882  casadi_assert(arg.size()==n_in_, "Incorrect number of inputs: Expected "
1883  + str(n_in_) + ", got " + str(arg.size()));
1884  std::map<std::string, M> ret;
1885  for (casadi_int i=0;i<n_in_;++i) {
1886  ret[name_in_[i]] = arg[i];
1887  }
1888  return ret;
1889  }

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

1922  {
1923  // Get default inputs
1924  std::vector<M> res_v(n_out_);
1925  for (casadi_int i=0; i<res_v.size(); ++i) {
1926  res_v[i] = std::numeric_limits<double>::quiet_NaN();
1927  }
1928 
1929  // Assign provided inputs
1930  for (auto&& e : res) {
1931  M a = e.second;
1932  res_v.at(index_out(e.first)) = a;
1933  }
1934  return res_v;
1935  }
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 1909 of file function_internal.hpp.

1910  {
1911  casadi_assert(res.size()==n_out_, "Incorrect number of outputs: Expected "
1912  + str(n_out_) + ", got " + str(res.size()));
1913  std::map<std::string, M> ret;
1914  for (casadi_int i=0;i<n_out_;++i) {
1915  ret[name_out_[i]] = res[i];
1916  }
1917  return ret;
1918  }

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.

175  {
176  // Note: i != this because of something something multiple inheritance
177  return str( (casadi_int)(i)) + "/" + static_cast<const Internal*>(this)->class_name();
178  }

◆ definition()

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

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

Definition at line 1076 of file function_internal.cpp.

1076  {
1077  std::stringstream s;
1078 
1079  // Print name
1080  s << name_ << ":(";
1081  // Print input arguments
1082  for (casadi_int i=0; i<n_in_; ++i) {
1083  if (!is_diff_in_.empty() && !is_diff_in_[i]) s << "#";
1084  s << name_in_[i] << sparsity_in_[i].postfix_dim() << (i==n_in_-1 ? "" : ",");
1085  }
1086  s << ")->(";
1087  // Print output arguments
1088  for (casadi_int i=0; i<n_out_; ++i) {
1089  if (!is_diff_out_.empty() && !is_diff_out_[i]) s << "#";
1090  s << name_out_[i] << sparsity_out_[i].postfix_dim() << (i==n_out_-1 ? "" : ",");
1091  }
1092  s << ")";
1093 
1094  return s.str();
1095  }

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

2043  {
2044  return new SXFunction(s);
2045  }
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 2184 of file function_internal.cpp.

2184  {
2185  // Highest index found in current inputs and outputs
2186  casadi_int highest_index = 0;
2187  // Loop over both input names and output names
2188  for (const std::vector<std::string>& name_io : {name_in_, name_out_}) {
2189  for (const std::string& n : name_io) {
2190  // Find end of prefix, skip if no prefix
2191  size_t end = n.find('_');
2192  if (end >= n.size()) continue;
2193  // Skip if too short
2194  if (end < prefix.size()) continue;
2195  // Skip if wrong prefix
2196  if (n.compare(0, prefix.size(), prefix) != 0) continue;
2197  // Beginning of index
2198  size_t begin = prefix.size();
2199  // Check if any index
2200  casadi_int this_index;
2201  if (begin == end) {
2202  // No prefix, implicitly 1
2203  this_index = 1;
2204  } else {
2205  // Read index from string
2206  this_index = std::stoi(n.substr(begin, end - begin));
2207  }
2208  // Find the highest index
2209  if (this_index > highest_index) highest_index = this_index;
2210  }
2211  }
2212  // Return one higher index
2213  if (highest_index == 0) {
2214  return prefix + "_";
2215  } else {
2216  return prefix + std::to_string(highest_index + 1) + "_";
2217  }
2218  }

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

Referenced by casadi::FunctionInternal::forward(), casadi::OnnxFunction::has_forward(), casadi::OnnxFunction::has_reverse(), 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 1097 of file function_internal.cpp.

1097  {
1098  stream << definition() << " " << class_name();
1099  if (more) {
1100  stream << std::endl;
1101  disp_more(stream);
1102  }
1103  }
virtual void disp_more(std::ostream &stream) const
Print more.

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

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

◆ disp_more()

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

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

Reimplemented from casadi::FunctionInternal.

Definition at line 202 of file sx_function.cpp.

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

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

◆ dm_in() [1/2]

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

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

Definition at line 3518 of file function_internal.cpp.

3518  {
3519  std::vector<DM> ret(n_in_);
3520  for (casadi_int i=0; i<ret.size(); ++i) {
3521  ret[i] = dm_in(i);
3522  }
3523  return ret;
3524  }
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 3526 of file function_internal.cpp.

3526  {
3527  std::vector<DM> ret(n_out_);
3528  for (casadi_int i=0; i<ret.size(); ++i) {
3529  ret[i] = dm_out(i);
3530  }
3531  return ret;
3532  }
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 1938 of file function_internal.hpp.

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

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

◆ eval()

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

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

Reimplemented from casadi::FunctionInternal.

Definition at line 72 of file sx_function.cpp.

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

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

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

1685  {
1686  const bvec_t nz = ~static_cast<bvec_t>(0);
1687  // Propagate signal activity forward (bit set = active (possibly nonzero))
1688  for (auto&& e : algorithm_) {
1689  switch (e.op) {
1690  case OP_CONST:
1691  w[e.i0] = (e.d!=0) ? nz : 0; break;
1692  case OP_PARAMETER:
1693  w[e.i0] = nz; break; // free variable: assume nonzero
1694  case OP_INPUT:
1695  w[e.i0] = (arg[e.i1]!=nullptr) ? arg[e.i1][e.i2] : 0;
1696  break;
1697  case OP_OUTPUT:
1698  if (res[e.i0]!=nullptr) res[e.i0][e.i2] = w[e.i1];
1699  break;
1700  case OP_CALL:
1701  call_activity(e, arg, res, iw, w);
1702  break;
1703  default: // Unary or binary operation
1704  if (casadi_math<double>::ndeps(e.op)==1) {
1705  // Zero input yields zero only for zero-preserving ops (sin, sqrt; not cos/exp)
1706  w[e.i0] = w[e.i1] ? nz : (operation_checker<F0XChecker>(e.op) ? 0 : nz);
1707  } else {
1708  const bool z0 = w[e.i1]!=0, z1 = w[e.i2]!=0;
1709  if (!z0 && !z1) w[e.i0] = operation_checker<F00Checker>(e.op) ? 0 : nz;
1710  else if (!z0 && z1) w[e.i0] = operation_checker<F0XChecker>(e.op) ? 0 : nz;
1711  else if ( z0 && !z1) w[e.i0] = operation_checker<FX0Checker>(e.op) ? 0 : nz;
1712  else w[e.i0] = nz;
1713  }
1714  break;
1715  }
1716  }
1717  return 0;
1718  }
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 2167 of file function_internal.cpp.

2167  {
2168  casadi_error("'eval_dm' not defined for " + class_name());
2169  }

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

446  {
447  return sp_forward(arg, res, iw, w, mem);
448  }
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 965 of file function_internal.cpp.

967  {
968  casadi_int dump_id = (dump_in_ || dump_out_ || dump_) ? get_dump_id() : 0;
969  if (dump_in_) dump_in(dump_id, arg);
970  if (dump_ && dump_id==0) dump();
971  if (print_in_) print_in(uout(), arg, false);
972  auto *m = static_cast<ProtoFunctionMemory*>(mem);
973 
974  // Avoid memory corruption
975  for (casadi_int i=0;i<n_in_;++i) {
976  casadi_assert(arg[i]==nullptr || arg[i]+nnz_in(i)<=w || arg[i]>=w+sz_w(),
977  "Memory corruption detected for input " + name_in_[i] + ".\n"+
978  "arg[" + str(i) + "] " + str(arg[i]) + "-" + str(arg[i]+nnz_in(i)) +
979  " intersects with w " + str(w)+"-"+str(w+sz_w())+".");
980  }
981  for (casadi_int i=0;i<n_out_;++i) {
982  casadi_assert(res[i]==nullptr || res[i]+nnz_out(i)<=w || res[i]>=w+sz_w(),
983  "Memory corruption detected for output " + name_out_[i]);
984  }
985  // Reset statistics
986  for (auto&& s : m->fstats) s.second.reset();
987  if (m->t_total) m->t_total->tic();
988  int ret;
989  if (eval_) {
990  auto *m = static_cast<FunctionMemory*>(mem);
991  m->stats_available = true;
992  int mem_ = 0;
993  if (checkout_) {
994 #ifdef CASADI_WITH_THREAD
995  std::lock_guard<std::mutex> lock(mtx_);
996 #endif //CASADI_WITH_THREAD
997  mem_ = checkout_();
998  }
999  ret = eval_(arg, res, iw, w, mem_);
1000  if (release_) {
1001 #ifdef CASADI_WITH_THREAD
1002  std::lock_guard<std::mutex> lock(mtx_);
1003 #endif //CASADI_WITH_THREAD
1004  release_(mem_);
1005  }
1006  } else {
1007  ret = eval(arg, res, iw, w, mem);
1008  }
1009  if (m->t_total) m->t_total->toc();
1010  // Show statistics
1011  print_time(m->fstats);
1012 
1013  if (dump_out_) dump_out(dump_id, res);
1014  if (print_out_) print_out(uout(), res, false);
1015  // Check all outputs for NaNs
1016  if (regularity_check_) {
1017  for (casadi_int i = 0; i < n_out_; ++i) {
1018  // Skip of not calculated
1019  if (!res[i]) continue;
1020  // Loop over nonzeros
1021  casadi_int nnz = this->nnz_out(i);
1022  for (casadi_int nz = 0; nz < nnz; ++nz) {
1023  if (isnan(res[i][nz]) || isinf(res[i][nz])) {
1024  // Throw readable error message
1025  casadi_error(str(res[i][nz]) + " detected for output " + name_out_[i] + " at "
1026  + sparsity_out(i).repr_el(nz));
1027  }
1028  }
1029  }
1030  }
1031  return ret;
1032  }
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 441 of file function_internal.hpp.

442  {
443  return eval_sx(arg, res, iw, w, mem, always_inline, never_inline);
444  }
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 1069 of file sx_function.cpp.

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

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

1827  {
1828 
1829  // Default values for options
1830  casadi_int indent_level = 0;
1831 
1832  // Read options
1833  for (auto&& op : options) {
1834  if (op.first=="indent_level") {
1835  indent_level = op.second;
1836  } else {
1837  casadi_error("Unknown option '" + op.first + "'.");
1838  }
1839  }
1840 
1841  // Construct indent string
1842  std::string indent;
1843  for (casadi_int i=0;i<indent_level;++i) {
1844  indent += " ";
1845  }
1846 
1847  // Non-cell aliases for inputs
1848  for (casadi_int i=0;i<n_in_;++i) {
1849  ss << indent << "argin_" << i << " = nonzeros_gen(varargin{" << i+1 << "});" << std::endl;
1850  }
1851 
1852  Function f = shared_from_this<Function>();
1853 
1854  for (casadi_int k=0;k<f.n_instructions();++k) {
1855  // Get operation
1856  casadi_int op = static_cast<casadi_int>(f.instruction_id(k));
1857  // Get input positions into workvector
1858  std::vector<casadi_int> o = f.instruction_output(k);
1859  // Get output positions into workvector
1860  std::vector<casadi_int> i = f.instruction_input(k);
1861  switch (op) {
1862  case OP_INPUT:
1863  {
1864  ss << indent << "w" << o[0] << " = " << "argin_" << i[0] << "(" << i[1]+1 << ");";
1865  ss << std::endl;
1866  }
1867  break;
1868  case OP_OUTPUT:
1869  {
1870  ss << indent << "argout_" << o[0] << "{" << o[1]+1 << "} = w" << i[0] << ";";
1871  ss << std::endl;
1872  }
1873  break;
1874  case OP_CONST:
1875  {
1876  std::ios_base::fmtflags fmtfl = ss.flags();
1877  ss << indent << "w" << o[0] << " = ";
1878  ss << std::scientific << std::setprecision(std::numeric_limits<double>::digits10 + 1);
1879  ss << f.instruction_constant(k) << ";" << std::endl;
1880  ss.flags(fmtfl);
1881  }
1882  break;
1883  case OP_SQ:
1884  {
1885  ss << indent << "w" << o[0] << " = " << "w" << i[0] << "^2;" << std::endl;
1886  }
1887  break;
1888  case OP_FABS:
1889  {
1890  ss << indent << "w" << o[0] << " = abs(" << "w" << i[0] << ");" << std::endl;
1891  }
1892  break;
1893  case OP_POW:
1894  case OP_CONSTPOW:
1895  ss << indent << "w" << o[0] << " = " << "w" << i[0] << ".^w" << i[1] << ";" << std::endl;
1896  break;
1897  case OP_NOT:
1898  ss << indent << "w" << o[0] << " = ~" << "w" << i[0] << ";" << std::endl;
1899  break;
1900  case OP_OR:
1901  ss << indent << "w" << o[0] << " = w" << i[0] << " | w" << i[1] << ";" << std::endl;
1902  break;
1903  case OP_AND:
1904  ss << indent << "w" << o[0] << " = w" << i[0] << " & w" << i[1] << ";" << std::endl;
1905  break;
1906  case OP_NE:
1907  ss << indent << "w" << o[0] << " = w" << i[0] << " ~= w" << i[1] << ";" << std::endl;
1908  break;
1909  case OP_IF_ELSE_ZERO:
1910  ss << indent << "w" << o[0] << " = ";
1911  ss << "if_else_zero_gen(w" << i[0] << ", w" << i[1] << ");" << std::endl;
1912  break;
1913  default:
1915  ss << indent << "w" << o[0] << " = " << casadi::casadi_math<double>::print(op,
1916  "w"+std::to_string(i[0]), "w"+std::to_string(i[1])) << ";" << std::endl;
1917  } else {
1918  ss << indent << "w" << o[0] << " = " << casadi::casadi_math<double>::print(op,
1919  "w"+std::to_string(i[0])) << ";" << std::endl;
1920  }
1921  }
1922  }
1923 
1924  }
@ 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_
Use just-in-time compiler.
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 2047 of file sx_function.cpp.

2048  {
2049  // Call to base class
2050  FunctionInternal::find(all_fun, max_depth);
2051  for (auto&& e : algorithm_) {
2052  if (e.op == OP_CALL) {
2053  const ExtendedAlgEl& m = call_.el.at(e.i1);
2054  add_embedded(all_fun, m.f, max_depth);
2055  }
2056  }
2057  }
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.

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

4059  {
4060  // Always of width 8
4061  casadi_assert_dev(time>=0);
4062  double log_time = log10(time);
4063  int magn = static_cast<int>(floor(log_time));
4064  int iprefix = static_cast<int>(floor(log_time/3));
4065  if (iprefix<-4) {
4066  sprint(buffer, 10, " 0");
4067  return;
4068  }
4069  if (iprefix>=5) {
4070  sprint(buffer, 10, " inf");
4071  return;
4072  }
4073  char prefixes[] = "TGMk munp";
4074  char prefix = prefixes[4-iprefix];
4075 
4076  int rem = magn-3*iprefix;
4077  double time_normalized = time/pow(10, 3*iprefix);
4078 
4079  if (rem==0) {
4080  sprint(buffer, 10, " %1.2f%cs", time_normalized, prefix);
4081  } else if (rem==1) {
4082  sprint(buffer, 10, " %2.2f%cs", time_normalized, prefix);
4083  } else {
4084  sprint(buffer, 10, "%3.2f%cs", time_normalized, prefix);
4085  }
4086  }
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 2220 of file function_internal.cpp.

2220  {
2221  casadi_assert_dev(nfwd>=0);
2222  // Used wrapped function if forward not available
2223  if (!enable_forward_ && !enable_fd_) {
2224  // Derivative information must be available
2225  casadi_assert(has_derivative(), "Derivatives cannot be calculated for " + name_);
2226  return wrap().forward(nfwd);
2227  }
2228  // Retrieve/generate cached
2229  Function f;
2230  std::string fname = forward_name(name_, nfwd);
2231  if (!incache(fname, f)) {
2232  casadi_int i;
2233  // Prefix to be used for forward seeds, sensitivities
2234  std::string pref = diff_prefix("fwd");
2235  // Names of inputs
2236  std::vector<std::string> inames;
2237  for (i=0; i<n_in_; ++i) inames.push_back(name_in_[i]);
2238  for (i=0; i<n_out_; ++i) inames.push_back("out_" + name_out_[i]);
2239  for (i=0; i<n_in_; ++i) inames.push_back(pref + name_in_[i]);
2240  // Names of outputs
2241  std::vector<std::string> onames;
2242  for (i=0; i<n_out_; ++i) onames.push_back(pref + name_out_[i]);
2243  // Options
2245  if (enable_forward_) {
2246  opts = combine(opts, generate_options("forward"));
2247  } else {
2248  opts = combine(opts, FunctionInternal::generate_options("forward"));
2249  }
2250  opts["derivative_of"] = self();
2251  // Generate derivative function
2252  casadi_assert_dev(enable_forward_ || enable_fd_);
2253  if (enable_forward_) {
2254  f = get_forward(nfwd, fname, inames, onames, opts);
2255  } else {
2256  opts = combine(opts, fd_options_);
2257  // Get FD method
2258  if (fd_method_.empty() || fd_method_=="central") {
2259  f = Function::create(new CentralDiff(fname, nfwd), opts);
2260  } else if (fd_method_=="forward") {
2261  f = Function::create(new ForwardDiff(fname, nfwd), opts);
2262  } else if (fd_method_=="backward") {
2263  f = Function::create(new BackwardDiff(fname, nfwd), opts);
2264  } else if (fd_method_=="smoothing") {
2265  f = Function::create(new Smoothing(fname, nfwd), opts);
2266  } else {
2267  casadi_error("Unknown 'fd_method': " + fd_method_);
2268  }
2269  }
2270  // Consistency check for inputs
2271  casadi_assert_dev(f.n_in()==n_in_ + n_out_ + n_in_);
2272  casadi_int ind=0;
2273  for (i=0; i<n_in_; ++i) f.assert_size_in(ind++, size1_in(i), size2_in(i));
2274  for (i=0; i<n_out_; ++i) f.assert_size_in(ind++, size1_out(i), size2_out(i));
2275  for (i=0; i<n_in_; ++i) f.assert_size_in(ind++, size1_in(i), nfwd*size2_in(i));
2276  // Consistency check for outputs
2277  casadi_assert_dev(f.n_out()==n_out_);
2278  for (i=0; i<n_out_; ++i) f.assert_sparsity_out(i, sparsity_out(i), nfwd);
2279  // Save to cache
2280  tocache_if_missing(f);
2281  }
2282  return f;
2283  }
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 3566 of file function_internal.cpp.

3566  {
3567  casadi_error("'free_mx' only defined for 'MXFunction'");
3568  }

◆ free_sx()

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

Reimplemented from casadi::FunctionInternal.

Definition at line 149 of file sx_function.hpp.

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

◆ from_compact()

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

Definition at line 1985 of file function_internal.cpp.

1986  {
1987  // Return value
1988  Sparsity r = sp;
1989  // Insert rows if sparse output
1990  if (numel_out(oind) != r.size1()) {
1991  casadi_assert_dev(r.size1() == nnz_out(oind));
1992  r.enlargeRows(numel_out(oind), sparsity_out(oind).find());
1993  }
1994  // Insert columns if sparse input
1995  if (numel_in(iind) != r.size2()) {
1996  casadi_assert_dev(r.size2() == nnz_in(iind));
1997  r.enlargeColumns(numel_in(iind), sparsity_in(iind).find());
1998  }
1999  // Return non-compact pattern
2000  return r;
2001  }
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 1575 of file function_internal.hpp.

1576  {
1577  std::vector<std::vector<MatType>> fseed(nfwd);
1578  for (casadi_int dir=0; dir<nfwd; ++dir) {
1579  fseed[dir].resize(n_in_);
1580  for (casadi_int iind=0; iind<n_in_; ++iind) {
1581  std::string n = "f" + str(dir) + "_" + name_in_[iind];
1582  Sparsity sp = is_diff_in_[iind] ? sparsity_in(iind) : Sparsity(size_in(iind));
1583  fseed[dir][iind] = MatType::sym(n, sp);
1584  }
1585  }
1586  return fseed;
1587  }

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

3181  {
3182  if (!enable_forward_ && !enable_fd_) return true;
3183  if (jac_penalty_==-1) return false;
3184 
3185  // Heuristic 1: Jac calculated via forward mode likely cheaper
3186  if (jac_penalty_*static_cast<double>(nnz_in())<nfwd) return true;
3187 
3188  // Heuristic 2: Jac calculated via reverse mode likely cheaper
3189  double w = ad_weight();
3190  if (enable_reverse_ &&
3191  jac_penalty_*(1-w)*static_cast<double>(nnz_out())<w*static_cast<double>(nfwd))
3192  return true; // NOLINT
3193 
3194  return false;
3195  }

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

3011  {
3012  casadi_error("'generate_dependencies' not defined for " + class_name());
3013  }

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

3575  {
3576  casadi_error("'generate_lifted' only defined for 'MXFunction'");
3577  }

◆ generate_options()

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

Reimplemented from casadi::FunctionInternal.

Definition at line 466 of file sx_function.cpp.

466  {
468  if (target=="clone") opts["default_in"] = default_in_;
469  opts["live_variables"] = live_variables_;
470  opts["just_in_time_sparsity"] = just_in_time_sparsity_;
471  opts["just_in_time_opencl"] = just_in_time_opencl_;
472  opts["print_instructions"] = print_instructions_;
473  return opts;
474  }

References default_in_, 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 1132 of file function_internal.hpp.

1132  {
1133  return eps;
1134  }
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 392 of file sx_function.hpp.

392 { 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 163 of file sx_function.hpp.

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

Referenced by init().

◆ get_function() [1/2]

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

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

Reimplemented from casadi::FunctionInternal.

Definition at line 1792 of file sx_function.cpp.

1792  {
1793  std::map<std::string, bool> flagged;
1794  for (auto&& a : algorithm_) {
1795  if (a.op==OP_CALL) {
1796  const auto& m = call_.el.at(a.i1);
1797  const Function &f = m.f;
1798  if (flagged.find(f.name())==flagged.end()) {
1799  flagged[f.name()] = true;
1800  }
1801  }
1802  }
1803  std::vector<std::string> ret;
1804  for (auto it : flagged) {
1805  ret.push_back(it.first);
1806  }
1807  return ret;
1808  }

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

1810  {
1811  for (auto&& a : algorithm_) {
1812  if (a.op==OP_CALL) {
1813  const auto& m = call_.el.at(a.i1);
1814  const Function &f = m.f;
1815  if (name==f.name()) return f;
1816  }
1817  }
1818  casadi_error("No such function '" + name + "'.");
1819  }

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

1929  {
1930  if (symmetric) {
1931  casadi_assert(sparsity_out_[oind].is_dense(),
1932  "Symmetry exploitation in Jacobian assumes dense expression. "
1933  "A potential workaround is to apply densify().");
1934  }
1935  // Check if we are able to propagate dependencies through the function
1936  if (has_spfwd() || has_sprev()) {
1937  // Get weighting factor
1938  double w = sp_weight();
1939 
1940  // Skip generation, assume dense
1941  if (w == -1) return Sparsity();
1942 
1943  Sparsity sp;
1944  if (nnz_in(iind) > 3*bvec_size && nnz_out(oind) > 3*bvec_size &&
1946  if (symmetric) {
1947  sp = get_jac_sparsity_hierarchical_symm(oind, iind);
1948  } else {
1949  sp = get_jac_sparsity_hierarchical(oind, iind);
1950  }
1951  } else {
1952  // Number of nonzero inputs and outputs
1953  casadi_int nz_in = nnz_in(iind);
1954  casadi_int nz_out = nnz_out(oind);
1955 
1956  // Number of forward sweeps we must make
1957  casadi_int nsweep_fwd = nz_in/bvec_size;
1958  if (nz_in%bvec_size) nsweep_fwd++;
1959 
1960  // Number of adjoint sweeps we must make
1961  casadi_int nsweep_adj = nz_out/bvec_size;
1962  if (nz_out%bvec_size) nsweep_adj++;
1963 
1964  // Use forward mode?
1965  if (w*static_cast<double>(nsweep_fwd) <= (1-w)*static_cast<double>(nsweep_adj)) {
1966  sp = get_jac_sparsity_gen<true>(oind, iind);
1967  } else {
1968  sp = get_jac_sparsity_gen<false>(oind, iind);
1969  }
1970  }
1971  return sp;
1972  } else {
1973  // Not calculated
1974  return Sparsity();
1975  }
1976  }
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 1273 of file function_internal.cpp.

1273  {
1274  // Number of nonzero inputs and outputs
1275  casadi_int nz_in = nnz_in(iind);
1276  casadi_int nz_out = nnz_out(oind);
1277 
1278  // Evaluation buffers
1279  std::vector<typename JacSparsityTraits<fwd>::arg_t> arg(sz_arg(), nullptr);
1280  std::vector<bvec_t*> res(sz_res(), nullptr);
1281  std::vector<casadi_int> iw(sz_iw());
1282  std::vector<bvec_t> w(sz_w(), 0);
1283 
1284  // Seeds and sensitivities
1285  std::vector<bvec_t> seed(nz_in, 0);
1286  arg[iind] = get_ptr(seed);
1287  std::vector<bvec_t> sens(nz_out, 0);
1288  res[oind] = get_ptr(sens);
1289  if (!fwd) std::swap(seed, sens);
1290 
1291  // Number of forward sweeps we must make
1292  casadi_int nsweep = seed.size() / bvec_size;
1293  if (seed.size() % bvec_size) nsweep++;
1294 
1295  // Print
1296  if (verbose_) {
1297  casadi_message(str(nsweep) + std::string(fwd ? " forward" : " reverse") + " sweeps "
1298  "needed for " + str(seed.size()) + " directions");
1299  }
1300 
1301  // Progress
1302  casadi_int progress = -10;
1303 
1304  // Temporary vectors
1305  std::vector<casadi_int> jcol, jrow;
1306 
1307  // Loop over the variables, bvec_size variables at a time
1308  for (casadi_int s=0; s<nsweep; ++s) {
1309 
1310  // Print progress
1311  if (verbose_) {
1312  casadi_int progress_new = (s*100)/nsweep;
1313  // Print when entering a new decade
1314  if (progress_new / 10 > progress / 10) {
1315  progress = progress_new;
1316  casadi_message(str(progress) + " %");
1317  }
1318  }
1319 
1320  // Nonzero offset
1321  casadi_int offset = s*bvec_size;
1322 
1323  // Number of local seed directions
1324  casadi_int ndir_local = seed.size()-offset;
1325  ndir_local = std::min(static_cast<casadi_int>(bvec_size), ndir_local);
1326 
1327  for (casadi_int i=0; i<ndir_local; ++i) {
1328  seed[offset+i] |= bvec_t(1)<<i;
1329  }
1330 
1331  // Propagate the dependencies
1332  JacSparsityTraits<fwd>::sp(this, get_ptr(arg), get_ptr(res),
1333  get_ptr(iw), get_ptr(w), memory(0));
1334 
1335  // Loop over the nonzeros of the output
1336  for (casadi_int el=0; el<sens.size(); ++el) {
1337 
1338  // Get the sparsity sensitivity
1339  bvec_t spsens = sens[el];
1340 
1341  if (!fwd) {
1342  // Clear the sensitivities for the next sweep
1343  sens[el] = 0;
1344  }
1345 
1346  // If there is a dependency in any of the directions
1347  if (spsens!=0) {
1348 
1349  // Loop over seed directions
1350  for (casadi_int i=0; i<ndir_local; ++i) {
1351 
1352  // If dependents on the variable
1353  if ((bvec_t(1) << i) & spsens) {
1354  // Add to pattern
1355  jcol.push_back(el);
1356  jrow.push_back(i+offset);
1357  }
1358  }
1359  }
1360  }
1361 
1362  // Remove the seeds
1363  for (casadi_int i=0; i<ndir_local; ++i) {
1364  seed[offset+i] = 0;
1365  }
1366  }
1367 
1368  // Construct sparsity pattern and return
1369  if (!fwd) swap(jrow, jcol);
1370  Sparsity ret = Sparsity::triplet(nz_out, nz_in, jcol, jrow);
1371  if (verbose_) {
1372  casadi_message("Formed Jacobian sparsity pattern (dimension " + str(ret.size()) + ", "
1373  + str(ret.nnz()) + " (" + str(ret.density()) + " %) nonzeros.");
1374  }
1375  return ret;
1376  }
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 1613 of file function_internal.cpp.

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

1379  {
1380  casadi_assert_dev(has_spfwd());
1381 
1382  // Number of nonzero inputs
1383  casadi_int nz = nnz_in(iind);
1384  casadi_assert_dev(nz==nnz_out(oind));
1385 
1386  // Evaluation buffers
1387  std::vector<const bvec_t*> arg(sz_arg(), nullptr);
1388  std::vector<bvec_t*> res(sz_res(), nullptr);
1389  std::vector<casadi_int> iw(sz_iw());
1390  std::vector<bvec_t> w(sz_w());
1391 
1392  // Seeds
1393  std::vector<bvec_t> seed(nz, 0);
1394  arg[iind] = get_ptr(seed);
1395 
1396  // Sensitivities
1397  std::vector<bvec_t> sens(nz, 0);
1398  res[oind] = get_ptr(sens);
1399 
1400  // Sparsity triplet accumulator
1401  std::vector<casadi_int> jcol, jrow;
1402 
1403  // Cols/rows of the coarse blocks
1404  std::vector<casadi_int> coarse(2, 0); coarse[1] = nz;
1405 
1406  // Cols/rows of the fine blocks
1407  std::vector<casadi_int> fine;
1408 
1409  // In each iteration, subdivide each coarse block in this many fine blocks
1410  casadi_int subdivision = bvec_size;
1411 
1412  Sparsity r = Sparsity::dense(1, 1);
1413 
1414  // The size of a block
1415  casadi_int granularity = nz;
1416 
1417  casadi_int nsweeps = 0;
1418 
1419  bool hasrun = false;
1420 
1421  while (!hasrun || coarse.size()!=nz+1) {
1422  if (verbose_) casadi_message("Block size: " + str(granularity));
1423 
1424  // Clear the sparsity triplet acccumulator
1425  jcol.clear();
1426  jrow.clear();
1427 
1428  // Clear the fine block structure
1429  fine.clear();
1430 
1431  Sparsity D = r.star_coloring();
1432 
1433  if (verbose_) {
1434  casadi_message("Star coloring on " + str(r.dim()) + ": "
1435  + str(D.size2()) + " <-> " + str(D.size1()));
1436  }
1437 
1438  // Clear the seeds
1439  std::fill(seed.begin(), seed.end(), 0);
1440 
1441  // Subdivide the coarse block
1442  for (casadi_int k=0; k<coarse.size()-1; ++k) {
1443  casadi_int diff = coarse[k+1]-coarse[k];
1444  casadi_int new_diff = diff/subdivision;
1445  if (diff%subdivision>0) new_diff++;
1446  std::vector<casadi_int> temp = range(coarse[k], coarse[k+1], new_diff);
1447  fine.insert(fine.end(), temp.begin(), temp.end());
1448  }
1449  if (fine.back()!=coarse.back()) fine.push_back(coarse.back());
1450 
1451  granularity = fine[1] - fine[0];
1452 
1453  // The index into the bvec bit vector
1454  casadi_int bvec_i = 0;
1455 
1456  // Create lookup tables for the fine blocks
1457  std::vector<casadi_int> fine_lookup = lookupvector(fine, nz+1);
1458 
1459  // Triplet data used as a lookup table
1460  std::vector<casadi_int> lookup_col;
1461  std::vector<casadi_int> lookup_row;
1462  std::vector<casadi_int> lookup_value;
1463 
1464  // The maximum number of fine blocks contained in one coarse block
1465  casadi_int n_fine_blocks_max = 0;
1466  for (casadi_int i=0;i<coarse.size()-1;++i) {
1467  casadi_int del = fine_lookup[coarse[i+1]]-fine_lookup[coarse[i]];
1468  n_fine_blocks_max = std::max(n_fine_blocks_max, del);
1469  }
1470 
1471  // Loop over all coarse seed directions from the coloring
1472  for (casadi_int csd=0; csd<D.size2(); ++csd) {
1473 
1474 
1475  casadi_int fci_offset = 0;
1476  casadi_int fci_cap = bvec_size-bvec_i;
1477 
1478  // Flag to indicate if all fine blocks have been handled
1479  bool f_finished = false;
1480 
1481  // Loop while not finished
1482  while (!f_finished) {
1483 
1484  // Loop over all coarse rows that are found in the coloring for this coarse seed direction
1485  for (casadi_int k=D.colind(csd); k<D.colind(csd+1); ++k) {
1486  casadi_int cci = D.row(k);
1487 
1488  // The first and last rows of the fine block
1489  casadi_int fci_start = fine_lookup[coarse[cci]];
1490  casadi_int fci_end = fine_lookup[coarse[cci+1]];
1491 
1492  // Local counter that modifies index into bvec
1493  casadi_int bvec_i_mod = 0;
1494 
1495  casadi_int value = -bvec_i + fci_offset + fci_start;
1496 
1497  //casadi_assert_dev(value>=0);
1498 
1499  // Loop over the rows of the fine block
1500  for (casadi_int fci = fci_offset; fci<std::min(fci_end-fci_start, fci_cap); ++fci) {
1501 
1502  // Loop over the coarse block cols that appear in the
1503  // coloring for the current coarse seed direction
1504  for (casadi_int cri=r.colind(cci);cri<r.colind(cci+1);++cri) {
1505  lookup_col.push_back(r.row(cri));
1506  lookup_row.push_back(bvec_i+bvec_i_mod);
1507  lookup_value.push_back(value);
1508  }
1509 
1510  // Toggle on seeds
1511  bvec_toggle(get_ptr(seed), fine[fci+fci_start], fine[fci+fci_start+1],
1512  bvec_i+bvec_i_mod);
1513  bvec_i_mod++;
1514  }
1515  }
1516 
1517  // Bump bvec_i for next major coarse direction
1518  bvec_i += std::min(n_fine_blocks_max, fci_cap);
1519 
1520  // Check if bvec buffer is full
1521  if (bvec_i==bvec_size || csd==D.size2()-1) {
1522  // Calculate sparsity for bvec_size directions at once
1523 
1524  // Statistics
1525  nsweeps+=1;
1526 
1527  // Construct lookup table
1528  IM lookup = IM::triplet(lookup_row, lookup_col, lookup_value,
1529  bvec_size, coarse.size());
1530 
1531  std::reverse(lookup_col.begin(), lookup_col.end());
1532  std::reverse(lookup_row.begin(), lookup_row.end());
1533  std::reverse(lookup_value.begin(), lookup_value.end());
1534  IM duplicates =
1535  IM::triplet(lookup_row, lookup_col, lookup_value, bvec_size, coarse.size())
1536  - lookup;
1537  duplicates = sparsify(duplicates);
1538  lookup(duplicates.sparsity()) = -bvec_size;
1539 
1540  // Propagate the dependencies
1541  JacSparsityTraits<true>::sp(this, get_ptr(arg), get_ptr(res),
1542  get_ptr(iw), get_ptr(w), nullptr);
1543 
1544  // Temporary bit work vector
1545  bvec_t spsens;
1546 
1547  // Loop over the cols of coarse blocks
1548  for (casadi_int cri=0; cri<coarse.size()-1; ++cri) {
1549 
1550  // Loop over the cols of fine blocks within the current coarse block
1551  for (casadi_int fri=fine_lookup[coarse[cri]];fri<fine_lookup[coarse[cri+1]];++fri) {
1552  // Lump individual sensitivities together into fine block
1553  bvec_or(get_ptr(sens), spsens, fine[fri], fine[fri+1]);
1554 
1555  // Loop over all bvec_bits
1556  for (casadi_int bvec_i=0;bvec_i<bvec_size;++bvec_i) {
1557  if (spsens & (bvec_t(1) << bvec_i)) {
1558  // if dependency is found, add it to the new sparsity pattern
1559  casadi_int ind = lookup.sparsity().get_nz(bvec_i, cri);
1560  if (ind==-1) continue;
1561  casadi_int lk = lookup->at(ind);
1562  if (lk>-bvec_size) {
1563  jrow.push_back(bvec_i+lk);
1564  jcol.push_back(fri);
1565  jrow.push_back(fri);
1566  jcol.push_back(bvec_i+lk);
1567  }
1568  }
1569  }
1570  }
1571  }
1572 
1573  // Clear the forward seeds/adjoint sensitivities, ready for next bvec sweep
1574  std::fill(seed.begin(), seed.end(), 0);
1575 
1576  // Clean lookup table
1577  lookup_col.clear();
1578  lookup_row.clear();
1579  lookup_value.clear();
1580  }
1581 
1582  if (n_fine_blocks_max>fci_cap) {
1583  fci_offset += std::min(n_fine_blocks_max, fci_cap);
1584  bvec_i = 0;
1585  fci_cap = bvec_size;
1586  } else {
1587  f_finished = true;
1588  }
1589  }
1590  }
1591 
1592  // Construct fine sparsity pattern
1593  r = Sparsity::triplet(fine.size()-1, fine.size()-1, jrow, jcol);
1594 
1595  // There may be false positives here that are not present
1596  // in the reverse mode that precedes it.
1597  // This can lead to an assymetrical result
1598  // cf. #1522
1599  r=r*r.T();
1600 
1601  coarse = fine;
1602  hasrun = true;
1603  }
1604  if (verbose_) {
1605  casadi_message("Number of sweeps: " + str(nsweeps));
1606  casadi_message("Formed Jacobian sparsity pattern (dimension " + str(r.size()) +
1607  ", " + str(r.nnz()) + " (" + str(r.density()) + " %) nonzeros.");
1608  }
1609 
1610  return r.T();
1611  }

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

1103  {
1104  return inf;
1105  }
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 1110 of file function_internal.hpp.

1110  {
1111  return -inf;
1112  }

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

1114  {
1115  return std::vector<double>(nnz_in(ind), 1.);
1116  }

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

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

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

327 { 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 2068 of file function_internal.cpp.

2070  {
2071  if (verbose_) casadi_message(name_ + "::get_partition");
2072  casadi_assert(allow_forward || allow_reverse, "Inconsistent options");
2073 
2074  // Sparsity pattern with transpose
2075  Sparsity &AT = jac_sparsity(oind, iind, compact, symmetric);
2076  Sparsity A = symmetric ? AT : AT.T();
2077 
2078  // Get seed matrices by graph coloring
2079  if (symmetric) {
2080  casadi_assert_dev(enable_forward_ || enable_fd_);
2081  casadi_assert_dev(allow_forward);
2082 
2083  // Star coloring if symmetric
2084  if (verbose_) casadi_message("FunctionInternal::getPartition star_coloring");
2085  D1 = A.star_coloring();
2086  if (verbose_) {
2087  casadi_message("Star coloring completed: " + str(D1.size2())
2088  + " directional derivatives needed ("
2089  + str(A.size1()) + " without coloring).");
2090  }
2091 
2092  } else {
2093  casadi_assert_dev(enable_forward_ || enable_fd_ || enable_reverse_);
2094  // Get weighting factor
2095  double w = ad_weight();
2096 
2097  // Which AD mode?
2098  if (w==1) allow_forward = false;
2099  if (w==0) allow_reverse = false;
2100  casadi_assert(allow_forward || allow_reverse, "Conflicting ad weights");
2101 
2102  // Best coloring encountered so far (relatively tight upper bound)
2103  double best_coloring = std::numeric_limits<double>::infinity();
2104 
2105  // Test forward mode first?
2106  bool test_fwd_first = allow_forward && w*static_cast<double>(A.size1()) <=
2107  (1-w)*static_cast<double>(A.size2());
2108  casadi_int mode_fwd = test_fwd_first ? 0 : 1;
2109 
2110  // Test both coloring modes
2111  for (casadi_int mode=0; mode<2; ++mode) {
2112  // Is this the forward mode?
2113  bool fwd = mode==mode_fwd;
2114 
2115  // Skip?
2116  if (!allow_forward && fwd) continue;
2117  if (!allow_reverse && !fwd) continue;
2118 
2119  // Perform the coloring
2120  if (fwd) {
2121  if (verbose_) casadi_message("Unidirectional coloring (forward mode)");
2122  bool d = best_coloring>=w*static_cast<double>(A.size1());
2123  casadi_int max_colorings_to_test =
2124  d ? A.size1() : static_cast<casadi_int>(floor(best_coloring/w));
2125  D1 = AT.uni_coloring(A, max_colorings_to_test);
2126  if (D1.is_null()) {
2127  if (verbose_) {
2128  casadi_message("Forward mode coloring interrupted (more than "
2129  + str(max_colorings_to_test) + " needed).");
2130  }
2131  } else {
2132  if (verbose_) {
2133  casadi_message("Forward mode coloring completed: "
2134  + str(D1.size2()) + " directional derivatives needed ("
2135  + str(A.size1()) + " without coloring).");
2136  }
2137  D2 = Sparsity();
2138  best_coloring = w*static_cast<double>(D1.size2());
2139  }
2140  } else {
2141  if (verbose_) casadi_message("Unidirectional coloring (adjoint mode)");
2142  bool d = best_coloring>=(1-w)*static_cast<double>(A.size2());
2143  casadi_int max_colorings_to_test =
2144  d ? A.size2() : static_cast<casadi_int>(floor(best_coloring/(1-w)));
2145 
2146  D2 = A.uni_coloring(AT, max_colorings_to_test);
2147  if (D2.is_null()) {
2148  if (verbose_) {
2149  casadi_message("Adjoint mode coloring interrupted (more than "
2150  + str(max_colorings_to_test) + " needed).");
2151  }
2152  } else {
2153  if (verbose_) {
2154  casadi_message("Adjoint mode coloring completed: "
2155  + str(D2.size2()) + " directional derivatives needed ("
2156  + str(A.size2()) + " without coloring).");
2157  }
2158  D1 = Sparsity();
2159  best_coloring = (1-w)*static_cast<double>(D2.size2());
2160  }
2161  }
2162  }
2163 
2164  }
2165  }
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 1125 of file function_internal.hpp.

1125  {
1126  return eps;
1127  }

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::ClpInterface, casadi::ClarabelInterface, casadi::MadmpecInterface, casadi::CbcInterface, casadi::BonminInterface, casadi::AlpaqaInterface, casadi::Rootfinder, casadi::OracleFunction, casadi::Nlpsol, and casadi::MXFunction.

Definition at line 3168 of file function_internal.cpp.

3168  {
3169  Dict stats = ProtoFunction::get_stats(mem);
3170  auto *m = static_cast<FunctionMemory*>(mem);
3171  casadi_assert(m->stats_available,
3172  "No stats available: Function '" + name_ + "' not set up. "
3173  "To get statistics, first evaluate it numerically.");
3174  return stats;
3175  }
virtual Dict get_stats(void *mem) const
Get all statistics.

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

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

◆ getAdaptorSolverName()

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

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

Definition at line 304 of file function_internal.hpp.

304 { return ""; }

◆ getCount()

Definition at line 60 of file generic_shared_internal.hpp.

205  {
206  return static_cast<const Internal*>(this)->count;
207  }

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

434 { return false;}

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

◆ has_forward()

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

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

Reimplemented from casadi::FunctionInternal.

Definition at line 128 of file x_function.hpp.

128 { return true;}

◆ has_free()

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

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

Reimplemented from casadi::FunctionInternal.

Definition at line 158 of file sx_function.hpp.

158 { return !free_vars_.empty();}

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

◆ has_function()

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

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

Definition at line 369 of file function_internal.hpp.

369 {return false;}

◆ has_jac_sparsity()

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

◆ has_jacobian()

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

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

Reimplemented from casadi::FunctionInternal.

Definition at line 150 of file x_function.hpp.

150 { return true;}

◆ has_memory()

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

Definition at line 3854 of file function_internal.cpp.

3854  {
3855  return ind<mem_.size();
3856  }

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

1055  {
1056  return get_options().find(option_name) != nullptr;
1057  }
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 1159 of file function_internal.hpp.

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

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

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

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

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

◆ init_copy_elision()

void casadi::SXFunction::init_copy_elision ( )

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

Definition at line 843 of file sx_function.cpp.

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

864  {
865  auto *m = static_cast<ProtoFunctionMemory*>(mem);
866  if (record_time_) {
867  m->add_stat("total");
868  m->t_total = &m->fstats.at("total");
869  } else {
870  m->t_total = nullptr;
871  }
872  return 0;
873  }

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

214  {
215  return algorithm_.at(k).d;
216  }

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

192 { 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 197 of file sx_function.hpp.

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

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

3599  {
3600  casadi_error("'instruction_MX' not defined for " + class_name());
3601  }

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

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

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

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

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

1821  {
1822  return type=="SXFunction" || (recursive && XFunction<SXFunction,
1823  SX, SXNode>::is_a(type, recursive));
1824  }
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 129 of file sx_function.cpp.

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

References algorithm_.

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

◆ isInput()

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

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

Definition at line 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 1915 of file function_internal.cpp.

1915  {
1916  // If derivative expression
1917  if (!derivative_of_.is_null()) {
1918  std::string n = derivative_of_.name();
1919  // Reverse move
1920  if (name_ == "adj1_" + n) {
1921  if (iind == oind) return true;
1922  }
1923  }
1924  // Not symmetric by default
1925  return false;
1926  }

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

2004  {
2005 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
2006  // Safe access to jac_sparsity_
2007  std::lock_guard<std::mutex> lock(jac_sparsity_mtx_);
2008 #endif // CASADI_WITH_THREADSAFE_SYMBOLICS
2009  // If first call, allocate cache
2010  for (bool c : {false, true}) {
2011  if (jac_sparsity_[c].empty()) jac_sparsity_[c].resize(n_in_ * n_out_);
2012  }
2013  // Flat index
2014  casadi_int ind = iind + oind * n_in_;
2015  // Reference to the block
2016  Sparsity& jsp = jac_sparsity_[compact].at(ind);
2017  // If null, generate
2018  if (jsp.is_null()) {
2019  // Use (non)-compact pattern, if given
2020  Sparsity& jsp_other = jac_sparsity_[!compact].at(ind);
2021  if (!jsp_other.is_null()) {
2022  jsp = compact ? to_compact(oind, iind, jsp_other) : from_compact(oind, iind, jsp_other);
2023  } else {
2024  // Generate pattern
2025  Sparsity sp;
2026  bool sp_is_compact;
2027  if (!is_diff_out_.at(oind) || !is_diff_in_.at(iind)) {
2028  // All-zero sparse
2029  sp = Sparsity(nnz_out(oind), nnz_in(iind));
2030  sp_is_compact = true;
2031  } else {
2032  // Use internal routine to determine sparsity
2033  if (has_spfwd() || has_sprev() || has_jac_sparsity(oind, iind)) {
2034  sp = get_jac_sparsity(oind, iind, symmetric);
2035  }
2036  // If null, dense
2037  if (sp.is_null()) sp = Sparsity::dense(nnz_out(oind), nnz_in(iind));
2038  // Is the return the compact pattern?
2039  sp_is_compact = sp.size1() == nnz_out(oind) && sp.size2() == nnz_in(iind);
2040  }
2041  // Save to cache and convert if needed
2042  if (sp_is_compact == compact) {
2043  jsp = sp;
2044  } else {
2045  jsp_other = sp;
2046  jsp = compact ? to_compact(oind, iind, sp) : from_compact(oind, iind, sp);
2047  }
2048  }
2049  }
2050 
2051  // Make sure the Jacobian is symmetric if requested, cf. #1522, #3074, #3134
2052  if (symmetric) {
2053  if (compact) {
2054  Sparsity sp = from_compact(oind, iind, jsp);
2055  if (!sp.is_symmetric()) {
2056  sp = sp * sp.T();
2057  jsp = to_compact(oind, iind, sp);
2058  }
2059  } else {
2060  if (!jsp.is_symmetric()) jsp = jsp * jsp.T();
2061  }
2062  }
2063 
2064  // Return a reference to the block
2065  return jsp;
2066  }
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 2403 of file function_internal.cpp.

2403  {
2404  // Used wrapped function if jacobian not available
2405  if (!has_jacobian()) {
2406  // Derivative information must be available
2407  casadi_assert(has_derivative(),
2408  "Derivatives cannot be calculated for " + name_);
2409  return wrap().jacobian();
2410  }
2411  // Retrieve/generate cached
2412  Function f;
2413  std::string fname = "jac_" + name_;
2414  if (!incache(fname, f)) {
2415  // Names of inputs
2416  std::vector<std::string> inames;
2417  for (casadi_int i=0; i<n_in_; ++i) inames.push_back(name_in_[i]);
2418  for (casadi_int i=0; i<n_out_; ++i) inames.push_back("out_" + name_out_[i]);
2419  // Names of outputs
2420  std::vector<std::string> onames;
2421  onames.reserve(n_in_ * n_out_);
2422  for (size_t oind = 0; oind < n_out_; ++oind) {
2423  for (size_t iind = 0; iind < n_in_; ++iind) {
2424  onames.push_back("jac_" + name_out_[oind] + "_" + name_in_[iind]);
2425  }
2426  }
2427  // Options
2429  opts["derivative_of"] = self();
2430  // Generate derivative function
2431  casadi_assert_dev(enable_jacobian_);
2432  f = get_jacobian(fname, inames, onames, opts);
2433  // Consistency checks
2434  casadi_assert(f.n_in() == inames.size(),
2435  "Mismatching input signature, expected " + str(inames));
2436  casadi_assert(f.n_out() == onames.size(),
2437  "Mismatching output signature, expected " + str(onames));
2438  // Save to cache
2439  tocache_if_missing(f);
2440  }
2441  return f;
2442  }
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 947 of file function_internal.hpp.

947 {}

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

1142  {
1143  Function f;
1144  if (parallelization=="serial") {
1145  // Serial maps are cached
1146  std::string fname = "map" + str(n) + "_" + name_;
1147  if (!incache(fname, f)) {
1148  // Create new serial map
1149  f = Map::create(parallelization, self(), n);
1150  casadi_assert_dev(f.name()==fname);
1151  // Save in cache
1152  tocache_if_missing(f);
1153  }
1154  } else {
1155  // Non-serial maps are not cached
1156  f = Map::create(parallelization, self(), n);
1157  }
1158  return f;
1159  }
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 3612 of file function_internal.cpp.

3613  {
3614  if (x.empty()) return x;
3615  // Check number of arguments
3616  casadi_assert(x.size()==n_in_, "mapsum_mx: Wrong number_i of arguments");
3617  // Number of parallel calls
3618  casadi_int npar = 1;
3619  // Check/replace arguments
3620  std::vector<MX> x_mod(x.size());
3621  for (casadi_int i=0; i<n_in_; ++i) {
3622  if (check_mat(x[i].sparsity(), sparsity_in_[i], npar)) {
3623  x_mod[i] = replace_mat(x[i], sparsity_in_[i], npar);
3624  } else {
3625  // Mismatching sparsity: The following will throw an error message
3626  npar = 0;
3627  check_arg(x, npar);
3628  }
3629  }
3630 
3631  casadi_int n = 1;
3632  for (casadi_int i=0; i<x_mod.size(); ++i) {
3633  n = std::max(x_mod[i].size2() / size2_in(i), n);
3634  }
3635 
3636  std::vector<casadi_int> reduce_in;
3637  for (casadi_int i=0; i<x_mod.size(); ++i) {
3638  if (x_mod[i].size2()/size2_in(i)!=n) {
3639  reduce_in.push_back(i);
3640  }
3641  }
3642 
3643  Function ms = self().map("mapsum", parallelization, n, reduce_in, range(n_out_));
3644 
3645  // Call the internal function
3646  return ms(x_mod);
3647  }
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 1801 of file function_internal.hpp.

1801  {
1802  check_arg(arg, npar);
1803  for (casadi_int i=0; i<n_in_; ++i) {
1804  if (arg.at(i).size1()!=size1_in(i)) return false;
1805  if (arg.at(i).size2()!=size2_in(i) && arg.at(i).size2()!=npar*size2_in(i)) return false;
1806  }
1807  return true;
1808  }

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

1811  {
1812  check_res(res, npar);
1813  for (casadi_int i=0; i<n_out_; ++i) {
1814  if (res.at(i).size1()!=size1_out(i)) return false;
1815  if (res.at(i).size2()!=size2_out(i) && res.at(i).size2()!=npar*size2_out(i)) return false;
1816  }
1817  return true;
1818  }
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 3847 of file function_internal.cpp.

3847  {
3848 #ifdef CASADI_WITH_THREAD
3849  std::lock_guard<std::mutex> lock(mtx_);
3850 #endif //CASADI_WITH_THREAD
3851  return mem_.at(ind);
3852  }

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

3563  {
3564  }

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

3542  {
3543  std::vector<MX> ret(n_in_);
3544  for (casadi_int i=0; i<ret.size(); ++i) {
3545  ret[i] = mx_in(i);
3546  }
3547  return ret;
3548  }
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 3534 of file function_internal.cpp.

3534  {
3535  return MX::sym(name_in_.at(ind), sparsity_in(ind));
3536  }
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 3550 of file function_internal.cpp.

3550  {
3551  std::vector<MX> ret(n_out_);
3552  for (casadi_int i=0; i<ret.size(); ++i) {
3553  ret[i] = mx_out(i);
3554  }
3555  return ret;
3556  }
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 187 of file sx_function.hpp.

187 { 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 236 of file sx_function.hpp.

236 { 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 2362 of file function_internal.cpp.

2362  {
2363  casadi_int ret=0;
2364  for (casadi_int iind=0; iind<n_in_; ++iind) ret += nnz_in(iind);
2365  return ret;
2366  }

References casadi::FunctionInternal::n_in_.

Referenced by casadi::FunctionInternal::adjViaJac(), casadi::FunctionInternal::call_gen(), casadi::JitFunction::codegen_body(), casadi::FunctionInternal::codegen_meta(), casadi::FunctionInternal::eval_gen(), casadi::CallbackInternal::finalize(), casadi::FunctionInternal::from_compact(), casadi::FunctionInternal::fwdViaJac(), casadi::FunctionInternal::generate_in(), casadi::FunctionInternal::get_jac_sparsity(), casadi::Expm::get_jac_sparsity(), casadi::FmuFunction::get_jac_sparsity(), casadi::FunctionInternal::get_jac_sparsity_gen(), casadi::FunctionInternal::get_jac_sparsity_hierarchical(), casadi::FunctionInternal::get_jac_sparsity_hierarchical_symm(), casadi::JitFunction::init(), casadi::Nlpsol::init(), casadi::CbcInterface::init(), casadi::ClpInterface::init(), casadi::CplexInterface::init(), casadi::OoqpInterface::init(), casadi::ProxqpInterface::init(), casadi::QpoasesInterface::init(), casadi::ImplicitToNlp::init(), casadi::FunctionInternal::jac_sparsity(), casadi::FunctionInternal::nz_in(), casadi::ImplicitToNlp::set_work(), casadi::CbcInterface::solve(), casadi::ClpInterface::solve(), casadi::CplexInterface::solve(), casadi::OoqpInterface::solve(), casadi::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 1007 of file function_internal.hpp.

1007 { 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 1009 of file function_internal.hpp.

1009 { 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 2374 of file function_internal.cpp.

2374  {
2375  casadi_int ret=0;
2376  for (casadi_int iind=0; iind<n_in_; ++iind) ret += numel_in(iind);
2377  return ret;
2378  }

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

1017 { 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 2380 of file function_internal.cpp.

2380  {
2381  casadi_int ret=0;
2382  for (casadi_int oind=0; oind<n_out_; ++oind) ret += numel_out(oind);
2383  return ret;
2384  }

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

1018 { 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 3702 of file function_internal.cpp.

3702  {
3703  // Disallow parallel inputs
3704  casadi_int npar = -1;
3705  if (!matching_arg(arg, npar)) {
3706  return nz_in(replace_arg(arg, npar));
3707  }
3708 
3709  std::vector<DM> arg2 = project_arg(arg, 1);
3710  std::vector<double> ret(nnz_in());
3711  casadi_int offset = 0;
3712  for (casadi_int i=0;i<n_in_;++i) {
3713  const double* e = arg2.at(i).ptr();
3714  std::copy(e, e+nnz_in(i), ret.begin()+offset);
3715  offset+= nnz_in(i);
3716  }
3717  return ret;
3718  }

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

3672  {
3673  casadi_assert(nnz_in()==arg.size(),
3674  "Dimension mismatch. Expecting " + str(nnz_in()) +
3675  ", got " + str(arg.size()) + " instead.");
3676 
3677  std::vector<DM> ret = dm_in();
3678  casadi_int offset = 0;
3679  for (casadi_int i=0;i<n_in_;++i) {
3680  DM& r = ret.at(i);
3681  std::copy(arg.begin()+offset, arg.begin()+offset+nnz_in(i), r.ptr());
3682  offset+= nnz_in(i);
3683  }
3684  return ret;
3685  }
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 3720 of file function_internal.cpp.

3720  {
3721  // Disallow parallel inputs
3722  casadi_int npar = -1;
3723  if (!matching_res(res, npar)) {
3724  return nz_out(replace_res(res, npar));
3725  }
3726 
3727  std::vector<DM> res2 = project_res(res, 1);
3728  std::vector<double> ret(nnz_out());
3729  casadi_int offset = 0;
3730  for (casadi_int i=0;i<n_out_;++i) {
3731  const double* e = res2.at(i).ptr();
3732  std::copy(e, e+nnz_out(i), ret.begin()+offset);
3733  offset+= nnz_out(i);
3734  }
3735  return ret;
3736  }
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 3687 of file function_internal.cpp.

3687  {
3688  casadi_assert(nnz_out()==res.size(),
3689  "Dimension mismatch. Expecting " + str(nnz_out()) +
3690  ", got " + str(res.size()) + " instead.");
3691 
3692  std::vector<DM> ret = dm_out();
3693  casadi_int offset = 0;
3694  for (casadi_int i=0;i<n_out_;++i) {
3695  DM& r = ret.at(i);
3696  std::copy(res.begin()+offset, res.begin()+offset+nnz_out(i), r.ptr());
3697  offset+= nnz_out(i);
3698  }
3699  return ret;
3700  }

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

◆ oracle()

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

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

Reimplemented in casadi::OracleFunction.

Definition at line 3939 of file function_internal.cpp.

3939  {
3940  casadi_error("'oracle' not defined for " + class_name());
3941  static Function singleton;
3942  return singleton;
3943  }

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

2069  {
2070 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
2071  std::lock_guard<std::mutex> lock(SX::get_mutex_temp());
2072 #endif // CASADI_WITH_THREADSAFE_SYMBOLICS
2073  // Stack used to sort the computational graph
2074  std::stack<SXNode*> s;
2075 
2076  // All nodes
2077  std::vector<SXNode*> nodes;
2078 
2079  // Add the list of nodes
2080  casadi_int ind=0;
2081  for (auto it = expr.begin(); it != expr.end(); ++it, ++ind) {
2082  casadi_int nz=0;
2083  for (auto itc = (*it)->begin(); itc != (*it)->end(); ++itc, ++nz) {
2084  // Add outputs to the list
2085  s.push(itc->get());
2087  }
2088  }
2089 
2090  // Clear temporary markers
2091  for (casadi_int i=0; i<nodes.size(); ++i) {
2092  nodes[i]->temp = 0;
2093  }
2094 
2095  std::vector<SX> ret(nodes.size());
2096  for (casadi_int i=0; i<nodes.size(); ++i) {
2097  ret[i] = SXElem::create(nodes[i]);
2098  }
2099 
2100  return ret;
2101  }

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

4100  {
4101  // Variable number of arguments
4102  va_list args;
4103  va_start(args, fmt);
4104  // Static & dynamic buffers
4105  char buf[256];
4106  size_t buf_sz = sizeof(buf);
4107  char* buf_dyn = nullptr;
4108  // Try to print with a small buffer
4109  casadi_int n = vsnprintf(buf, buf_sz, fmt, args);
4110  // Need a larger buffer?
4111  if (n>static_cast<casadi_int>(buf_sz)) {
4112  buf_sz = static_cast<size_t>(n+1);
4113  buf_dyn = new char[buf_sz];
4114  n = vsnprintf(buf_dyn, buf_sz, fmt, args);
4115  }
4116  // Print buffer content
4117  if (n>=0) uout() << (buf_dyn ? buf_dyn : buf) << std::flush;
4118  // Cleanup
4119  delete[] buf_dyn;
4120  va_end(args);
4121  // Throw error if failure
4122  casadi_assert(n>=0, "Print failure while processing '" + std::string(fmt) + "'");
4123  }

References casadi::uout().

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

◆ print() [2/2]

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

Definition at line 138 of file sx_function.cpp.

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

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

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

◆ print_arg() [1/2]

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

Definition at line 273 of file sx_function.cpp.

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

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

◆ print_arg() [2/2]

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

Definition at line 234 of file sx_function.cpp.

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

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

Referenced by codegen_body(), and eval().

◆ print_canonical() [1/3]

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

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

Definition at line 909 of file function_internal.cpp.

909  {
910  StreamStateGuard backup(stream);
911  normalized_setup(stream);
912  if (nz) {
913  stream << "[";
914  for (casadi_int i=0; i<sz; ++i) {
915  if (i>0) stream << ", ";
916  normalized_out(stream, nz[i]);
917  }
918  stream << "]";
919  } else {
920  stream << "NULL";
921  }
922  }

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

925  {
926  StreamStateGuard backup(stream);
927  normalized_setup(stream);
928  if (nz) {
929  if (!sp.is_scalar(true)) {
930  stream << sp.dim(false) << ": ";
931  stream << "[";
932  }
933  for (casadi_int i=0; i<sp.nnz(); ++i) {
934  if (i>0) stream << ", ";
935  normalized_out(stream, nz[i]);
936  }
937  if (!sp.is_scalar(true)) {
938  stream << "]";
939  if (!sp.is_dense()) {
940  stream << ", colind: [";
941  for (casadi_int i=0; i<sp.size2()+1; ++i) {
942  if (i>0) stream << ", ";
943  stream << sp.colind()[i];
944  }
945  stream << "]";
946  stream << ", row: [";
947  for (casadi_int i=0; i<sp.nnz(); ++i) {
948  if (i>0) stream << ", ";
949  stream << sp.row()[i];
950  }
951  stream << "]";
952  }
953  }
954  } else {
955  stream << "NULL";
956  }
957  }

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

959  {
960  StreamStateGuard backup(stream);
961  normalized_setup(stream);
962  normalized_out(stream, a);
963  }

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

1034  {
1035  stream << " Number of inputs: " << n_in_ << std::endl;
1036  for (casadi_int i=0; i<n_in_; ++i) {
1037  stream << " Input " << i << " (\"" << name_in_[i] << "\"): "
1038  << sparsity_in_[i].dim() << std::endl;
1039  }
1040  stream << " Number of outputs: " << n_out_ << std::endl;
1041  for (casadi_int i=0; i<n_out_; ++i) {
1042  stream << " Output " << i << " (\"" << name_out_[i] << "\"): "
1043  << sparsity_out_[i].dim() << std::endl;
1044  }
1045  }

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

875  {
876  stream << "Function " << name_ << " (" << this << ")" << std::endl;
877  for (casadi_int i=0; i<n_in_; ++i) {
878  stream << "Input " << i << " (" << name_in_[i] << "): ";
879  if (arg[i]) {
880  if (print_canonical_) {
881  print_canonical(stream, sparsity_in_[i], arg[i]);
882  } else {
883  DM::print_default(stream, sparsity_in_[i], arg[i], truncate);
884  }
885  stream << std::endl;
886  } else {
887  stream << "NULL" << std::endl;
888  }
889  }
890  }
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 1051 of file function_internal.cpp.

1051  {
1052  get_options().print_one(name, stream);
1053  }
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 1047 of file function_internal.cpp.

1047  {
1048  get_options().print_all(stream);
1049  }
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 892 of file function_internal.cpp.

892  {
893  stream << "Function " << name_ << " (" << this << ")" << std::endl;
894  for (casadi_int i=0; i<n_out_; ++i) {
895  stream << "Output " << i << " (" << name_out_[i] << "): ";
896  if (res[i]) {
897  if (print_canonical_) {
898  print_canonical(stream, sparsity_out_[i], res[i]);
899  } else {
900  DM::print_default(stream, sparsity_out_[i], res[i], truncate);
901  }
902  stream << std::endl;
903  } else {
904  stream << "NULL" << std::endl;
905  }
906  }
907  }

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

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

◆ print_res() [1/2]

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

Definition at line 291 of file sx_function.cpp.

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

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

◆ print_res() [2/2]

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

Definition at line 304 of file sx_function.cpp.

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

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

Referenced by codegen_body(), and eval().

◆ print_time()

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

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

Definition at line 4020 of file function_internal.cpp.

4020  {
4021  if (!print_time_) return;
4022  // Length of the name being printed
4023  size_t name_len=0;
4024  for (auto &&s : fstats) {
4025  name_len = std::max(s.first.size(), name_len);
4026  }
4027  name_len = std::max(name_.size(), name_len);
4028 
4029  // Print name with a given length. Format: "%NNs "
4030  char namefmt[10];
4031  sprint(namefmt, sizeof(namefmt), "%%%ds ", static_cast<casadi_int>(name_len));
4032 
4033  // Print header
4034  print(namefmt, name_.c_str());
4035 
4036  print(" : %8s %10s %8s %10s %9s\n", "t_proc", "(avg)", "t_wall", "(avg)", "n_eval");
4037 
4038 
4039  char buffer_proc[10];
4040  char buffer_wall[10];
4041  char buffer_proc_avg[10];
4042  char buffer_wall_avg[10];
4043 
4044  // Print keys
4045  for (const auto &s : fstats) {
4046  if (s.second.n_call!=0) {
4047  print(namefmt, s.first.c_str());
4048  format_time(buffer_proc, s.second.t_proc);
4049  format_time(buffer_wall, s.second.t_wall);
4050  format_time(buffer_proc_avg, s.second.t_proc/s.second.n_call);
4051  format_time(buffer_wall_avg, s.second.t_wall/s.second.n_call);
4052  print(" | %s (%s) %s (%s) %9d\n",
4053  buffer_proc, buffer_proc_avg,
4054  buffer_wall, buffer_wall_avg, s.second.n_call);
4055  }
4056  }
4057  }
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 1673 of file function_internal.hpp.

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

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

1714  {
1715  return arg;
1716  }

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

1566  {
1567  for (auto i=v.begin(); i!=v.end(); ++i) {
1568  if (!i->is_zero()) return false;
1569  }
1570  return true;
1571  }

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

◆ release()

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

Definition at line 3879 of file function_internal.cpp.

3879  {
3880 #ifdef CASADI_WITH_THREAD
3881  std::lock_guard<std::mutex> lock(mtx_);
3882 #endif //CASADI_WITH_THREAD
3883  unused_.push(mem);
3884  }

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

1849  {
1850  std::vector<M> r(arg.size());
1851  for (casadi_int i=0; i<r.size(); ++i) r[i] = replace_mat(arg[i], sparsity_in(i), npar);
1852  return r;
1853  }

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

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

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

1865  {
1866  std::vector<std::vector<M> > r(fseed.size());
1867  for (casadi_int d=0; d<r.size(); ++d) r[d] = replace_arg(fseed[d], npar);
1868  return r;
1869  }

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

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

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

2285  {
2286  casadi_assert_dev(nadj>=0);
2287  // Used wrapped function if reverse not available
2288  if (!enable_reverse_) {
2289  // Derivative information must be available
2290  casadi_assert(has_derivative(), "Derivatives cannot be calculated for " + name_);
2291  return wrap().reverse(nadj);
2292  }
2293  // Retrieve/generate cached
2294  Function f;
2295  std::string fname = reverse_name(name_, nadj);
2296  if (!incache(fname, f)) {
2297  casadi_int i;
2298  // Prefix to be used for adjoint seeds, sensitivities
2299  std::string pref = diff_prefix("adj");
2300  // Names of inputs
2301  std::vector<std::string> inames;
2302  for (i=0; i<n_in_; ++i) inames.push_back(name_in_[i]);
2303  for (i=0; i<n_out_; ++i) inames.push_back("out_" + name_out_[i]);
2304  for (i=0; i<n_out_; ++i) inames.push_back(pref + name_out_[i]);
2305  // Names of outputs
2306  std::vector<std::string> onames;
2307  for (casadi_int i=0; i<n_in_; ++i) onames.push_back(pref + name_in_[i]);
2308  // Options
2310  opts = combine(opts, generate_options("reverse"));
2311  opts["derivative_of"] = self();
2312  // Generate derivative function
2313  casadi_assert_dev(enable_reverse_);
2314  f = get_reverse(nadj, fname, inames, onames, opts);
2315  // Consistency check for inputs
2316  casadi_assert_dev(f.n_in()==n_in_ + n_out_ + n_out_);
2317  casadi_int ind=0;
2318  for (i=0; i<n_in_; ++i) f.assert_size_in(ind++, size1_in(i), size2_in(i));
2319  for (i=0; i<n_out_; ++i) f.assert_size_in(ind++, size1_out(i), size2_out(i));
2320  for (i=0; i<n_out_; ++i) f.assert_size_in(ind++, size1_out(i), nadj*size2_out(i));
2321  // Consistency check for outputs
2322  casadi_assert_dev(f.n_out()==n_in_);
2323  for (i=0; i<n_in_; ++i) f.assert_sparsity_out(i, sparsity_in(i), nadj);
2324  // Save to cache
2325  tocache_if_missing(f);
2326  }
2327  return f;
2328  }
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 672 of file function_internal.hpp.

672  {
673  return "adj" + str(nadj) + "_" + fcn;
674  }

References casadi::str().

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

◆ self()

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

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

Definition at line 353 of file function_internal.hpp.

353 { return shared_from_this<Function>();}

Referenced by casadi::casadi_uno_term_cb_cpp().

◆ serialize()

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

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

Definition at line 4393 of file function_internal.cpp.

4393  {
4394  serialize_type(s);
4395  serialize_body(s);
4396  }
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 1999 of file sx_function.cpp.

1999  {
2001  s.version("SXFunction", 3);
2002  s.pack("SXFunction::n_instr", algorithm_.size());
2003 
2004  s.pack("SXFunction::worksize", worksize_);
2005  s.pack("SXFunction::free_vars", free_vars_);
2006  s.pack("SXFunction::operations", operations_);
2007  s.pack("SXFunction::constants", constants_);
2008  s.pack("SXFunction::default_in", default_in_);
2009 
2010  s.pack("SXFunction::call_sz_arg", call_.sz_arg);
2011  s.pack("SXFunction::call_sz_res", call_.sz_res);
2012  s.pack("SXFunction::call_sz_iw", call_.sz_iw);
2013  s.pack("SXFunction::call_sz_w", call_.sz_w);
2014  s.pack("SXFunction::call_sz_arg", call_.sz_w_arg);
2015  s.pack("SXFunction::call_sz_res", call_.sz_w_res);
2016 
2017  s.pack("SXFunction::call_el_size", call_.el.size());
2018  // Loop over ExtendedALgEl elements
2019  for (const auto& n : call_.el) {
2020  s.pack("SXFunction::call_el_f", n.f);
2021  s.pack("SXFunction::call_el_dep", n.dep);
2022  s.pack("SXFunction::call_el_res", n.res);
2023  s.pack("SXFunction::call_el_copy_elision_arg", n.copy_elision_arg);
2024  s.pack("SXFunction::call_el_copy_elision_offset", n.copy_elision_offset);
2025  }
2026 
2027  s.pack("SXFunction::copy_elision", copy_elision_);
2028 
2029  // Loop over algorithm
2030  for (const auto& e : algorithm_) {
2031  s.pack("SXFunction::ScalarAtomic::op", e.op);
2032  s.pack("SXFunction::ScalarAtomic::i0", e.i0);
2033  s.pack("SXFunction::ScalarAtomic::i1", e.i1);
2034  s.pack("SXFunction::ScalarAtomic::i2", e.i2);
2035  }
2036 
2037  s.pack("SXFunction::live_variables", live_variables_);
2038  s.pack("SXFunction::print_instructions", print_instructions_);
2039 
2041  }
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(), 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 3964 of file function_internal.cpp.

3964  {
3965 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
3966  // Safe access to jac_sparsity_
3967  std::lock_guard<std::mutex> lock(jac_sparsity_mtx_);
3968 #endif // CASADI_WITH_THREADSAFE_SYMBOLICS
3969  casadi_int ind = iind + oind * n_in_;
3970  jac_sparsity_[false].resize(n_in_ * n_out_);
3971  jac_sparsity_[false].at(ind) = sp;
3972  jac_sparsity_[true].resize(n_in_ * n_out_);
3973  jac_sparsity_[true].at(ind) = to_compact(oind, iind, sp);
3974  }

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

3739  {
3740  set_work(mem, arg, res, iw, w);
3741  set_temp(mem, arg, res, iw, w);
3742  auto *m = static_cast<FunctionMemory*>(mem);
3743  m->stats_available = true;
3744  }
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 1180 of file sx_function.cpp.

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

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

2497  {
2498  return "int " + fname + "(const casadi_real** arg, casadi_real** res, "
2499  "casadi_int* iw, casadi_real* w, int mem)";
2500  }

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

◆ signature_unrolled()

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

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

Definition at line 2502 of file function_internal.cpp.

2502  {
2503  std::vector<std::string> args;
2504  for (auto e : name_in_) {
2505  args.push_back("const casadi_real* " + str(e));
2506  }
2507  for (auto e : name_out_) {
2508  args.push_back("casadi_real* " + str(e));
2509  }
2510  args.push_back("const casadi_real** arg");
2511  args.push_back("casadi_real** res");
2512  args.push_back("casadi_int* iw");
2513  args.push_back("casadi_real* w");
2514  args.push_back("int mem");
2515  return "int " + fname + "_unrolled(" + join(args, ", ") + ")";
2516  }

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

1658  {
1659  // Fall back when forward mode not allowed
1660  if (sp_weight()==1 || sp_weight()==-1)
1661  return FunctionInternal::sp_forward(arg, res, iw, w, mem);
1662  // Propagate sparsity forward
1663  for (auto&& e : algorithm_) {
1664  switch (e.op) {
1665  case OP_CONST:
1666  case OP_PARAMETER:
1667  w[e.i0] = 0; break;
1668  case OP_INPUT:
1669  w[e.i0] = (arg[e.i1]!=nullptr && is_diff_in_[e.i1]) ? arg[e.i1][e.i2] : 0;
1670  break;
1671  case OP_OUTPUT:
1672  if (res[e.i0]!=nullptr) res[e.i0][e.i2] = is_diff_out_[e.i0] ? w[e.i1] : 0;
1673  break;
1674  case OP_CALL:
1675  call_fwd(e, arg, res, iw, w);
1676  break;
1677  default: // Unary or binary operation
1678  w[e.i0] = w[e.i1] | w[e.i2]; break;
1679  }
1680  }
1681  return 0;
1682  }

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

3045  {
3046  // Get the sparsity of the Jacobian block
3047  Sparsity sp = jac_sparsity(oind, iind, true, false);
3048  if (sp.is_null() || sp.nnz() == 0) return 0; // Skip if zero
3049  // Carry out the sparse matrix-vector multiplication
3050  casadi_int d1 = sp.size2();
3051  const casadi_int *colind = sp.colind(), *row = sp.row();
3052  for (casadi_int cc=0; cc<d1; ++cc) {
3053  for (casadi_int el = colind[cc]; el < colind[cc+1]; ++el) {
3054  res[oind][row[el]] |= arg[iind][cc];
3055  }
3056  }
3057  return 0;
3058  }

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

1743  {
1744  // Fall back when reverse mode not allowed
1745  if (sp_weight()==0 || sp_weight()==-1)
1746  return FunctionInternal::sp_reverse(arg, res, iw, w, mem);
1747  std::fill_n(w, sz_w(), 0);
1748 
1749  // Propagate sparsity backward
1750  for (auto it=algorithm_.rbegin(); it!=algorithm_.rend(); ++it) {
1751  // Temp seed
1752  bvec_t seed;
1753 
1754  // Propagate seeds
1755  switch (it->op) {
1756  case OP_CONST:
1757  case OP_PARAMETER:
1758  w[it->i0] = 0;
1759  break;
1760  case OP_INPUT:
1761  if (arg[it->i1]!=nullptr && is_diff_in_[it->i1])
1762  arg[it->i1][it->i2] |= w[it->i0];
1763  w[it->i0] = 0;
1764  break;
1765  case OP_OUTPUT:
1766  if (res[it->i0]!=nullptr && is_diff_out_[it->i0]) {
1767  w[it->i1] |= res[it->i0][it->i2];
1768  res[it->i0][it->i2] = 0;
1769  }
1770  break;
1771  case OP_CALL:
1772  call_rev(*it, arg, res, iw, w);
1773  break;
1774  default: // Unary or binary operation
1775  seed = w[it->i0];
1776  w[it->i0] = 0;
1777  w[it->i1] |= seed;
1778  w[it->i2] |= seed;
1779  }
1780  }
1781  return 0;
1782  }
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 3475 of file function_internal.cpp.

3475  {
3476  // If reverse mode propagation unavailable, use forward
3477  if (!has_sprev()) return 0;
3478 
3479  // If forward mode propagation unavailable, use reverse
3480  if (!has_spfwd()) return 1;
3481 
3482  // Use the (potentially user set) option
3483  return ad_weight_sp_;
3484  }

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

4088  {
4089  // Variable number of arguments
4090  va_list args;
4091  va_start(args, fmt);
4092  // Print to buffer
4093  casadi_int n = vsnprintf(buf, buf_sz, fmt, args);
4094  // Cleanup
4095  va_end(args);
4096  // Throw error if failure
4097  casadi_assert(n>=0 && n<buf_sz, "Print failure while processing '" + std::string(fmt) + "'");
4098  }

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

4156  {
4157  switch (status) {
4158  case SOLVER_RET_LIMITED: return "SOLVER_RET_LIMITED";
4159  case SOLVER_RET_NAN: return "SOLVER_RET_NAN";
4160  case SOLVER_RET_SUCCESS: return "SOLVER_RET_SUCCESS";
4161  default: return "SOLVER_RET_UNKNOWN";
4162  }
4163  }
@ 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 1788 of file sx_function.cpp.

1788  {
1789  return in_;
1790  }

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

1784  {
1785  return in_.at(ind);
1786  }

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

3510  {
3511  std::vector<SX> ret(n_out_);
3512  for (casadi_int i=0; i<ret.size(); ++i) {
3513  ret[i] = sx_out(i);
3514  }
3515  return ret;
3516  }
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 1207 of file function_internal.cpp.

1207  {
1208  return self()(arg);
1209  }

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

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

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

3093  {
3094  sz_arg = this->sz_arg();
3095  sz_res = this->sz_res();
3096  sz_iw = this->sz_iw();
3097  sz_w = this->sz_w();
3098  }

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

1979  {
1980  // Strip rows and columns
1981  std::vector<casadi_int> mapping;
1982  return sp.sub(sparsity_out(oind).find(), sparsity_in(iind).find(), mapping);
1983  }

References casadi::FunctionInternal::find(), casadi::FunctionInternal::sparsity_in(), casadi::FunctionInternal::sparsity_out(), and casadi::Sparsity::sub().

Referenced by casadi::FunctionInternal::jac_sparsity(), and casadi::FunctionInternal::set_jac_sparsity().

◆ tocache()

void casadi::FunctionInternal::tocache ( const Function f,
const std::string &  suffix = "" 
) const
inherited

◆ tocache_if_missing()

void casadi::FunctionInternal::tocache_if_missing ( Function f,
const std::string &  suffix = "" 
) const
inherited

◆ uses_output()

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

◆ weak()

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

Definition at line 67 of file generic_shared_internal.hpp.

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

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

1186  {
1187  Function f;
1188  if (!incache(name, f)) {
1189  // Options
1190  Dict opts;
1191  opts["derivative_of"] = derivative_of_;
1192  opts["ad_weight"] = ad_weight();
1193  opts["ad_weight_sp"] = sp_weight();
1194  opts["max_num_dir"] = max_num_dir_;
1195  opts["is_diff_in"] = is_diff_in_;
1196  opts["is_diff_out"] = is_diff_out_;
1197  // Wrap the function
1198  std::vector<MX> arg = mx_in();
1199  std::vector<MX> res = self()(arg);
1200  f = Function(name, arg, res, name_in_, name_out_, opts);
1201  // Save in cache
1202  tocache_if_missing(f);
1203  }
1204  return f;
1205  }

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

1161  {
1162  return wrap_as_needed("wrap_" + name_, opts);
1163  }
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 1165 of file function_internal.cpp.

1165  {
1166  if (opts.empty() && name==name_) return shared_from_this<Function>();
1167  // Options
1168  Dict my_opts = opts;
1169  my_opts["derivative_of"] = derivative_of_;
1170  if (my_opts.find("ad_weight")==my_opts.end())
1171  my_opts["ad_weight"] = ad_weight();
1172  if (my_opts.find("ad_weight_sp")==my_opts.end())
1173  my_opts["ad_weight_sp"] = sp_weight();
1174  if (my_opts.find("max_num_dir")==my_opts.end())
1175  my_opts["max_num_dir"] = max_num_dir_;
1176  // Wrap the function
1177  std::vector<MX> arg = mx_in();
1178  std::vector<MX> res = self()(arg);
1179  return Function(name, arg, res, name_in_, name_out_, my_opts);
1180  }

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 270 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 276 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 273 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},
{"Map", Map::deserialize},
{"MapSum", MapSum::deserialize},
{"Nlpsol", Nlpsol::deserialize},
{"Rootfinder", Rootfinder::deserialize},
{"Integrator", Integrator::deserialize},
{"External", External::deserialize},
{"Conic", Conic::deserialize},
{"FmuFunction", FmuFunction::deserialize},
{"BlazingSplineFunction", BlazingSplineFunction::deserialize},
}
static ProtoFunction * deserialize(DeserializingStream &s)
Deserialize into MX.
void deserialize(DeserializingStream &s, SDPToSOCPMem &m)
Definition: conic.cpp: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)
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)
Deserialize without type information.
Definition: switch.hpp:150

Definition at line 1511 of file function_internal.hpp.

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

◆ dump_

bool casadi::FunctionInternal::dump_
inherited

◆ dump_count_

casadi_int casadi::FunctionInternal::dump_count_
mutableinherited

◆ dump_dir_

std::string casadi::FunctionInternal::dump_dir_
inherited

◆ dump_format_

std::string casadi::FunctionInternal::dump_format_
inherited

◆ dump_in_

bool casadi::FunctionInternal::dump_in_
inherited

◆ dump_out_

bool casadi::FunctionInternal::dump_out_
inherited

◆ enable_fd_

bool casadi::FunctionInternal::enable_fd_
inherited

◆ enable_fd_op_

bool casadi::FunctionInternal::enable_fd_op_
inherited

◆ enable_forward_

bool casadi::FunctionInternal::enable_forward_
inherited

◆ enable_forward_op_

bool casadi::FunctionInternal::enable_forward_op_
inherited

◆ enable_jacobian_

bool casadi::FunctionInternal::enable_jacobian_
inherited

◆ enable_jacobian_op_

bool casadi::FunctionInternal::enable_jacobian_op_
inherited

◆ enable_reverse_

bool casadi::FunctionInternal::enable_reverse_
inherited

◆ enable_reverse_op_

bool casadi::FunctionInternal::enable_reverse_op_
inherited

◆ error_on_fail_

bool casadi::ProtoFunction::error_on_fail_
inherited

◆ eval_

eval_t casadi::FunctionInternal::eval_
inherited

◆ fd_method_

std::string casadi::FunctionInternal::fd_method_
inherited

◆ fd_options_

Dict casadi::FunctionInternal::fd_options_
inherited

◆ fd_step_

double casadi::FunctionInternal::fd_step_
inherited

◆ forward_options_

Dict casadi::FunctionInternal::forward_options_
inherited

◆ free_vars_

std::vector<SXElem> casadi::SXFunction::free_vars_

◆ has_refcount_

bool casadi::FunctionInternal::has_refcount_
inherited

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

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

◆ live_variables_

bool casadi::SXFunction::live_variables_

Definition at line 407 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 1309 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(), 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 1309 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::FmuFunction::FmuFunction(), casadi::FunctionInternal::forward(), casadi::KinsolInterface::func(), casadi::FunctionInternal::FunctionInternal(), casadi::FunctionInternal::generate_out(), casadi::LinearInterpolantJac::get_jacobian(), casadi::FunctionInternal::init(), casadi::MapSum::init(), casadi::Nlpsol::init(), casadi::Switch::init(), casadi::FunctionInternal::jac_sparsity(), casadi::FunctionInternal::jacobian(), casadi::FunctionInternal::mapsum_mx(), casadi::FunctionInternal::matching_res(), casadi::FunctionInternal::mx_out(), casadi::FunctionInternal::nnz_out(), casadi::FunctionInternal::numel_out(), casadi::FunctionInternal::nz_out(), casadi::FunctionInternal::print_dimensions(), casadi::FunctionInternal::print_out(), casadi::KinsolInterface::psetup(), casadi::FunctionInternal::reverse(), casadi::FmuFunction::serialize_body(), casadi::FunctionInternal::set_jac_sparsity(), casadi::Rootfinder::set_work(), casadi::QpToNlp::solve(), casadi::KinsolInterface::solve(), casadi::FastNewton::solve(), casadi::ImplicitToNlp::solve(), casadi::Newton::solve(), casadi::FunctionInternal::sp_forward(), casadi::Integrator::sp_forward(), casadi::MXFunction::sp_forward(), casadi::Rootfinder::sp_forward(), casadi::FunctionInternal::sp_reverse(), casadi::Integrator::sp_reverse(), casadi::Map::sp_reverse(), casadi::MapSum::sp_reverse(), casadi::MXFunction::sp_reverse(), casadi::Rootfinder::sp_reverse(), and casadi::FunctionInternal::sx_out().

◆ name_

std::string casadi::ProtoFunction::name_
inherited

Definition at line 246 of file function_internal.hpp.

Referenced by casadi::MXFunction::ad_forward(), ad_forward(), casadi::MXFunction::ad_reverse(), ad_reverse(), casadi::Integrator::augmented_dae(), casadi::OracleFunction::calc_function(), casadi::FunctionInternal::call_forward(), casadi::FunctionInternal::call_reverse(), casadi::FunctionInternal::codegen_body(), casadi::External::codegen_body(), casadi::External::codegen_checkout(), casadi::External::codegen_declarations(), casadi::MXFunction::codegen_declarations(), codegen_declarations(), casadi::External::codegen_decref(), casadi::External::codegen_incref(), casadi::FunctionInternal::codegen_meta(), casadi::FunctionInternal::codegen_name(), casadi::External::codegen_release(), casadi::FunctionInternal::codegen_sparsities(), casadi::ProtoFunction::construct(), casadi::OracleFunction::create_function(), casadi::FunctionInternal::definition(), casadi::FunctionInternal::eval(), casadi::MXFunction::eval(), eval(), casadi::FunctionInternal::eval_mx(), casadi::MXFunction::eval_mx(), eval_mx(), eval_sx(), casadi::FmuFunction::factory(), casadi::FunctionInternal::finalize(), casadi::FunctionInternal::forward(), casadi::FunctionInternal::FunctionInternal(), casadi::Integrator::get_forward(), casadi::Integrator::get_forward_dae(), casadi::Map::get_function(), casadi::MapSum::get_function(), casadi::OracleFunction::get_function(), casadi::GenericExternal::get_jac_sparsity(), casadi::BlazingSplineFunction::get_jacobian(), casadi::FunctionInternal::get_n_in(), casadi::External::get_n_in(), casadi::FunctionInternal::get_n_out(), casadi::External::get_n_out(), casadi::FunctionInternal::get_name_in(), casadi::External::get_name_in(), casadi::FunctionInternal::get_name_out(), casadi::External::get_name_out(), casadi::FunctionInternal::get_partition(), casadi::Integrator::get_reverse(), casadi::FunctionInternal::get_sparsity_in(), casadi::GenericExternal::get_sparsity_in(), casadi::FunctionInternal::get_sparsity_out(), casadi::GenericExternal::get_sparsity_out(), casadi::FunctionInternal::get_stats(), casadi::External::has_forward(), casadi::GenericExternal::has_jac_sparsity(), casadi::External::has_jacobian(), casadi::External::has_reverse(), casadi::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::MXFunction::print_arg(), print_arg(), casadi::FunctionInternal::print_in(), casadi::FunctionInternal::print_out(), casadi::MXFunction::print_res(), print_res(), casadi::ProtoFunction::print_time(), casadi::ProtoFunction::ProtoFunction(), casadi::CvodesInterface::reset(), casadi::IdasInterface::reset(), casadi::IdasInterface::resetB(), casadi::FunctionInternal::reverse(), casadi::ProtoFunction::serialize_body(), casadi::GurobiInterface::solve(), casadi::SnoptInterface::solve(), casadi::Integrator::sp_forward(), casadi::Integrator::sp_reverse(), casadi::FunctionInternal::wrap(), and casadi::FunctionInternal::wrap_as_needed().

◆ name_in_

std::vector<std::string> casadi::FunctionInternal::name_in_
inherited

◆ name_out_

std::vector<std::string> casadi::FunctionInternal::name_out_
inherited

◆ never_inline_

bool casadi::FunctionInternal::never_inline_
inherited

◆ operations_

std::vector<SXElem> casadi::SXFunction::operations_

◆ options_

const Options casadi::SXFunction::options_
static
Initial value:
{{"default_in",
"Default input values"}},
{"just_in_time_sparsity",
"Propagate sparsity patterns using just-in-time "
"compilation to a CPU or GPU using OpenCL"}},
{"just_in_time_opencl",
"Just-in-time compilation for numeric evaluation using OpenCL (experimental)"}},
{"live_variables",
"Reuse variables in the work vector"}},
{"cse",
"Perform common subexpression elimination (complexity is N*log(N) in graph size)"}},
{"allow_free",
"Allow construction with free variables (Default: false)"}},
{"allow_duplicate_io_names",
"Allow construction with duplicate io names (Default: false)"}},
{"print_instructions",
"Print each operation during evaluation. Influenced by print_canonical."}}
}
}
static const Options options_
Options.
@ OT_DOUBLEVECTOR

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

Definition at line 326 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 249 of file function_internal.hpp.

Referenced by casadi::MXFunction::ad_forward(), ad_forward(), casadi::MXFunction::ad_reverse(), ad_reverse(), casadi::Integrator::advance(), casadi::ProtoFunction::change_option(), casadi::BSplineInterpolant::construct_graph(), casadi::OracleFunction::create_function(), casadi::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: