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);
433 "Matrix product with incompatible dimensions. Lhs is "
434 + x.
dim() +
" and rhs is " + y.
dim() +
".");
440 return (*this)->is_stacked(y, n);
444 return (*this)->is_equal(y);
448 const std::vector<casadi_int>& row)
const {
449 return (*this)->is_equal(nrow, ncol,
colind,
row);
453 const casadi_int* colind,
const casadi_int* row)
const {
454 return (*this)->is_equal(nrow, ncol,
colind,
row);
462 std::vector< unsigned char > mapping;
479 "Sparsity::append: Dimension mismatch. "
480 "You attempt to append a shape " + sp.
dim()
481 +
" to a shape " +
dim()
482 +
". The number of columns must match.");
486 }
else if (
size1()==0) {
508 "Sparsity::appendColumns: Dimension mismatch. You attempt to "
509 "append a shape " + sp.
dim() +
" to a shape "
510 +
dim() +
". The number of rows must match.");
514 }
else if (
size2()==0) {
530 static ScalarSparsity ret;
535 static ScalarSparseSparsity ret;
540 static EmptySparsity ret;
545 const std::vector<casadi_int>& cc,
bool ind1) {
551 casadi_assert_dev(cc.size() ==
size2());
555 *
this = (*this)->_enlargeColumns(ncol, cc, ind1);
560 casadi_assert_dev(rr.size() ==
size1());
564 *
this = (*this)->_enlargeRows(nrow, rr, ind1);
570 casadi_int n = std::min(nrow, ncol);
573 std::vector<casadi_int>
colind(ncol+1, n);
574 for (casadi_int cc=0; cc<n; ++cc)
colind[cc] = cc;
577 std::vector<casadi_int>
row =
range(n);
588 return (*this)->dim(with_nz);
600 return "[" +
dim(
false) +
"]";
603 return "[" +
dim(
true) +
"]";
608 return (*this)->repr_el(k);
623 "LDL factorization requires a symmetric matrix");
629 std::vector<casadi_int> tmp;
632 return Aperm.
ldl(tmp,
false);
635 casadi_int n=
size1();
639 std::vector<casadi_int> w(3*n);
641 std::vector<casadi_int> parent(n);
643 std::vector<casadi_int> L_colind(1+n);
646 std::vector<casadi_int> L_row(L_colind.back());
650 return Sparsity(n, n, L_colind, L_row,
true).T();
655 std::vector<casadi_int>& pc,
bool amd)
const {
664 std::vector<casadi_int> tmp;
667 return Aperm.
qr_sparse(V, R, prinv, tmp,
false);
674 std::vector<casadi_int> leftmost(
size1);
675 std::vector<casadi_int> parent(
size2);
677 std::vector<casadi_int> iw(
size1 + 7*
size2 + 1);
680 casadi_int nrow_ext, v_nnz, r_nnz;
683 &nrow_ext, &v_nnz, &r_nnz,
get_ptr(iw));
686 std::vector<casadi_int> sp_v(2 +
size2 + 1 + v_nnz);
687 std::vector<casadi_int> sp_r(2 +
size2 + 1 + r_nnz);
691 prinv.resize(nrow_ext);
696 casadi_int
Sparsity::dfs(casadi_int j, casadi_int top, std::vector<casadi_int>& xi,
697 std::vector<casadi_int>& pstack,
698 const std::vector<casadi_int>& pinv,
699 std::vector<bool>& marked)
const {
700 return (*this)->dfs(j, top, xi, pstack, pinv, marked);
703 casadi_int
Sparsity::scc(std::vector<casadi_int>& index, std::vector<casadi_int>& offset)
const {
704 return (*this)->scc(index,
offset);
708 return (*this)->amd();
711 casadi_int
Sparsity::btf(std::vector<casadi_int>& rowperm, std::vector<casadi_int>& colperm,
712 std::vector<casadi_int>& rowblock, std::vector<casadi_int>& colblock,
713 std::vector<casadi_int>& coarse_rowblock,
714 std::vector<casadi_int>& coarse_colblock)
const {
716 return (*this)->btf(rowperm, colperm, rowblock, colblock,
717 coarse_rowblock, coarse_colblock);
718 }
catch (std::exception &e) {
719 CASADI_THROW_ERROR(
"btf", e.what());
724 (*this)->spsolve(
X,
B, tr);
728 return (*this)->rowsSequential(strictly);
732 *
this = (*this)->_removeDuplicates(mapping);
736 std::vector<casadi_int> loc;
742 (*this)->find(loc, ind1);
746 (*this)->get_nz(indices);
766 return (*this)->largest_first();
775 (*this)->spy_matlab(mfile);
779 const Dict& options)
const {
780 (*this)->export_code(lang, stream, options);
784 (*this)->spy(stream);
788 return (*this)->is_transpose(*y);
792 return (*this)->is_reshape(*y);
796 return (*this)->hash();
799 void Sparsity::assign_cached(casadi_int nrow, casadi_int ncol,
800 const std::vector<casadi_int>& colind,
801 const std::vector<casadi_int>& row,
bool order_rows) {
802 casadi_assert_dev(
colind.size()==ncol+1);
803 casadi_assert_dev(
row.size()==
colind.back());
807 void Sparsity::assign_cached(casadi_int nrow, casadi_int ncol,
808 const casadi_int* colind,
const casadi_int* row,
bool order_rows) {
810 if (ncol==0 && nrow==0) {
814 }
else if (ncol==1 && nrow==1) {
827 casadi_assert(
colind[0]==0,
828 "Compressed Column Storage is not sane. "
829 "First element of colind must be zero.");
832 for (casadi_int c=0; c<ncol; c++) {
834 "Compressed Column Storage is not sane. "
835 "colind must be monotone.");
839 bool rows_ordered =
true;
840 for (casadi_int c=0; c<ncol; ++c) {
841 casadi_int last_r = -1;
843 casadi_int r =
row[k];
845 casadi_assert(r>=0 && r<nrow,
846 "Compressed Column Storage is not sane.\n"
847 "row[ " +
str(k) +
" == " +
str(r) +
" not in range "
848 "[0, " +
str(nrow) +
")");
850 if (r<=last_r) rows_ordered =
false;
857 casadi_assert(order_rows,
858 "Compressed Column Storage is not sane.\n"
859 "Row indices not strictly monotonically increasing for each "
860 "column and reordering is not enabled.");
864 std::vector<casadi_int> col(
nnz);
865 for (casadi_int c=0; c<ncol; ++c) {
866 for (casadi_int k=
colind[c]; k<
colind[c+1]; ++k) col[k] = c;
876 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
878 std::lock_guard<std::mutex> lock(cachingmap_mtx);
885 casadi_int bucket_count_before = cache.bucket_count();
888 if (bucket_count_before>0) {
891 std::pair<CachingMap::iterator, CachingMap::iterator> eq = cache.equal_range(h);
894 for (CachingMap::iterator i=eq.first; i!=eq.second; ++i) {
897 WeakRef& wref = i->second;
900 SharedObject ref_shared;
903 if (wref.shared_if_alive(ref_shared)) {
906 Sparsity ref = shared_cast<Sparsity>(ref_shared);
909 if (ref.is_equal(nrow, ncol,
colind,
row)) {
922 CachingMap::iterator j=i;
924 for (; j!=eq.second; ++j) {
927 SharedObject ref_shared;
928 if (j->second.shared_if_alive(ref_shared)) {
931 Sparsity ref = shared_cast<Sparsity>(ref_shared);
934 if (ref.is_equal(nrow, ncol,
colind,
row)) {
957 cache.insert(std::pair<std::size_t, WeakRef>(h, *
this));
960 casadi_int bucket_count_after = cache.bucket_count();
963 if (bucket_count_before!=bucket_count_after) {
964 CachingMap::const_iterator i=cache.begin();
965 while (i!=cache.end()) {
966 if (!i->second.alive()) {
975 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
976 std::mutex Sparsity::cachingmap_mtx;
980 return x->
_tril(includeDiagonal);
984 return x->
_triu(includeDiagonal);
988 return (*this)->get_lower();
992 return (*this)->get_upper();
996 std::size_t
hash_sparsity(casadi_int nrow, casadi_int ncol,
const std::vector<casadi_int>& colind,
997 const std::vector<casadi_int>& row) {
1002 const casadi_int* colind,
const casadi_int* row) {
1013 casadi_assert_dev(nrow>=0);
1014 casadi_assert_dev(ncol>=0);
1016 std::vector<casadi_int>
colind(ncol+1);
1017 for (casadi_int cc=0; cc<ncol+1; ++cc)
colind[cc] = cc*nrow;
1020 std::vector<casadi_int>
row(ncol*nrow);
1021 for (casadi_int cc=0; cc<ncol; ++cc)
1022 for (casadi_int rr=0; rr<nrow; ++rr)
1023 row[rr+cc*nrow] = rr;
1029 casadi_assert(n>=0,
"Sparsity::upper expects a positive integer as argument");
1030 casadi_int nrow=n, ncol=n;
1033 row.reserve((n*(n+1))/2);
1037 for (casadi_int cc=0; cc<ncol; ++cc) {
1039 for (casadi_int rr=0; rr<=cc; ++rr) {
1050 casadi_assert(n>=0,
"Sparsity::lower expects a positive integer as argument");
1051 casadi_int nrow=n, ncol=n;
1054 row.reserve((n*(n+1))/2);
1058 for (casadi_int cc=0; cc<ncol; ++cc) {
1060 for (casadi_int rr=cc; rr<nrow; ++rr) {
1071 casadi_assert(n>=0,
"Sparsity::band expects a positive integer as argument");
1072 casadi_assert((p<0? -p : p)<n,
1073 "Sparsity::band: position of band schould be smaller then size argument");
1075 casadi_int nc = n-(p<0? -p : p);
1077 std::vector< casadi_int >
row(nc);
1079 casadi_int
offset = std::max(p, casadi_int(0));
1080 for (casadi_int i=0;i<nc;i++) {
1084 std::vector< casadi_int >
colind(n+1);
1086 offset = std::min(p, casadi_int(0));
1087 for (casadi_int i=0;i<n+1;i++) {
1088 colind[i] = std::max(std::min(i+
offset, nc), casadi_int(0));
1098 for (casadi_int i=-p;i<=p;++i) {
1105 std::vector<casadi_int>
row(1, el),
colind(2);
1112 casadi_int nrow, casadi_int ncol) {
1113 std::vector<casadi_int> all_rows, all_cols;
1114 all_rows.reserve(
row.size()*col.size());
1115 all_cols.reserve(
row.size()*col.size());
1116 for (std::vector<casadi_int>::const_iterator c_it=col.begin(); c_it!=col.end(); ++c_it) {
1117 casadi_assert(*c_it>=0 && *c_it<ncol,
"Sparsity::rowcol: Column index out of bounds");
1118 for (std::vector<casadi_int>::const_iterator r_it=
row.begin(); r_it!=
row.end(); ++r_it) {
1119 casadi_assert(*r_it>=0 && *r_it<nrow,
"Sparsity::rowcol: Row index out of bounds");
1120 all_rows.push_back(*r_it);
1121 all_cols.push_back(*c_it);
1128 const std::vector<casadi_int>& col, std::vector<casadi_int>& mapping,
1129 bool invert_mapping) {
1131 casadi_assert_dev(nrow>=0);
1132 casadi_assert_dev(ncol>=0);
1133 casadi_assert(col.size()==
row.size(),
"inconsistent lengths");
1136 std::vector<casadi_int> r_colind(ncol+1, 0);
1137 std::vector<casadi_int> r_row;
1138 r_row.reserve(
row.size());
1141 casadi_int last_col=-1, last_row=-1;
1142 bool perfectly_ordered=
true;
1143 for (casadi_int k=0; k<col.size(); ++k) {
1145 casadi_assert(col[k]>=0 && col[k]<ncol,
1146 "Column index (" +
str(col[k]) +
") out of bounds [0," +
str(ncol) +
"[");
1147 casadi_assert(
row[k]>=0 &&
row[k]<nrow,
1148 "Row index out of bounds (" +
str(
row[k]) +
") out of bounds [0," +
str(nrow) +
"[");
1151 perfectly_ordered = perfectly_ordered && (col[k]<last_col ||
1152 (col[k]==last_col &&
row[k]<=last_row));
1158 if (perfectly_ordered) {
1160 r_row.resize(
row.size());
1161 std::copy(
row.begin(),
row.end(), r_row.begin());
1165 for (casadi_int i=0; i<ncol; ++i) {
1166 while (el<col.size() && col[el]==i) el++;
1171 mapping.resize(
row.size());
1172 for (casadi_int k=0; k<
row.size(); ++k) mapping[k] = k;
1175 return Sparsity(nrow, ncol, r_colind, r_row);
1179 std::vector<casadi_int>& mapping1 = invert_mapping ? r_row : mapping;
1180 std::vector<casadi_int>& mapping2 = invert_mapping ? mapping : r_row;
1183 mapping1.reserve(std::max(nrow+1,
static_cast<casadi_int
>(col.size())));
1186 std::vector<casadi_int>& rowcount = mapping1;
1187 rowcount.resize(nrow+1);
1188 std::fill(rowcount.begin(), rowcount.end(), 0);
1189 for (std::vector<casadi_int>::const_iterator it=
row.begin(); it!=
row.end(); ++it) {
1194 for (casadi_int i=0; i<nrow; ++i) {
1195 rowcount[i+1] += rowcount[i];
1199 mapping2.resize(
row.size());
1200 for (casadi_int k=0; k<
row.size(); ++k) {
1201 mapping2[rowcount[
row[k]]++] = k;
1206 std::vector<casadi_int>& colcount = r_colind;
1208 for (std::vector<casadi_int>::const_iterator it=mapping2.begin(); it!=mapping2.end(); ++it) {
1209 colcount[col[*it]+1]++;
1213 for (casadi_int i=0; i<ncol; ++i) {
1214 colcount[i+1] += colcount[i];
1218 mapping1.resize(col.size());
1219 for (std::vector<casadi_int>::const_iterator it=mapping2.begin(); it!=mapping2.end(); ++it) {
1220 mapping1[colcount[col[*it]]++] = *it;
1224 casadi_int r_el = 0;
1225 r_row.resize(col.size());
1228 std::vector<casadi_int>::const_iterator it=mapping1.begin();
1232 for (casadi_int i=0; i<ncol; ++i) {
1235 casadi_int j_prev = -1;
1238 while (it!=mapping1.end() && col[*it]==i) {
1241 casadi_int el = *it;
1245 casadi_int j =
row[el];
1251 if (invert_mapping) {
1253 mapping2[el] = r_el-1;
1257 mapping1[r_el-1] = el;
1265 r_colind[i+1] = r_el;
1272 if (!invert_mapping) {
1273 mapping1.resize(r_el);
1276 return Sparsity(nrow, ncol, r_colind, r_row);
1280 const std::vector<casadi_int>& col) {
1281 std::vector<casadi_int> mapping;
1286 const std::vector<casadi_int>& nz,
bool ind1) {
1287 casadi_assert(nrow>0,
"nrow must be >0.");
1288 std::vector<casadi_int>
row(nz.size());
1289 std::vector<casadi_int> col(nz.size());
1290 for (casadi_int i=0;i<nz.size();++i) {
1291 casadi_int k = nz[i];
1301 "is_singular: only defined for square matrices, but got " +
dim());
1311 return (*this)->sp();
1314 Sparsity::operator
const std::vector<casadi_int>&()
const {
1315 return (*this)->sp();
1319 const casadi_int* sp = *
this;
1320 casadi_int nrow = sp[0], ncol = sp[1];
1321 const casadi_int* colind = sp+2, *row = sp+2+ncol+1;
1327 casadi_assert_dev(v.size() >= 2);
1328 casadi_int nrow = v[0];
1329 casadi_int ncol = v[1];
1330 casadi_assert_dev(v.size() >= 2 + ncol+1);
1331 casadi_int
nnz = v[2 + ncol];
1333 bool sparse = v.size() == 2 + ncol+1 +
nnz;
1334 casadi_assert_dev(
dense || sparse);
1341 casadi_assert_dev(v!=
nullptr);
1344 casadi_int nrow = v[0];
1345 casadi_int ncol = v[1];
1346 const casadi_int *
colind = v+2;
1352 if (nrow*ncol ==
nnz) {
1357 const casadi_int *
row = v + 2 + ncol+1;
1360 std::vector<casadi_int>(
row,
row+
nnz), order_rows);
1366 "Sparsity::permutation supplied list is not a permutation.");
1367 std::vector<casadi_int>
colind =
range(p.size()+1);
1376 casadi_assert(
is_permutation(),
"Sparsity::permutation called on non-permutation matrix.");
1385 return (*this)->bw_upper();
1389 return (*this)->bw_lower();
1394 if (sp.empty())
return Sparsity(1, 0);
1395 if (sp.size()==1)
return sp.front();
1398 casadi_int nnz_total = 0;
1399 for (casadi_int i=0; i<sp.size(); ++i) nnz_total += sp[i].
nnz();
1402 std::vector<casadi_int> ret_row, ret_col;
1403 ret_row.reserve(nnz_total);
1404 ret_col.reserve(nnz_total);
1405 casadi_int ret_ncol = 0;
1406 casadi_int ret_nrow = 0;
1407 for (casadi_int i=0; i<sp.size() && ret_nrow==0; ++i)
1408 ret_nrow = sp[i].
size1();
1411 for (std::vector<Sparsity>::const_iterator i=sp.begin(); i!=sp.end(); ++i) {
1413 casadi_int sp_nrow = i->size1();
1414 casadi_int sp_ncol = i->size2();
1415 const casadi_int* sp_colind = i->colind();
1416 const casadi_int* sp_row = i->row();
1417 casadi_assert(sp_nrow==ret_nrow || sp_nrow==0,
1418 "Sparsity::horzcat: Mismatching number of rows");
1421 for (casadi_int cc=0; cc<sp_ncol; ++cc) {
1422 for (casadi_int k=sp_colind[cc]; k<sp_colind[cc+1]; ++k) {
1423 ret_row.push_back(sp_row[k]);
1424 ret_col.push_back(cc + ret_ncol);
1429 ret_ncol += sp_ncol;
1435 casadi_int a_ncol = a.
size2();
1436 casadi_int b_ncol = b.
size2();
1437 casadi_int a_nrow = a.
size1();
1438 casadi_int b_nrow = b.
size1();
1441 const casadi_int* a_colind = a.
colind();
1442 const casadi_int* a_row = a.
row();
1443 const casadi_int* b_colind = b.
colind();
1444 const casadi_int* b_row = b.
row();
1446 std::vector<casadi_int> r_colind(a_ncol*b_ncol+1, 0);
1447 std::vector<casadi_int> r_row(a.
nnz()*b.
nnz());
1449 casadi_int* r_colind_ptr =
get_ptr(r_colind);
1450 casadi_int* r_row_ptr =
get_ptr(r_row);
1455 for (casadi_int a_cc=0; a_cc<a_ncol; ++a_cc) {
1456 casadi_int a_start = a_colind[a_cc];
1457 casadi_int a_stop = a_colind[a_cc+1];
1459 for (casadi_int b_cc=0; b_cc<b_ncol; ++b_cc) {
1460 casadi_int b_start = b_colind[b_cc];
1461 casadi_int b_stop = b_colind[b_cc+1];
1463 for (casadi_int a_el=a_start; a_el<a_stop; ++a_el) {
1464 casadi_int a_r = a_row[a_el];
1466 for (casadi_int b_el=b_start; b_el<b_stop; ++b_el) {
1467 casadi_int b_r = b_row[b_el];
1468 r_row_ptr[i++] = a_r*b_nrow+b_r;
1472 r_colind_ptr[j] = r_colind_ptr[j-1] + (b_stop-b_start)*(a_stop-a_start);
1475 return Sparsity(a_nrow*b_nrow, a_ncol*b_ncol, r_colind, r_row);
1480 if (sp.empty())
return Sparsity(0, 1);
1481 if (sp.size()==1)
return sp.front();
1484 casadi_int nnz_total = 0;
1485 for (casadi_int i=0; i<sp.size(); ++i) nnz_total += sp[i].
nnz();
1488 std::vector<casadi_int> ret_row, ret_col;
1489 ret_row.reserve(nnz_total);
1490 ret_col.reserve(nnz_total);
1491 casadi_int ret_nrow = 0;
1492 casadi_int ret_ncol = 0;
1493 for (casadi_int i=0; i<sp.size() && ret_ncol==0; ++i)
1494 ret_ncol = sp[i].
size2();
1497 for (std::vector<Sparsity>::const_iterator i=sp.begin(); i!=sp.end(); ++i) {
1499 casadi_int sp_nrow = i->size1();
1500 casadi_int sp_ncol = i->size2();
1501 const casadi_int* sp_colind = i->colind();
1502 const casadi_int* sp_row = i->row();
1503 casadi_assert(sp_ncol==ret_ncol || sp_ncol==0,
1504 "Sparsity::vertcat: Mismatching number of columns");
1507 for (casadi_int cc=0; cc<sp_ncol; ++cc) {
1508 for (casadi_int k=sp_colind[cc]; k<sp_colind[cc+1]; ++k) {
1509 ret_row.push_back(sp_row[k] + ret_nrow);
1510 ret_col.push_back(cc);
1515 ret_nrow += sp_nrow;
1524 std::vector<casadi_int>
colind(1, 0);
1525 std::vector<casadi_int>
row;
1528 for (casadi_int i=0;i<v.size();++i) {
1529 const casadi_int* colind_ = v[i].colind();
1530 casadi_int ncol = v[i].size2();
1531 const casadi_int* row_ = v[i].row();
1532 casadi_int sz = v[i].nnz();
1533 for (casadi_int k=1; k<ncol+1; ++k) {
1534 colind.push_back(colind_[k]+nz);
1536 for (casadi_int k=0; k<sz; ++k) {
1537 row.push_back(row_[k]+m);
1548 const std::vector<casadi_int>& offset) {
1550 casadi_assert_dev(!
offset.empty());
1551 casadi_assert_dev(
offset.front()==0);
1553 "horzsplit(Sparsity, std::vector<casadi_int>): Last elements of offset "
1554 "(" +
str(
offset.back()) +
") must equal the number of columns "
1559 casadi_int n =
offset.size()-1;
1562 const casadi_int* colind_x = x.
colind();
1563 const casadi_int* row_x = x.
row();
1566 std::vector<Sparsity> ret;
1571 casadi_int ncol, nrow = x.
size1();
1574 for (casadi_int i=0; i<n; ++i) {
1575 casadi_int first_col =
offset[i];
1576 casadi_int last_col =
offset[i+1];
1577 ncol = last_col - first_col;
1581 std::copy(colind_x+first_col, colind_x+last_col+1,
colind.begin());
1582 for (std::vector<casadi_int>::iterator it=
colind.begin()+1; it!=
colind.end(); ++it)
1586 std::copy(row_x+colind_x[first_col], row_x+colind_x[last_col],
row.begin());
1597 const std::vector<casadi_int>& offset) {
1599 for (std::vector<Sparsity>::iterator it=ret.begin(); it!=ret.end(); ++it) {
1606 std::vector< Sparsity > ret;
1607 for (casadi_int i=0; i<v.size(); ++i)
1613 const std::vector<casadi_int>& offset1,
1614 const std::vector<casadi_int>& offset2) {
1616 casadi_assert_dev(!offset1.empty());
1617 casadi_assert_dev(offset1.front()==0);
1618 casadi_assert(offset1.back()==x.
size1(),
1619 "diagsplit(Sparsity, offset1, offset2): Last elements of offset1 "
1620 "(" +
str(offset1.back()) +
") must equal the number of rows "
1622 casadi_assert(offset2.back()==x.
size2(),
1623 "diagsplit(Sparsity, offset1, offset2): Last elements of offset2 "
1624 "(" +
str(offset2.back()) +
") must equal the number of rows "
1628 casadi_assert_dev(offset1.size()==offset2.size());
1631 casadi_int n = offset1.size()-1;
1634 std::vector<Sparsity> ret;
1639 for (casadi_int i=0; i<n; ++i) {
1640 ret.push_back(x2(
Slice(offset1[i], offset1[i+1]),
1641 Slice(offset2[i], offset2[i+1])).sparsity());
1656 std::vector<casadi_int> rowperm, colperm, rowblock, colblock, coarse_rowblock, coarse_colblock;
1657 x.
btf(rowperm, colperm, rowblock, colblock, coarse_rowblock, coarse_colblock);
1658 return coarse_colblock.at(3);
1661 Sparsity::operator
const casadi_int*()
const {
1662 return &(*this)->sp().front();
1667 casadi_assert(A.
size1()==x.
size2(),
"Dimension error. Got " + x.
dim()
1668 +
" times " + A.
dim() +
".");
1670 casadi_int n_row = A.
size2();
1671 casadi_int n_col = x.
size1();
1674 std::vector<bool> Bwork(n_col);
1675 std::vector<casadi_int> Iwork(n_row+1+n_col);
1677 const casadi_int* Aj = A.
row();
1678 const casadi_int* Ap = A.
colind();
1679 const casadi_int* Bj = x.
row();
1680 const casadi_int* Bp = x.
colind();
1681 casadi_int *Cp =
get_ptr(Iwork);
1682 casadi_int *mask = Cp+n_row+1;
1686 std::fill(mask, mask+n_col, -1);
1690 for (casadi_int i = 0; i < n_row; i++) {
1691 casadi_int row_nnz = 0;
1692 for (casadi_int jj = Ap[i]; jj < Ap[i+1]; jj++) {
1693 casadi_int j = Aj[jj];
1694 for (casadi_int kk = Bp[j]; kk < Bp[j+1]; kk++) {
1695 casadi_int k = Bj[kk];
1702 casadi_int next_nnz =
nnz + row_nnz;
1708 casadi_int *next =
get_ptr(Iwork) + n_row+1;
1709 std::fill(next, next+n_col, -1);
1710 std::vector<bool> & sums = Bwork;
1711 std::fill(sums.begin(), sums.end(),
false);
1714 for (casadi_int i = 0; i < n_row; i++) {
1715 casadi_int head = -2;
1716 casadi_int length = 0;
1717 casadi_int jj_start = Ap[i];
1718 casadi_int jj_end = Ap[i+1];
1719 for (casadi_int jj = jj_start; jj < jj_end; jj++) {
1720 casadi_int j = Aj[jj];
1721 casadi_int kk_start = Bp[j];
1722 casadi_int kk_end = Bp[j+1];
1723 for (casadi_int kk = kk_start; kk < kk_end; kk++) {
1724 casadi_int k = Bj[kk];
1726 if (next[k] == -1) {
1733 for (casadi_int jj = 0; jj < length; jj++) {
1737 casadi_int temp = head;
1754 "Dimension error. Got x=" + x_sp.
dim() +
", y=" + y_sp.
dim()
1755 +
" and z=" + z_sp.
dim() +
".");
1758 const casadi_int* y_colind = y_sp.
colind();
1759 const casadi_int* y_row = y_sp.
row();
1760 const casadi_int* x_colind = x_sp.
colind();
1761 const casadi_int* x_row = x_sp.
row();
1762 const casadi_int* z_colind = z_sp.
colind();
1763 const casadi_int* z_row = z_sp.
row();
1766 casadi_int ncol = z_sp.
size2();
1767 for (casadi_int cc=0; cc<ncol; ++cc) {
1769 for (casadi_int kk=z_colind[cc]; kk<z_colind[cc+1]; ++kk) {
1770 w[z_row[kk]] = z[kk];
1774 for (casadi_int kk=y_colind[cc]; kk<y_colind[cc+1]; ++kk) {
1775 casadi_int rr = y_row[kk];
1779 for (casadi_int kk1=x_colind[rr]; kk1<x_colind[rr+1]; ++kk1) {
1780 w[x_row[kk1]] |= x[kk1] | yy;
1785 for (casadi_int kk=z_colind[cc]; kk<z_colind[cc+1]; ++kk) {
1786 z[kk] = w[z_row[kk]];
1798 "Dimension error. Got x=" + x_sp.
dim() +
", y=" + y_sp.
dim()
1799 +
" and z=" + z_sp.
dim() +
".");
1802 const casadi_int* y_colind = y_sp.
colind();
1803 const casadi_int* y_row = y_sp.
row();
1804 const casadi_int* x_colind = x_sp.
colind();
1805 const casadi_int* x_row = x_sp.
row();
1806 const casadi_int* z_colind = z_sp.
colind();
1807 const casadi_int* z_row = z_sp.
row();
1812 casadi_int nrow = z_sp.
size1();
1816 casadi_int ncol = z_sp.
size2();
1817 for (casadi_int cc=0; cc<ncol; ++cc) {
1819 for (casadi_int kk=z_colind[cc]; kk<z_colind[cc+1]; ++kk) {
1820 w[z_row[kk]] = z[kk];
1824 for (casadi_int kk=y_colind[cc]; kk<y_colind[cc+1]; ++kk) {
1825 casadi_int rr = y_row[kk];
1829 for (casadi_int kk1=x_colind[rr]; kk1<x_colind[rr+1]; ++kk1) {
1830 yy |= w[x_row[kk1]];
1831 x[kk1] |= w[x_row[kk1]];
1837 for (casadi_int kk=z_colind[cc]; kk<z_colind[cc+1]; ++kk) {
1838 z[kk] = w[z_row[kk]];
1848 std::vector<unsigned char> mapping;
1849 X.unite(x, mapping);
1852 const casadi_int* Y_colind =
Y.colind();
1853 const casadi_int* Y_row =
Y.row();
1854 std::vector<casadi_int> y_colind(
Y.size2()+1, 0);
1855 std::vector<casadi_int> y_row;
1856 y_row.reserve(
Y.nnz());
1857 casadi_assert_dev(
Y.nnz()==mapping.size());
1861 for (casadi_int cc=0; cc<
Y.size2(); ++cc) {
1862 y_colind[cc+1] = y_colind[cc];
1864 for (casadi_int kk=Y_colind[cc]; kk<Y_colind[cc+1]; ++kk) {
1866 casadi_int e = mapping[i++];
1870 y_row.push_back(Y_row[kk]);
1872 casadi_assert_dev(e==1);
1877 Sparsity ret(
Y.size1(),
Y.size2(), y_colind, y_row,
true);
1889 const std::string& format_hint,
const std::set<std::string>& file_formats) {
1890 if (format_hint.empty()) {
1894 "Extension '" + extension +
"' not recognised. "
1900 "File format hint '" + format_hint +
"' not recognised. "
1910 if (format==
"mtx") {
1911 out << std::scientific << std::setprecision(std::numeric_limits<double>::digits10 + 1);
1912 out <<
"%%MatrixMarket matrix coordinate pattern general" << std::endl;
1913 out <<
size1() <<
" " <<
size2() <<
" " <<
nnz() << std::endl;
1915 std::vector<casadi_int> col =
get_col();
1917 for (casadi_int k=0;k<
row.size();++k) {
1918 out <<
row[k]+1 <<
" " << col[k]+1 << std::endl;
1921 casadi_error(
"Unknown format '" + format +
"'");
1928 casadi_assert(in.good(),
"Could not open '" +
filename +
"'.");
1929 if (format==
"mtx") {
1931 std::vector<casadi_int>
row, col;
1934 while (std::getline(in, line)) {
1936 casadi_assert(line==
"%%MatrixMarket matrix coordinate pattern general",
"Wrong header");
1938 }
else if (line_num==1) {
1939 std::stringstream stream(line);
1947 std::stringstream stream(line);
1957 casadi_error(
"Unknown format '" + format +
"'");
1962 bool with_x_diag,
bool with_lam_g_diag) {
1964 casadi_assert(H.
is_square(),
"H must be square");
1965 casadi_assert(H.
size1() == J.
size2(),
"Dimension mismatch");
1968 if (with_x_diag)
return kkt(H +
diag(H.
size()), J,
false, with_lam_g_diag);
1990 s.
pack(
"SparsityInternal::compressed", std::vector<casadi_int>{});
1997 std::vector<casadi_int> i;
1998 s.
unpack(
"SparsityInternal::compressed", i);
2007 std::stringstream ss;
2013 std::stringstream ss;
Helper class for Serialization.
void unpack(Sparsity &e)
Reconstruct an object from the input stream.
static void open(std::ofstream &, const std::string &path, std::ios_base::openmode mode=std::ios_base::out)
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 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_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 mtimes(const Sparsity &x, const Sparsity &y)
Enlarge matrix.
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.
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.
const casadi_int * colind() const
Get a reference to the colindex of all column element (see class description)
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.
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.
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.