26 #ifndef CASADI_SETNONZEROS_IMPL_HPP
27 #define CASADI_SETNONZEROS_IMPL_HPP
29 #include "setnonzeros.hpp"
30 #include "casadi_misc.hpp"
31 #include "serializing_stream.hpp"
41 std::pair<Slice, Slice> sl =
to_slice2(nz);
42 return create(y, x, sl.first, sl.second);
73 const std::vector<casadi_int>& nz) :
SetNonzeros<Add>(y, x), nz_(nz) {
76 std::vector<bool> already_set(this->
nnz(),
false);
77 for (std::vector<casadi_int>::reverse_iterator i=
nz_.rbegin(); i!=
nz_.rend(); ++i) {
79 if (already_set[*i]) {
82 already_set[*i] =
true;
123 std::vector<casadi_int> nz =
all();
127 const casadi_int* orow = osp.
row();
128 std::vector<casadi_int> ocol = osp.
get_col();
131 const Sparsity &isp = dep(1).sparsity();
132 std::vector<casadi_int> icol = isp.
get_col();
136 std::vector<casadi_int> onz_count(osp.
nnz()+2, 0);
137 for (std::vector<casadi_int>::const_iterator it=nz.begin(); it!=nz.end(); ++it) {
142 for (casadi_int i=0; i<onz_count.size()-1; ++i) {
143 onz_count[i+1] += onz_count[i];
147 std::vector<casadi_int> nz_order(nz.size());
148 for (casadi_int k=0; k<nz.size(); ++k) {
150 nz_order[onz_count[1+nz[k]]++] = k;
154 std::vector<casadi_int>& with_duplicates = onz_count;
155 onz_count.resize(nz.size());
156 for (casadi_int k=0; k<nz.size(); ++k) {
158 casadi_int onz_k = nz[nz_order[k]];
162 with_duplicates[k] = ocol[onz_k]*osp.
size1() + orow[onz_k];
164 with_duplicates[k] = -1;
169 std::vector<casadi_int> el_output;
173 std::vector<casadi_int> r_colind, r_row, r_nz, r_ind;
182 r_nz.resize(with_duplicates.size());
183 std::copy(with_duplicates.begin(), with_duplicates.end(), r_nz.begin());
184 res[0].sparsity().get_nz(r_nz);
195 bool elements_to_add =
false;
196 for (std::vector<casadi_int>::iterator k=r_nz.begin(); k!=r_nz.end(); ++k) {
199 elements_to_add =
true;
207 if (!elements_to_add)
return;
210 r_ind.resize(el_output.size());
211 std::copy(el_output.begin(), el_output.end(), r_ind.begin());
212 res[0].sparsity().get_nz(r_ind);
215 for (std::vector<casadi_int>::iterator k=r_nz.begin(); k!=r_nz.end(); ++k) {
216 if (*k>=0 && nz[*k]>=0 && r_ind[nz[*k]]<0) {
221 res[0] = res[0]->get_project(sp);
224 std::copy(el_output.begin(), el_output.end(), r_ind.begin());
225 res[0].sparsity().get_nz(r_ind);
232 for (std::vector<casadi_int>::iterator k=r_nz.begin(); k!=r_nz.end(); ++k) {
239 res[0] = arg[1]->get_nzadd(res[0], r_nz);
244 std::vector<std::vector<MX> >& fsens)
const {
246 std::vector<casadi_int> nz =
all();
249 casadi_int nfwd = fsens.size();
253 const casadi_int* orow = osp.
row();
254 std::vector<casadi_int> ocol;
257 const Sparsity &isp = dep(1).sparsity();
258 std::vector<casadi_int> icol;
260 bool first_run =
true;
262 std::vector<casadi_int> onz_count;
264 std::vector<casadi_int> nz_order;
267 std::vector<casadi_int>& with_duplicates = onz_count;
270 std::vector<casadi_int> el_output;
273 std::vector<casadi_int> r_colind, r_row, r_nz, r_ind;
276 for (casadi_int d=0; d<nfwd; ++d) {
279 const MX& arg = fseed[d][1];
280 const MX& arg0 = fseed[d][0];
282 MX& res = fsens[d][0];
311 onz_count.resize(osp.
nnz()+2, 0);
312 for (std::vector<casadi_int>::const_iterator it=nz.begin(); it!=nz.end(); ++it) {
317 for (casadi_int i=0; i<onz_count.size()-1; ++i) {
318 onz_count[i+1] += onz_count[i];
322 nz_order.resize(nz.size());
323 for (casadi_int k=0; k<nz.size(); ++k) {
325 nz_order[onz_count[1+nz[k]]++] = k;
328 onz_count.resize(nz.size());
329 for (casadi_int k=0; k<nz.size(); ++k) {
331 casadi_int onz_k = nz[nz_order[k]];
335 with_duplicates[k] = ocol[onz_k]*osp.
size1() + orow[onz_k];
337 with_duplicates[k] = -1;
349 r_nz.resize(with_duplicates.size());
350 std::copy(with_duplicates.begin(), with_duplicates.end(), r_nz.begin());
363 bool elements_to_add =
false;
364 for (std::vector<casadi_int>::iterator k=r_nz.begin(); k!=r_nz.end(); ++k) {
367 elements_to_add =
true;
375 if (!elements_to_add)
continue;
378 r_ind.resize(el_output.size());
379 std::copy(el_output.begin(), el_output.end(), r_ind.begin());
383 for (std::vector<casadi_int>::iterator k=r_nz.begin(); k!=r_nz.end(); ++k) {
384 if (*k>=0 && nz[*k]>=0 && r_ind[nz[*k]]<0) {
392 std::copy(el_output.begin(), el_output.end(), r_ind.begin());
400 for (std::vector<casadi_int>::iterator k=r_nz.begin(); k!=r_nz.end(); ++k) {
414 std::vector<std::vector<MX> >& asens)
const {
416 std::vector<casadi_int> nz =
all();
419 casadi_int nadj = aseed.size();
423 const casadi_int* orow = osp.
row();
424 std::vector<casadi_int> ocol;
427 const Sparsity &isp = dep(1).sparsity();
428 const casadi_int* irow = isp.
row();
429 std::vector<casadi_int> icol;
431 std::vector<casadi_int> onz_count;
434 std::vector<casadi_int> nz_order;
436 std::vector<casadi_int>& with_duplicates = onz_count;
439 std::vector<casadi_int> el_output;
441 bool first_run =
true;
444 std::vector<casadi_int> r_colind, r_row, r_nz, r_ind;
446 for (casadi_int d=0; d<nadj; ++d) {
447 if (osp==aseed[d][0].sparsity()) {
457 asens[d][1] += aseed[d][0]->get_nzref(isp, nz);
461 asens[d][0] += aseed[d][0];
469 onz_count.resize(osp.
nnz()+2, 0);
470 for (std::vector<casadi_int>::const_iterator it=nz.begin(); it!=nz.end(); ++it) {
475 for (casadi_int i=0; i<onz_count.size()-1; ++i) {
476 onz_count[i+1] += onz_count[i];
480 nz_order.resize(nz.size());
481 for (casadi_int k=0; k<nz.size(); ++k) {
483 nz_order[onz_count[1+nz[k]]++] = k;
487 onz_count.resize(nz.size());
488 for (casadi_int k=0; k<nz.size(); ++k) {
490 casadi_int onz_k = nz[nz_order[k]];
494 with_duplicates[k] = ocol[onz_k]*osp.
size1() + orow[onz_k];
496 with_duplicates[k] = -1;
505 r_ind.resize(el_output.size());
506 std::copy(el_output.begin(), el_output.end(), r_ind.begin());
507 aseed[d][0].sparsity().get_nz(r_ind);
510 r_colind.resize(isp.
size2()+1);
511 std::fill(r_colind.begin(), r_colind.end(), 0);
516 for (casadi_int k=0; k<nz.size(); ++k) {
519 casadi_int el = nz[k];
522 if (el==-1)
continue;
525 casadi_int el_arg = r_ind[el];
528 if (el_arg==-1)
continue;
531 r_nz.push_back(el_arg);
534 casadi_int i=icol[k], j=irow[k];
542 for (casadi_int i=1; i<r_colind.size(); ++i) r_colind[i] += r_colind[i-1];
548 asens[d][1] += aseed[d][0]->get_nzref(f_sp, r_nz);
552 asens[d][0] += aseed[d][0];
555 asens[d][0] += aseed[d][0];
563 eval(
const double** arg,
double** res, casadi_int* iw,
double* w)
const {
564 return eval_gen<double>(arg, res, iw, w);
570 return eval_gen<SXElem>(arg, res, iw, w);
576 eval_gen(
const T** arg, T** res, casadi_int* iw, T* w)
const {
577 const T* idata0 = arg[0];
578 const T* idata = arg[1];
580 if (idata0 != odata) {
581 std::copy(idata0, idata0+this->dep(0).nnz(), odata);
583 for (
auto k=this->nz_.begin(); k!=this->nz_.end(); ++k, ++idata) {
585 if (*k>=0) odata[*k] += *idata;
587 if (*k>=0) odata[*k] = *idata;
595 eval(
const double** arg,
double** res, casadi_int* iw,
double* w)
const {
596 return eval_gen<double>(arg, res, iw, w);
602 return eval_gen<SXElem>(arg, res, iw, w);
608 eval_gen(
const T** arg, T** res, casadi_int* iw, T* w)
const {
609 const T* idata0 = arg[0];
610 const T* idata = arg[1];
612 if (idata0 != odata) {
613 std::copy(idata0, idata0+this->dep(0).nnz(), odata);
615 T* odata_stop = odata + s_.stop;
616 for (odata += s_.start; odata != odata_stop; odata += s_.step) {
628 eval(
const double** arg,
double** res, casadi_int* iw,
double* w)
const {
629 return eval_gen<double>(arg, res, iw, w);
635 return eval_gen<SXElem>(arg, res, iw, w);
641 eval_gen(
const T** arg, T** res, casadi_int* iw, T* w)
const {
642 const T* idata0 = arg[0];
643 const T* idata = arg[1];
645 if (idata0 != odata) {
646 std::copy(idata0, idata0 + this->dep(0).nnz(), odata);
648 T* outer_stop = odata + outer_.stop;
649 T* outer = odata + outer_.start;
650 for (; outer != outer_stop; outer += outer_.step) {
651 for (
T* inner = outer+inner_.start;
652 inner != outer+inner_.stop;
653 inner += inner_.step) {
667 const bvec_t *a0 = arg[0];
670 casadi_int n = this->nnz();
673 if (r != a0) std::copy(a0, a0+n, r);
674 for (
auto k=this->nz_.begin(); k!=this->nz_.end(); ++k, ++a) {
676 if (*k>=0) r[*k] |= *a;
678 if (*k>=0) r[*k] = *a;
689 for (
auto k=this->nz_.begin(); k!=this->nz_.end(); ++k, ++a) {
704 const bvec_t *a0 = arg[0];
707 casadi_int n = this->nnz();
710 if (r != a0) std::copy(a0, a0+n, r);
711 for (casadi_int k=s_.start; k!=s_.stop; k+=s_.step) {
726 for (casadi_int k=s_.start; k!=s_.stop; k+=s_.step) {
739 const bvec_t *a0 = arg[0];
742 casadi_int n = this->nnz();
745 if (r != a0) std::copy(a0, a0+n, r);
746 for (casadi_int k1=outer_.start; k1!=outer_.stop; k1+=outer_.step) {
747 for (casadi_int k2=k1+inner_.start; k2!=k1+inner_.stop; k2+=inner_.step) {
763 for (casadi_int k1=outer_.start; k1!=outer_.stop; k1+=outer_.step) {
764 for (casadi_int k2=k1+inner_.start; k2!=k1+inner_.stop; k2+=inner_.step) {
777 std::stringstream ss;
778 ss <<
"(" << arg.at(0) << nz_ << (Add ?
" += " :
" = ") << arg.at(1) <<
")";
784 std::stringstream ss;
785 ss <<
"(" << arg.at(0) <<
"[" << s_ <<
"]" << (Add ?
" += " :
" = ") << arg.at(1) <<
")";
791 std::stringstream ss;
792 ss <<
"(" << arg.at(0) <<
"[" << outer_ <<
";" << inner_ <<
"]" << (Add ?
" += " :
" = ")
799 std::vector<casadi_int> nz =
all();
806 if (!this->sameOpAndDeps(node, depth))
return false;
810 if (n==
nullptr)
return false;
813 if (this->sparsity()!=node->
sparsity())
return false;
816 if (this->nz_.size()!=n->
nz_.size())
return false;
817 if (!std::equal(this->nz_.begin(), this->nz_.end(), n->
nz_.begin()))
return false;
825 if (!this->sameOpAndDeps(node, depth))
return false;
829 if (n==
nullptr)
return false;
832 if (this->sparsity()!=node->
sparsity())
return false;
835 if (this->s_ != n->
s_)
return false;
843 if (!this->sameOpAndDeps(node, depth))
return false;
847 if (n==
nullptr)
return false;
850 if (this->sparsity()!=node->
sparsity())
return false;
853 if (this->inner_ != n->
inner_ || this->outer_!=n->
outer_)
return false;
861 const std::vector<casadi_int>& arg,
862 const std::vector<casadi_int>& res,
863 const std::vector<bool>& arg_is_ref,
864 std::vector<bool>& res_is_ref)
const {
866 if (arg[0]!=res[0] || arg_is_ref[0]) {
867 g << g.
copy(g.
work(arg[0], this->dep(0).nnz(), arg_is_ref[0]), this->nnz(),
868 g.
work(res[0], this->nnz(),
false)) <<
'\n';
872 std::string ind = g.
constant(this->nz_);
875 g.
local(
"cii",
"const casadi_int",
"*");
876 g.
local(
"rr",
"casadi_real",
"*");
877 g.
local(
"cs",
"const casadi_real",
"*");
878 g <<
"for (cii=" << ind <<
", rr=" << g.
work(res[0], this->nnz(),
false) <<
", "
879 <<
"cs=" << g.
work(arg[1], this->dep(1).nnz(), arg_is_ref[1]) <<
"; cii!=" << ind
880 <<
"+" << this->nz_.size() <<
"; ++cii, ++cs) ";
882 g <<
"if (*cii>=0) ";
884 g <<
"rr[*cii] " << (Add?
"+=":
"=") <<
" *cs;\n";
890 const std::vector<casadi_int>& arg,
891 const std::vector<casadi_int>& res,
892 const std::vector<bool>& arg_is_ref,
893 std::vector<bool>& res_is_ref)
const {
895 if (arg[0]!=res[0] || arg_is_ref[0]) {
896 g << g.
copy(g.
work(arg[0], this->dep(0).nnz(), arg_is_ref[0]), this->nnz(),
897 g.
work(res[0], this->nnz(),
false)) <<
'\n';
901 g.
local(
"rr",
"casadi_real",
"*");
902 g.
local(
"cs",
"const casadi_real",
"*");
903 g <<
"for (rr=" << g.
work(res[0], this->nnz(),
false) <<
"+" << s_.start <<
", cs="
904 << g.
work(arg[1], this->dep(1).nnz(), arg_is_ref[1]) <<
"; rr!="
905 << g.
work(res[0], this->nnz(),
false) <<
"+" << s_.stop
906 <<
"; rr+=" << s_.step <<
")"
907 <<
" *rr " << (Add?
"+=":
"=") <<
" *cs++;\n";
913 const std::vector<casadi_int>& arg,
914 const std::vector<casadi_int>& res,
915 const std::vector<bool>& arg_is_ref,
916 std::vector<bool>& res_is_ref)
const {
918 if (arg[0]!=res[0] || arg_is_ref[0]) {
919 g << g.
copy(g.
work(arg[0], this->dep(0).nnz(), arg_is_ref[0]), this->nnz(),
920 g.
work(res[0], this->nnz(),
false)) <<
'\n';
924 g.
local(
"rr",
"casadi_real",
"*");
925 g.
local(
"cs",
"const casadi_real",
"*");
926 g.
local(
"tt",
"casadi_real",
"*");
927 g <<
"for (rr=" << g.
work(res[0], this->nnz(),
false) <<
"+" << outer_.start
928 <<
", cs=" << g.
work(arg[1], this->dep(1).nnz(), arg_is_ref[1]) <<
"; rr!="
929 << g.
work(res[0], this->nnz(),
false) <<
"+" << outer_.stop
930 <<
"; rr+=" << outer_.step <<
")"
931 <<
" for (tt=rr+" << inner_.start <<
"; tt!=rr+" << inner_.stop
932 <<
"; tt+=" << inner_.step <<
")"
933 <<
" *tt " << (Add?
"+=":
"=") <<
" *cs++;\n";
939 s.
pack(
"SetNonzerosVector::nonzeros", nz_);
944 s.
unpack(
"SetNonzerosVector::nonzeros",
nz_);
950 s.
pack(
"SetNonzeros::type",
'a');
956 s.
pack(
"SetNonzerosSlice::slice", s_);
961 s.
unpack(
"SetNonzerosSlice::slice",
s_);
967 s.
pack(
"SetNonzeros::type",
'b');
973 s.
pack(
"SetNonzerosSlice2::inner", inner_);
974 s.
pack(
"SetNonzerosSlice2::outer", outer_);
986 s.
pack(
"SetNonzeros::type",
'c');
992 s.
unpack(
"SetNonzeros::type", t);
997 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.
std::string constant(const std::vector< casadi_int > &v)
Represent an array constant; adding it when new.
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.
casadi_int nnz() const
Get the number of (structural) non-zero elements.
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.
static void copy_rev(bvec_t *arg, bvec_t *res, casadi_int len)
Propagate sparsities backwards through a copy operation.
const Sparsity & sparsity() const
Get the sparsity.
virtual MX get_project(const Sparsity &sp) const
Create set sparse.
casadi_int nnz(casadi_int i=0) const
bool matches_sparsity(const std::vector< T > &arg) const
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.
The basic scalar symbolic class of CasADi.
Helper class for Serialization.
void pack(const Sparsity &e)
Serializes an object to the output stream.
int eval_gen(const T **arg, T **res, casadi_int *iw, T *w) const
Evaluate the function (template)
void eval_mx(const std::vector< MX > &arg, std::vector< MX > &res) const override
Evaluate symbolically (MX)
int sp_reverse(bvec_t **arg, bvec_t **res, casadi_int *iw, bvec_t *w) const override
Propagate sparsity backwards.
int sp_forward(const bvec_t **arg, bvec_t **res, casadi_int *iw, bvec_t *w) const override
Propagate sparsity forward.
int eval(const double **arg, double **res, casadi_int *iw, double *w) const override
Evaluate the function numerically.
void serialize_type(SerializingStream &s) const override
Serialize type information.
void serialize_body(SerializingStream &s) const override
Serialize an object without type information.
bool is_equal(const MXNode *node, casadi_int depth) const override
Check if two nodes are equivalent up to a given depth.
SetNonzerosSlice2(const MX &y, const MX &x, const Slice &inner, const Slice &outer)
Constructor.
int eval_sx(const SXElem **arg, SXElem **res, casadi_int *iw, SXElem *w) const override
Evaluate the function symbolically (SX)
std::string disp(const std::vector< std::string > &arg) const override
Print expression.
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 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.
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.
int eval_gen(const T **arg, T **res, casadi_int *iw, T *w) const
Evaluate the function (template)
SetNonzerosSlice(const MX &y, const MX &x, const Slice &s)
Constructor.
bool is_equal(const MXNode *node, casadi_int depth) const override
Check if two nodes are equivalent up to a given depth.
int eval_sx(const SXElem **arg, SXElem **res, casadi_int *iw, SXElem *w) const override
Evaluate the function symbolically (SX)
int sp_reverse(bvec_t **arg, bvec_t **res, casadi_int *iw, bvec_t *w) const override
Propagate sparsity backwards.
void serialize_type(SerializingStream &s) const override
Serialize type information.
int sp_forward(const bvec_t **arg, bvec_t **res, casadi_int *iw, bvec_t *w) const override
Propagate sparsity forward.
Add the nonzeros of a matrix to another matrix.
SetNonzerosVector(const MX &y, const MX &x, const std::vector< casadi_int > &nz)
Constructor.
bool is_equal(const MXNode *node, casadi_int depth) const override
Check if two nodes are equivalent up to a given depth.
void eval_mx(const std::vector< MX > &arg, std::vector< MX > &res) const override
Evaluate symbolically (MX)
std::vector< casadi_int > nz_
Operation sequence.
int sp_forward(const bvec_t **arg, bvec_t **res, casadi_int *iw, bvec_t *w) const override
Propagate sparsity forward.
int eval(const double **arg, double **res, casadi_int *iw, double *w) const override
Evaluate the function numerically.
std::string disp(const std::vector< std::string > &arg) const override
Print expression.
void serialize_body(SerializingStream &s) const override
Serialize an object without type information.
int sp_reverse(bvec_t **arg, bvec_t **res, casadi_int *iw, bvec_t *w) const override
Propagate sparsity backwards.
int eval_gen(const T **arg, T **res, casadi_int *iw, T *w) const
Evaluate the function (template)
void serialize_type(SerializingStream &s) const override
Serialize type information.
int eval_sx(const SXElem **arg, SXElem **res, casadi_int *iw, SXElem *w) const override
Evaluate the function symbolically (SX)
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.
Assign or add entries to a matrix.
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 create(const MX &y, const MX &x, const std::vector< casadi_int > &nz)
Create functions.
void ad_forward(const std::vector< std::vector< MX > > &fseed, std::vector< std::vector< MX > > &fsens) const override
Calculate forward mode directional derivatives.
void eval_mx(const std::vector< MX > &arg, std::vector< MX > &res) const override
Evaluate symbolically (MX)
SetNonzeros(const MX &y, const MX &x)
Constructor.
static MXNode * deserialize(DeserializingStream &s)
Deserialize with type disambiguation.
Matrix< casadi_int > mapping() const override
Get an IM representation of a GetNonzeros or SetNonzeros node.
~SetNonzeros() override=0
Destructor.
Class representing a Slice.
casadi_int stop
stop value: use std::numeric_limits<casadi_int>::max() to indicate unboundedness
casadi_int start
start value: negative values will get added to length
casadi_int get_nz(casadi_int rr, casadi_int cc) const
Get the index of an existing non-zero element.
casadi_int size1() const
Get the number of rows.
std::vector< casadi_int > find(bool ind1=SWIG_IND1) const
Get the location of all non-zero elements as they would appear in a Dense matrix.
Sparsity unite(const Sparsity &y, std::vector< unsigned char > &mapping) const
Union of two sparsity patterns.
std::vector< casadi_int > get_col() const
Get the column for each non-zero entry.
casadi_int nnz() const
Get the number of (structural) non-zeros.
casadi_int size2() const
Get the number of columns.
const casadi_int * row() const
Get a reference to row-vector,.
template class CASADI_EXPORT Matrix< casadi_int >
unsigned long long bvec_t
bool has_negative(const std::vector< T > &v)
Check if the vector has negative entries.
bool CASADI_EXPORT is_slice(const IM &x, bool ind1=false)
Is the IM a Slice.
bool CASADI_EXPORT is_slice2(const std::vector< casadi_int > &v)
Check if an index vector can be represented more efficiently as two nested slices.
bool all(const std::vector< bool > &v)
Check if all arguments are true.
std::pair< Slice, Slice > CASADI_EXPORT to_slice2(const std::vector< casadi_int > &v)
Construct nested slices from an index vector (requires is_slice2(v) to be true)
Slice CASADI_EXPORT to_slice(const IM &x, bool ind1=false)
Convert IM to Slice.