26 #ifndef CASADI_BINARY_MX_IMPL_HPP
27 #define CASADI_BINARY_MX_IMPL_HPP
29 #include "binary_mx.hpp"
30 #include "casadi_misc.hpp"
31 #include "global_options.hpp"
32 #include "serializing_stream.hpp"
38 template<
bool ScX,
bool ScY>
48 template<
bool ScX,
bool ScY>
52 template<
bool ScX,
bool ScY>
57 template<
bool ScX,
bool ScY>
59 return operation_checker<NonnegativeChecker>(op_);
62 template<
bool ScX,
bool ScY>
64 const std::vector<bool>& unique)
const {
65 bool unique_x = !unique.empty() && unique[0];
66 bool unique_y = unique.size() >= 2 && unique[1];
67 res[0] =
MX::binary(op_, arg[0], arg[1], unique_x, unique_y);
70 template<
bool ScX,
bool ScY>
72 std::vector<std::array<MX, 3> >& res)
const {
76 template<
bool ScX,
bool ScY>
78 std::vector<std::vector<MX> >& fsens)
const {
84 for (casadi_int d=0; d<fsens.size(); ++d) {
88 fsens[d][0] = pd[0]*fseed[d][0] + pd[1]*fseed[d][1];
93 template<
bool ScX,
bool ScY>
95 std::vector<std::vector<MX> >& asens)
const {
101 for (casadi_int d=0; d<aseed.size(); ++d) {
105 if (!s.
is_scalar() && dep(1).is_scalar()) {
106 asens[d][1] +=
dot(dep(0), s);
112 for (casadi_int c=0; c<2; ++c) {
118 if (pd[c].size()!=s.
size()) pd[c] =
MX(s.sparsity(), pd[c]);
129 template<
bool ScX,
bool ScY>
132 const std::vector<casadi_int>& arg,
const std::vector<casadi_int>& res,
133 const std::vector<bool>& arg_is_ref, std::vector<bool>& res_is_ref)
const {
135 if (nnz()==0)
return;
144 inplace = res[0]==arg[0] && !arg_is_ref[0];
152 std::string r = g.
workel(res[0]);
153 std::string x = g.
workel(arg[0]);
154 std::string y = g.
workel(arg[1]);
164 g.
local(
"rr",
"casadi_real",
"*");
165 g.
local(
"i",
"casadi_int");
166 g <<
"for (i=0, " <<
"rr=" << g.
work(res[0], nnz(),
false);
170 if (!ScX && !inplace) {
171 g.
local(
"cr",
"const casadi_real",
"*");
172 g <<
", cr=" << g.
work(arg[0], dep(0).nnz(), arg_is_ref[0]);
184 g.
local(
"cs",
"const casadi_real",
"*");
185 g <<
", cs=" << g.
work(arg[1], dep(1).nnz(), arg_is_ref[1]);
195 g <<
"; i<" << nnz() <<
"; ++i) ";
201 g << casadi_math<double>::sep(op_) <<
"= " << y;
203 g <<
" = " << g.
print_op(op_, x, y);
208 template<
bool ScX,
bool ScY>
210 eval(
const double** arg,
double** res, casadi_int* iw,
double* w)
const {
211 return eval_gen<double>(arg, res, iw, w);
214 template<
bool ScX,
bool ScY>
217 return eval_gen<SXElem>(arg, res, iw, w);
220 template<
bool ScX,
bool ScY>
223 eval_gen(
const T*
const* arg, T*
const* res, casadi_int* iw, T* w)
const {
226 const T* input0 = arg[0];
227 const T* input1 = arg[1];
239 template<
bool ScX,
bool ScY>
242 const bvec_t *a0=arg[0], *a1=arg[1];
245 for (casadi_int i=0; i<n; ++i) {
248 else if (ScX && !ScY)
250 else if (!ScX && ScY)
253 *r++ = *a0++ | *a1++;
258 template<
bool ScX,
bool ScY>
262 const bool f00 = operation_checker<F00Checker>(op_);
263 const bool f0x = operation_checker<F0XChecker>(op_);
264 const bool fx0 = operation_checker<FX0Checker>(op_);
265 const bvec_t nz = ~static_cast<bvec_t>(0);
266 const bvec_t *a0=arg[0], *a1=arg[1];
269 for (casadi_int i=0; i<n; ++i) {
270 const bool z0 = (*a0)!=0;
271 const bool z1 = (*a1)!=0;
273 if (!z0 && !z1) out = f00 ? 0 : nz;
274 else if (!z0 && z1) out = f0x ? 0 : nz;
275 else if ( z0 && !z1) out = fx0 ? 0 : nz;
284 template<
bool ScX,
bool ScY>
287 bvec_t *a0=arg[0], *a1=arg[1], *r = res[0];
289 for (casadi_int i=0; i<n; ++i) {
304 template<
bool ScX,
bool ScY>
306 bool unique_x,
bool unique_y)
const {
326 template<
bool ScX,
bool ScY>
329 s.
pack(
"BinaryMX::op",
static_cast<int>(op_));
332 template<
bool ScX,
bool ScY>
337 char type = type_x | (type_y << 1);
338 s.
pack(
"BinaryMX::scalar_flags", type);
341 template<
bool ScX,
bool ScY>
344 s.
unpack(
"BinaryMX::scalar_flags", t);
357 template<
bool ScX,
bool ScY>
364 template<
bool ScX,
bool ScY>
367 if (!ScX && !ScY && op_ ==
OP_SUB) {
369 if (dep(0).is_op(
OP_PROJECT) && dep(0).dep(0).is_eye()) {
371 if (dep(1).is_op(
OP_PROJECT) && dep(1).dep(0).sparsity().is_triu(
true)) {
380 template<
bool ScX,
bool ScY>
383 if (!ScX && !ScY && op_ ==
OP_SUB) {
385 if (dep(0).is_op(
OP_PROJECT) && dep(0).dep(0).is_eye()) {
387 if (dep(1).is_op(
OP_PROJECT) && dep(1).dep(0).sparsity().is_tril(
true)) {
Represents any binary operation that involves two matrices.
bool is_nonnegative() const override
Check if not negative.
int sp_reverse(bvec_t **arg, bvec_t **res, casadi_int *iw, bvec_t *w) const override
Propagate sparsity backwards.
std::string disp(const std::vector< std::string > &arg) const override
Print expression.
int eval(const double **arg, double **res, casadi_int *iw, double *w) const override
Evaluate the function numerically.
~BinaryMX() override
Destructor.
casadi_int op() const override
Get the operation.
int eval_activity(const bvec_t **arg, bvec_t **res, casadi_int *iw, bvec_t *w) const override
Propagate signal activity forward.
void eval_mx(const std::vector< MX > &arg, std::vector< MX > &res, const std::vector< bool > &unique=std::vector< bool >()) const override
Evaluate symbolically (MX)
static MXNode * deserialize(DeserializingStream &s)
Deserialize with type disambiguation.
MX get_solve_tril(const MX &r, bool tr) const override
Solve a system of linear equations, lower triangular A.
int sp_forward(const bvec_t **arg, bvec_t **res, casadi_int *iw, bvec_t *w) const override
Propagate sparsity forward.
MX _get_binary(casadi_int op, const MX &y, bool scX, bool scY, bool unique_x=false, bool unique_y=false) const override
Get a binary operation operation.
void ad_reverse(const std::vector< std::vector< MX > > &aseed, std::vector< std::vector< MX > > &asens) const override
Calculate reverse mode directional derivatives.
MX get_solve_triu(const MX &r, bool tr) const override
Solve a system of linear equations, upper triangular A.
void ad_forward(const std::vector< std::vector< MX > > &fseed, std::vector< std::vector< MX > > &fsens) const override
Calculate forward mode directional derivatives.
int eval_sx(const SXElem **arg, SXElem **res, casadi_int *iw, SXElem *w) const override
Evaluate the function symbolically (SX)
BinaryMX(Operation op, const MX &x, const MX &y)
Constructor.
int eval_gen(const T *const *arg, T *const *res, casadi_int *iw, T *w) const
Evaluate the function (template)
void eval_linear(const std::vector< std::array< MX, 3 > > &arg, std::vector< std::array< MX, 3 > > &res) const override
Evaluate the MX node on a const/linear/nonlinear partition.
void serialize_type(SerializingStream &s) const override
Serialize type information.
void serialize_body(SerializingStream &s) const override
Serialize an object without type information.
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.
Helper class for C code generation.
bool codegen_scalars
Codegen scalar.
std::string work(casadi_int n, casadi_int sz, bool is_ref) const
std::string print_op(casadi_int op, const std::string &a0)
Print an operation to a c file.
void local(const std::string &name, const std::string &type, const std::string &ref="")
Declare a local variable.
std::string workel(casadi_int n) const
Helper class for Serialization.
void unpack(Sparsity &e)
Reconstruct an object from the input stream.
std::pair< casadi_int, casadi_int > size() const
Get the shape as a pair (number of rows, number of columns)
bool is_scalar(bool scalar_and_dense=false) const
Check if the matrix is scalar, i.e. 1-by-1.
static bool simplification_on_the_fly
Indicates whether simplifications should be made on the fly.
Node class for MX objects.
virtual void serialize_type(SerializingStream &s) const
Serialize type information.
virtual MX get_solve_triu(const MX &r, bool tr) const
Solve a system of linear equations, upper triangular A.
virtual MX get_solve_tril_unity(const MX &r, bool tr) const
Solve a system of linear equations, lower triangular A, unity diagnal.
virtual MX _get_binary(casadi_int op, const MX &y, bool scX, bool scY, bool unique_x=false, bool unique_y=false) const
Get a binary operation operation (matrix-matrix)
virtual MX get_solve_tril(const MX &r, bool tr) const
Solve a system of linear equations, lower triangular A.
virtual MX get_solve_triu_unity(const MX &r, bool tr) const
Solve a system of linear equations, upper triangular A, unity diagonal.
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.
const Sparsity & sparsity() const
Get the sparsity pattern.
static bool is_equal(const MX &x, const MX &y, casadi_int depth=0)
MX dep(casadi_int ch=0) const
Get the ch-th dependency (child node) of this node.
static MX binary(casadi_int op, const MX &x, const MX &y, bool unique_x=false, bool unique_y=false)
Create an elementwise binary or unary node from an operation code.
The basic scalar symbolic class of CasADi.
Helper class for Serialization.
void pack(const Sparsity &e)
Serializes an object to the output stream.
double if_else_zero(double x, double y)
Conditional assignment.
unsigned long long bvec_t
T dot(const std::vector< T > &a, const std::vector< T > &b)
Operation
Enum for quick access to any node.
static void der(unsigned char op, const T &x, const T &y, const T &f, T *d)
Evaluate a built in derivative function.
static void fun_linear(unsigned char op, const T *x, const T *y, T *f)
Evaluate function on a const/linear/nonlinear partition.
static std::string print(unsigned char op, const std::string &x, const std::string &y)
Print.
static void fun(unsigned char op, const T &x, const T &y, T &f)
Evaluate a built in function (scalar-scalar)