25 #ifndef CASADI_MATRIX_IMPL_HPP
26 #define CASADI_MATRIX_IMPL_HPP
32 #include "sx_node.hpp"
35 #include "serializing_stream.hpp"
38 template<
typename Scalar>
41 template<
typename Scalar>
44 template<
typename Scalar>
47 template<
typename Scalar>
49 template<
typename Scalar>
51 template<
typename Scalar>
54 template<
typename Scalar>
57 std::chrono::system_clock::now().time_since_epoch().count());
59 template<
typename Scalar>
64 template<
typename Scalar>
66 return sparsity().has_nz(rr, cc);
69 template<
typename Scalar>
72 casadi_error(
"Only scalar Matrix could have a truth value, but you "
73 "provided a shape" + dim());
75 return nonzeros().at(0)!=0;
78 template<
typename Scalar>
83 casadi_int k = sparsity().get_nz(rr.
scalar(size1()), cc.
scalar(size2()));
93 get(m, ind1, rr.
all(size1(), ind1), cc.
all(size2(), ind1));
96 template<
typename Scalar>
100 get(m, ind1, rr.
all(size1(), ind1), cc);
103 template<
typename Scalar>
107 get(m, ind1, rr, cc.
all(size2(), ind1));
110 template<
typename Scalar>
120 "Marix::get: First index must be a dense vector");
122 "Marix::get: Second index must be a dense vector");
125 std::vector<casadi_int> mapping;
126 Sparsity sp = sparsity().
sub(rr.nonzeros(), cc.nonzeros(), mapping, ind1);
130 for (casadi_int k=0; k<mapping.size(); ++k) m->at(k) = nonzeros().at(mapping[k]);
133 template<
typename Scalar>
137 casadi_int r = rr.
scalar(numel());
138 casadi_int k = sparsity().get_nz(r % size1(), r / size1());
140 m = nonzeros().at(k);
148 get(m, ind1, rr.
all(numel(), ind1));
151 template<
typename Scalar>
155 return get(m, ind1,
to_slice(rr, ind1));
160 return get_nz(m, ind1, rr);
164 std::vector<casadi_int> mapping;
168 bool tr = (is_column() && rr.
is_row()) || (is_row() && rr.
is_column());
172 for (casadi_int k=0; k<mapping.size(); ++k) m->at(k) = nonzeros().at(mapping[k]);
175 template<
typename Scalar>
177 casadi_assert(size()==sp.
size(),
178 "Shape mismatch. This matrix has shape "
179 + str(size()) +
", but supplied sparsity index has shape "
180 + str(sp.
size()) +
".");
181 m = project(*
this, sp);
184 template<
typename Scalar>
189 casadi_int oldsize = sparsity_.nnz();
190 casadi_int ind = sparsity_.add_nz(rr.
scalar(size1()), cc.
scalar(size2()));
191 if (oldsize == sparsity_.nnz()) {
192 nonzeros_.at(ind) = m.scalar();
194 nonzeros_.insert(nonzeros_.begin()+ind, m.scalar());
200 set(m, ind1, rr.
all(size1(), ind1), cc.
all(size2(), ind1));
203 template<
typename Scalar>
207 set(m, ind1, rr.
all(size1(), ind1), cc);
210 template<
typename Scalar>
214 set(m, ind1, rr, cc.
all(size2(), ind1));
217 template<
typename Scalar>
227 return set(m, ind1, rr.
T(), cc);
232 return set(m, ind1, rr, cc.
T());
237 "Matrix::set: First index not dense vector");
239 "Matrix::set: Second index not dense vector");
245 return set(repmat(m, rr.
size1(), cc.
size1()), ind1, rr, cc);
249 return set(m.
T(), ind1, rr, cc);
252 casadi_error(
"Dimension mismatch. lhs is " + str(rr.
size1()) +
"-by-"
253 + str(cc.
size1()) +
", while rhs is " + str(m.
size()));
258 casadi_int sz1 = size1(), sz2 = size2();
261 casadi_assert_in_range(rr.nonzeros(), -sz1+ind1, sz1+ind1);
262 casadi_assert_in_range(cc.nonzeros(), -sz2+ind1, sz2+ind1);
266 erase(rr.nonzeros(), cc.nonzeros(), ind1);
271 for (casadi_int j=0; j<el.
size2(); ++j) {
272 casadi_int this_j = cc->at(j) - ind1;
273 if (this_j<0) this_j += sz2;
274 for (casadi_int k=el.
colind(j); k<el.
colind(j+1); ++k) {
275 casadi_int i = m.
row(k);
276 casadi_int this_i = rr->at(i) - ind1;
277 if (this_i<0) this_i += sz1;
278 el->at(k) = this_i + this_j*sz1;
281 return set(m,
false, el);
284 template<
typename Scalar>
288 casadi_int r = rr.
scalar(numel());
289 casadi_int oldsize = sparsity_.nnz();
290 casadi_int ind = sparsity_.add_nz(r % size1(), r / size1());
291 if (oldsize == sparsity_.nnz()) {
292 nonzeros_.at(ind) = m.scalar();
294 nonzeros_.insert(nonzeros_.begin()+ind, m.scalar());
300 set(m, ind1, rr.
all(numel(), ind1));
303 template<
typename Scalar>
307 return set(m, ind1,
to_slice(rr, ind1));
314 erase(rr.nonzeros(), ind1);
331 return set(m.
T(), ind1, rr);
334 casadi_error(
"Dimension mismatch. lhs is " + str(rr.
size())
335 +
", while rhs is " + str(m.
size()));
340 casadi_int sz1 = size1(), sz2 = size2(), sz = nnz(), nel = numel(), rrsz = rr.
nnz();
346 casadi_assert_in_range(rr.nonzeros(), -nel+ind1, nel+ind1);
350 return set_nz(m, ind1, rr);
354 std::vector<casadi_int> new_row =
355 sparsity().get_row(), new_col=sparsity().get_col(), nz(rr.nonzeros());
356 new_row.reserve(sz+rrsz);
357 new_col.reserve(sz+rrsz);
359 for (std::vector<casadi_int>::iterator i=nz.begin(); i!=nz.end(); ++i) {
362 new_row.push_back(*i % sz1);
363 new_col.push_back(*i / sz1);
368 if (sp != sparsity()) *
this = project(*
this, sp);
371 sparsity().get_nz(nz);
374 for (casadi_int i=0; i<nz.size(); ++i) {
375 nonzeros().at(nz[i]) = m->at(i);
379 template<
typename Scalar>
381 casadi_assert(size()==sp.
size(),
382 "set(Sparsity sp): shape mismatch. This matrix has shape "
383 + str(size()) +
", but supplied sparsity index has shape "
384 + str(sp.
size()) +
".");
385 std::vector<casadi_int> ii = sp.
find();
387 (*this)(ii) = densify(m);
389 (*this)(ii) = densify(m(ii));
393 template<
typename Scalar>
397 m = nonzeros().at(kk.
scalar(nnz()));
402 get_nz(m, ind1, kk.
all(nnz(), ind1));
405 template<
typename Scalar>
409 return get_nz(m, ind1,
to_slice(kk, ind1));
413 const std::vector<casadi_int>& k = kk.nonzeros();
414 casadi_int sz = nnz();
417 casadi_assert_in_range(k, -sz+ind1, sz+ind1);
420 bool tr = (is_column() && kk.
is_row()) || (is_row() && kk.
is_column());
424 for (casadi_int el=0; el<k.size(); ++el) {
425 casadi_assert(!(ind1 && k[el]<=0),
"Matlab is 1-based, but requested index "
426 + str(k[el]) +
". Note that negative slices are"
427 " disabled in the Matlab interface. "
428 "Possibly you may want to use 'end'.");
429 casadi_int k_el = k[el]-ind1;
430 m->at(el) = nonzeros().at(k_el>=0 ? k_el : k_el+sz);
434 template<
typename Scalar>
438 nonzeros().at(kk.
scalar(nnz())) = m.scalar();
443 set_nz(m, ind1, kk.
all(nnz(), ind1));
446 template<
typename Scalar>
450 return set_nz(m, ind1,
to_slice(kk, ind1));
461 return set_nz(project(m, kk.
sparsity()), ind1, kk);
465 return set_nz(m.
T(), ind1, kk);
468 casadi_error(
"Dimension mismatch. lhs is " + str(kk.
size())
469 +
", while rhs is " + str(m.
size()));
474 const std::vector<casadi_int>& k = kk.nonzeros();
475 casadi_int sz = nnz();
478 casadi_assert_in_range(k, -sz+ind1, sz+ind1);
481 for (casadi_int el=0; el<k.size(); ++el) {
482 casadi_assert(!(ind1 && k[el]<=0),
483 "Matlab is 1-based, but requested index " + str(k[el])
484 +
". Note that negative slices are disabled in the Matlab interface. "
485 "Possibly you may want to use 'end'.");
486 casadi_int k_el = k[el]-ind1;
487 nonzeros().at(k_el>=0 ? k_el : k_el+sz) = m->at(el);
491 template<
typename Scalar>
493 return densify(x, 0);
496 template<
typename Scalar>
498 const Matrix<Scalar>& val) {
500 casadi_assert_dev(val.is_scalar());
503 if (x.is_dense())
return x;
506 casadi_int nrow = x.size1();
507 casadi_int ncol = x.size2();
508 const casadi_int* colind = x.colind();
509 const casadi_int* row = x.row();
510 auto it = x.nonzeros().cbegin();
513 std::vector<Scalar> d(nrow*ncol, val.scalar());
516 for (casadi_int cc=0; cc<ncol; ++cc) {
517 for (casadi_int el=colind[cc]; el<colind[cc+1]; ++el) {
518 d[cc*nrow + row[el]] = *it++;
526 template<
typename Scalar>
528 if (axis==-1) axis = x.is_row();
529 Matrix<Scalar> ret = x;
531 for (casadi_int i=1;i<x.size1();++i)
532 ret(i, Slice()) += ret(i-1, Slice());
534 for (casadi_int i=1;i<x.size2();++i)
535 ret(Slice(), i) += ret(Slice(), i-1);
540 template<
typename Scalar>
542 const Matrix<Scalar>& A,
const Matrix<Scalar>& B,
const Matrix<Scalar>& C,
543 const std::vector<casadi_int>& dim_a,
const std::vector<casadi_int>& dim_b,
544 const std::vector<casadi_int>& dim_c,
545 const std::vector<casadi_int>& a,
const std::vector<casadi_int>& b,
546 const std::vector<casadi_int>& c) {
547 std::vector<casadi_int> iter_dims;
548 std::vector<casadi_int> strides_a;
549 std::vector<casadi_int> strides_b;
550 std::vector<casadi_int> strides_c;
552 iter_dims, strides_a, strides_b, strides_c);
554 const std::vector<Scalar>& Av = A.nonzeros();
555 const std::vector<Scalar>& Bv = B.nonzeros();
557 Matrix<Scalar> ret = C;
558 std::vector<Scalar>& Cv = ret.nonzeros();
560 einstein_eval(n_iter, iter_dims, strides_a, strides_b, strides_c,
561 get_ptr(Av), get_ptr(Bv), get_ptr(Cv));
565 template<
typename Scalar>
567 const std::vector<casadi_int>& dim_a,
const std::vector<casadi_int>& dim_b,
568 const std::vector<casadi_int>& dim_c,
569 const std::vector<casadi_int>& a,
const std::vector<casadi_int>& b,
570 const std::vector<casadi_int>& c) {
572 dim_a, dim_b, dim_c, a, b, c);
575 template<
typename Scalar>
579 template<
typename Scalar>
583 template<
typename Scalar>
585 sparsity_(
Sparsity::dense(x.size(), 1)), nonzeros_(x) {
588 template<
typename Scalar>
590 sparsity_ = m.sparsity_;
591 nonzeros_ = m.nonzeros_;
595 template<
typename Scalar>
596 std::vector<Scalar>* Matrix<Scalar>::operator->() {
600 template<
typename Scalar>
601 const std::vector<Scalar>* Matrix<Scalar>::operator->()
const {
605 template<
typename Scalar>
608 template<
typename Scalar>
610 casadi_assert(numel()==1,
"Not a scalar");
612 std::streamsize precision = stream.precision();
613 std::streamsize width = stream.width();
614 std::ios_base::fmtflags flags = stream.flags();
616 stream.precision(stream_precision_);
617 stream.width(stream_width_);
618 if (stream_scientific_) {
619 stream.setf(std::ios::scientific);
621 stream.unsetf(std::ios::scientific);
629 stream << std::flush;
630 stream.precision(precision);
635 template<
typename Scalar>
637 print_vector(stream, sparsity(), ptr(), truncate);
640 template<
typename Scalar>
642 const Scalar* nonzeros,
bool truncate) {
643 casadi_assert(sp.
is_column(),
"Not a vector");
646 std::vector<std::string> nz, inter;
647 print_split(sp.
nnz(), nonzeros, nz, inter);
650 for (casadi_int i=0; i<inter.size(); ++i)
651 stream <<
"@" << (i+1) <<
"=" << inter[i] <<
", ";
655 const casadi_int* row = sp.
row();
656 casadi_int nnz = sp.
nnz();
657 casadi_int size1 = sp.
size1();
660 const casadi_int max_numel = 1000;
661 if (truncate && size1<=max_numel) truncate=
false;
668 for (casadi_int rr=0; rr<size1; ++rr) {
670 std::string s = el<nnz && rr==row[el] ? nz.at(el++) :
"00";
673 if (truncate && rr>=3 && rr<size1-3) {
675 if (rr==3) stream <<
", ...";
678 if (rr!=0) stream <<
", ";
682 stream <<
"]" << std::flush;
685 template<
typename Scalar>
687 print_dense(stream, sparsity(), ptr(), truncate);
690 template<
typename Scalar>
692 print_sparse(stream, sparsity(), ptr(), truncate);
695 template<
typename Scalar>
697 std::vector<std::string>& inter)
const {
699 print_split(nnz(), ptr(), nz, inter);
702 template<
typename Scalar>
704 const Scalar* nonzeros,
bool truncate) {
707 }
else if (sp.
numel()==1) {
711 print_scalar(stream, *nonzeros);
714 print_vector(stream, sp, nonzeros, truncate);
715 }
else if (std::max(sp.
size1(), sp.
size2())<=10 ||
716 static_cast<double>(sp.
nnz())/
static_cast<double>(sp.
numel())>=0.5) {
718 print_dense(stream, sp, nonzeros, truncate);
720 print_sparse(stream, sp, nonzeros, truncate);
724 template<
typename Scalar>
726 std::streamsize precision = stream.precision();
727 std::streamsize width = stream.width();
728 std::ios_base::fmtflags flags = stream.flags();
730 stream.precision(stream_precision_);
731 stream.width(stream_width_);
732 if (stream_scientific_) {
733 stream.setf(std::ios::scientific);
735 stream.unsetf(std::ios::scientific);
738 stream << std::flush;
740 stream.precision(precision);
745 template<
typename Scalar>
747 std::vector<std::string>& nz,
748 std::vector<std::string>& inter) {
753 std::stringstream ss;
754 ss.precision(stream_precision_);
755 ss.width(stream_width_);
756 if (stream_scientific_) {
757 ss.setf(std::ios::scientific);
759 ss.unsetf(std::ios::scientific);
763 for (casadi_int i=0; i<nz.size(); ++i) {
764 ss.str(std::string());
770 template<
typename Scalar>
772 const Scalar* nonzeros,
bool truncate) {
774 casadi_int size1 = sp.size1();
775 casadi_int size2 = sp.size2();
776 const casadi_int* colind = sp.colind();
777 const casadi_int* row = sp.row();
778 casadi_int nnz = sp.nnz();
782 stream <<
"all zero sparse: " << size1 <<
"-by-" << size2 << std::flush;
787 stream <<
"sparse: " << size1 <<
"-by-" << size2 <<
", " << nnz <<
" nnz";
790 std::vector<std::string> nz, inter;
791 print_split(nnz, nonzeros, nz, inter);
794 for (casadi_int i=0; i<inter.size(); ++i)
795 stream << std::endl <<
" @" << (i+1) <<
"=" << inter[i] <<
",";
799 const casadi_int max_nnz = 1000;
800 if (truncate && nnz<=max_nnz) truncate=
false;
803 for (casadi_int cc=0; cc<size2; ++cc) {
804 for (casadi_int el=colind[cc]; el<colind[cc+1]; ++el) {
805 if (truncate && el>=3 && el<nnz-3) {
806 if (el==3) stream << std::endl <<
" ...";
808 stream << std::endl <<
" (" << row[el] <<
", " << cc <<
") -> " << nz.at(el);
809 InterruptHandler::check();
813 stream << std::flush;
816 template<
typename Scalar>
818 const Scalar* nonzeros,
bool truncate) {
820 std::vector<std::string> nz, inter;
821 print_split(sp.nnz(), nonzeros, nz, inter);
824 for (casadi_int i=0; i<inter.size(); ++i)
825 stream <<
"@" << (i+1) <<
"=" << inter[i] <<
", ";
829 casadi_int size1 = sp.size1();
830 casadi_int size2 = sp.size2();
831 const casadi_int* colind = sp.colind();
832 const casadi_int* row = sp.row();
835 const casadi_int max_numel = 1000;
836 if (truncate && size1*size2<=max_numel) truncate=
false;
839 bool truncate_rows = truncate && size1>=7;
840 bool truncate_columns = truncate && size2>=7;
843 std::vector<casadi_int> ind(colind, colind+size2+1);
846 bool oneliner=size1<=1;
849 for (casadi_int rr=0; rr<size1; ++rr) {
851 bool print_row = !(truncate_rows && rr>=3 && rr<size1-3);
855 if (!oneliner) stream << std::endl;
857 }
else if (print_row) {
862 for (casadi_int cc=0; cc<size2; ++cc) {
864 std::string s = ind[cc]<colind[cc+1] && row[ind[cc]]==rr
865 ? nz.at(ind[cc]++) :
"00";
868 if (!print_row)
continue;
871 bool print_column = !(truncate_columns && cc>=3 && cc<size2-3);
875 if (cc!=0) stream <<
", ";
886 if (!oneliner) stream << std::endl;
888 stream <<
" ...," << std::endl;
894 stream << std::flush;
897 template<
typename Scalar>
899 to_file(filename, sparsity(), ptr(), format);
902 template<
typename Scalar>
904 print_default(stream, sparsity(), ptr());
907 template<
typename Scalar>
909 std::stringstream ss;
914 template<
typename Scalar>
916 reserve(nnz, size2());
919 template<
typename Scalar>
921 nonzeros().reserve(nnz);
924 template<
typename Scalar>
926 sparsity_.resize(nrow, ncol);
929 template<
typename Scalar>
931 sparsity_ = Sparsity(0, 0);
935 template<
typename Scalar>
938 Sparsity::dense(1, 1)),
939 nonzeros_(std::vector<Scalar>(1, static_cast<Scalar>(val))) {
942 template<
typename Scalar>
945 casadi_int nrow=d.size();
946 casadi_int ncol=d.empty() ? 1 : d.front().size();
949 for (casadi_int rr=0; rr<nrow; ++rr) {
950 casadi_assert(ncol==d[rr].size(),
952 "Attempting to construct a matrix from a nested list.\n"
953 "I got convinced that the desired size is (" + str(nrow) +
" x " + str(ncol)
954 +
" ), but now I encounter a vector of size (" + str(d[rr].size()) +
" )");
959 nonzeros().resize(nrow*ncol);
960 typename std::vector<Scalar>::iterator it=nonzeros_.begin();
961 for (casadi_int cc=0; cc<ncol; ++cc) {
962 for (casadi_int rr=0; rr<nrow; ++rr) {
963 *it++ =
static_cast<Scalar
>(d[rr][cc]);
968 template<
typename Scalar>
972 template<
typename Scalar>
976 template<
typename Scalar>
980 template<
typename Scalar>
982 sparsity_(sp), nonzeros_(sp.nnz(), val) {
985 template<
typename Scalar>
987 sparsity_(sp), nonzeros_(d) {
988 casadi_assert(sp.nnz()==d.size(),
"Size mismatch.\n"
989 "You supplied a sparsity of " + sp.dim()
990 +
", but the supplied vector is of length " + str(d.size()));
993 template<
typename Scalar>
996 *
this = Matrix<Scalar>(sp, d.scalar(),
false);
997 }
else if (sp.nnz()==0) {
998 casadi_assert(d.nnz()==0,
999 "You passed nonzeros (" + d.dim(
true) +
1000 ") to the constructor of a fully sparse matrix (" + sp.dim(
true) +
").");
1001 *
this = Matrix<Scalar>(sp);
1002 }
else if (d.is_column() || d.size1()==1) {
1003 casadi_assert_dev(sp.nnz()==d.numel());
1005 *
this = Matrix<Scalar>(sp, d.nonzeros(),
false);
1007 *
this = Matrix<Scalar>(sp, densify(d).nonzeros(),
false);
1010 casadi_error(
"Matrix(Sparsity, Matrix): Only allowed for scalars and vectors");
1014 template<
typename Scalar>
1015 Matrix<Scalar> Matrix<Scalar>::unary(casadi_int op,
const Matrix<Scalar> &x) {
1020 std::vector<Scalar>& ret_data = ret.nonzeros();
1021 const std::vector<Scalar>& x_data = x.nonzeros();
1024 for (casadi_int el=0; el<x.nnz(); ++el) {
1025 casadi_math<Scalar>::fun(op, x_data[el], x_data[el], ret_data[el]);
1029 if (!x.is_dense() && !operation_checker<F0XChecker>(op)) {
1032 casadi_math<Scalar>::fun(op, 0, 0, fcn_0);
1034 ret = densify(ret, fcn_0);
1041 template<
typename Scalar>
1043 return unary(OP_NEG, *
this);
1046 template<
typename Scalar>
1051 template<
typename Scalar>
1053 const Matrix<Scalar>& a) {
1054 if (a.is_scalar() || b.is_scalar())
return b/a;
1055 return solve(a.T(), b.T()).T();
1058 template<
typename Scalar>
1060 const Matrix<Scalar>& b) {
1061 if (a.is_scalar() || b.is_scalar())
return b/a;
1065 template<
typename Scalar>
1067 return binary(OP_PRINTME, *
this, y);
1070 template<
typename Scalar>
1072 const std::vector<casadi_int>& cc,
bool ind1) {
1074 std::vector<casadi_int> mapping = sparsity_.erase(rr, cc, ind1);
1077 for (casadi_int k=0; k<mapping.size(); ++k)
1078 nonzeros()[k] = nonzeros()[mapping[k]];
1081 nonzeros().resize(mapping.size());
1084 template<
typename Scalar>
1087 std::vector<casadi_int> mapping = sparsity_.erase(rr, ind1);
1090 for (casadi_int k=0; k<mapping.size(); ++k)
1091 nonzeros()[k] = nonzeros()[mapping[k]];
1094 nonzeros().resize(mapping.size());
1097 template<
typename Scalar>
1099 const std::vector<casadi_int>& cc) {
1100 casadi_assert_bounded(rr, size1());
1101 casadi_assert_bounded(cc, size2());
1104 std::vector<casadi_int> rrc =
complement(rr, size1());
1105 std::vector<casadi_int> ccc =
complement(cc, size2());
1107 Matrix<Scalar> ret = (*this)(rrc, ccc);
1113 template<
typename Scalar>
1115 const std::vector<casadi_int>& cc,
bool ind1) {
1116 sparsity_.enlarge(nrow, ncol, rr, cc, ind1);
1119 template<
typename Scalar>
1124 template<
typename Scalar>
1125 std::vector<Scalar>& Matrix<Scalar>::nonzeros() {
1129 template<
typename Scalar>
1130 const std::vector<Scalar>& Matrix<Scalar>::nonzeros()
const {
1134 template<
typename Scalar>
1135 Scalar* Matrix<Scalar>::ptr() {
1136 return nonzeros_.empty() ? nullptr : &nonzeros_.front();
1139 template<
typename Scalar>
1140 const Scalar* Matrix<Scalar>::ptr()
const {
1141 return nonzeros_.empty() ? nullptr : &nonzeros_.front();
1144 template<
typename Scalar>
1149 template<
typename Scalar>
1150 Matrix<Scalar> Matrix<Scalar>::mtimes(
const Matrix<Scalar> &x,
const Matrix<Scalar> &y) {
1151 if (x.is_scalar() || y.is_scalar()) {
1156 return mac(x, y, z);
1160 template<
typename Scalar>
1161 Matrix<Scalar> Matrix<Scalar>::mac(
const Matrix<Scalar> &x,
1162 const Matrix<Scalar> &y,
1163 const Matrix<Scalar> &z) {
1164 if (x.is_scalar() || y.is_scalar()) {
1170 casadi_assert(x.size2()==y.size1(),
1171 "Matrix product with incompatible dimensions. Lhs is "
1172 + x.dim() +
" and rhs is " + y.dim() +
".");
1174 casadi_assert(y.size2()==z.size2(),
1175 "Matrix addition with incompatible dimensions. Lhs is "
1176 + mtimes(x, y).dim() +
" and rhs is " + z.dim() +
".");
1178 casadi_assert(x.size1()==z.size1(),
1179 "Matrix addition with incompatible dimensions. Lhs is "
1180 + mtimes(x, y).dim() +
" and rhs is " + z.dim() +
".");
1185 }
else if (y.is_eye()) {
1187 }
else if (x.is_zero() || y.is_zero()) {
1191 Matrix<Scalar> ret = z;
1192 std::vector<Scalar> work(x.size1());
1193 casadi_mtimes(x.ptr(), x.sparsity(), y.ptr(), y.sparsity(),
1194 ret.ptr(), ret.sparsity(), get_ptr(work),
false);
1199 template<
typename Scalar>
1200 Matrix<Scalar> Matrix<Scalar>::
1201 _bilin(
const Matrix<Scalar>& A,
const Matrix<Scalar>& x,
1202 const Matrix<Scalar>& y) {
1203 return casadi_bilin(A.ptr(), A.sparsity(), x.ptr(), y.ptr());
1206 template<
typename Scalar>
1207 Matrix<Scalar> Matrix<Scalar>::
1208 _rank1(
const Matrix<Scalar>& A,
const Matrix<Scalar>& alpha,
1209 const Matrix<Scalar>& x,
const Matrix<Scalar>& y) {
1210 Matrix<Scalar> ret = A;
1211 casadi_rank1(ret.ptr(), ret.sparsity(), *alpha.ptr(), x.ptr(), y.ptr());
1216 template<
typename Scalar>
1217 Matrix<Scalar> Matrix<Scalar>::
1218 _logsumexp(
const Matrix<Scalar>& x) {
1219 Matrix<Scalar> mx = mmax(x);
1220 return mx+log(sum1(exp(x-mx)));
1223 template<
typename Scalar>
1226 if ((size1()==0 && size2()==0) || is_scalar())
return *
this;
1229 std::vector<casadi_int> mapping;
1230 Sparsity s = sparsity().transpose(mapping);
1233 Matrix<Scalar> ret = zeros(s);
1236 for (casadi_int i=0; i<mapping.size(); ++i)
1237 ret->at(i) = nonzeros().at(mapping[i]);
1242 template<
typename Scalar>
1243 const Scalar Matrix<Scalar>::scalar()
const {
1245 casadi_assert(is_scalar(),
"Can only convert 1-by-1 matrices to scalars");
1249 return nonzeros()[0];
1254 template<
typename Scalar>
1255 Matrix<Scalar> Matrix<Scalar>::binary(casadi_int op,
1256 const Matrix<Scalar> &x,
1257 const Matrix<Scalar> &y) {
1258 if (x.is_scalar()) {
1259 return scalar_matrix(op, x, y);
1260 }
else if (y.is_scalar()) {
1261 return matrix_scalar(op, x, y);
1263 return matrix_matrix(op, x, y);
1267 template<
typename Scalar>
1268 Matrix<Scalar> Matrix<Scalar>::
1269 scalar_matrix(casadi_int op,
const Matrix<Scalar> &x,
const Matrix<Scalar> &y) {
1270 if ( (operation_checker<FX0Checker>(op) && y.nnz()==0) ||
1271 (operation_checker<F0XChecker>(op) && x.nnz()==0))
1278 std::vector<Scalar>& ret_data = ret.nonzeros();
1279 const std::vector<Scalar>& x_data = x.nonzeros();
1281 const std::vector<Scalar>& y_data = y.nonzeros();
1284 for (casadi_int el=0; el<y.nnz(); ++el) {
1285 casadi_math<Scalar>::fun(op, x_val, y_data[el], ret_data[el]);
1289 if (!y.is_dense() && !operation_checker<FX0Checker>(op)) {
1294 ret = densify(ret, fcn_0);
1301 template<
typename Scalar>
1302 Matrix<Scalar> Matrix<Scalar>::
1303 matrix_scalar(casadi_int op,
const Matrix<Scalar> &x,
const Matrix<Scalar> &y) {
1305 if ( (operation_checker<FX0Checker>(op) && y.nnz()==0) ||
1306 (operation_checker<F0XChecker>(op) && x.nnz()==0))
1313 std::vector<Scalar>& ret_data = ret.nonzeros();
1314 const std::vector<Scalar>& x_data = x.nonzeros();
1315 const std::vector<Scalar>& y_data = y.nonzeros();
1319 for (casadi_int el=0; el<x.nnz(); ++el) {
1320 casadi_math<Scalar>::fun(op, x_data[el], y_val, ret_data[el]);
1324 if (!x.is_dense() && !operation_checker<F0XChecker>(op)) {
1329 ret = densify(ret, fcn_0);
1336 template<
typename Scalar>
1337 Matrix<Scalar> Matrix<Scalar>::
1338 matrix_matrix(casadi_int op,
const Matrix<Scalar> &x,
const Matrix<Scalar> &y) {
1340 if (x.size() != y.size()) {
1342 if (!x.is_empty() && !y.is_empty()) {
1343 if (x.size1() == y.size1() && x.size2() % y.size2() == 0) {
1344 return matrix_matrix(op, x, repmat(y, 1, x.size2() / y.size2()));
1345 }
else if (y.size1() == x.size1() && y.size2() % x.size2() == 0) {
1346 return matrix_matrix(op, repmat(x, 1, y.size2() / x.size2()), y);
1350 if (x.size1()==0 && y.size1()==0 && x.size2()>0 && y.size2()>0) {
1351 if (x.size2() % y.size2() == 0) {
1352 return Matrix<Scalar>(0, x.size2());
1353 }
else if (y.size2() % x.size2() == 0) {
1354 return Matrix<Scalar>(0, y.size2());
1358 casadi_error(
"Dimension mismatch for " + casadi_math<Scalar>::print(op,
"x",
"y") +
1359 ", x is " + x.dim() +
", while y is " + y.dim());
1364 const Sparsity& x_sp = x.sparsity();
1365 const Sparsity& y_sp = y.sparsity();
1366 Sparsity r_sp = x_sp.combine(y_sp, operation_checker<F0XChecker>(op),
1367 operation_checker<FX0Checker>(op));
1370 Matrix<Scalar> r = zeros(r_sp);
1375 casadi_math<Scalar>::fun(op, x.ptr(), y.ptr(), r.ptr(), r_sp.nnz());
1376 }
else if (y_sp==r_sp) {
1378 Matrix<Scalar> x_mod = x(r_sp);
1379 casadi_math<Scalar>::fun(op, x_mod.ptr(), y.ptr(), r.ptr(), r_sp.nnz());
1380 }
else if (x_sp==r_sp) {
1382 Matrix<Scalar> y_mod = y(r_sp);
1383 casadi_math<Scalar>::fun(op, x.ptr(), y_mod.ptr(), r.ptr(), r_sp.nnz());
1386 Matrix<Scalar> x_mod = x(r_sp);
1387 Matrix<Scalar> y_mod = y(r_sp);
1388 casadi_math<Scalar>::fun(op, x_mod.ptr(), y_mod.ptr(), r.ptr(), r_sp.nnz());
1392 if (!r.is_dense() && !operation_checker<F00Checker>(op)) {
1397 r = densify(r, fcn_0);
1403 template<
typename Scalar>
1405 const std::vector<casadi_int>& col,
1406 const Matrix<Scalar>& d) {
1407 return triplet(row, col, d, *std::max_element(row.begin(), row.end()),
1408 *std::max_element(col.begin(), col.end()));
1411 template<
typename Scalar>
1413 const std::vector<casadi_int>& col,
1414 const Matrix<Scalar>& d,
1415 const std::pair<casadi_int, casadi_int>& rc) {
1416 return triplet(row, col, d, rc.first, rc.second);
1419 template<
typename Scalar>
1421 const std::vector<casadi_int>& col,
1422 const Matrix<Scalar>& d,
1423 casadi_int nrow, casadi_int ncol) {
1424 casadi_assert(col.size()==row.size() && col.size()==d.nnz(),
1425 "Argument error in Matrix<Scalar>::triplet(row, col, d): "
1426 "supplied lists must all be of equal length, but got: "
1427 + str(row.size()) +
", " + str(col.size()) +
" and " + str(d.nnz()));
1428 std::vector<casadi_int> mapping;
1430 return Matrix<Scalar>(sp, d.nz(mapping));
1433 template<
typename Scalar>
1438 template<
typename Scalar>
1440 casadi_assert(std::numeric_limits<Scalar>::has_infinity,
1441 "Datatype cannot represent infinity");
1442 return Matrix<Scalar>(sp, std::numeric_limits<Scalar>::infinity(),
false);
1446 template<
typename Scalar>
1448 return inf(rc.first, rc.second);
1451 template<
typename Scalar>
1456 template<
typename Scalar>
1458 casadi_assert(std::numeric_limits<Scalar>::has_quiet_NaN,
1459 "Datatype cannot represent not-a-number");
1460 return Matrix<Scalar>(sp, std::numeric_limits<Scalar>::quiet_NaN(),
false);
1463 template<
typename Scalar>
1465 return nan(rc.first, rc.second);
1468 template<
typename Scalar>
1473 template<
typename Scalar>
1478 template<
typename Scalar>
1483 template<
typename Scalar>
1485 casadi_error(
"'element_hash' not defined for " + type_name());
1488 template<
typename Scalar>
1490 casadi_error(
"'is_leaf' not defined for " + type_name());
1493 template<
typename Scalar>
1495 casadi_error(
"'is_commutative' not defined for " + type_name());
1498 template<
typename Scalar>
1503 template<
typename Scalar>
1505 casadi_error(
"'op' not defined for " + type_name());
1508 template<
typename Scalar>
1510 casadi_error(
"'is_op' not defined for " + type_name());
1513 template<
typename Scalar>
1515 std::ostream &stream,
const Dict& options)
const {
1516 casadi_error(
"'export_code' not defined for " + type_name());
1519 template<
typename Scalar>
1524 template<
typename Scalar>
1525 bool Matrix<Scalar>::has_duplicates()
const {
1526 casadi_error(
"'has_duplicates' not defined for " + type_name());
1529 template<
typename Scalar>
1530 void Matrix<Scalar>::reset_input()
const {
1531 casadi_error(
"'reset_input' not defined for " + type_name());
1534 template<
typename Scalar>
1536 const std::string& format_hint) {
1537 casadi_error(
"'from_file' not defined for " + type_name());
1540 template<
typename Scalar>
1549 template<
typename Scalar>
1558 template<
typename Scalar>
1560 if (!is_dense())
return false;
1568 template<
typename Scalar>
1570 if (!is_dense())
return false;
1578 template<
typename Scalar>
1587 template<
typename Scalar>
1591 if (!sparsity().is_diag())
return false;
1599 template<
typename Scalar>
1600 bool Matrix<Scalar>::is_equal(
const Matrix<Scalar> &x,
const Matrix<Scalar> &y,
1603 casadi_assert(x.size() == y.size(),
"Dimension mismatch");
1606 if (x.sparsity() != y.sparsity()) {
1607 Sparsity sp = x.sparsity() + y.sparsity();
1608 return is_equal(project(x, sp), project(y, sp), depth);
1612 auto y_it = y.nonzeros().begin();
1613 for (
auto&& e : x.nonzeros()) {
1622 template<
typename Scalar>
1623 inline Matrix<Scalar> mmin_nonstatic(
const Matrix<Scalar> &x) {
1624 if (x.is_empty())
return Matrix<Scalar>();
1625 return casadi_mmin(x.ptr(), x.nnz(), x.is_dense());
1628 template<
typename Scalar>
1630 return mmin_nonstatic(x);
1634 template<
typename Scalar>
1635 inline Matrix<Scalar> mmax_nonstatic(
const Matrix<Scalar> &x) {
1636 if (x.is_empty())
return Matrix<Scalar>();
1637 return casadi_mmax(x.ptr(), x.nnz(), x.is_dense());
1640 template<
typename Scalar>
1642 return mmax_nonstatic(x);
1645 template<
typename Scalar>
1654 template<
typename Scalar>
1659 template<
typename Scalar>
1661 return static_cast< std::vector<Scalar>
>(*this);
1664 template<
typename Scalar>
1666 casadi_error(
"'name' not defined for " + type_name());
1669 template<
typename Scalar>
1671 casadi_error(
"'dep' not defined for " + type_name());
1674 template<
typename Scalar>
1676 casadi_error(
"'n_dep' not defined for " + type_name());
1679 template<
typename Scalar>
1686 template<
typename Scalar>
1688 const std::pair<casadi_int, casadi_int>& rc) {
1689 return rand(rc.first, rc.second);
1692 template<
typename Scalar>
1694 const Sparsity& sp,
bool intersect) {
1696 return project(x, sp.intersect(x.sparsity()),
false);
1698 casadi_assert(sp.size()==x.size(),
"Dimension mismatch");
1700 std::vector<Scalar> w(x.size1());
1701 casadi_project(x.ptr(), x.sparsity(), ret.ptr(), sp, get_ptr(w));
1706 template<
typename Scalar>
1708 casadi_error(
"'set_max_depth' not defined for " + type_name());
1711 template<
typename Scalar>
1713 casadi_error(
"'get_max_depth' not defined for " + type_name());
1716 template<
typename Scalar>
1718 casadi_int n = x.size2();
1719 casadi_assert(n == x.size1(),
"matrix must be square");
1722 if (x.is_scalar())
return x;
1725 if (n==2)
return x(0, 0) * x(1, 1) - x(0, 1) * x(1, 0);
1728 Matrix<Scalar> ret = 0;
1733 Matrix<casadi_int> sp =
IM::ones(x.sparsity());
1736 Matrix<casadi_int> row_count = Matrix<casadi_int>::sum2(sp);
1739 if (!row_count.is_dense())
return 0;
1742 Matrix<casadi_int> col_count = Matrix<casadi_int>::sum1(sp).T();
1745 if (!row_count.is_dense())
return 0;
1747 casadi_int min_row = std::distance(row_count.nonzeros().begin(),
1748 std::min_element(row_count.nonzeros().begin(),
1749 row_count.nonzeros().end()));
1750 casadi_int min_col = std::distance(col_count.nonzeros().begin(),
1751 std::min_element(col_count.nonzeros().begin(),
1752 col_count.nonzeros().end()));
1754 if (min_row <= min_col) {
1756 casadi_int j = row_count.sparsity().row(min_row);
1758 Matrix<Scalar> row = x(j, Slice(0, n));
1760 std::vector< casadi_int > col_i = row.sparsity().get_col();
1762 for (casadi_int k=0; k<row.nnz(); ++k) {
1764 ret += row->at(k)*cofactor(x, col_i.at(k), j);
1769 casadi_int i = col_count.sparsity().row(min_col);
1771 Matrix<Scalar> col = x(Slice(0, n), i);
1773 const casadi_int* row_i = col.row();
1775 for (casadi_int k=0; k<col.nnz(); ++k) {
1777 ret += col->at(k)*cofactor(x, i, row_i[k]);
1784 template<
typename Scalar>
1785 Matrix<Scalar> Matrix<Scalar>::sum2(
const Matrix<Scalar>& x) {
1789 template<
typename Scalar>
1790 Matrix<Scalar> Matrix<Scalar>::sum1(
const Matrix<Scalar>& x) {
1794 template<
typename Scalar>
1796 casadi_int i, casadi_int j) {
1797 casadi_int n = x.size2();
1798 casadi_assert(n == x.size1(),
"minor: matrix must be square");
1804 Matrix<Scalar> M = Matrix<Scalar>(n-1, n-1);
1806 std::vector<casadi_int> col = x.sparsity().get_col();
1807 const casadi_int* row = x.sparsity().row();
1809 for (casadi_int k=0; k<x.nnz(); ++k) {
1810 casadi_int i1 = col[k];
1811 casadi_int j1 = row[k];
1813 if (i1 == i || j1 == j)
continue;
1815 casadi_int i2 = (i1<i)?i1:i1-1;
1816 casadi_int j2 = (j1<j)?j1:j1-1;
1818 M(j2, i2) = x(j1, i1);
1823 template<
typename Scalar>
1827 Matrix<Scalar> minor_ij = minor(A, i, j);
1829 casadi_int sign_i = 1-2*((i+j) % 2);
1831 return sign_i * minor_ij;
1834 template<
typename Scalar>
1836 casadi_int n = x.size2();
1837 casadi_assert(n == x.size1(),
"adj: matrix must be square");
1840 Matrix<Scalar> temp;
1843 Matrix<Scalar> C = Matrix<Scalar>(n, n);
1844 for (casadi_int i=0; i<n; ++i)
1845 for (casadi_int j=0; j<n; ++j) {
1846 temp = cofactor(x, i, j);
1847 if (!temp.is_zero()) C(j, i) = temp;
1853 template<
typename Scalar>
1856 return adj(x)/det(x);
1859 template<
typename Scalar>
1860 Matrix<Scalar> Matrix<Scalar>::reshape(
const Matrix<Scalar>& x,
1861 casadi_int nrow, casadi_int ncol) {
1862 Sparsity sp = Sparsity::reshape(x.sparsity(), nrow, ncol);
1863 return Matrix<Scalar>(sp, x.nonzeros(),
false);
1866 template<
typename Scalar>
1867 Matrix<Scalar> Matrix<Scalar>::reshape(
const Matrix<Scalar>& x,
const Sparsity& sp) {
1869 if (sp==x.sparsity())
return x;
1872 casadi_assert_dev(sp.is_reshape(x.sparsity()));
1874 return Matrix<Scalar>(sp, x.nonzeros(),
false);
1877 template<
typename Scalar>
1878 Matrix<Scalar> Matrix<Scalar>::sparsity_cast(
const Matrix<Scalar>& x,
const Sparsity& sp) {
1880 if (sp==x.sparsity())
return x;
1882 casadi_assert_dev(sp.nnz()==x.nnz());
1884 return Matrix<Scalar>(sp, x.nonzeros(),
false);
1887 template<
typename Scalar>
1889 casadi_assert(x.is_square(),
"trace: must be square");
1891 const Scalar* d=x.ptr();
1892 casadi_int size2 = x.size2();
1893 const casadi_int *colind=x.colind(), *row=x.row();
1894 for (casadi_int c=0; c<size2; c++) {
1895 for (casadi_int k=colind[c]; k!=colind[c+1]; ++k) {
1904 template<
typename Scalar>
1906 Matrix<Scalar>::blockcat(
const std::vector< std::vector<Matrix<Scalar> > > &v) {
1907 std::vector< Matrix<Scalar> > ret;
1908 for (casadi_int i=0; i<v.size(); ++i)
1909 ret.push_back(horzcat(v[i]));
1910 return vertcat(ret);
1913 template<
typename Scalar>
1914 Matrix<Scalar> Matrix<Scalar>::horzcat(
const std::vector<Matrix<Scalar> > &v) {
1916 std::vector<Sparsity> sp(v.size());
1917 for (casadi_int i=0; i<v.size(); ++i) sp[i] = v[i].sparsity();
1918 Matrix<Scalar> ret = zeros(Sparsity::horzcat(sp));
1921 auto i=ret->begin();
1922 for (
auto&& j : v) {
1923 std::copy(j->begin(), j->end(), i);
1929 template<
typename Scalar>
1930 std::vector<Matrix<Scalar> >
1931 Matrix<Scalar>::horzsplit(
const Matrix<Scalar>& x,
const std::vector<casadi_int>& offset) {
1933 std::vector<Sparsity> sp = Sparsity::horzsplit(x.sparsity(), offset);
1936 std::vector<Matrix<Scalar> > ret;
1937 ret.reserve(sp.size());
1940 auto i=x.nonzeros().begin();
1941 for (
auto&& j : sp) {
1942 auto i_next = i + j.nnz();
1943 ret.push_back(Matrix<Scalar>(j, std::vector<Scalar>(i, i_next),
false));
1948 casadi_assert_dev(i==x.nonzeros().end());
1952 template<
typename Scalar>
1953 Matrix<Scalar> Matrix<Scalar>::vertcat(
const std::vector<Matrix<Scalar> > &v) {
1954 std::vector<Matrix<Scalar> > vT(v.size());
1955 for (casadi_int i=0; i<v.size(); ++i) vT[i] = v[i].T();
1956 return horzcat(vT).T();
1959 template<
typename Scalar>
1960 std::vector< Matrix<Scalar> >
1961 Matrix<Scalar>::vertsplit(
const Matrix<Scalar>& x,
const std::vector<casadi_int>& offset) {
1962 std::vector< Matrix<Scalar> > ret = horzsplit(x.T(), offset);
1963 for (
auto&& e : ret) e = e.T();
1967 template<
typename Scalar>
1968 std::vector< Matrix<Scalar> >
1969 Matrix<Scalar>::diagsplit(
const Matrix<Scalar>& x,
const std::vector<casadi_int>& offset1,
1970 const std::vector<casadi_int>& offset2) {
1972 casadi_assert_dev(!offset1.empty());
1973 casadi_assert_dev(offset1.front()==0);
1974 casadi_assert_dev(offset1.back()==x.size1());
1978 casadi_assert_dev(!offset2.empty());
1979 casadi_assert_dev(offset2.front()==0);
1980 casadi_assert_dev(offset2.back()==x.size2());
1984 casadi_int n = offset1.size()-1;
1987 std::vector< Matrix<Scalar> > ret;
1990 for (casadi_int i=0; i<n; ++i) {
1991 ret.push_back(x(Slice(offset1[i], offset1[i+1]), Slice(offset2[i], offset2[i+1])));
1997 template<
typename Scalar>
1999 const Matrix<Scalar> &y) {
2000 casadi_assert(x.size()==y.size(),
"dot: Dimension mismatch");
2001 if (x.sparsity()!=y.sparsity()) {
2002 Sparsity sp = x.sparsity() * y.sparsity();
2003 return dot(project(x, sp), project(y, sp));
2005 return casadi_dot(x.nnz(), x.ptr(), y.ptr());
2008 template<
typename Scalar>
2010 if (!x.is_dense())
return false;
2012 for (casadi_int i=0; i<x.nnz(); ++i) {
2013 ret = ret && x->at(i)==1;
2018 template<
typename Scalar>
2020 if (!x.is_dense())
return false;
2022 for (casadi_int i=0; i<x.nnz(); ++i) {
2023 ret = ret || x->at(i)==1;
2028 template<
typename Scalar>
2030 return casadi_norm_1(x.nnz(), x.ptr());
2033 template<
typename Scalar>
2035 if (x.is_vector()) {
2038 casadi_error(
"2-norms currently only supported for vectors. "
2039 "Did you intend to calculate a Frobenius norms (norm_fro)?");
2043 template<
typename Scalar>
2045 return casadi_norm_2(x.nnz(), x.ptr());
2048 template<
typename Scalar>
2051 Matrix<Scalar> s = 0;
2052 for (
auto i=x.nonzeros().begin(); i!=x.nonzeros().end(); ++i) {
2053 s = fmax(s, fabs(Matrix<Scalar>(*i)));
2058 template<
typename Scalar>
2061 Matrix<Scalar>& V, Matrix<Scalar> &R, Matrix<Scalar>& beta,
2062 std::vector<casadi_int>& prinv, std::vector<casadi_int>& pc,
bool amd) {
2065 A.sparsity().qr_sparse(spV, spR, prinv, pc, amd);
2067 casadi_int nrow_ext = spV.size1(), ncol = spV.size2();
2070 beta = nan(ncol, 1);
2071 std::vector<Scalar> w(nrow_ext);
2072 casadi_qr(A.sparsity(), A.ptr(), get_ptr(w), spV, V.ptr(),
2073 spR, R.ptr(), beta.ptr(),
2074 get_ptr(prinv), get_ptr(pc));
2077 template<
typename Scalar>
2079 qr_solve(
const Matrix<Scalar>& b,
const Matrix<Scalar>& v,
2080 const Matrix<Scalar>& r,
const Matrix<Scalar>& beta,
2081 const std::vector<casadi_int>& prinv,
const std::vector<casadi_int>& pc,
2084 casadi_int ncol = v.size2();
2085 casadi_int nrow = b.size1(), nrhs = b.size2();
2086 casadi_assert(r.size()==v.size(),
"'r', 'v' dimension mismatch");
2087 casadi_assert(beta.is_vector() && beta.numel()==ncol,
"'beta' has wrong dimension");
2088 casadi_assert(prinv.size()==r.size1(),
"'pinv' has wrong dimension");
2090 std::vector<Scalar> w(nrow+ncol);
2092 Matrix<Scalar> x = densify(b);
2093 casadi_qr_solve(x.ptr(), nrhs, tr, v.sparsity(), v.ptr(), r.sparsity(), r.ptr(),
2094 beta.ptr(), get_ptr(prinv), get_ptr(pc), get_ptr(w));
2098 template<
typename Scalar>
2100 Matrix<Scalar>& Q, Matrix<Scalar> &R) {
2103 casadi_assert(A.size1()>=A.size2(),
"qr: fewer rows than columns");
2106 Q = R = Matrix<Scalar>();
2107 for (casadi_int i=0; i<A.size2(); ++i) {
2109 Matrix<Scalar> ai = A(Slice(), i);
2110 Matrix<Scalar> qi = ai;
2112 Matrix<Scalar> ri = Matrix<Scalar>(A.size2(), 1);
2115 for (casadi_int j=0; j<i; ++j) {
2118 Matrix<Scalar> qj = Q(Slice(), j);
2120 ri(j, 0) = mtimes(qi.T(), qj);
2124 if (ri.has_nz(j, 0))
2125 qi -= ri(j, 0) * qj;
2129 ri(i, 0) = norm_2(qi);
2133 Q = Matrix<Scalar>::horzcat({Q, qi});
2134 R = Matrix<Scalar>::horzcat({R, ri});
2138 template<
typename Scalar>
2140 Matrix<Scalar>& LT, std::vector<casadi_int>& p,
bool amd) {
2142 Sparsity Lt_sp = A.sparsity().ldl(p, amd);
2145 casadi_int n=A.size1();
2148 std::vector<Scalar> D_nz(n), L_nz(Lt_sp.nnz()), w(n);
2149 casadi_ldl(A.sparsity(), get_ptr(A.nonzeros()), Lt_sp,
2150 get_ptr(L_nz), get_ptr(D_nz), get_ptr(p), get_ptr(w));
2153 LT = Matrix<Scalar>(Lt_sp, L_nz);
2157 template<
typename Scalar>
2159 ldl_solve(
const Matrix<Scalar>& b,
const Matrix<Scalar>& D,
const Matrix<Scalar>& LT,
2160 const std::vector<casadi_int>& p) {
2162 casadi_int n = b.size1(), nrhs = b.size2();
2163 casadi_assert(p.size()==n,
"'p' has wrong dimension");
2164 casadi_assert(LT.size1()==n && LT.size2()==n,
"'LT' has wrong dimension");
2165 casadi_assert(D.is_vector() && D.numel()==n,
"'D' has wrong dimension");
2167 Matrix<Scalar> x = densify(b);
2168 std::vector<Scalar> w(n);
2169 casadi_ldl_solve(x.ptr(), nrhs, LT.sparsity(), LT.ptr(), D.ptr(), get_ptr(p), get_ptr(w));
2173 template<
typename Scalar>
2175 Matrix<Scalar> X = A;
2176 casadi_int n = X.size1();
2177 casadi_int m = X.size2();
2178 casadi_assert(m>=n,
"nullspace(): expecting a flat matrix (more columns than rows), "
2179 "but got " + str(X.dim()) +
".");
2181 Matrix<Scalar> seed =
DM::eye(m)(Slice(0, m), Slice(n, m));
2183 std::vector< Matrix<Scalar> > us;
2184 std::vector< Matrix<Scalar> > betas;
2186 Matrix<Scalar> beta;
2188 for (casadi_int i=0;i<n;++i) {
2189 Matrix<Scalar> x = X(i, Slice(i, m));
2190 Matrix<Scalar> u = Matrix<Scalar>(x);
2191 Matrix<Scalar> sigma = sqrt(sum2(x*x));
2192 const Matrix<Scalar>& x0 = x(0, 0);
2195 Matrix<Scalar> b = -copysign(sigma, x0);
2197 u(Slice(0), Slice(1, m-i))*= 1/(x0-b);
2200 X(Slice(i, n), Slice(i, m)) -=
2201 beta*mtimes(mtimes(X(Slice(i, n), Slice(i, m)), u.T()), u);
2203 betas.push_back(beta);
2206 for (casadi_int i=n-1;i>=0;--i) {
2207 seed(Slice(i, m), Slice(0, m-n)) -=
2208 betas[i]*mtimes(us[i].T(), mtimes(us[i], seed(Slice(i, m), Slice(0, m-n))));
2215 template<
typename Scalar>
2218 Matrix<Scalar> D, LT;
2219 std::vector<casadi_int> p;
2220 ldl(A, D, LT, p,
false);
2224 return mtimes(diag(sqrt(D)), LT);
2227 template<
typename Scalar>
2230 casadi_assert(a.size1() == b.size1(),
"solve Ax=b: dimension mismatch: b has "
2231 + str(b.size1()) +
" rows while A has " + str(a.size1()) +
".");
2232 casadi_assert(a.size1() == a.size2(),
"solve: A not square but " + str(a.dim()));
2236 Matrix<Scalar> x = b;
2237 const casadi_int* Arow = a.row();
2238 const casadi_int* Acolind = a.colind();
2239 const std::vector<Scalar> & Adata = a.nonzeros();
2240 for (casadi_int i=0; i<a.size2(); ++i) {
2241 for (casadi_int k=0; k<b.size2(); ++k) {
2242 if (!x.has_nz(i, k))
continue;
2244 for (casadi_int kk=Acolind[i+1]-1; kk>=Acolind[i] && Arow[kk]>i; --kk) {
2245 casadi_int j = Arow[kk];
2246 x(j, k) -= Adata[kk]*x(i, k);
2251 }
else if (a.is_triu()) {
2253 Matrix<Scalar> x = b;
2254 const casadi_int* Arow = a.row();
2255 const casadi_int* Acolind = a.colind();
2256 const std::vector<Scalar> & Adata = a.nonzeros();
2257 for (casadi_int i=a.size2()-1; i>=0; --i) {
2258 for (casadi_int k=0; k<b.size2(); ++k) {
2259 if (!x.has_nz(i, k))
continue;
2261 for (casadi_int kk=Acolind[i]; kk<Acolind[i+1] && Arow[kk]<i; ++kk) {
2262 casadi_int j = Arow[kk];
2263 x(j, k) -= Adata[kk]*x(i, k);
2268 }
else if (a.has_zeros()) {
2272 return solve(sparsify(a), b);
2277 std::vector<casadi_int> rowperm, colperm, rowblock, colblock;
2278 std::vector<casadi_int> coarse_rowblock, coarse_colblock;
2279 a.sparsity().btf(rowperm, colperm, rowblock, colblock,
2280 coarse_rowblock, coarse_colblock);
2283 Matrix<Scalar> bperm = b(rowperm, Slice());
2286 Matrix<Scalar> Aperm = a(rowperm, colperm);
2289 Matrix<Scalar> xperm;
2292 if (Aperm.is_tril()) {
2295 xperm = solve(Aperm, bperm);
2297 }
else if (a.size2()<=3) {
2300 xperm = mtimes(inv_minor(Aperm), bperm);
2305 Matrix<Scalar> Q, R;
2309 xperm = solve(R, mtimes(Q.T(), bperm));
2313 std::vector<casadi_int> inv_colperm(colperm.size());
2314 for (casadi_int k=0; k<colperm.size(); ++k)
2315 inv_colperm[colperm[k]] = k;
2318 Matrix<Scalar> x = xperm(inv_colperm, Slice());
2323 template<
typename Scalar>
2325 solve(
const Matrix<Scalar>& a,
const Matrix<Scalar>& b,
2326 const std::string& lsolver,
const Dict& dict) {
2327 casadi_error(
"'solve' with plugin not defined for " + type_name());
2328 return Matrix<Scalar>();
2331 template<
typename Scalar>
2333 inv(
const Matrix<Scalar>& a) {
2337 template<
typename Scalar>
2339 inv(
const Matrix<Scalar>& a,
2340 const std::string& lsolver,
const Dict& dict) {
2341 casadi_error(
"'inv' with plugin not defined for " + type_name());
2342 return Matrix<Scalar>();
2345 template<
typename Scalar>
2347 if (A.size2()>=A.size1()) {
2348 return solve(mtimes(A, A.T()), A).T();
2350 return solve(mtimes(A.T(), A), A.T());
2354 template<
typename Scalar>
2356 pinv(
const Matrix<Scalar>& A,
const std::string& lsolver,
const Dict& dict) {
2357 casadi_error(
"'solve' not defined for " + type_name());
2358 return Matrix<Scalar>();
2361 template<
typename Scalar>
2363 expm_const(
const Matrix<Scalar>& A,
const Matrix<Scalar>& t) {
2364 casadi_error(
"'solve' not defined for " + type_name());
2365 return Matrix<Scalar>();
2368 template<
typename Scalar>
2370 expm(
const Matrix<Scalar>& A) {
2371 casadi_error(
"'solve' not defined for " + type_name());
2372 return Matrix<Scalar>();
2375 template<
typename Scalar>
2376 Matrix<Scalar> Matrix<Scalar>::kron(
const Matrix<Scalar>& a,
const Matrix<Scalar>& b) {
2377 std::vector<Scalar> ret(a.nnz()*b.nnz());
2378 casadi_kron(get_ptr(a), a.sparsity(), get_ptr(b), b.sparsity(), get_ptr(ret));
2380 Sparsity sp_ret = Sparsity::kron(a.sparsity(), b.sparsity());
2381 return Matrix<Scalar>(sp_ret, ret,
false);
2384 template<
typename Scalar>
2387 std::vector<casadi_int> mapping;
2389 Sparsity sp = A.sparsity().get_diag(mapping);
2391 Matrix<Scalar> ret = zeros(sp);
2393 for (casadi_int k=0; k<mapping.size(); k++) ret.nz(k) = A.nz(mapping[k]);
2400 template<
typename Scalar>
2401 Matrix<Scalar> Matrix<Scalar>::diagcat(
const std::vector< Matrix<Scalar> > &A) {
2402 std::vector<Scalar> data;
2404 std::vector<Sparsity> sp;
2405 for (casadi_int i=0;i<A.size();++i) {
2406 data.insert(data.end(), A[i].nonzeros().begin(), A[i].nonzeros().end());
2407 sp.push_back(A[i].sparsity());
2410 return Matrix<Scalar>(Sparsity::diagcat(sp), data,
false);
2413 template<
typename Scalar>
2416 std::vector<unsigned char> mapping;
2417 Sparsity sp = A.sparsity().unite(B.sparsity(), mapping);
2420 Matrix<Scalar> ret = zeros(sp);
2423 casadi_int elA=0, elB=0;
2424 for (casadi_int k=0; k<mapping.size(); ++k) {
2425 if (mapping[k]==1) {
2426 ret.nonzeros()[k] = A.nonzeros()[elA++];
2427 }
else if (mapping[k]==2) {
2428 ret.nonzeros()[k] = B.nonzeros()[elB++];
2430 casadi_error(
"Pattern intersection not empty");
2434 casadi_assert_dev(A.nnz()==elA);
2435 casadi_assert_dev(B.nnz()==elB);
2440 template<
typename Scalar>
2442 casadi_assert(p.is_dense(),
"polynomial coefficients vector must be dense");
2443 casadi_assert(p.is_vector() && p.nnz()>0,
"polynomial coefficients must be a vector");
2444 Matrix<Scalar> ret = x;
2445 for (
auto&& e : ret.nonzeros()) {
2446 e = casadi_polyval(p.ptr(), p.numel()-1, e);
2451 template<
typename Scalar>
2453 const Matrix<Scalar>& y) {
2454 casadi_assert(y.size1()==x.size2(),
"Dimension error. Got " + x.dim()
2455 +
" times " + y.dim() +
".");
2458 std::vector<Scalar> dwork(x.size1());
2459 std::vector<casadi_int> iwork(x.size1()+1+y.size2());
2462 return casadi_norm_inf_mul(x.ptr(), x.sparsity(), y.ptr(), y.sparsity(),
2463 get_ptr(dwork), get_ptr(iwork));
2466 template<
typename Scalar>
2468 Matrix<Scalar> &weights, Matrix<Scalar>& terms) {
2469 casadi_error(
"'expand' not defined for " + type_name());
2472 template<
typename Scalar>
2474 const Matrix<Scalar>& tval,
2475 const Matrix<Scalar>& val) {
2476 casadi_error(
"'pw_const' not defined for " + type_name());
2477 return Matrix<Scalar>();
2480 template<
typename Scalar>
2482 const Matrix<Scalar>& tval,
2483 const Matrix<Scalar>& val) {
2484 casadi_error(
"'pw_lin' not defined for " + type_name());
2485 return Matrix<Scalar>();
2488 template<
typename Scalar>
2490 const Matrix<Scalar> &if_true,
2491 const Matrix<Scalar> &if_false,
2492 bool short_circuit) {
2493 return if_else_zero(cond, if_true) + if_else_zero(!cond, if_false);
2496 template<
typename Scalar>
2498 const std::vector<Matrix<Scalar> >& x,
2499 const Matrix<Scalar>& x_default,
2500 bool short_circuit) {
2501 casadi_assert(!short_circuit,
2502 "Short-circuiting 'conditional' not supported for " + type_name());
2503 casadi_assert(ind.is_scalar(
true),
2504 "conditional: first argument must be scalar. Got " + ind.dim()+
" instead.");
2506 Matrix<Scalar> ret = x_default;
2507 for (casadi_int k=0; k<x.size(); ++k) {
2508 ret = if_else(ind==k, x[k], ret, short_circuit);
2513 template<
typename Scalar>
2515 return (1+sign(x))/2;
2518 template<
typename Scalar>
2520 return 0.5*(sign(x+0.5)-sign(x-0.5));
2523 template<
typename Scalar>
2525 return rectangle(x/2)*(1-fabs(x));
2528 template<
typename Scalar>
2530 return x*heaviside(x);
2533 template<
typename Scalar>
2536 const Matrix<Scalar> &x,
const Matrix<Scalar> &a,
2537 const Matrix<Scalar> &b, casadi_int order) {
2538 return gauss_quadrature(f, x, a, b, order, Matrix<Scalar>());
2541 template<
typename Scalar>
2543 const Matrix<Scalar>& x,
2544 const Matrix<Scalar>& a,
2545 const Matrix<Scalar>& b, casadi_int order,
2546 const Matrix<Scalar>& w) {
2547 casadi_error(
"'gauss_quadrature' not defined for " + type_name());
2548 return Matrix<Scalar>();
2551 template<
typename Scalar>
2556 template<
typename Scalar>
2558 const Matrix<Scalar>& v,
2559 const Matrix<Scalar>& vdef) {
2560 casadi_error(
"'substitute' not defined for " + type_name());
2561 return Matrix<Scalar>();
2564 template<
typename Scalar>
2565 std::vector<Matrix<Scalar> >
2567 const std::vector<Matrix<Scalar> >& v,
2568 const std::vector<Matrix<Scalar> >& vdef) {
2569 casadi_error(
"'substitute' not defined for " + type_name());
2570 return std::vector<Matrix<Scalar> >();
2573 template<
typename Scalar>
2575 std::vector<Matrix<Scalar> >& vdef,
2576 std::vector<Matrix<Scalar> >& ex,
2578 casadi_error(
"'substitute_inplace' not defined for " + type_name());
2581 template<
typename Scalar>
2583 casadi_error(
"'depends_on' not defined for " + type_name());
2587 template<
typename Scalar>
2588 std::vector< Matrix<Scalar> >
Matrix<Scalar>::cse(
const std::vector< Matrix<Scalar> >& e) {
2589 casadi_error(
"'cse' not defined for " + type_name());
2594 template<
typename Scalar>
2596 jacobian(
const Matrix<Scalar> &f,
const Matrix<Scalar> &x,
const Dict& opts) {
2597 casadi_error(
"'jacobian' not defined for " + type_name());
2598 return Matrix<Scalar>();
2601 template<
typename Scalar>
2603 const Matrix<Scalar> &x,
2605 casadi_error(
"'hessian' not defined for " + type_name());
2606 return Matrix<Scalar>();
2609 template<
typename Scalar>
2611 const Matrix<Scalar> &x,
2614 casadi_error(
"'hessian' not defined for " + type_name());
2615 return Matrix<Scalar>();
2618 template<
typename Scalar>
2619 std::vector<std::vector<Matrix<Scalar> > >
2621 forward(
const std::vector<Matrix<Scalar> > &ex,
2622 const std::vector<Matrix<Scalar> > &arg,
2623 const std::vector<std::vector<Matrix<Scalar> > > &v,
2625 casadi_error(
"'forward' not defined for " + type_name());
2628 template<
typename Scalar>
2629 std::vector<std::vector<Matrix<Scalar> > >
2631 reverse(
const std::vector<Matrix<Scalar> > &ex,
2632 const std::vector<Matrix<Scalar> > &arg,
2633 const std::vector<std::vector<Matrix<Scalar> > > &v,
2635 casadi_error(
"'reverse' not defined for " + type_name());
2638 template<
typename Scalar>
2641 casadi_int order,
bool tr) {
2642 casadi_error(
"'which_depends' not defined for " + type_name());
2643 return std::vector<bool>();
2646 template<
typename Scalar>
2649 casadi_error(
"'jacobian_sparsity' not defined for " + type_name());
2653 template<
typename Scalar>
2655 const Matrix<Scalar>& x,
2656 const Matrix<Scalar>& a, casadi_int order) {
2657 casadi_error(
"'taylor' not defined for " + type_name());
2658 return Matrix<Scalar>();
2661 template<
typename Scalar>
2663 const Matrix<Scalar>& x,
2664 const Matrix<Scalar>& a, casadi_int order) {
2665 casadi_error(
"'mtaylor' not defined for " + type_name());
2666 return Matrix<Scalar>();
2669 template<
typename Scalar>
2671 const Matrix<Scalar>& x,
2672 const Matrix<Scalar>& a, casadi_int order,
2673 const std::vector<casadi_int>&order_contributions) {
2674 casadi_error(
"'mtaylor' not defined for " + type_name());
2675 return Matrix<Scalar>();
2678 template<
typename Scalar>
2680 casadi_error(
"'n_nodes' not defined for " + type_name());
2684 template<
typename Scalar>
2687 const std::vector<std::string>& args) {
2688 casadi_error(
"'print_operator' not defined for " + type_name());
2689 return std::string();
2692 template<
typename Scalar>
2694 casadi_error(
"'symvar' not defined for " + type_name());
2695 return std::vector<Matrix<Scalar> >();
2698 template<
typename Scalar>
2700 std::vector<Matrix<Scalar>>& vdef,
const Dict& opts) {
2701 casadi_error(
"'extract' not defined for " + type_name());
2704 template<
typename Scalar>
2706 std::vector<Matrix<Scalar> >& v,
2707 std::vector<Matrix<Scalar> >& vdef,
2708 const std::string& v_prefix,
2709 const std::string& v_suffix) {
2710 casadi_error(
"'shared' not defined for " + type_name());
2713 template<
typename Scalar>
2715 const Matrix<Scalar>&x) {
2716 casadi_error(
"'poly_coeff' not defined for " + type_name());
2719 template<
typename Scalar>
2721 casadi_error(
"'poly_roots' not defined for " + type_name());
2724 template<
typename Scalar>
2726 casadi_error(
"'eig_symbolic' not defined for " + type_name());
2729 template<
typename Scalar>
2731 Function f(
"f", std::vector<SX>{}, std::vector<SX>{m});
2732 return f(std::vector<DM>{})[0];
2735 template<
typename Scalar>
2738 bool remove_nothing =
true;
2739 for (
auto it=x.nonzeros().begin(); it!=x.nonzeros().end() && remove_nothing; ++it) {
2742 if (remove_nothing)
return x;
2745 casadi_int size1 = x.size1();
2746 casadi_int size2 = x.size2();
2747 const casadi_int* colind = x.colind();
2748 const casadi_int* row = x.row();
2751 std::vector<casadi_int> new_colind(1, 0), new_row;
2752 std::vector<Scalar> new_data;
2755 for (casadi_int cc=0; cc<size2; ++cc) {
2757 for (casadi_int el=colind[cc]; el<colind[cc+1]; ++el) {
2761 new_data.push_back(x->at(el));
2764 new_row.push_back(row[el]);
2768 new_colind.push_back(new_row.size());
2772 Sparsity sp(size1, size2, new_colind, new_row);
2775 return Matrix<Scalar>(sp, new_data);
2779 template<
typename Scalar>
2781 casadi_error(
"'get_input' not defined for " + type_name());
2784 template<
typename Scalar>
2786 casadi_error(
"'get_free' not defined for " + type_name());
2789 template<
typename Scalar>
2790 Matrix<Scalar>::operator double()
const {
2791 casadi_assert_dev(is_scalar());
2792 return static_cast<double>(scalar());
2795 template<
typename Scalar>
2796 Matrix<Scalar>::operator casadi_int()
const {
2797 casadi_assert_dev(is_scalar());
2798 return static_cast<casadi_int
>(scalar());
2801 template<
typename Scalar>
2802 Matrix<Scalar> Matrix<Scalar>::_sym(
const std::string& name,
const Sparsity& sp) {
2803 casadi_error(
"'sym' not defined for " + type_name());
2806 template<
typename Scalar>
2809 casadi_error(
"'rand' not defined for " + type_name());
2812 template<
typename Scalar>
2814 std::stringstream ss;
2819 template<
typename Scalar>
2821 s.pack(
"Matrix::sparsity", sparsity());
2822 s.pack(
"Matrix::nonzeros", nonzeros());
2825 template<
typename Scalar>
2828 s.unpack(
"Matrix::sparsity", sp);
2829 std::vector<Scalar> nz;
2830 s.unpack(
"Matrix::nonzeros", nz);
2831 return Matrix<Scalar>(sp, nz,
false);
2834 template<
typename Scalar>
2836 SerializingStream s(stream);
2840 template<
typename Scalar>
2842 DeserializingStream s(stream);
2846 template<
typename Scalar>
2848 std::stringstream ss;
2850 return deserialize(ss);
Sparsity sparsity() const
Get the sparsity pattern.
bool is_dense() const
Check if the matrix expression is dense.
bool is_column() const
Check if the matrix is a column vector (i.e. size2()==1)
casadi_int row(casadi_int el) const
Get the sparsity pattern. See the Sparsity class for details.
bool is_vector() const
Check if the matrix is a row or column vector.
casadi_int nnz() const
Get the number of (structural) non-zero elements.
casadi_int size2() const
Get the second dimension (i.e. number of columns)
bool is_row() const
Check if the matrix is a row vector (i.e. size1()==1)
casadi_int size1() const
Get the first dimension (i.e. number of rows)
static Matrix< Scalar > ones(casadi_int nrow=1, casadi_int ncol=1)
Create a dense matrix or a matrix with specified sparsity with all entries one.
casadi_int colind(casadi_int col) const
Get the sparsity pattern. See the Sparsity class for details.
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.
std::pair< casadi_int, casadi_int > size() const
Get the shape.
bool is_scalar(bool scalar_and_dense=false) const
Check if the matrix expression is scalar.
Sparse matrix class. SX and DM are specializations.
bool has_nz(casadi_int rr, casadi_int cc) const
Returns true if the matrix has a non-zero at location rr, cc.
bool has_zeros() const
Check if the matrix has any zero entries which are not structural zeros.
void print_split(std::vector< std::string > &nz, std::vector< std::string > &inter) const
Get strings corresponding to the nonzeros and the interdependencies.
bool is_one() const
check if the matrix is 1 (note that false negative answers are possible)
void remove(const std::vector< casadi_int > &rr, const std::vector< casadi_int > &cc)
Remove columns and rows.
bool is_regular() const
Checks if expression does not contain NaN or Inf.
Matrix< Scalar > T() const
Transpose the matrix.
static void set_max_depth(casadi_int eq_depth=1)
Set or reset the depth to which equalities are being checked for simplifications.
static void set_precision(casadi_int precision)
Set the 'precision, width & scientific' used in printing and serializing to streams.
void get(Matrix< Scalar > &m, bool ind1, const Slice &rr) const
void resize(casadi_int nrow, casadi_int ncol)
Sparsity get_sparsity() const
Get an owning reference to the sparsity pattern.
void print_sparse(std::ostream &stream, bool truncate=true) const
Print sparse matrix style.
static void set_width(casadi_int width)
static Matrix< Scalar > deserialize(std::istream &stream)
Build Sparsity from serialization.
casadi_int element_hash() const
Returns a number that is unique for a given symbolic scalar.
bool is_commutative() const
Check whether a binary SX is commutative.
void set(const Matrix< Scalar > &m, bool ind1, const Slice &rr)
bool is_symbolic() const
Check if symbolic (Dense)
static std::vector< Matrix< Scalar > > get_free(const Function &f)
Get free.
static casadi_int get_max_depth()
Get the depth to which equalities are being checked for simplifications.
Matrix< Scalar > operator+() const
bool is_smooth() const
Check if smooth.
static std::string type_name()
Get name of the class.
static Matrix< Scalar > nan(const Sparsity &sp)
create a matrix with all nan
bool is_minus_one() const
check if the matrix is -1 (note that false negative answers are possible)
void to_file(const std::string &filename, const std::string &format="") const
static void set_scientific(bool scientific)
static Matrix< Scalar > triplet(const std::vector< casadi_int > &row, const std::vector< casadi_int > &col, const Matrix< Scalar > &d)
Construct a sparse matrix from triplet form.
void disp(std::ostream &stream, bool more=false) const
Print a representation of the object.
static Matrix< Scalar > rand(casadi_int nrow=1, casadi_int ncol=1)
Create a matrix with uniformly distributed random numbers.
bool __nonzero__() const
Returns the truth value of a Matrix.
bool is_eye() const
check if the matrix is an identity matrix (note that false negative answers
bool is_op(casadi_int op) const
Is it a certain operation.
void erase(const std::vector< casadi_int > &rr, const std::vector< casadi_int > &cc, bool ind1=false)
Erase a submatrix (leaving structural zeros in its place)
static void rng(casadi_int seed)
Seed the random number generator.
std::vector< Scalar > get_elements() const
Get all elements.
static std::vector< Matrix< Scalar > > get_input(const Function &f)
Get function input.
Matrix< Scalar > dep(casadi_int ch=0) const
Get expressions of the children of the expression.
bool is_zero() const
check if the matrix is 0 (note that false negative answers are possible)
static Matrix< Scalar > inf(const Sparsity &sp)
create a matrix with all inf
std::string serialize() const
Serialize.
void enlarge(casadi_int nrow, casadi_int ncol, const std::vector< casadi_int > &rr, const std::vector< casadi_int > &cc, bool ind1=false)
Enlarge matrix.
void print_dense(std::ostream &stream, bool truncate=true) const
Print dense matrix-stype.
bool is_constant() const
Check if the matrix is constant (note that false negative answers are possible)
void reserve(casadi_int nnz)
void export_code(const std::string &lang, std::ostream &stream=casadi::uout(), const Dict &options=Dict()) const
Export matrix in specific language.
casadi_int op() const
Get operation type.
static Matrix< Scalar > eye(casadi_int n)
create an n-by-n identity matrix
bool is_valid_input() const
Check if matrix can be used to define function inputs.
void set_nz(const Matrix< Scalar > &m, bool ind1, const Slice &k)
bool is_integer() const
Check if the matrix is integer-valued.
Matrix< Scalar > operator-() const
void print_vector(std::ostream &stream, bool truncate=true) const
Print vector-style.
casadi_int n_dep() const
Get the number of dependencies of a binary SXElem.
std::string get_str(bool more=false) const
Get string representation.
Matrix< Scalar > printme(const Matrix< Scalar > &y) const
bool is_leaf() const
Check if SX is a leaf of the SX graph.
void get_nz(Matrix< Scalar > &m, bool ind1, const Slice &k) const
std::string name() const
Get name (only if symbolic scalar)
std::vector< Scalar > get_nonzeros() const
Get all nonzeros.
void print_scalar(std::ostream &stream) const
Print scalar.
static Matrix< double > from_file(const std::string &filename, const std::string &format_hint="")
Class representing a Slice.
std::vector< casadi_int > all() const
Get a vector of indices.
casadi_int scalar(casadi_int len) const
Get scalar (if is_scalar)
bool is_scalar(casadi_int len) const
Is the slice a scalar.
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 sub(const std::vector< casadi_int > &rr, const std::vector< casadi_int > &cc, std::vector< casadi_int > &mapping, bool ind1=false) const
Get a submatrix.
casadi_int numel() const
The total number of elements, including structural zeros, i.e. size2()*size1()
casadi_int size1() const
Get the number of rows.
static Sparsity dense(casadi_int nrow, casadi_int ncol=1)
Create a dense rectangular sparsity pattern *.
static Sparsity diag(casadi_int nrow)
Create diagonal sparsity pattern *.
Sparsity T() const
Transpose the matrix.
bool is_column() const
Check if the pattern is a column vector (i.e. size2()==1)
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 *.
casadi_int nnz() const
Get the number of (structural) non-zeros.
casadi_int size2() const
Get the number of columns.
casadi_int row(casadi_int el) const
Get the row of a non-zero element.
bool is_empty(bool both=false) const
Check if the sparsity is empty.
std::pair< casadi_int, casadi_int > size() const
Get the shape.
static bool is_almost_zero(const T &val, double tol)
static bool is_constant(const T &val)
static bool is_equal(const T &x, const T &y, casadi_int depth)
static bool is_one(const T &val)
static bool is_integer(const T &val)
static bool is_minus_one(const T &val)
static bool is_zero(const T &val)
void einstein_eval(casadi_int n_iter, const std::vector< casadi_int > &iter_dims, const std::vector< casadi_int > &strides_a, const std::vector< casadi_int > &strides_b, const std::vector< casadi_int > &strides_c, const T *a_in, const T *b_in, T *c_in)
casadi_int einstein_process(const T &A, const T &B, const T &C, const std::vector< casadi_int > &dim_a, const std::vector< casadi_int > &dim_b, const std::vector< casadi_int > &dim_c, const std::vector< casadi_int > &a, const std::vector< casadi_int > &b, const std::vector< casadi_int > &c, std::vector< casadi_int > &iter_dims, std::vector< casadi_int > &strides_a, std::vector< casadi_int > &strides_b, std::vector< casadi_int > &strides_c)
bool is_monotone(const std::vector< T > &v)
Check if the vector is monotone.
GenericType::Dict Dict
C++ equivalent of Python's dict or MATLAB's struct.
CASADI_EXPORT std::vector< casadi_int > complement(const std::vector< casadi_int > &v, casadi_int size)
Returns the list of all i in [0, size[ not found in supplied list.
bool is_regular(const std::vector< T > &v)
Checks if array does not contain NaN or Inf.
Slice CASADI_EXPORT to_slice(const IM &x, bool ind1=false)
Convert IM to Slice.