27 #include "sparsity_internal.hpp"
29 #include "casadi_misc.hpp"
30 #include "serializing_stream.hpp"
31 #include "filesystem_impl.hpp"
34 #define CASADI_THROW_ERROR(FNAME, WHAT) \
35 throw CasadiException("Error in Sparsity::" FNAME " at " + CASADI_WHERE + ":\n"\
41 class EmptySparsity :
public Sparsity {
44 const casadi_int
colind[1] = {0};
45 own(
new SparsityInternal(0, 0, colind,
nullptr));
49 class ScalarSparsity :
public Sparsity {
52 const casadi_int
colind[2] = {0, 1};
53 const casadi_int
row[1] = {0};
54 own(
new SparsityInternal(1, 1, colind, row));
58 class ScalarSparseSparsity :
public Sparsity {
60 ScalarSparseSparsity() {
61 const casadi_int
colind[2] = {0, 0};
62 const casadi_int
row[1] = {0};
63 own(
new SparsityInternal(1, 1, colind, row));
69 casadi_assert_dev(dummy==0);
79 casadi_assert_dev(nrow>=0);
80 casadi_assert_dev(ncol>=0);
81 std::vector<casadi_int>
row,
colind(ncol+1, 0);
86 casadi_assert_dev(rc.first>=0);
87 casadi_assert_dev(rc.second>=0);
88 std::vector<casadi_int>
row,
colind(rc.second+1, 0);
89 assign_cached(rc.first, rc.second,
colind,
row);
93 const std::vector<casadi_int>& row,
bool order_rows) {
94 casadi_assert_dev(nrow>=0);
95 casadi_assert_dev(ncol>=0);
96 assign_cached(nrow, ncol,
colind,
row, order_rows);
100 const casadi_int* colind,
const casadi_int* row,
bool order_rows) {
101 casadi_assert_dev(nrow>=0);
102 casadi_assert_dev(ncol>=0);
104 *
this =
dense(nrow, ncol);
108 assign_cached(nrow, ncol, colindv, rowv, order_rows);
125 return (*this)->size1();
129 return (*this)->size2();
133 return (*this)->numel();
138 r *=
static_cast<double>(
nnz());
139 r /=
static_cast<double>(
size1());
140 r /=
static_cast<double>(
size2());
145 return (*this)->is_empty(both);
149 return (*this)->nnz();
153 return (*this)->size();
158 case 1:
return size1();
159 case 2:
return size2();
161 casadi_error(
"Axis must be 1 or 2.");
165 return (*this)->row();
169 return (*this)->colind();
173 if (el<0 || el>=
nnz()) {
174 throw std::out_of_range(
"Sparsity::row: Index " +
str(el)
175 +
" out of range [0," +
str(
nnz()) +
")");
181 if (cc<0 || cc>
size2()) {
182 throw std::out_of_range(
"Sparsity::colind: Index "
183 +
str(cc) +
" out of range [0," +
str(
size2()) +
"]");
190 *
this = (*this)->_resize(nrow, ncol);
196 if (rr<0) rr +=
size1();
197 if (cc<0) cc +=
size2();
200 casadi_assert(rr>=0 && rr<
size1(),
"Row index out of bounds");
201 casadi_assert(cc>=0 && cc<
size2(),
"Column index out of bounds");
212 std::vector<casadi_int> rowv(
nnz+1);
216 for (casadi_int c=cc; c<
size2; ++c) colindv[c+1]++;
218 return rowv.size()-1;
224 if (
row[ind] == rr) {
226 }
else if (
row[ind] > rr) {
233 rowv.insert(rowv.begin()+ind, rr);
234 for (casadi_int c=cc+1; c<
size2+1; ++c) colindv[c]++;
242 return get_nz(rr, cc)!=-1;
247 return (*this)->get_nz(rr, cc);
256 casadi_assert_dev(x.
nnz()==sp.
nnz());
265 const std::vector<casadi_int>& cc)
const {
266 return (*this)->get_nz(rr, cc);
270 return (*this)->is_scalar(scalar_and_dense);
274 return (*this)->is_dense();
278 return (*this)->is_diag();
282 return (*this)->is_row();
286 return (*this)->is_column();
290 return (*this)->is_vector();
294 return (*this)->is_square();
298 return (*this)->is_permutation();
302 return (*this)->is_selection(allow_empty);
306 return (*this)->is_orthonormal(allow_empty);
310 return (*this)->is_orthonormal_rows(allow_empty);
314 return (*this)->is_orthonormal_columns(allow_empty);
318 return (*this)->is_symmetric();
322 return (*this)->is_tril(strictly);
326 return (*this)->is_triu(strictly);
330 std::vector<casadi_int>& mapping,
bool ind1)
const {
331 return (*this)->
sub(rr, *sp, mapping, ind1);
335 std::vector<casadi_int>& mapping,
bool ind1)
const {
336 return (*this)->
sub(rr, cc, mapping, ind1);
340 const std::vector<casadi_int>& cc,
bool ind1) {
341 std::vector<casadi_int> mapping;
342 *
this = (*this)->_erase(rr, cc, ind1, mapping);
346 std::vector<casadi_int>
Sparsity::erase(
const std::vector<casadi_int>& rr,
bool ind1) {
347 std::vector<casadi_int> mapping;
348 *
this = (*this)->_erase(rr, ind1, mapping);
353 return (*this)->nnz_lower(strictly);
357 return (*this)->nnz_upper(strictly);
361 return (*this)->nnz_diag();
365 return (*this)->get_colind();
369 return (*this)->get_col();
373 return (*this)->get_row();
391 return (*this)->
transpose(mapping, invert_mapping);
400 std::vector<unsigned char>& mapping)
const {
401 return (*this)->
combine(y, f0x_is_zero, fx0_is_zero, mapping);
405 bool fx0_is_zero)
const {
406 return (*this)->
combine(y, f0x_is_zero, fx0_is_zero);
410 return (*this)->
combine(y,
false,
false, mapping);
414 return (*this)->
combine(y,
false,
false);
418 std::vector<unsigned char>& mapping)
const {
419 return (*this)->
combine(y,
true,
true, mapping);
423 return (*this)->
combine(y,
true,
true);
427 return (*this)->is_subset(rhs);
431 const std::string& ) {
434 "Matrix product with incompatible dimensions. Lhs is "
435 + x.
dim() +
" and rhs is " + y.
dim() +
".");
441 return (*this)->is_stacked(y, n);
445 return (*this)->is_equal(y);
449 const std::vector<casadi_int>& row)
const {
450 return (*this)->is_equal(nrow, ncol,
colind,
row);
454 const casadi_int* colind,
const casadi_int* row)
const {
455 return (*this)->is_equal(nrow, ncol,
colind,
row);
463 std::vector< unsigned char > mapping;
480 "Sparsity::append: Dimension mismatch. "
481 "You attempt to append a shape " + sp.
dim()
482 +
" to a shape " +
dim()
483 +
". The number of columns must match.");
487 }
else if (
size1()==0) {
509 "Sparsity::appendColumns: Dimension mismatch. You attempt to "
510 "append a shape " + sp.
dim() +
" to a shape "
511 +
dim() +
". The number of rows must match.");
515 }
else if (
size2()==0) {
531 static ScalarSparsity ret;
536 static ScalarSparseSparsity ret;
541 static EmptySparsity ret;
546 const std::vector<casadi_int>& cc,
bool ind1) {
552 casadi_assert_dev(cc.size() ==
size2());
556 *
this = (*this)->_enlargeColumns(ncol, cc, ind1);
561 casadi_assert_dev(rr.size() ==
size1());
565 *
this = (*this)->_enlargeRows(nrow, rr, ind1);
571 casadi_int n = std::min(nrow, ncol);
574 std::vector<casadi_int>
colind(ncol+1, n);
575 for (casadi_int cc=0; cc<n; ++cc)
colind[cc] = cc;
578 std::vector<casadi_int>
row =
range(n);
589 return (*this)->dim(with_nz);
601 return "[" +
dim(
false) +
"]";
604 return "[" +
dim(
true) +
"]";
609 return (*this)->repr_el(k);
624 "LDL factorization requires a symmetric matrix");
630 std::vector<casadi_int> tmp;
633 return Aperm.
ldl(tmp,
false);
636 casadi_int n=
size1();
640 std::vector<casadi_int> w(3*n);
642 std::vector<casadi_int> parent(n);
644 std::vector<casadi_int> L_colind(1+n);
647 std::vector<casadi_int> L_row(L_colind.back());
651 return Sparsity(n, n, L_colind, L_row,
true).T();
656 std::vector<casadi_int>& pc,
bool amd)
const {
665 std::vector<casadi_int> tmp;
668 Aperm.
qr_sparse(V, R, prinv, tmp,
false);
676 std::vector<casadi_int> leftmost(
size1);
677 std::vector<casadi_int> parent(
size2);
679 std::vector<casadi_int> iw(
size1 + 7*
size2 + 1);
682 casadi_int nrow_ext, v_nnz, r_nnz;
685 &nrow_ext, &v_nnz, &r_nnz,
get_ptr(iw));
688 std::vector<casadi_int> sp_v(2 +
size2 + 1 + v_nnz);
689 std::vector<casadi_int> sp_r(2 +
size2 + 1 + r_nnz);
693 prinv.resize(nrow_ext);
698 casadi_int
Sparsity::dfs(casadi_int j, casadi_int top, std::vector<casadi_int>& xi,
699 std::vector<casadi_int>& pstack,
700 const std::vector<casadi_int>& pinv,
701 std::vector<bool>& marked)
const {
702 return (*this)->dfs(j, top, xi, pstack, pinv, marked);
705 casadi_int
Sparsity::scc(std::vector<casadi_int>& index, std::vector<casadi_int>& offset)
const {
706 return (*this)->scc(index,
offset);
710 return (*this)->amd();
713 casadi_int
Sparsity::btf(std::vector<casadi_int>& rowperm, std::vector<casadi_int>& colperm,
714 std::vector<casadi_int>& rowblock, std::vector<casadi_int>& colblock,
715 std::vector<casadi_int>& coarse_rowblock,
716 std::vector<casadi_int>& coarse_colblock)
const {
718 return (*this)->btf(rowperm, colperm, rowblock, colblock,
719 coarse_rowblock, coarse_colblock);
720 }
catch (std::exception &e) {
721 CASADI_THROW_ERROR(
"btf", e.what());
726 (*this)->spsolve(
X,
B, tr);
730 return (*this)->rowsSequential(strictly);
734 *
this = (*this)->_removeDuplicates(mapping);
738 std::vector<casadi_int> loc;
744 (*this)->find(loc, ind1);
748 (*this)->get_nz(indices);
760 const Dict& opts)
const {
763 }
catch (std::exception &e) {
764 CASADI_THROW_ERROR(
"star_coloring_new", e.what());
777 return (*this)->largest_first();
786 (*this)->spy_matlab(mfile);
790 const Dict& options)
const {
791 (*this)->export_code(lang, stream, options);
795 (*this)->spy(stream);
799 return (*this)->is_transpose(*y);
803 return (*this)->is_reshape(*y);
807 std::vector<casadi_int>& col)
const {
808 return (*this)->is_compactible(
row, col);
812 return (*this)->hash();
815 void Sparsity::assign_cached(casadi_int nrow, casadi_int ncol,
816 const std::vector<casadi_int>& colind,
817 const std::vector<casadi_int>& row,
bool order_rows) {
818 casadi_assert_dev(
colind.size()==ncol+1);
819 casadi_assert_dev(
row.size()==
colind.back());
823 void Sparsity::assign_cached(casadi_int nrow, casadi_int ncol,
824 const casadi_int* colind,
const casadi_int* row,
bool order_rows) {
826 if (ncol==0 && nrow==0) {
830 }
else if (ncol==1 && nrow==1) {
843 casadi_assert(
colind[0]==0,
844 "Compressed Column Storage is not sane. "
845 "First element of colind must be zero.");
848 for (casadi_int c=0; c<ncol; c++) {
850 "Compressed Column Storage is not sane. "
851 "colind must be monotone.");
855 bool rows_ordered =
true;
856 for (casadi_int c=0; c<ncol; ++c) {
857 casadi_int last_r = -1;
859 casadi_int r =
row[k];
861 casadi_assert(r>=0 && r<nrow,
862 "Compressed Column Storage is not sane.\n"
863 "row[ " +
str(k) +
" == " +
str(r) +
" not in range "
864 "[0, " +
str(nrow) +
")");
866 if (r<=last_r) rows_ordered =
false;
873 casadi_assert(order_rows,
874 "Compressed Column Storage is not sane.\n"
875 "Row indices not strictly monotonically increasing for each "
876 "column and reordering is not enabled.");
880 std::vector<casadi_int> col(
nnz);
881 for (casadi_int c=0; c<ncol; ++c) {
882 for (casadi_int k=
colind[c]; k<
colind[c+1]; ++k) col[k] = c;
892 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
894 std::lock_guard<std::mutex> lock(cachingmap_mtx);
901 casadi_int bucket_count_before = cache.bucket_count();
904 if (bucket_count_before>0) {
907 std::pair<CachingMap::iterator, CachingMap::iterator> eq = cache.equal_range(h);
910 for (CachingMap::iterator i=eq.first; i!=eq.second; ++i) {
913 WeakRef& wref = i->second;
916 SharedObject ref_shared;
919 if (wref.shared_if_alive(ref_shared)) {
922 Sparsity ref = shared_cast<Sparsity>(ref_shared);
925 if (ref.is_equal(nrow, ncol,
colind,
row)) {
938 CachingMap::iterator j=i;
940 for (; j!=eq.second; ++j) {
943 SharedObject ref_shared;
944 if (j->second.shared_if_alive(ref_shared)) {
947 Sparsity ref = shared_cast<Sparsity>(ref_shared);
950 if (ref.is_equal(nrow, ncol,
colind,
row)) {
973 cache.insert(std::pair<std::size_t, WeakRef>(h, *
this));
976 casadi_int bucket_count_after = cache.bucket_count();
979 if (bucket_count_before!=bucket_count_after) {
980 CachingMap::const_iterator i=cache.begin();
981 while (i!=cache.end()) {
982 if (!i->second.alive()) {
991 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
992 std::mutex Sparsity::cachingmap_mtx;
996 return x->
_tril(includeDiagonal);
1000 return x->
_triu(includeDiagonal);
1004 return (*this)->get_lower();
1008 return (*this)->get_upper();
1012 std::size_t
hash_sparsity(casadi_int nrow, casadi_int ncol,
const std::vector<casadi_int>& colind,
1013 const std::vector<casadi_int>& row) {
1018 const casadi_int* colind,
const casadi_int* row) {
1029 casadi_assert_dev(nrow>=0);
1030 casadi_assert_dev(ncol>=0);
1032 std::vector<casadi_int>
colind(ncol+1);
1033 for (casadi_int cc=0; cc<ncol+1; ++cc)
colind[cc] = cc*nrow;
1036 std::vector<casadi_int>
row(ncol*nrow);
1037 for (casadi_int cc=0; cc<ncol; ++cc)
1038 for (casadi_int rr=0; rr<nrow; ++rr)
1039 row[rr+cc*nrow] = rr;
1045 casadi_assert(n>=0,
"Sparsity::upper expects a positive integer as argument");
1046 casadi_int nrow=n, ncol=n;
1049 row.reserve((n*(n+1))/2);
1053 for (casadi_int cc=0; cc<ncol; ++cc) {
1055 for (casadi_int rr=0; rr<=cc; ++rr) {
1066 casadi_assert(n>=0,
"Sparsity::lower expects a positive integer as argument");
1067 casadi_int nrow=n, ncol=n;
1070 row.reserve((n*(n+1))/2);
1074 for (casadi_int cc=0; cc<ncol; ++cc) {
1076 for (casadi_int rr=cc; rr<nrow; ++rr) {
1087 casadi_assert(n>=0,
"Sparsity::band expects a positive integer as argument");
1088 casadi_assert((p<0? -p : p)<n,
1089 "Sparsity::band: position of band schould be smaller then size argument");
1091 casadi_int nc = n-(p<0? -p : p);
1093 std::vector< casadi_int >
row(nc);
1095 casadi_int
offset = std::max(p, casadi_int(0));
1096 for (casadi_int i=0;i<nc;i++) {
1100 std::vector< casadi_int >
colind(n+1);
1102 offset = std::min(p, casadi_int(0));
1103 for (casadi_int i=0;i<n+1;i++) {
1104 colind[i] = std::max(std::min(i+
offset, nc), casadi_int(0));
1114 for (casadi_int i=-p;i<=p;++i) {
1121 std::vector<casadi_int>
row(1, el),
colind(2);
1128 casadi_int nrow, casadi_int ncol) {
1129 std::vector<casadi_int> all_rows, all_cols;
1130 all_rows.reserve(
row.size()*col.size());
1131 all_cols.reserve(
row.size()*col.size());
1132 for (std::vector<casadi_int>::const_iterator c_it=col.begin(); c_it!=col.end(); ++c_it) {
1133 casadi_assert(*c_it>=0 && *c_it<ncol,
"Sparsity::rowcol: Column index out of bounds");
1134 for (std::vector<casadi_int>::const_iterator r_it=
row.begin(); r_it!=
row.end(); ++r_it) {
1135 casadi_assert(*r_it>=0 && *r_it<nrow,
"Sparsity::rowcol: Row index out of bounds");
1136 all_rows.push_back(*r_it);
1137 all_cols.push_back(*c_it);
1144 const std::vector<casadi_int>& col, std::vector<casadi_int>& mapping,
1145 bool invert_mapping) {
1147 casadi_assert_dev(nrow>=0);
1148 casadi_assert_dev(ncol>=0);
1149 casadi_assert(col.size()==
row.size(),
"inconsistent lengths");
1152 std::vector<casadi_int> r_colind(ncol+1, 0);
1153 std::vector<casadi_int> r_row;
1154 r_row.reserve(
row.size());
1157 casadi_int last_col=-1, last_row=-1;
1158 bool perfectly_ordered=
true;
1159 for (casadi_int k=0; k<col.size(); ++k) {
1161 casadi_assert(col[k]>=0 && col[k]<ncol,
1162 "Column index (" +
str(col[k]) +
") out of bounds [0," +
str(ncol) +
"[");
1163 casadi_assert(
row[k]>=0 &&
row[k]<nrow,
1164 "Row index out of bounds (" +
str(
row[k]) +
") out of bounds [0," +
str(nrow) +
"[");
1167 perfectly_ordered = perfectly_ordered && (col[k]<last_col ||
1168 (col[k]==last_col &&
row[k]<=last_row));
1174 if (perfectly_ordered) {
1176 r_row.resize(
row.size());
1177 std::copy(
row.begin(),
row.end(), r_row.begin());
1181 for (casadi_int i=0; i<ncol; ++i) {
1182 while (el<col.size() && col[el]==i) el++;
1187 mapping.resize(
row.size());
1188 for (casadi_int k=0; k<
row.size(); ++k) mapping[k] = k;
1191 return Sparsity(nrow, ncol, r_colind, r_row);
1195 std::vector<casadi_int>& mapping1 = invert_mapping ? r_row : mapping;
1196 std::vector<casadi_int>& mapping2 = invert_mapping ? mapping : r_row;
1199 mapping1.reserve(std::max(nrow+1,
static_cast<casadi_int
>(col.size())));
1202 std::vector<casadi_int>& rowcount = mapping1;
1203 rowcount.resize(nrow+1);
1204 std::fill(rowcount.begin(), rowcount.end(), 0);
1205 for (std::vector<casadi_int>::const_iterator it=
row.begin(); it!=
row.end(); ++it) {
1210 for (casadi_int i=0; i<nrow; ++i) {
1211 rowcount[i+1] += rowcount[i];
1215 mapping2.resize(
row.size());
1216 for (casadi_int k=0; k<
row.size(); ++k) {
1217 mapping2[rowcount[
row[k]]++] = k;
1222 std::vector<casadi_int>& colcount = r_colind;
1224 for (std::vector<casadi_int>::const_iterator it=mapping2.begin(); it!=mapping2.end(); ++it) {
1225 colcount[col[*it]+1]++;
1229 for (casadi_int i=0; i<ncol; ++i) {
1230 colcount[i+1] += colcount[i];
1234 mapping1.resize(col.size());
1235 for (std::vector<casadi_int>::const_iterator it=mapping2.begin(); it!=mapping2.end(); ++it) {
1236 mapping1[colcount[col[*it]]++] = *it;
1240 casadi_int r_el = 0;
1241 r_row.resize(col.size());
1244 std::vector<casadi_int>::const_iterator it=mapping1.begin();
1248 for (casadi_int i=0; i<ncol; ++i) {
1251 casadi_int j_prev = -1;
1254 while (it!=mapping1.end() && col[*it]==i) {
1257 casadi_int el = *it;
1261 casadi_int j =
row[el];
1267 if (invert_mapping) {
1269 mapping2[el] = r_el-1;
1273 mapping1[r_el-1] = el;
1281 r_colind[i+1] = r_el;
1288 if (!invert_mapping) {
1289 mapping1.resize(r_el);
1292 return Sparsity(nrow, ncol, r_colind, r_row);
1296 const std::vector<casadi_int>& col) {
1297 std::vector<casadi_int> mapping;
1302 const std::vector<casadi_int>& nz,
bool ind1) {
1303 casadi_assert(nrow>0,
"nrow must be >0.");
1304 std::vector<casadi_int>
row(nz.size());
1305 std::vector<casadi_int> col(nz.size());
1306 for (casadi_int i=0;i<nz.size();++i) {
1307 casadi_int k = nz[i];
1317 "is_singular: only defined for square matrices, but got " +
dim());
1327 return (*this)->sp();
1330 Sparsity::operator
const std::vector<casadi_int>&()
const {
1331 return (*this)->sp();
1335 const casadi_int* sp = *
this;
1336 casadi_int nrow = sp[0], ncol = sp[1];
1337 const casadi_int* colind = sp+2, *row = sp+2+ncol+1;
1343 casadi_assert_dev(v.size() >= 2);
1344 casadi_int nrow = v[0];
1345 casadi_int ncol = v[1];
1346 casadi_assert_dev(v.size() >= 2 + ncol+1);
1347 casadi_int
nnz = v[2 + ncol];
1349 bool sparse = v.size() == 2 + ncol+1 +
nnz;
1350 casadi_assert_dev(
dense || sparse);
1357 casadi_assert_dev(v!=
nullptr);
1360 casadi_int nrow = v[0];
1361 casadi_int ncol = v[1];
1362 const casadi_int *
colind = v+2;
1368 if (nrow*ncol ==
nnz) {
1373 const casadi_int *
row = v + 2 + ncol+1;
1376 std::vector<casadi_int>(
row,
row+
nnz), order_rows);
1382 "Sparsity::permutation supplied list is not a permutation.");
1383 std::vector<casadi_int>
colind =
range(p.size()+1);
1392 casadi_assert(
is_permutation(),
"Sparsity::permutation called on non-permutation matrix.");
1401 return (*this)->bw_upper();
1405 return (*this)->bw_lower();
1410 if (sp.empty())
return Sparsity(1, 0);
1411 if (sp.size()==1)
return sp.front();
1414 casadi_int nnz_total = 0;
1415 for (casadi_int i=0; i<sp.size(); ++i) nnz_total += sp[i].
nnz();
1418 std::vector<casadi_int> ret_row, ret_col;
1419 ret_row.reserve(nnz_total);
1420 ret_col.reserve(nnz_total);
1421 casadi_int ret_ncol = 0;
1422 casadi_int ret_nrow = 0;
1423 for (casadi_int i=0; i<sp.size() && ret_nrow==0; ++i)
1424 ret_nrow = sp[i].
size1();
1427 for (std::vector<Sparsity>::const_iterator i=sp.begin(); i!=sp.end(); ++i) {
1429 casadi_int sp_nrow = i->size1();
1430 casadi_int sp_ncol = i->size2();
1431 const casadi_int* sp_colind = i->colind();
1432 const casadi_int* sp_row = i->row();
1433 casadi_assert(sp_nrow==ret_nrow || sp_nrow==0,
1434 "Sparsity::horzcat: Mismatching number of rows");
1437 for (casadi_int cc=0; cc<sp_ncol; ++cc) {
1438 for (casadi_int k=sp_colind[cc]; k<sp_colind[cc+1]; ++k) {
1439 ret_row.push_back(sp_row[k]);
1440 ret_col.push_back(cc + ret_ncol);
1445 ret_ncol += sp_ncol;
1451 casadi_int a_ncol = a.
size2();
1452 casadi_int b_ncol = b.
size2();
1453 casadi_int a_nrow = a.
size1();
1454 casadi_int b_nrow = b.
size1();
1457 const casadi_int* a_colind = a.
colind();
1458 const casadi_int* a_row = a.
row();
1459 const casadi_int* b_colind = b.
colind();
1460 const casadi_int* b_row = b.
row();
1462 std::vector<casadi_int> r_colind(a_ncol*b_ncol+1, 0);
1463 std::vector<casadi_int> r_row(a.
nnz()*b.
nnz());
1465 casadi_int* r_colind_ptr =
get_ptr(r_colind);
1466 casadi_int* r_row_ptr =
get_ptr(r_row);
1471 for (casadi_int a_cc=0; a_cc<a_ncol; ++a_cc) {
1472 casadi_int a_start = a_colind[a_cc];
1473 casadi_int a_stop = a_colind[a_cc+1];
1475 for (casadi_int b_cc=0; b_cc<b_ncol; ++b_cc) {
1476 casadi_int b_start = b_colind[b_cc];
1477 casadi_int b_stop = b_colind[b_cc+1];
1479 for (casadi_int a_el=a_start; a_el<a_stop; ++a_el) {
1480 casadi_int a_r = a_row[a_el];
1482 for (casadi_int b_el=b_start; b_el<b_stop; ++b_el) {
1483 casadi_int b_r = b_row[b_el];
1484 r_row_ptr[i++] = a_r*b_nrow+b_r;
1488 r_colind_ptr[j] = r_colind_ptr[j-1] + (b_stop-b_start)*(a_stop-a_start);
1491 return Sparsity(a_nrow*b_nrow, a_ncol*b_ncol, r_colind, r_row);
1495 casadi_int xrow = sp_x.
size1();
1496 casadi_int xcol = sp_x.
size2();
1497 casadi_assert(xrow > 0 && xcol > 0,
1498 "Sparsity::kron_contract: sp_x must be nonempty");
1499 casadi_assert(sp_m.
size1() % xrow == 0 && sp_m.
size2() % xcol == 0,
1500 "Sparsity::kron_contract: sp_m dims must be multiples of sp_x dims");
1501 casadi_int yrow = sp_m.
size1() / xrow;
1502 casadi_int ycol = sp_m.
size2() / xcol;
1505 casadi_int split_r = inner ? xrow : yrow;
1506 casadi_int split_c = inner ? xcol : ycol;
1508 std::vector<bool> x_dense(xrow * xcol,
false);
1509 const casadi_int* x_colind = sp_x.
colind();
1510 const casadi_int* x_row = sp_x.
row();
1511 for (casadi_int cc = 0; cc < xcol; ++cc) {
1512 for (casadi_int el = x_colind[cc]; el < x_colind[cc+1]; ++el) {
1513 x_dense[cc*xrow + x_row[el]] =
true;
1518 std::vector<bool> y_dense(yrow * ycol,
false);
1519 const casadi_int* m_colind = sp_m.
colind();
1520 const casadi_int* m_row = sp_m.
row();
1521 casadi_int outer_c_count = sp_m.
size2() / split_c;
1522 for (casadi_int outer_c = 0; outer_c < outer_c_count; ++outer_c) {
1523 for (casadi_int inner_c = 0; inner_c < split_c; ++inner_c) {
1524 casadi_int cc = outer_c*split_c + inner_c;
1525 casadi_int y_c = inner ? outer_c : inner_c;
1526 casadi_int x_c = inner ? inner_c : outer_c;
1527 for (casadi_int el = m_colind[cc]; el < m_colind[cc+1]; ++el) {
1528 casadi_int rr = m_row[el];
1529 casadi_int outer_r = rr / split_r;
1530 casadi_int inner_r = rr % split_r;
1531 casadi_int y_r = inner ? outer_r : inner_r;
1532 casadi_int x_r = inner ? inner_r : outer_r;
1533 if (x_dense[x_c*xrow + x_r]) {
1534 y_dense[y_c*yrow + y_r] =
true;
1540 std::vector<casadi_int> y_colind(ycol + 1, 0);
1541 std::vector<casadi_int> y_row;
1542 for (casadi_int j = 0; j < ycol; ++j) {
1543 for (casadi_int i = 0; i < yrow; ++i) {
1544 if (y_dense[j*yrow + i]) y_row.push_back(i);
1546 y_colind[j+1] = y_row.size();
1548 return Sparsity(yrow, ycol, y_colind, y_row);
1553 if (sp.empty())
return Sparsity(0, 1);
1554 if (sp.size()==1)
return sp.front();
1557 casadi_int nnz_total = 0;
1558 for (casadi_int i=0; i<sp.size(); ++i) nnz_total += sp[i].
nnz();
1561 std::vector<casadi_int> ret_row, ret_col;
1562 ret_row.reserve(nnz_total);
1563 ret_col.reserve(nnz_total);
1564 casadi_int ret_nrow = 0;
1565 casadi_int ret_ncol = 0;
1566 for (casadi_int i=0; i<sp.size() && ret_ncol==0; ++i)
1567 ret_ncol = sp[i].
size2();
1570 for (std::vector<Sparsity>::const_iterator i=sp.begin(); i!=sp.end(); ++i) {
1572 casadi_int sp_nrow = i->size1();
1573 casadi_int sp_ncol = i->size2();
1574 const casadi_int* sp_colind = i->colind();
1575 const casadi_int* sp_row = i->row();
1576 casadi_assert(sp_ncol==ret_ncol || sp_ncol==0,
1577 "Sparsity::vertcat: Mismatching number of columns");
1580 for (casadi_int cc=0; cc<sp_ncol; ++cc) {
1581 for (casadi_int k=sp_colind[cc]; k<sp_colind[cc+1]; ++k) {
1582 ret_row.push_back(sp_row[k] + ret_nrow);
1583 ret_col.push_back(cc);
1588 ret_nrow += sp_nrow;
1597 std::vector<casadi_int>
colind(1, 0);
1598 std::vector<casadi_int>
row;
1601 for (casadi_int i=0;i<v.size();++i) {
1602 const casadi_int* colind_ = v[i].colind();
1603 casadi_int ncol = v[i].size2();
1604 const casadi_int* row_ = v[i].row();
1605 casadi_int sz = v[i].nnz();
1606 for (casadi_int k=1; k<ncol+1; ++k) {
1607 colind.push_back(colind_[k]+nz);
1609 for (casadi_int k=0; k<sz; ++k) {
1610 row.push_back(row_[k]+m);
1621 const std::vector<casadi_int>& offset) {
1623 casadi_assert_dev(!
offset.empty());
1624 casadi_assert_dev(
offset.front()==0);
1626 "horzsplit(Sparsity, std::vector<casadi_int>): Last elements of offset "
1627 "(" +
str(
offset.back()) +
") must equal the number of columns "
1632 casadi_int n =
offset.size()-1;
1635 const casadi_int* colind_x = x.
colind();
1636 const casadi_int* row_x = x.
row();
1639 std::vector<Sparsity> ret;
1644 casadi_int ncol, nrow = x.
size1();
1647 for (casadi_int i=0; i<n; ++i) {
1648 casadi_int first_col =
offset[i];
1649 casadi_int last_col =
offset[i+1];
1650 ncol = last_col - first_col;
1654 std::copy(colind_x+first_col, colind_x+last_col+1,
colind.begin());
1655 for (std::vector<casadi_int>::iterator it=
colind.begin()+1; it!=
colind.end(); ++it)
1659 std::copy(row_x+colind_x[first_col], row_x+colind_x[last_col],
row.begin());
1670 const std::vector<casadi_int>& offset) {
1672 for (std::vector<Sparsity>::iterator it=ret.begin(); it!=ret.end(); ++it) {
1679 std::vector< Sparsity > ret;
1680 for (casadi_int i=0; i<v.size(); ++i)
1686 const std::vector<casadi_int>& offset1,
1687 const std::vector<casadi_int>& offset2) {
1689 casadi_assert_dev(!offset1.empty());
1690 casadi_assert_dev(offset1.front()==0);
1691 casadi_assert(offset1.back()==x.
size1(),
1692 "diagsplit(Sparsity, offset1, offset2): Last elements of offset1 "
1693 "(" +
str(offset1.back()) +
") must equal the number of rows "
1695 casadi_assert(offset2.back()==x.
size2(),
1696 "diagsplit(Sparsity, offset1, offset2): Last elements of offset2 "
1697 "(" +
str(offset2.back()) +
") must equal the number of rows "
1701 casadi_assert_dev(offset1.size()==offset2.size());
1704 casadi_int n = offset1.size()-1;
1707 std::vector<Sparsity> ret;
1712 for (casadi_int i=0; i<n; ++i) {
1713 ret.push_back(x2(
Slice(offset1[i], offset1[i+1]),
1714 Slice(offset2[i], offset2[i+1])).sparsity());
1729 std::vector<casadi_int> rowperm, colperm, rowblock, colblock, coarse_rowblock, coarse_colblock;
1730 x.
btf(rowperm, colperm, rowblock, colblock, coarse_rowblock, coarse_colblock);
1731 return coarse_colblock.at(3);
1734 Sparsity::operator
const casadi_int*()
const {
1735 return &(*this)->sp().front();
1740 casadi_assert(A.
size1()==x.
size2(),
"Dimension error. Got " + x.
dim()
1741 +
" times " + A.
dim() +
".");
1743 casadi_int n_row = A.
size2();
1744 casadi_int n_col = x.
size1();
1747 std::vector<bool> Bwork(n_col);
1748 std::vector<casadi_int> Iwork(n_row+1+n_col);
1750 const casadi_int* Aj = A.
row();
1751 const casadi_int* Ap = A.
colind();
1752 const casadi_int* Bj = x.
row();
1753 const casadi_int* Bp = x.
colind();
1754 casadi_int *Cp =
get_ptr(Iwork);
1755 casadi_int *mask = Cp+n_row+1;
1759 std::fill(mask, mask+n_col, -1);
1763 for (casadi_int i = 0; i < n_row; i++) {
1764 casadi_int row_nnz = 0;
1765 for (casadi_int jj = Ap[i]; jj < Ap[i+1]; jj++) {
1766 casadi_int j = Aj[jj];
1767 for (casadi_int kk = Bp[j]; kk < Bp[j+1]; kk++) {
1768 casadi_int k = Bj[kk];
1775 casadi_int next_nnz =
nnz + row_nnz;
1781 casadi_int *next =
get_ptr(Iwork) + n_row+1;
1782 std::fill(next, next+n_col, -1);
1783 std::vector<bool> & sums = Bwork;
1784 std::fill(sums.begin(), sums.end(),
false);
1787 for (casadi_int i = 0; i < n_row; i++) {
1788 casadi_int head = -2;
1789 casadi_int length = 0;
1790 casadi_int jj_start = Ap[i];
1791 casadi_int jj_end = Ap[i+1];
1792 for (casadi_int jj = jj_start; jj < jj_end; jj++) {
1793 casadi_int j = Aj[jj];
1794 casadi_int kk_start = Bp[j];
1795 casadi_int kk_end = Bp[j+1];
1796 for (casadi_int kk = kk_start; kk < kk_end; kk++) {
1797 casadi_int k = Bj[kk];
1799 if (next[k] == -1) {
1806 for (casadi_int jj = 0; jj < length; jj++) {
1810 casadi_int temp = head;
1823 template<
bool COMBINE_AND>
1830 "Dimension error. Got x=" + x_sp.
dim() +
", y=" + y_sp.
dim()
1831 +
" and z=" + z_sp.
dim() +
".");
1834 const casadi_int* y_colind = y_sp.
colind();
1835 const casadi_int* y_row = y_sp.
row();
1836 const casadi_int* x_colind = x_sp.
colind();
1837 const casadi_int* x_row = x_sp.
row();
1838 const casadi_int* z_colind = z_sp.
colind();
1839 const casadi_int* z_row = z_sp.
row();
1842 casadi_int ncol = z_sp.
size2();
1843 for (casadi_int cc=0; cc<ncol; ++cc) {
1845 for (casadi_int kk=z_colind[cc]; kk<z_colind[cc+1]; ++kk) {
1846 w[z_row[kk]] = z[kk];
1850 for (casadi_int kk=y_colind[cc]; kk<y_colind[cc+1]; ++kk) {
1851 casadi_int rr = y_row[kk];
1855 for (casadi_int kk1=x_colind[rr]; kk1<x_colind[rr+1]; ++kk1) {
1856 w[x_row[kk1]] |= COMBINE_AND ? (x[kk1] & yy) : (x[kk1] | yy);
1861 for (casadi_int kk=z_colind[cc]; kk<z_colind[cc+1]; ++kk) {
1862 z[kk] = w[z_row[kk]];
1871 mul_bvec_fwd<false>(x, x_sp, y, y_sp, z, z_sp, w);
1878 mul_bvec_fwd<true>(x, x_sp, y, y_sp, z, z_sp, w);
1888 "Dimension error. Got x=" + x_sp.
dim() +
", y=" + y_sp.
dim()
1889 +
" and z=" + z_sp.
dim() +
".");
1892 const casadi_int* y_colind = y_sp.
colind();
1893 const casadi_int* y_row = y_sp.
row();
1894 const casadi_int* x_colind = x_sp.
colind();
1895 const casadi_int* x_row = x_sp.
row();
1896 const casadi_int* z_colind = z_sp.
colind();
1897 const casadi_int* z_row = z_sp.
row();
1902 casadi_int nrow = z_sp.
size1();
1906 casadi_int ncol = z_sp.
size2();
1907 for (casadi_int cc=0; cc<ncol; ++cc) {
1909 for (casadi_int kk=z_colind[cc]; kk<z_colind[cc+1]; ++kk) {
1910 w[z_row[kk]] = z[kk];
1914 for (casadi_int kk=y_colind[cc]; kk<y_colind[cc+1]; ++kk) {
1915 casadi_int rr = y_row[kk];
1919 for (casadi_int kk1=x_colind[rr]; kk1<x_colind[rr+1]; ++kk1) {
1920 yy |= w[x_row[kk1]];
1921 x[kk1] |= w[x_row[kk1]];
1927 for (casadi_int kk=z_colind[cc]; kk<z_colind[cc+1]; ++kk) {
1928 z[kk] = w[z_row[kk]];
1938 std::vector<unsigned char> mapping;
1939 X.unite(x, mapping);
1942 const casadi_int* Y_colind =
Y.colind();
1943 const casadi_int* Y_row =
Y.row();
1944 std::vector<casadi_int> y_colind(
Y.size2()+1, 0);
1945 std::vector<casadi_int> y_row;
1946 y_row.reserve(
Y.nnz());
1947 casadi_assert_dev(
Y.nnz()==mapping.size());
1951 for (casadi_int cc=0; cc<
Y.size2(); ++cc) {
1952 y_colind[cc+1] = y_colind[cc];
1954 for (casadi_int kk=Y_colind[cc]; kk<Y_colind[cc+1]; ++kk) {
1956 casadi_int e = mapping[i++];
1960 y_row.push_back(Y_row[kk]);
1962 casadi_assert_dev(e==1);
1967 Sparsity ret(
Y.size1(),
Y.size2(), y_colind, y_row,
true);
1979 const std::string& format_hint,
const std::set<std::string>& file_formats) {
1980 if (format_hint.empty()) {
1984 "Extension '" + extension +
"' not recognised. "
1990 "File format hint '" + format_hint +
"' not recognised. "
1999 std::ostream& out = *out_ptr;
2000 if (format==
"mtx") {
2001 out << std::scientific << std::setprecision(std::numeric_limits<double>::digits10 + 1);
2002 out <<
"%%MatrixMarket matrix coordinate pattern general" << std::endl;
2003 out <<
size1() <<
" " <<
size2() <<
" " <<
nnz() << std::endl;
2005 std::vector<casadi_int> col =
get_col();
2007 for (casadi_int k=0;k<
row.size();++k) {
2008 out <<
row[k]+1 <<
" " << col[k]+1 << std::endl;
2011 casadi_error(
"Unknown format '" + format +
"'");
2018 std::istream& in = *in_ptr;
2019 if (format==
"mtx") {
2021 std::vector<casadi_int>
row, col;
2024 while (std::getline(in, line)) {
2026 if (!line.empty() && line.back()==
'\r') line.pop_back();
2027 casadi_assert(line==
"%%MatrixMarket matrix coordinate pattern general",
"Wrong header");
2029 }
else if (line_num==1) {
2030 std::stringstream stream(line);
2038 std::stringstream stream(line);
2048 casadi_error(
"Unknown format '" + format +
"'");
2053 bool with_x_diag,
bool with_lam_g_diag) {
2055 casadi_assert(H.
is_square(),
"H must be square");
2056 casadi_assert(H.
size1() == J.
size2(),
"Dimension mismatch");
2059 if (with_x_diag)
return kkt(H +
diag(H.
size()), J,
false, with_lam_g_diag);
2081 s.
pack(
"SparsityInternal::compressed", std::vector<casadi_int>{});
2088 std::vector<casadi_int> i;
2089 s.
unpack(
"SparsityInternal::compressed", i);
2098 std::stringstream ss;
2104 std::stringstream ss;
Helper class for Serialization.
void unpack(Sparsity &e)
Reconstruct an object from the input stream.
static std::unique_ptr< std::ostream > ofstream_ptr(const std::string &path, std::ios_base::openmode mode=std::ios_base::out)
static std::unique_ptr< std::istream > ifstream_ptr(const std::string &path, std::ios_base::openmode mode=std::ios_base::in, bool fail=true)
static MatType zeros(casadi_int nrow=1, casadi_int ncol=1)
Create a dense matrix or a matrix with specified sparsity with all entries zero.
SharedObjectInternal * get() const
Get a const pointer to the node.
bool is_null() const
Is a null pointer?
void own(SharedObjectInternal *node)
SharedObjectInternal * operator->() const
Access a member function or object.
Helper class for Serialization.
void pack(const Sparsity &e)
Serializes an object to the output stream.
Class representing a Slice.
static std::vector< casadi_int > offset(const std::vector< Sparsity > &v, bool vert=true)
Sparsity get_diag(std::vector< casadi_int > &mapping) const
Get the diagonal of the matrix/create a diagonal matrix.
static void ldl_colind(const casadi_int *sp, casadi_int *parent, casadi_int *l_colind, casadi_int *w)
Calculate the column offsets for the L factor of an LDL^T factorization.
Sparsity makeDense(std::vector< casadi_int > &mapping) const
Make a patten dense.
Sparsity _mtimes(const Sparsity &y) const
Sparsity pattern for a matrix-matrix product (details in public class)
Sparsity pattern_inverse() const
Take the inverse of a sparsity pattern; flip zeros and non-zeros.
static void ldl_row(const casadi_int *sp, const casadi_int *parent, casadi_int *l_colind, casadi_int *l_row, casadi_int *w)
Calculate the row indices for the L factor of an LDL^T factorization.
Sparsity pmult(const std::vector< casadi_int > &p, bool permute_rows=true, bool permute_cols=true, bool invert_permutation=false) const
Permute rows and/or columns.
Sparsity star_coloring_new(std::vector< casadi_int > &which_color, const Dict &opts) const
Perform a star coloring.
Sparsity transpose(std::vector< casadi_int > &mapping, bool invert_mapping=false) const
Transpose the matrix and get the reordering of the non-zero entries,.
Sparsity _appendColumns(const SparsityInternal &sp) const
Append another sparsity patten horizontally.
Sparsity sub(const std::vector< casadi_int > &rr, const std::vector< casadi_int > &cc, std::vector< casadi_int > &mapping, bool ind1) const
Get a submatrix.
Sparsity star_coloring2(casadi_int ordering, casadi_int cutoff) const
An improved distance-2 coloring algorithm.
Sparsity _tril(bool includeDiagonal) const
Get lower triangular part.
Sparsity _appendVector(const SparsityInternal &sp) const
Append another sparsity patten vertically (vectors only)
static void qr_init(const casadi_int *sp, const casadi_int *sp_tr, casadi_int *leftmost, casadi_int *parent, casadi_int *pinv, casadi_int *nrow_ext, casadi_int *v_nnz, casadi_int *r_nnz, casadi_int *w)
Setup QP solver.
Sparsity _triu(bool includeDiagonal) const
Get upper triangular part.
Sparsity uni_coloring(const Sparsity &AT, casadi_int cutoff) const
Perform a unidirectional coloring.
Sparsity T() const
Transpose the matrix.
Sparsity _reshape(casadi_int nrow, casadi_int ncol) const
Reshape a sparsity, order of nonzeros remains the same.
static void qr_sparsities(const casadi_int *sp_a, casadi_int nrow_ext, casadi_int *sp_v, casadi_int *sp_r, const casadi_int *leftmost, const casadi_int *parent, const casadi_int *pinv, casadi_int *iw)
Get the row indices for V and R in QR factorization.
Sparsity combine(const Sparsity &y, bool f0x_is_zero, bool function0_is_zero, std::vector< unsigned char > &mapping) const
Sparsity star_coloring(casadi_int ordering, casadi_int cutoff) const
A greedy distance-2 coloring algorithm.
static void etree(const casadi_int *sp, casadi_int *parent, casadi_int *w, casadi_int ata)
Calculate the elimination tree for a matrix.
std::vector< casadi_int > get_upper() const
Get nonzeros in upper triangular part.
casadi_int get_nz(casadi_int rr, casadi_int cc) const
Get the index of an existing non-zero element.
Sparsity pmult(const std::vector< casadi_int > &p, bool permute_rows=true, bool permute_columns=true, bool invert_permutation=false) const
Permute rows and/or columns.
Sparsity(casadi_int dummy=0)
Default constructor.
static Sparsity banded(casadi_int n, casadi_int p)
Create banded square sparsity pattern.
bool is_subset(const Sparsity &rhs) const
Is subset?
static Sparsity upper(casadi_int n)
Create a upper triangular square sparsity pattern *.
static const Sparsity & getScalar()
(Dense) scalar
bool is_stacked(const Sparsity &y, casadi_int n) const
Check if pattern is horizontal repeat of another.
Sparsity makeDense(std::vector< casadi_int > &mapping) const
Make a patten dense.
Sparsity intersect(const Sparsity &y, std::vector< unsigned char > &mapping) const
Intersection of two sparsity patterns.
static Sparsity vertcat(const std::vector< Sparsity > &sp)
Enlarge matrix.
bool is_vector() const
Check if the pattern is a row or column vector.
std::vector< casadi_int > erase(const std::vector< casadi_int > &rr, const std::vector< casadi_int > &cc, bool ind1=false)
Erase rows and/or columns of a 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()
static CachingMap & getCache()
Cached sparsity patterns.
std::unordered_multimap< std::size_t, WeakRef > CachingMap
Enlarge matrix.
casadi_int size1() const
Get the number of rows.
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.
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.
static Sparsity permutation(const std::vector< casadi_int > &p, bool invert=false)
Construct a permutation matrix P from a permutation vector p.
casadi_int dfs(casadi_int j, casadi_int top, std::vector< casadi_int > &xi, std::vector< casadi_int > &pstack, const std::vector< casadi_int > &pinv, std::vector< bool > &marked) const
Depth-first search on the adjacency graph of the sparsity.
static std::set< std::string > file_formats
Enlarge matrix.
static const Sparsity & getScalarSparse()
(Sparse) scalar
Sparsity star_coloring(casadi_int ordering=1, casadi_int cutoff=std::numeric_limits< casadi_int >::max()) const
Perform a star coloring of a symmetric matrix:
static Sparsity rowcol(const std::vector< casadi_int > &row, const std::vector< casadi_int > &col, casadi_int nrow, casadi_int ncol)
Construct a block sparsity pattern from (row, col) vectors.
Sparsity pattern_inverse() const
Take the inverse of a sparsity pattern; flip zeros and non-zeros.
static Sparsity diag(casadi_int nrow)
Create diagonal sparsity pattern *.
static Sparsity sum2(const Sparsity &x)
Enlarge matrix.
bool is_orthonormal(bool allow_empty=false) const
Are both rows and columns orthonormal ?
const std::vector< casadi_int > permutation_vector(bool invert=false) const
Construct permutation vector from permutation matrix.
casadi_int nnz_lower(bool strictly=false) const
Number of non-zeros in the lower triangular half,.
casadi_int scc(std::vector< casadi_int > &index, std::vector< casadi_int > &offset) const
Find the strongly connected components of the bigraph defined by the sparsity pattern.
std::string dim(bool with_nz=false) const
Get the dimension as a string.
static Sparsity dense(casadi_int nrow, casadi_int ncol=1)
Create a dense rectangular sparsity pattern *.
static Sparsity triu(const Sparsity &x, bool includeDiagonal=true)
Enlarge matrix.
Sparsity transpose(std::vector< casadi_int > &mapping, bool invert_mapping=false) const
Transpose the matrix and get the reordering of the non-zero entries.
Sparsity T() const
Transpose the matrix.
bool is_column() const
Check if the pattern is a column vector (i.e. size2()==1)
Sparsity unite(const Sparsity &y, std::vector< unsigned char > &mapping) const
Union of two sparsity patterns.
void spsolve(bvec_t *X, bvec_t *B, bool tr) const
Propagate sparsity through a linear solve.
void spy(std::ostream &stream=casadi::uout()) const
Print a textual representation of sparsity.
bool is_compactible(std::vector< casadi_int > &row, std::vector< casadi_int > &col) const
Check if the nonzero pattern is the Cartesian product of a row and a column subset.
bool is_reshape(const Sparsity &y) const
Check if the sparsity is a reshape of another.
void get_crs(std::vector< casadi_int > &rowind, std::vector< casadi_int > &col) const
Get the sparsity in compressed row storage (CRS) format.
static std::string file_format(const std::string &filename, const std::string &format_hint, const std::set< std::string > &file_formats)
Enlarge matrix.
SparsityInternal * get() const
void removeDuplicates(std::vector< casadi_int > &mapping)
Remove duplicate entries.
static Sparsity deserialize(std::istream &stream)
Build Sparsity from serialization.
bool is_scalar(bool scalar_and_dense=false) const
Is scalar?
std::vector< casadi_int > get_lower() const
Get nonzeros in lower triangular part.
bool has_nz(casadi_int rr, casadi_int cc) const
Returns true if the pattern has a non-zero at location rr, cc.
bool is_orthonormal_rows(bool allow_empty=false) const
Are the rows of the pattern orthonormal ?
static Sparsity blockcat(const std::vector< std::vector< Sparsity > > &v)
Enlarge matrix.
void enlargeColumns(casadi_int ncol, const std::vector< casadi_int > &cc, bool ind1=false)
Enlarge the matrix along the second dimension (i.e. insert columns)
static Sparsity create(SparsityInternal *node)
Create from node.
const SparsityInternal * operator->() const
Access a member function or object.
void append(const Sparsity &sp)
Append another sparsity patten vertically (NOTE: only efficient if vector)
casadi_int add_nz(casadi_int rr, casadi_int cc)
Get the index of a non-zero element.
bool is_row() const
Check if the pattern is a row vector (i.e. size1()==1)
Sparsity get_diag(std::vector< casadi_int > &mapping) const
static Sparsity tril(const Sparsity &x, bool includeDiagonal=true)
Enlarge matrix.
std::vector< casadi_int > etree(bool ata=false) const
Calculate the elimination tree.
static Sparsity unit(casadi_int n, casadi_int el)
Create the sparsity pattern for a unit vector of length n and a nonzero on.
bool is_diag() const
Is diagonal?
std::vector< casadi_int > get_col() const
Get the column for each non-zero entry.
static std::vector< Sparsity > vertsplit(const Sparsity &x, const std::vector< casadi_int > &offset)
Enlarge matrix.
Sparsity star_coloring_new(std::vector< casadi_int > &which_color, const Dict &opts=Dict()) const
Perform a star coloring of a symmetric matrix:
static Sparsity reshape(const Sparsity &x, casadi_int nrow, casadi_int ncol)
Enlarge matrix.
bool is_equal(const Sparsity &y) const
static const Sparsity & getEmpty()
Empty zero-by-zero.
static void mul_sparsityR(bvec_t *x, const Sparsity &x_sp, bvec_t *y, const Sparsity &y_sp, bvec_t *z, const Sparsity &z_sp, bvec_t *w)
Propagate sparsity using 0-1 logic through a matrix product,.
static std::vector< Sparsity > horzsplit(const Sparsity &x, const std::vector< casadi_int > &offset)
Enlarge matrix.
void enlargeRows(casadi_int nrow, const std::vector< casadi_int > &rr, bool ind1=false)
Enlarge the matrix along the first dimension (i.e. insert rows)
bool is_tril(bool strictly=false) const
Is lower triangular?
Sparsity combine(const Sparsity &y, bool f0x_is_zero, bool function0_is_zero, std::vector< unsigned char > &mapping) const
Combine two sparsity patterns.
std::vector< casadi_int > amd() const
Approximate minimal degree preordering.
void spy_matlab(const std::string &mfile) const
Generate a script for Matlab or Octave which visualizes.
casadi_int nnz_upper(bool strictly=false) const
Number of non-zeros in the upper triangular half,.
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,.
casadi_int btf(std::vector< casadi_int > &rowperm, std::vector< casadi_int > &colperm, std::vector< casadi_int > &rowblock, std::vector< casadi_int > &colblock, std::vector< casadi_int > &coarse_rowblock, std::vector< casadi_int > &coarse_colblock) const
Calculate the block triangular form (BTF)
std::string serialize() const
Serialize.
bool is_selection(bool allow_empty=false) const
Is this a selection matrix?
std::pair< casadi_int, casadi_int > size() const
Get the shape.
static Sparsity sparsity_cast(const Sparsity &x, const Sparsity &sp)
Enlarge matrix.
Sparsity sparsity_cast_mod(const Sparsity &X, const Sparsity &Y) const
Propagates subset according to sparsity cast.
bool is_permutation() const
Is this a permutation matrix?
std::vector< casadi_int > get_colind() const
Get the column index for each column.
Sparsity ldl(std::vector< casadi_int > &p, bool amd=true) const
Symbolic LDL factorization.
static casadi_int sprank(const Sparsity &x)
Enlarge matrix.
bool is_empty(bool both=false) const
Check if the sparsity is empty.
casadi_int bw_upper() const
Upper half-bandwidth.
const SparsityInternal & operator*() const
Reference to internal structure.
static Sparsity sum1(const Sparsity &x)
Enlarge matrix.
static Sparsity kron(const Sparsity &a, const Sparsity &b)
Enlarge matrix.
bool is_singular() const
Check whether the sparsity-pattern indicates structural singularity.
void export_code(const std::string &lang, std::ostream &stream=casadi::uout(), const Dict &options=Dict()) const
Export matrix in specific language.
void to_file(const std::string &filename, const std::string &format_hint="") const
std::vector< casadi_int > compress(bool canonical=true) const
Compress a sparsity pattern.
static std::vector< Sparsity > diagsplit(const Sparsity &x, const std::vector< casadi_int > &offset1, const std::vector< casadi_int > &offset2)
Enlarge matrix.
void get_triplet(std::vector< casadi_int > &row, std::vector< casadi_int > &col) const
Get the sparsity in sparse triplet format.
static Sparsity horzcat(const std::vector< Sparsity > &sp)
Accessed by SparsityInterface.
static casadi_int norm_0_mul(const Sparsity &x, const Sparsity &A)
Enlarge matrix.
double density() const
The percentage of nonzero.
Sparsity uni_coloring(const Sparsity &AT=Sparsity(), casadi_int cutoff=std::numeric_limits< casadi_int >::max()) const
Perform a unidirectional coloring: A greedy distance-2 coloring algorithm.
Sparsity operator+(const Sparsity &b) const
Union of two sparsity patterns.
static Sparsity diagcat(const std::vector< Sparsity > &v)
Enlarge matrix.
casadi_int nnz_diag() const
Number of non-zeros on the diagonal, i.e. the number of elements (i, j) with j==i.
bool is_transpose(const Sparsity &y) const
Check if the sparsity is the transpose of another.
std::size_t hash() const
Enlarge matrix.
std::vector< casadi_int > get_row() const
Get the row for each non-zero entry.
void appendColumns(const Sparsity &sp)
Append another sparsity patten horizontally.
void get_ccs(std::vector< casadi_int > &colind, std::vector< casadi_int > &row) const
Get the sparsity in compressed column storage (CCS) format.
static Sparsity nonzeros(casadi_int nrow, casadi_int ncol, const std::vector< casadi_int > &nz, bool ind1=SWIG_IND1)
Create a sparsity from nonzeros.
static bool test_cast(const SharedObjectInternal *ptr)
Check if a particular cast is allowed.
static void mul_activityF(const bvec_t *x, const Sparsity &x_sp, const bvec_t *y, const Sparsity &y_sp, bvec_t *z, const Sparsity &z_sp, bvec_t *w)
Propagate signal activity through a matrix product, forward mode.
const casadi_int * colind() const
Get a reference to the colindex of all column element (see class description)
static Sparsity kron_contract(const Sparsity &sp_m, const Sparsity &sp_x, bool inner)
Output sparsity of casadi::KronContract.
static Sparsity lower(casadi_int n)
Create a lower triangular square sparsity pattern *.
bool is_dense() const
Is dense?
bool is_orthonormal_columns(bool allow_empty=false) const
Are the columns of the pattern orthonormal ?
static void mul_sparsityF(const bvec_t *x, const Sparsity &x_sp, const bvec_t *y, const Sparsity &y_sp, bvec_t *z, const Sparsity &z_sp, bvec_t *w)
Propagate sparsity using 0-1 logic through a matrix product,.
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 *.
static Sparsity band(casadi_int n, casadi_int p)
Create a single band in a square sparsity pattern.
static Sparsity kkt(const Sparsity &H, const Sparsity &J, bool with_x_diag=true, bool with_lam_g_diag=true)
Get KKT system sparsity.
void resize(casadi_int nrow, casadi_int ncol)
Resize.
static Sparsity mtimes(const Sparsity &x, const Sparsity &y, const std::string &blas="reference")
Enlarge matrix.
std::string postfix_dim() const
Dimension string as a postfix to a name.
bool is_square() const
Is square?
void qr_sparse(Sparsity &V, Sparsity &R, std::vector< casadi_int > &prinv, std::vector< casadi_int > &pc, bool amd=true) const
Symbolic QR factorization.
static Sparsity from_file(const std::string &filename, const std::string &format_hint="")
static Sparsity compressed(const std::vector< casadi_int > &v, bool order_rows=false)
bool rowsSequential(bool strictly=true) const
Do the rows appear sequentially on each column.
bool is_triu(bool strictly=false) const
Is upper triangular?
std::vector< casadi_int > largest_first() const
Order the columns by decreasing degree.
std::string repr_el(casadi_int k) const
Describe the nonzero location k as a string.
Sparsity star_coloring2(casadi_int ordering=1, casadi_int cutoff=std::numeric_limits< casadi_int >::max()) const
Perform a star coloring of a symmetric matrix:
bool is_symmetric() const
Is symmetric?
casadi_int bw_lower() const
Lower half-bandwidth.
std::vector< casadi_int > range(casadi_int start, casadi_int stop, casadi_int step, casadi_int len)
Range function.
std::vector< casadi_int > invert_permutation(const std::vector< casadi_int > &a)
inverse a permutation vector
unsigned long long bvec_t
void casadi_fill(T1 *x, casadi_int n, T1 alpha)
FILL: x <- alpha.
bool is_monotone(const std::vector< T > &v)
Check if the vector is monotone.
static void mul_bvec_fwd(const bvec_t *x, const Sparsity &x_sp, const bvec_t *y, const Sparsity &y_sp, bvec_t *z, const Sparsity &z_sp, bvec_t *w)
std::string str(const T &v)
String representation, any type.
GenericType::Dict Dict
C++ equivalent of Python's dict or MATLAB's struct.
void hash_combine(std::size_t &seed, T v)
Generate a hash value incrementally (function taken from boost)
std::size_t hash_sparsity(casadi_int nrow, casadi_int ncol, const std::vector< casadi_int > &colind, const std::vector< casadi_int > &row)
Hash a sparsity pattern.
T * get_ptr(std::vector< T > &v)
Get a pointer to the data contained in the vector.
bool is_permutation(const std::vector< casadi_int > &order)
Does the list represent a permutation?
std::string filename(const std::string &path)
Compact representation of a sparsity pattern.