26 #ifndef CASADI_SETNONZEROS_PARAM_IMPL_HPP
27 #define CASADI_SETNONZEROS_PARAM_IMPL_HPP
29 #include "setnonzeros_param.hpp"
30 #include "casadi_misc.hpp"
31 #include "serializing_stream.hpp"
44 casadi_assert(outer.
is_vector() && outer.
is_dense(),
"outer must be dense vector");
50 casadi_assert(inner.
is_vector() && inner.
is_dense(),
"inner must be dense vector");
56 casadi_assert(inner.
is_vector() && inner.
is_dense(),
"inner must be dense vector");
57 casadi_assert(outer.
is_vector() && outer.
is_dense(),
"outer must be dense vector");
64 this->set_dep(y, x, nz);
70 this->set_dep({y, x, nz, nz2});
84 eval_mx(
const std::vector<MX>& arg, std::vector<MX>& res)
const {
86 MX arg0 = project(arg[0], this->dep(0).sparsity());
87 MX arg1 = project(arg[1], this->dep(1).sparsity());
98 eval_mx(
const std::vector<MX>& arg, std::vector<MX>& res)
const {
100 MX arg0 = project(arg[0], this->dep(0).sparsity());
101 MX arg1 = project(arg[1], this->dep(1).sparsity());
104 res[0] = arg1->
get_nzadd(arg0, inner, outer_);
112 eval_mx(
const std::vector<MX>& arg, std::vector<MX>& res)
const {
114 MX arg0 = project(arg[0], this->dep(0).sparsity());
115 MX arg1 = project(arg[1], this->dep(1).sparsity());
118 res[0] = arg1->
get_nzadd(arg0, inner_, outer);
126 eval_mx(
const std::vector<MX>& arg, std::vector<MX>& res)
const {
128 MX arg0 = project(arg[0], this->dep(0).sparsity());
129 MX arg1 = project(arg[1], this->dep(1).sparsity());
133 res[0] = arg1->
get_nzadd(arg0, inner, outer);
141 std::vector<std::vector<MX> >& fsens)
const {
142 const MX& nz = this->dep(2);
144 for (casadi_int d=0; d<fsens.size(); ++d) {
147 MX arg0 = project(fseed[d][0], this->dep(0).sparsity());
148 MX arg1 = project(fseed[d][1], this->dep(1).sparsity());
162 MX& res = fsens[d][0];
175 std::vector<std::vector<MX> >& asens)
const {
176 const MX& nz = this->dep(2);
177 for (casadi_int d=0; d<aseed.size(); ++d) {
178 MX seed = project(aseed[d][0], this->sparsity());
201 std::vector<std::vector<MX> >& fsens)
const {
202 const MX& inner = this->dep(2);
203 for (casadi_int d=0; d<fsens.size(); ++d) {
204 MX arg0 = project(fseed[d][0], this->dep(0).sparsity());
205 MX arg1 = project(fseed[d][1], this->dep(1).sparsity());
207 MX& res = fsens[d][0];
211 res = arg1->
get_nzadd(res, inner, outer_);
220 std::vector<std::vector<MX> >& asens)
const {
221 const MX& inner = this->dep(2);
222 for (casadi_int d=0; d<aseed.size(); ++d) {
223 MX seed = project(aseed[d][0], this->sparsity());
224 asens[d][1] += seed->
get_nz_ref(inner, outer_);
235 std::vector<std::vector<MX> >& fsens)
const {
236 const MX& outer = this->dep(2);
237 for (casadi_int d=0; d<fsens.size(); ++d) {
238 MX arg0 = project(fseed[d][0], this->dep(0).sparsity());
239 MX arg1 = project(fseed[d][1], this->dep(1).sparsity());
241 MX& res = fsens[d][0];
245 res = arg1->
get_nzadd(res, inner_, outer);
254 std::vector<std::vector<MX> >& asens)
const {
255 const MX& outer = this->dep(2);
256 for (casadi_int d=0; d<aseed.size(); ++d) {
257 MX seed = project(aseed[d][0], this->sparsity());
258 asens[d][1] += seed->
get_nz_ref(inner_, outer);
269 std::vector<std::vector<MX> >& fsens)
const {
270 const MX& inner = this->dep(2);
271 const MX& outer = this->dep(3);
272 for (casadi_int d=0; d<fsens.size(); ++d) {
273 MX arg0 = project(fseed[d][0], this->dep(0).sparsity());
274 MX arg1 = project(fseed[d][1], this->dep(1).sparsity());
276 MX& res = fsens[d][0];
280 res = arg1->
get_nzadd(res, inner, outer);
289 std::vector<std::vector<MX> >& asens)
const {
290 const MX& inner = this->dep(2);
291 const MX& outer = this->dep(3);
292 for (casadi_int d=0; d<aseed.size(); ++d) {
293 MX seed = project(aseed[d][0], this->sparsity());
294 asens[d][1] += seed->
get_nz_ref(inner, outer);
305 eval(
const double** arg,
double** res, casadi_int* iw,
double* w)
const {
306 const double* idata0 = arg[0];
307 const double* idata = arg[1];
308 const double* nz = arg[2];
309 double* odata = res[0];
311 casadi_int nnz = this->dep(2).nnz();
312 casadi_int max_ind = this->dep(0).nnz();
313 if (idata0 != odata) {
314 std::copy(idata0, idata0+this->dep(0).nnz(), odata);
316 for (casadi_int k=0; k<nnz; ++k) {
318 casadi_int index =
static_cast<casadi_int
>(*nz++);
320 if (index>=0 && index<max_ind) odata[index] += *idata;
322 if (index>=0 && index<max_ind) odata[index] = *idata;
331 eval(
const double** arg,
double** res, casadi_int* iw,
double* w)
const {
332 const double* idata0 = arg[0];
333 const double* idata = arg[1];
334 const double* nz = arg[2];
335 double* odata = res[0];
337 casadi_int nnz = this->dep(2).nnz();
338 casadi_int max_ind = this->dep(0).nnz();
339 if (idata0 != odata) {
340 std::copy(idata0, idata0+this->dep(0).nnz(), odata);
343 casadi_int* inner = iw; iw += nnz;
344 for (casadi_int i=0; i<nnz; ++i) {
346 inner[i] =
static_cast<casadi_int
>(*nz++);
348 for (casadi_int i=outer_.start;i<outer_.stop;i+= outer_.step) {
350 for (casadi_int* inner_it=inner; inner_it!=inner+nnz; ++inner_it) {
351 casadi_int index = i+*inner_it;
353 if (index>=0 && index<max_ind) odata[index] += *idata;
355 if (index>=0 && index<max_ind) odata[index] = *idata;
365 eval(
const double** arg,
double** res, casadi_int* iw,
double* w)
const {
366 const double* idata0 = arg[0];
367 const double* idata = arg[1];
368 const double* nz = arg[2];
369 double* odata = res[0];
371 casadi_int nnz = this->dep(2).nnz();
372 casadi_int max_ind = this->dep(0).nnz();
373 if (idata0 != odata) {
374 std::copy(idata0, idata0+this->dep(0).nnz(), odata);
376 for (casadi_int k=0; k<nnz; ++k) {
378 casadi_int ind =
static_cast<casadi_int
>(*nz++);
379 for (casadi_int j=0;j<inner_.stop;j+= inner_.step) {
380 casadi_int index = ind+j;
382 if (index>=0 && index<max_ind) odata[index] += *idata;
384 if (index>=0 && index<max_ind) odata[index] = *idata;
394 eval(
const double** arg,
double** res, casadi_int* iw,
double* w)
const {
395 const double* idata0 = arg[0];
396 const double* idata = arg[1];
397 const double* nz = arg[2];
398 const double* nz2 = arg[3];
399 double* odata = res[0];
401 casadi_int nnz = this->dep(2).nnz();
402 casadi_int nnz2 = this->dep(3).nnz();
403 casadi_int max_ind = this->dep(0).nnz();
404 if (idata0 != odata) {
405 std::copy(idata0, idata0+this->dep(0).nnz(), odata);
408 casadi_int* inner = iw; iw += nnz;
409 for (casadi_int i=0; i<nnz; ++i) {
411 inner[i] =
static_cast<casadi_int
>(*nz++);
414 for (casadi_int k=0; k<nnz2; ++k) {
416 casadi_int ind =
static_cast<casadi_int
>(*nz2++);
417 for (casadi_int* inner_it=inner; inner_it!=inner+nnz; ++inner_it) {
418 casadi_int index = ind+*inner_it;
420 if (index>=0 && index<max_ind) odata[index] += *idata;
422 if (index>=0 && index<max_ind) odata[index] = *idata;
433 return this->dep(2).nnz();
439 return this->dep(2).nnz();
451 std::fill(r, r+this->nnz(), arg0 | arg1);
461 std::fill(res[0], res[0]+this->nnz(),
bvec_t(0));
463 for (casadi_int i=0;i<this->dep(0).nnz();++i) {
466 for (casadi_int i=0;i<this->dep(1).nnz();++i) {
474 std::stringstream ss;
475 ss <<
"(" << arg.at(0) <<
"[" << arg.at(2) <<
"]";
476 ss << (Add ?
" += " :
" = ") << arg.at(1) <<
")";
482 std::stringstream ss;
483 ss <<
"(" << arg.at(0) <<
"[(" << arg.at(2) <<
";" << outer_ <<
")]";
484 ss << (Add ?
" += " :
" = ") << arg.at(1) <<
")";
490 std::stringstream ss;
491 ss <<
"(" << arg.at(0) <<
"[(" << inner_ <<
";" << arg.at(2) <<
")]";
492 ss << (Add ?
" += " :
" = ") << arg.at(1) <<
")";
498 std::stringstream ss;
499 ss <<
"(" << arg.at(0) <<
"[(" << arg.at(2) <<
";" << arg.at(3) <<
")]";
500 ss << (Add ?
" += " :
" = ") << arg.at(1) <<
")";
507 const std::vector<casadi_int>& arg,
508 const std::vector<casadi_int>& res,
509 const std::vector<bool>& arg_is_ref,
510 std::vector<bool>& res_is_ref)
const {
512 if (arg[0]!=res[0] || arg_is_ref[0]) {
513 g << g.
copy(g.
work(arg[0], this->dep(0).nnz(), arg_is_ref[0]), this->nnz(),
514 g.
work(res[0], this->nnz(),
false)) <<
'\n';
521 const std::vector<casadi_int>& arg,
522 const std::vector<casadi_int>& res,
523 const std::vector<bool>& arg_is_ref,
524 std::vector<bool>& res_is_ref)
const {
527 casadi_int n = this->dep(1).nnz();
529 std::string a1 = g.
work(arg[1], n, arg_is_ref[1]);
530 std::string a2 = g.
work(arg[2], n, arg_is_ref[2]);
532 g.
local(
"i",
"casadi_int");
533 g.
local(
"cr",
"const casadi_real",
"*");
534 g.
local(
"cs",
"const casadi_real",
"*");
535 g <<
"for (cs=" << a1 <<
", cr=" << a2
536 <<
"; cs!=" << a1 <<
"+" << n
537 <<
"; ++cs) { i=(int) *cr++; if (i>=0 && i<" << this->dep(0).nnz() <<
") "
538 << g.
work(res[0], this->nnz(),
false) <<
"[i] " << (Add?
"+= ":
"= ")
545 const std::vector<casadi_int>& arg,
546 const std::vector<casadi_int>& res,
547 const std::vector<bool>& arg_is_ref,
548 std::vector<bool>& res_is_ref)
const {
551 casadi_int n = this->dep(1).nnz();
552 casadi_int n_inner = this->dep(2).nnz();
554 g.
local(
"cii",
"const casadi_int",
"*");
555 g.
local(
"i",
"casadi_int");
556 g <<
"for (i=0;i<" << n_inner <<
";++i) iw[i] = (int) "
557 << g.
work(arg[2], n_inner, arg_is_ref[2]) <<
"[i];\n";
559 g.
local(
"cs",
"const casadi_real",
"*");
560 g.
local(
"k",
"casadi_int");
561 g <<
"for (cs=" << g.
work(arg[1], n, arg_is_ref[1])
562 <<
", k=" << outer_.start <<
";k<" << outer_.stop <<
";k+=" << outer_.step <<
") ";
563 g <<
"for (cii=iw; cii!=iw" <<
"+" << n_inner <<
"; ++cii) { i=k+*cii; "
564 <<
"if (i>=0 && i<" << this->dep(0).nnz() <<
") "
565 << g.
work(res[0], this->nnz(),
false) <<
"[i] " << (Add?
"+= ":
"= ")
572 const std::vector<casadi_int>& arg,
573 const std::vector<casadi_int>& res,
574 const std::vector<bool>& arg_is_ref,
575 std::vector<bool>& res_is_ref)
const {
578 casadi_int n = this->dep(1).nnz();
579 casadi_int n_outer = this->dep(2).nnz();
581 g.
local(
"i",
"casadi_int");
582 g.
local(
"j",
"casadi_int");
583 g.
local(
"k",
"casadi_int");
584 g.
local(
"cr",
"const casadi_real",
"*");
585 g.
local(
"cs",
"const casadi_real",
"*");
586 g <<
"for (cr=" << g.
work(arg[2], n_outer, arg_is_ref[2])
587 <<
", cs=" << g.
work(arg[1], n, arg_is_ref[1])
588 <<
"; cr!=" << g.
work(arg[2], n_outer, arg_is_ref[2]) <<
"+" << n_outer
590 g <<
"for (j=(int) *cr, "
591 <<
"k=" << inner_.start <<
";k<" << inner_.stop <<
";k+=" << inner_.step <<
") ";
593 <<
"if (i>=0 && i<" << this->dep(0).nnz() <<
") "
594 << g.
work(res[0], this->nnz(),
false) <<
"[i] " << (Add?
"+= ":
"= ")
601 const std::vector<casadi_int>& arg,
602 const std::vector<casadi_int>& res,
603 const std::vector<bool>& arg_is_ref,
604 std::vector<bool>& res_is_ref)
const {
606 casadi_int n = this->dep(1).nnz();
607 casadi_int n_outer = this->dep(3).nnz();
608 casadi_int n_inner = this->dep(2).nnz();
610 g.
local(
"cii",
"const casadi_int",
"*");
611 g.
local(
"i",
"casadi_int");
612 g <<
"for (i=0;i<" << n_inner <<
";++i) iw[i] = (int) "
613 << g.
work(arg[2], n_inner, arg_is_ref[2]) <<
"[i];\n";
615 g.
local(
"j",
"casadi_int");
616 g.
local(
"cr",
"const casadi_real",
"*");
617 g.
local(
"cs",
"const casadi_real",
"*");
618 g <<
"for (cr=" << g.
work(arg[3], n_outer, arg_is_ref[3])
619 <<
", cs=" << g.
work(arg[1], n, arg_is_ref[1])
620 <<
"; cr!=" << g.
work(arg[3], n_outer, arg_is_ref[3]) <<
"+" << n_outer
622 g <<
"for (j=(int) *cr, cii=iw; cii!=iw" <<
"+" << n_inner <<
"; ++cii) { i=j+*cii; "
623 <<
"if (i>=0 && i<" << this->dep(0).nnz() <<
") "
624 << g.
work(res[0], this->nnz(),
false) <<
"[i] " << (Add?
"+= ":
"= ")
641 s.
pack(
"SetNonzerosParam::type",
'a');
647 s.
pack(
"SetNonzerosParamSlice::outer", outer_);
659 s.
pack(
"SetNonzerosParam::type",
'b');
665 s.
pack(
"SetNonzerosSliceParam::inner", inner_);
677 s.
pack(
"SetNonzerosParam::type",
'c');
684 s.
pack(
"SetNonzerosParam::type",
'd');
695 s.
unpack(
"SetNonzerosParam::type", t);
701 default: casadi_assert_dev(
false);
Helper class for C code generation.
std::string work(casadi_int n, casadi_int sz, bool is_ref) const
std::string copy(const std::string &arg, std::size_t n, const std::string &res)
Create a copy operation.
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.
bool is_dense() const
Check if the matrix expression is dense.
bool is_vector() const
Check if the matrix is a row or column vector.
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.
Node class for MX objects.
virtual void serialize_type(SerializingStream &s) const
Serialize type information.
virtual MX get_nzassign(const MX &y, const std::vector< casadi_int > &nz) const
Assign the nonzeros of a matrix to another matrix.
virtual MX get_nz_ref(const MX &nz) const
Get the nonzeros of matrix, parametrically.
virtual void serialize_body(SerializingStream &s) const
Serialize an object without type information.
virtual MX get_nzadd(const MX &y, const std::vector< casadi_int > &nz) const
Add the nonzeros of a matrix to another matrix.
static MX create(MXNode *node)
Create from node.
const Sparsity & sparsity() const
Get the sparsity pattern.
Helper class for Serialization.
void pack(const Sparsity &e)
Serializes an object to the output stream.
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.
SetNonzerosParamParam(const MX &y, const MX &x, const MX &inner, const MX &outer)
Constructor.
void eval_mx(const std::vector< MX > &arg, std::vector< MX > &res) const override
Evaluate symbolically (MX)
int eval(const double **arg, double **res, casadi_int *iw, double *w) const override
Evaluate the function numerically.
void ad_forward(const std::vector< std::vector< MX > > &fseed, std::vector< std::vector< MX > > &fsens) const override
Calculate forward mode directional derivatives.
std::string disp(const std::vector< std::string > &arg) const override
Print expression.
size_t sz_iw() const override
Get required length of iw field.
void ad_reverse(const std::vector< std::vector< MX > > &aseed, std::vector< std::vector< MX > > &asens) const override
Calculate reverse mode directional derivatives.
void serialize_type(SerializingStream &s) const override
Serialize type information.
SetNonzerosParamSlice(const MX &y, const MX &x, const MX &inner, const Slice &outer)
Constructor.
std::string disp(const std::vector< std::string > &arg) const override
Print expression.
void serialize_type(SerializingStream &s) const override
Serialize 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.
size_t sz_iw() const override
Get required length of iw field.
void ad_reverse(const std::vector< std::vector< MX > > &aseed, std::vector< std::vector< MX > > &asens) const override
Calculate reverse mode directional derivatives.
void eval_mx(const std::vector< MX > &arg, std::vector< MX > &res) const override
Evaluate symbolically (MX)
void ad_forward(const std::vector< std::vector< MX > > &fseed, std::vector< std::vector< MX > > &fsens) const override
Calculate forward mode directional derivatives.
void serialize_body(SerializingStream &s) const override
Serialize an object without type information.
int eval(const double **arg, double **res, casadi_int *iw, double *w) const override
Evaluate the function numerically.
Add the nonzeros of a matrix to another matrix, parametrically.
void ad_reverse(const std::vector< std::vector< MX > > &aseed, std::vector< std::vector< MX > > &asens) const override
Calculate reverse mode directional derivatives.
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.
std::string disp(const std::vector< std::string > &arg) const override
Print expression.
void serialize_type(SerializingStream &s) const override
Serialize type information.
void eval_mx(const std::vector< MX > &arg, std::vector< MX > &res) const override
Evaluate symbolically (MX)
int eval(const double **arg, double **res, casadi_int *iw, double *w) const override
Evaluate the function numerically.
void serialize_body(SerializingStream &s) const override
Serialize an object without type information.
void ad_forward(const std::vector< std::vector< MX > > &fseed, std::vector< std::vector< MX > > &fsens) const override
Calculate forward mode directional derivatives.
SetNonzerosParamVector(const MX &y, const MX &x, const MX &nz)
Constructor.
Assign or add entries to a matrix, parametrically.
static MXNode * deserialize(DeserializingStream &s)
Deserialize with type disambiguation.
int sp_forward(const bvec_t **arg, bvec_t **res, casadi_int *iw, bvec_t *w) const override
Propagate sparsity forward.
SetNonzerosParam(const MX &y, const MX &x, const MX &nz)
Constructor.
~SetNonzerosParam() override=0
Destructor.
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.
static MX create(const MX &y, const MX &x, const MX &nz)
Create functions.
int sp_reverse(bvec_t **arg, bvec_t **res, casadi_int *iw, bvec_t *w) const override
Propagate sparsity backwards.
int eval(const double **arg, double **res, casadi_int *iw, double *w) const override
Evaluate the function numerically.
void eval_mx(const std::vector< MX > &arg, std::vector< MX > &res) const override
Evaluate symbolically (MX)
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.
void serialize_type(SerializingStream &s) const override
Serialize type information.
void serialize_body(SerializingStream &s) const override
Serialize an object without type information.
std::string disp(const std::vector< std::string > &arg) const override
Print expression.
void ad_reverse(const std::vector< std::vector< MX > > &aseed, std::vector< std::vector< MX > > &asens) const override
Calculate reverse mode directional derivatives.
void ad_forward(const std::vector< std::vector< MX > > &fseed, std::vector< std::vector< MX > > &fsens) const override
Calculate forward mode directional derivatives.
SetNonzerosSliceParam(const MX &y, const MX &x, const Slice &inner, const MX &outer)
Constructor.
Class representing a Slice.
unsigned long long bvec_t
bvec_t bvec_or(const bvec_t *arg, casadi_int n)
Bit-wise or operation on bvec_t array.