26 #include "casadi_call.hpp"
27 #include "function_internal.hpp"
28 #include "casadi_misc.hpp"
29 #include "serializing_stream.hpp"
31 #define CASADI_THROW_ERROR(FNAME, WHAT) \
32 throw CasadiException("Error in Call::" FNAME " for '" + fcn_.name() + "' "\
33 "[" + fcn_.class_name() + "] at " + CASADI_WHERE + ":\n" + std::string(WHAT));
40 return project(x, sp);
54 casadi_error(
"Cannot create function call node: Dimension mismatch for argument "
55 +
str(i) +
". Argument has shape " +
str(x.
size())
56 +
" but function input has shape " +
str(sp.
size()));
62 MX this_ = shared_from_this<MX>();
66 if (!
cache_.incache(oind, ret)) {
68 cache_.tocache_if_missing(oind, ret);
76 casadi_int num_in = fcn.
n_in();
77 casadi_assert(arg.size()==num_in,
"Argument list length (" +
str(arg.size())
78 +
") does not match number of inputs (" +
str(num_in)
79 +
") for function " + fcn.
name());
82 std::vector<MX> arg1(num_in);
83 for (casadi_int i=0; i<num_in; ++i) {
90 std::string
Call::disp(
const std::vector<std::string>& arg)
const {
93 for (casadi_int i=0; i<
n_dep(); ++i) {
101 int Call::eval(
const double** arg,
double** res, casadi_int* iw,
double* w)
const {
102 return fcn_(arg, res, iw, w);
114 return fcn_(arg, res, iw, w);
118 const std::vector<bool>& unique)
const {
123 std::vector<std::vector<MX>>& fsens)
const {
126 std::vector<MX> arg(
n_dep());
127 for (casadi_int i=0; i<arg.size(); ++i) arg[i] =
dep(i);
128 std::vector<MX> res(
nout());
129 for (casadi_int i=0; i<res.size(); ++i) res[i] =
get_output(i);
133 }
catch (std::exception& e) {
134 CASADI_THROW_ERROR(
"ad_forward", e.what());
139 std::vector<std::vector<MX>>& asens)
const {
144 std::vector<MX> arg(
n_dep());
145 for (casadi_int i=0; i<arg.size(); ++i) arg[i] =
dep(i);
146 std::vector<MX> res(
nout());
147 for (casadi_int i=0; i<res.size(); ++i) res[i] =
get_output(i);
149 std::vector<std::vector<MX>> v;
151 for (casadi_int i=0; i<v.size(); ++i) {
152 for (casadi_int j=0; j<v[i].size(); ++j) {
154 if (v[i][j].is_empty())
continue;
158 asens[i][j] += v[i][j];
161 }
catch (std::exception& e) {
162 CASADI_THROW_ERROR(
"ad_reverse", e.what());
167 return fcn_(arg, res, iw, w);
175 return fcn_.
rev(arg, res, iw, w);
183 const std::vector<casadi_int>& arg,
184 const std::vector<casadi_int>& res,
185 const std::vector<bool>& arg_is_ref,
186 std::vector<bool>& res_is_ref)
const {
188 g.
local(
"arg1",
"const casadi_real",
"**");
189 for (casadi_int i=0; i<arg.size(); ++i) {
190 g <<
"arg1[" << i <<
"]=" << g.
work(arg[i],
fcn_.
nnz_in(i), arg_is_ref[i]) <<
";\n";
194 g.
local(
"res1",
"casadi_real",
"**");
195 for (casadi_int i=0; i<res.size(); ++i) {
196 g <<
"res1[" << i <<
"]=" << g.
work(res[i],
fcn_.
nnz_out(i),
false) <<
";\n";
200 std::string flag = g(
fcn_,
"arg1",
"res1",
"iw",
"w");
201 g <<
"if (" << flag <<
") return 1;\n";
226 bool any_zero_in =
false;
227 for (
const MX& a : arg)
if (a.is_zero()) { any_zero_in =
true;
break; }
229 std::vector<bool> mask;
230 mask.reserve(fcn.
nnz_in());
231 for (casadi_int i=0; i<fcn.
n_in(); ++i)
232 mask.insert(mask.end(), fcn.
nnz_in(i), !arg[i].is_zero());
233 std::vector<bool> onz = fcn.
activity(mask);
234 bool all_out_zero =
true;
235 for (
bool active : onz)
if (active) { all_out_zero =
false;
break; }
237 std::vector<MX> ret(fcn.
n_out());
261 for (
const std::vector<MX>& seed_dir : seed) {
262 for (
const MX& s : seed_dir) {
264 if (s.is_zero())
continue;
static std::vector< MX > create(const Function &fcn, const std::vector< MX > &arg)
Create function call node.
Call(const Function &fcn, const std::vector< MX > &arg)
Constructor (should not be used directly)
WeakCache< casadi_int, MX > cache_
Output node cache.
int sp_reverse(bvec_t **arg, bvec_t **res, casadi_int *iw, bvec_t *w) const override
Propagate sparsity backwards.
void serialize_body(SerializingStream &s) const override
Serialize an object without type information.
size_t sz_w() const override
Get required length of w field.
MX get_output(casadi_int oind) const override
Get an output.
int eval(const double **arg, double **res, casadi_int *iw, double *w) const override
Evaluate the function numerically.
void generate(CodeGenerator &g, const std::vector< casadi_int > &arg, const std::vector< casadi_int > &res, const std::vector< bool > &arg_is_ref, std::vector< bool > &res_is_ref) const override
Generate code for the operation.
int eval_activity(const bvec_t **arg, bvec_t **res, casadi_int *iw, bvec_t *w) const override
Propagate signal activity forward (recurses into the callee)
size_t sz_res() const override
Get required length of res field.
static MX create_call(const Function &fcn, const std::vector< MX > &arg)
Create function call node.
void ad_forward(const std::vector< std::vector< MX > > &fseed, std::vector< std::vector< MX > > &fsens) const override
Calculate forward mode directional derivatives.
size_t sz_iw() const override
Get required length of iw field.
int sp_forward(const bvec_t **arg, bvec_t **res, casadi_int *iw, bvec_t *w) const override
Propagate sparsity forward.
size_t sz_arg() const override
Get required length of arg field.
void eval_mx(const std::vector< MX > &arg, std::vector< MX > &res, const std::vector< bool > &unique={}) const override
Evaluate symbolically (MX)
casadi_int nout() const override
Number of outputs.
void add_dependency(CodeGenerator &g) const override
Add a dependent function.
void ad_reverse(const std::vector< std::vector< MX > > &aseed, std::vector< std::vector< MX > > &asens) const override
Calculate reverse mode directional derivatives.
static MX projectArg(const MX &x, const Sparsity &sp, casadi_int i)
Project a function input to a particular sparsity.
std::string disp(const std::vector< std::string > &arg) const override
Print expression.
static MX common_cond(const std::vector< std::vector< MX >> &seed)
Find a common conditional argument for all seeds.
int eval_sx(const SXElem **arg, SXElem **res, casadi_int *iw, SXElem *w) const override
Evaluate the function symbolically (SX)
Helper class for C code generation.
std::string add_dependency(const Function &f)
Add a function dependency.
std::string work(casadi_int n, casadi_int sz, bool is_ref) const
void local(const std::string &name, const std::string &type, const std::string &ref="")
Declare a local variable.
Helper class for Serialization.
void unpack(Sparsity &e)
Reconstruct an object from the input stream.
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 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.
casadi_int nnz_out() const
Get number of output nonzeros.
size_t sz_res() const
Get required length of res field.
casadi_int size2_out(casadi_int ind) const
Get output dimension.
const Sparsity & sparsity_out(casadi_int ind) const
Get sparsity of a given output.
const std::string & name() const
Name of the function.
int rev(bvec_t **arg, bvec_t **res, casadi_int *iw, bvec_t *w, int mem=0) const
Propagate sparsity backward.
const Sparsity & sparsity_in(casadi_int ind) const
Get sparsity of a given input.
size_t sz_iw() const
Get required length of iw field.
casadi_int n_out() const
Get the number of function outputs.
casadi_int n_in() const
Get the number of function inputs.
size_t sz_w() const
Get required length of w field.
size_t sz_arg() const
Get required length of arg field.
casadi_int nnz_in() const
Get number of input nonzeros.
casadi_int size1_out(casadi_int ind) const
Get output dimension.
int eval_activity(const bvec_t **arg, bvec_t **res, casadi_int *iw, bvec_t *w, int mem=0) const
Propagate signal activity forward (bit set = active (possibly nonzero))
std::vector< bool > activity(const std::vector< bool > &arg) const
Output signal activity induced by a given input activity.
bool is_empty(bool both=false) const
Check if the sparsity is empty, i.e. if one of the dimensions is zero.
std::pair< casadi_int, casadi_int > size() const
Get the shape.
casadi_int size2() const
Get the second dimension (i.e. number of columns)
casadi_int size1() const
Get the first dimension (i.e. number of rows)
static MX zeros(casadi_int nrow=1, casadi_int ncol=1)
Create a dense matrix or a matrix with specified sparsity with all entries zero.
bool is_scalar(bool scalar_and_dense=false) const
Check if the matrix expression is scalar.
const Sparsity & sparsity() const
Get the sparsity.
const MX & dep(casadi_int ind=0) const
dependencies - functions that have to be evaluated before this one
casadi_int n_dep() const
Number of dependencies.
virtual void serialize_body(SerializingStream &s) const
Serialize an object without type information.
void set_sparsity(const Sparsity &sparsity)
Set the sparsity.
void set_dep(const MX &dep)
Set unary dependency.
static MX create(MXNode *node)
Create from node.
static bool is_equal(const MX &x, const MX &y, casadi_int depth=0)
MX T() const
Transpose the matrix.
static std::vector< MX > createMultipleOutput(MXNode *node)
Create from node (multiple-outputs)
MX dep(casadi_int ch=0) const
Get the nth dependency as MX.
The basic scalar symbolic class of CasADi.
Helper class for Serialization.
void pack(const Sparsity &e)
Serializes an object to the output stream.
bool is_vector() const
Check if the pattern is a row or column vector.
casadi_int size1() const
Get the number of rows.
casadi_int nnz() const
Get the number of (structural) non-zeros.
casadi_int size2() const
Get the number of columns.
std::pair< casadi_int, casadi_int > size() const
Get the shape.
static Sparsity scalar(bool dense_scalar=true)
Create a scalar sparsity pattern *.
bool is_empty(bool both=false) const
Check if the sparsity is empty.
unsigned long long bvec_t
double if_else(double x, double y, double z)
std::string str(const T &v)
String representation, any type.