27 #include "sparsity_internal.hpp" 
   28 #include "casadi_misc.hpp" 
   29 #include "global_options.hpp" 
   36       casadi_int *w, casadi_int ata) {
 
   42     casadi_int r, c, k, rnext;
 
   44     casadi_int nrow = *
sp++, ncol = *
sp++;
 
   47     casadi_int *ancestor=w;
 
   52       for (r=0; r<nrow; ++r) prev[r] = -1;
 
   55     for (c=0; c<ncol; ++c) {
 
   63         while (r!=-1 && r<c) {
 
   66           if (rnext==-1) parent[r] = c;
 
   69         if (ata) prev[
row[k]] = c;
 
   75                                       casadi_int* head, 
const casadi_int* next,
 
   76                                       casadi_int* post, casadi_int* stack) {
 
   81     casadi_int i, p, top=0;
 
  100       casadi_int* post, casadi_int* w) {
 
  107     casadi_int *head, *next, *stack;
 
  112     for (j=0; j<n; ++j) head[j] = -1;
 
  114     for (j=n-1; j>=0; --j) {
 
  116         next[j] = head[parent[j]];
 
  120     for (j=0; j<n; j++) {
 
  128   leaf(casadi_int i, casadi_int j, 
const casadi_int* first, casadi_int* maxfirst,
 
  129        casadi_int* prevleaf, casadi_int* ancestor, casadi_int* jleaf) {
 
  134     casadi_int q, s, sparent, jprev;
 
  137     if (i<=j || first[j]<=maxfirst[i]) 
return -1;
 
  139     maxfirst[i] = first[j];
 
  144     *jleaf = (jprev == -1) ? 1 : 2;
 
  146     if (*jleaf==1) 
return i;
 
  148     for (q=jprev; q!=ancestor[q]; q=ancestor[q]) {}
 
  149     for (s=jprev; s!=q; s=sparent) {
 
  150       sparent = ancestor[s];
 
  158   qr_counts(
const casadi_int* tr_sp, 
const casadi_int* parent,
 
  159             const casadi_int* post, casadi_int* counts, casadi_int* w) {
 
  164     casadi_int ncol = *tr_sp++, nrow = *tr_sp++;
 
  165     const casadi_int *rowind=tr_sp, *col=tr_sp+nrow+1;
 
  166     casadi_int i, j, k, J, p, q, jleaf, *maxfirst, *prevleaf,
 
  167       *ancestor, *head=
nullptr, *next=
nullptr, *first;
 
  176     for (k=0; k<ncol; ++k) first[k]=-1;
 
  177     for (k=0; k<ncol; ++k) {
 
  180       counts[j] = (first[j]==-1) ? 1 : 0;
 
  181       for (; j!=-1 && first[j]==-1; j=parent[j]) first[j]=k;
 
  184     for (k=0; k<ncol; ++k) ancestor[post[k]] = k;
 
  185     for (k=0; k<ncol+1; ++k) head[k]=-1;
 
  186     for (i=0; i<nrow; ++i) {
 
  187       for (k=ncol, p=rowind[i]; p<rowind[i+1]; ++p) {
 
  188         k = std::min(k, ancestor[col[p]]);
 
  196     for (k=0; k<ncol; ++k) maxfirst[k]=-1;
 
  197     for (k=0; k<ncol; ++k) prevleaf[k]=-1;
 
  199     for (i=0; i<ncol; ++i) ancestor[i]=i;
 
  200     for (k=0; k<ncol; ++k) {
 
  203       if (parent[j]!=-1) counts[parent[j]]--; 
 
  206         for (p=rowind[J]; p<rowind[J+1]; ++p) {
 
  208           q = 
leaf(i, j, first, maxfirst, prevleaf, ancestor, &jleaf);
 
  209           if (jleaf>=1) counts[j]++; 
 
  210           if (jleaf==2) counts[q]--; 
 
  214       if (parent[j]!=-1) ancestor[j]=parent[j];
 
  217     for (j=0; j<ncol; ++j) {
 
  218       if (parent[j]!=-1) counts[parent[j]] += counts[j];
 
  222     casadi_int sum_counts = 0;
 
  223     for (j=0; j<ncol; ++j) sum_counts += counts[j];
 
  228   qr_nnz(
const casadi_int* sp, casadi_int* pinv, casadi_int* leftmost,
 
  229          const casadi_int* parent, casadi_int* nrow_ext, casadi_int* w) {
 
  235     casadi_int nrow = 
sp[0], ncol = 
sp[1];
 
  238     casadi_int *next=w; w+=nrow;
 
  239     casadi_int *head=w; w+=ncol;
 
  240     casadi_int *tail=w; w+=ncol;
 
  241     casadi_int *nque=w; w+=ncol;
 
  243     casadi_int r, c, k, pa;
 
  245     for (c=0; c<ncol; ++c) head[c] = -1;
 
  246     for (c=0; c<ncol; ++c) tail[c] = -1;
 
  247     for (c=0; c<ncol; ++c) nque[c] = 0;
 
  248     for (r=0; r<nrow; ++r) leftmost[r] = -1;
 
  250     for (c=ncol-1; c>=0; --c) {
 
  252         leftmost[
row[k]] = c;
 
  256     for (r=nrow-1; r>=0; --r) {
 
  261       if (nque[c]++ == 0) tail[c]=r; 
 
  266     casadi_int v_nnz = 0;
 
  267     casadi_int nrow_new = nrow;
 
  268     for (c=0; c<ncol; ++c) {
 
  271       if (r<0) r=nrow_new++; 
 
  273       if (--nque[c]<=0) 
continue; 
 
  275       if ((pa=parent[c]) != -1) {
 
  277         if (nque[pa]==0) tail[pa] = tail[c];
 
  278         next[tail[c]] = head[pa];
 
  283     for (r=0; r<nrow; ++r) 
if (pinv[r]<0) pinv[r] = c++;
 
  284     if (nrow_ext) *nrow_ext = nrow_new;
 
  289   qr_init(
const casadi_int* sp, 
const casadi_int* sp_tr,
 
  290           casadi_int* leftmost, casadi_int* parent, casadi_int* pinv,
 
  291           casadi_int* nrow_ext, casadi_int* v_nnz, casadi_int* r_nnz, casadi_int* w) {
 
  293     casadi_int ncol = 
sp[1];
 
  297     casadi_int* post = w; w += ncol;
 
  300     *r_nnz = 
qr_counts(sp_tr, parent, post, w, w+ncol);
 
  302     *v_nnz = 
qr_nnz(
sp, pinv, leftmost, parent, nrow_ext, w);
 
  306   qr_sparsities(
const casadi_int* sp_a, casadi_int nrow_ext, casadi_int* sp_v, casadi_int* sp_r,
 
  307                 const casadi_int* leftmost, 
const casadi_int* parent, 
const casadi_int* pinv,
 
  314     casadi_int ncol = sp_a[1];
 
  315     const casadi_int *
colind=sp_a+2, *
row=sp_a+2+ncol+1;
 
  316     casadi_int *v_colind=sp_v+2, *v_row=sp_v+2+ncol+1;
 
  317     casadi_int *r_colind=sp_r+2, *r_row=sp_r+2+ncol+1;
 
  319     sp_v[0] = sp_r[0] = nrow_ext;
 
  320     sp_v[1] = sp_r[1] = ncol;
 
  322     casadi_int* s = iw; iw += ncol;
 
  324     casadi_int r, c, k, k1, top, len, k2, r2;
 
  326     for (r=0; r<nrow_ext; ++r) iw[r] = -1;
 
  328     casadi_int nnz_r=0, nnz_v=0;
 
  330     for (c=0; c<ncol; ++c) {
 
  334       v_colind[c] = k1 = nnz_v;
 
  340         r = leftmost[
row[k]]; 
 
  342         for (len=0; iw[r]!=c; r=parent[r]) {
 
  346         while (len>0) s[--top] = s[--len]; 
 
  348         if (r>c && iw[r]<c) {
 
  354       for (k = top; k<ncol; ++k) {
 
  360           for (k2=v_colind[r]; k2<v_colind[r+1]; ++k2) {
 
  373     r_colind[ncol] = nnz_r;
 
  374     v_colind[ncol] = nnz_v;
 
  378   ldl_colind(
const casadi_int* sp, casadi_int* parent, casadi_int* l_colind, casadi_int* w) {
 
  383     casadi_int n = 
sp[0];
 
  388     casadi_int* visited=w; w+=n;
 
  390     for (c=0; c<n; ++c) {
 
  398         while (visited[r]!=c) {
 
  400           if (parent[r]==-1) parent[r]=c;
 
  409     for (c=0; c<n; ++c) l_colind[c+1] += l_colind[c];
 
  413   ldl_row(
const casadi_int* sp, 
const casadi_int* parent, casadi_int* l_colind,
 
  414       casadi_int* l_row, casadi_int *w) {
 
  420     casadi_int n = 
sp[0];
 
  423     casadi_int *visited=w; w+=n;
 
  427     for (c=0; c<n; ++c) {
 
  433         while (visited[r]!=c) {
 
  434           l_row[l_colind[r]++] = c; 
 
  442     for (c=0; c<n; ++c) {
 
  451       const casadi_int* colind, 
const casadi_int* row) :
 
  452     sp_(2 + ncol+1 + colind[ncol]), btf_(nullptr) {
 
  464 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS 
  466   std::lock_guard<std::mutex> lock(btf_mtx_);
 
  469       btf_ = 
new SparsityInternal::Btf();
 
  470       btf_->nb = 
btf(btf_->rowperm, btf_->colperm, btf_->rowblock, btf_->colblock,
 
  471                      btf_->coarse_rowblock, btf_->coarse_colblock);
 
  485       stream << 
"colind: " << 
get_colind() << std::endl;
 
  486       stream << 
"row:    " << 
get_row() << std::endl;
 
  492     std::vector<casadi_int> col(
nnz());
 
  493     for (casadi_int r=0; r<
size2(); ++r) {
 
  494       for (casadi_int el = 
colind[r]; el < 
colind[r+1]; ++el) {
 
  503     std::vector<casadi_int> mapping;
 
  509       std::vector<casadi_int>& mapping, 
bool invert_mapping)
 const {
 
  511     std::vector<casadi_int> trans_col = 
get_row();
 
  512     std::vector<casadi_int> trans_row = 
get_col();
 
  519                                          std::vector<casadi_int>& pstack,
 
  520                                          const std::vector<casadi_int>& pinv,
 
  521                                          std::vector<bool>& marked)
 const {
 
  529     const casadi_int* 
row = this->
row();
 
  537       casadi_int jnew = !pinv.empty() ? (pinv[j]) : j;
 
  542         pstack[head] = (jnew < 0) ? 0 : 
colind[jnew];
 
  547       casadi_int p2 = (jnew < 0) ? 0 : 
colind[jnew+1];
 
  550       for (casadi_int p = pstack[head]; p< p2; ++p) {
 
  553         casadi_int i = 
row[p];
 
  556         if (marked[i]) continue ;
 
  584                             std::vector<casadi_int>& r)
 const {
 
  590     std::vector<casadi_int> tmp;
 
  594     std::vector<casadi_int> xi(2*
size2()+1);
 
  595     std::vector<casadi_int>& Blk = xi;
 
  597     std::vector<casadi_int> pstack(
size2()+1);
 
  602     std::vector<bool> marked(
size2(), 
false);
 
  604     casadi_int top = 
size2();
 
  607     for (casadi_int i = 0; i<
size2(); ++i) {
 
  609         top = 
dfs(i, top, xi, pstack, tmp, marked);
 
  613     std::fill(marked.begin(), marked.end(), 
false);
 
  616     casadi_int nb = 
size2();
 
  619     for (casadi_int k=0 ; k < 
size2() ; ++k) {
 
  621       casadi_int i = xi[k];
 
  624       if (marked[i]) 
continue;
 
  628       top = AT.
dfs(i, top, p, pstack, tmp, marked);
 
  633     for (casadi_int k = nb ; k <= 
size2() ; ++k)
 
  640     for (casadi_int b = 0 ; b < nb ; b++) {
 
  641       for (casadi_int k = r[b]; k<r[b+1] ; ++k)
 
  646     for (casadi_int i=0; i<
size2(); ++i) {
 
  652     for (casadi_int i=nb; i>0; --i) {
 
  666     casadi_assert(
is_symmetric(), 
"AMD requires a symmetric matrix");
 
  668     casadi_int n=
size2();
 
  673     casadi_int col_begin, col_end=0;
 
  674     for (casadi_int c=0; c<n; ++c) {
 
  679       for (casadi_int k=col_begin; k<col_end; ++k) {
 
  687     casadi_int dense = 
static_cast<casadi_int
>(10*sqrt(
static_cast<double>(n)));
 
  688     dense = std::max(casadi_int(16), dense);
 
  689     dense = std::min(n-2, dense);
 
  691     std::vector<casadi_int> 
P(n+1);
 
  693     std::vector<casadi_int> len(n+1), nv(n+1), next(n+1), head(n+1), elen(n+1), degree(n+1),
 
  698     casadi_int mindeg = 0;
 
  700     casadi_int lemax = 0;
 
  706     #define FLIP(i) (-(i)-2) 
  710     for (casadi_int k = 0; k<n; ++k) len[k] = 
colind[k+1] - 
colind[k];
 
  712     casadi_int nzmax = 
row.size();
 
  713     for (casadi_int i=0; i<=n; ++i) {
 
  728     for (casadi_int i = 0; i < n; ++i) {
 
  735       } 
else if (d > dense) {              
 
  742         if (head[d] != -1) 
P[head[d]] = i;
 
  750       for (k = -1; mindeg < n && (k = head[mindeg]) == -1; mindeg++) {}
 
  751       if (next[k] != -1) 
P[next[k]] = -1;
 
  752       head[mindeg] = next[k];          
 
  753       casadi_int elenk = elen[k];             
 
  754       casadi_int nvk = nv[k];                     
 
  757       if (elenk > 0 && 
nnz + mindeg >= nzmax) {
 
  758         for (casadi_int j = 0; j < n; j++) {
 
  760           if ((p = 
colind[j]) >= 0) {  
 
  766         for (q = 0, p = 0; p < 
nnz; ) { 
 
  768           if ((j = FLIP(
row[p++])) >= 0) { 
 
  771             for (casadi_int k3 = 0; k3 < len[j]-1; k3++) 
row[q++] = 
row[p++];
 
  780       casadi_int pk1 = (elenk == 0) ? p : 
nnz;      
 
  781       casadi_int pk2 = pk1;
 
  782       casadi_int e, pj, ln;
 
  783       for (casadi_int k1 = 1; k1 <= elenk + 1; k1++) {
 
  793         for (casadi_int k2 = 1; k2 <= ln; k2++) {
 
  794           casadi_int i = 
row[pj++];
 
  796           if ((nvi = nv[i]) <= 0) 
continue; 
 
  800           if (next[i] != -1) 
P[next[i]] = 
P[i];
 
  802             next[
P[i]] = next[i];
 
  804             head[degree[i]] = next[i];
 
  812       if (elenk != 0) 
nnz = pk2;        
 
  819       for (casadi_int pk = pk1; pk < pk2; pk++) {   
 
  820         casadi_int i = 
row[pk];
 
  822         if ((eln = elen[i]) <= 0) 
continue; 
 
  823         casadi_int nvi = -nv[i];                   
 
  824         casadi_int wnvi = mark - nvi;
 
  829           } 
else if (w[e] != 0) {   
 
  830             w[e] = degree[e] + wnvi; 
 
  835       for (casadi_int pk = pk1; pk < pk2; pk++) { 
 
  836         casadi_int i = 
row[pk];                   
 
  837         casadi_int p1 = 
colind[i];
 
  838         casadi_int p2 = p1 + elen[i] - 1;
 
  840         for (h = 0, d = 0, p = p1; p <= p2; p++) { 
 
  843             casadi_int dext = w[e] - mark;    
 
  854         elen[i] = pn - p1 + 1; 
 
  856         casadi_int p4 = p1 + len[i];
 
  857         for (p = p2 + 1; p < p4; p++) { 
 
  858           casadi_int j = 
row[p];
 
  860           if ((nvj = nv[j]) <= 0) 
continue; 
 
  867           casadi_int nvi = -nv[i];
 
  874           degree[i] = std::min(degree[i], d);   
 
  878           len[i] = pn - p1 + 1;     
 
  886       lemax = std::max(lemax, dk);
 
  889       for (casadi_int pk = pk1; pk < pk2; pk++) {
 
  890         casadi_int i = 
row[pk];
 
  891         if (nv[i] >= 0) 
continue;      
 
  895         for (; i != -1 && next[i] != -1; i = next[i], mark++) {
 
  897           casadi_int eln = elen[i];
 
  899           casadi_int jlast = i;
 
  900           for (casadi_int j = next[i]; j != -1; ) { 
 
  901             casadi_int ok = (len[j] == ln) && (elen[j] == eln);
 
  902             for (p = 
colind[j] + 1; ok && p <= 
colind[j] + ln - 1; p++) {
 
  903               if (w[
row[p]] != mark) ok = 0; 
 
  921       for (p = pk1, pk = pk1; pk < pk2; pk++) {  
 
  922         casadi_int i = 
row[pk];
 
  924         if ((nvi = -nv[i]) <= 0) 
continue; 
 
  926         d = degree[i] + dk - nvi;         
 
  927         d = std::min(d, n - nel - nvi);
 
  928         if (head[d] != -1) 
P[head[d]] = i;
 
  932         mindeg = std::min(mindeg, d);    
 
  937       if ((len[k] = p-pk1) == 0) {      
 
  941       if (elenk != 0) 
nnz = p;          
 
  944     for (casadi_int i = 0; i < n; i++) 
colind[i] = FLIP(
colind[i]); 
 
  945     for (casadi_int j = 0; j <= n; j++) head[j] = -1;
 
  946     for (casadi_int j = n; j >= 0; j--) {            
 
  947       if (nv[j] > 0) 
continue;            
 
  948       next[j] = head[
colind[j]];          
 
  951     for (casadi_int e = n; e >= 0; e--) {            
 
  952       if (nv[e] <= 0) 
continue;           
 
  954         next[e] = head[
colind[e]];        
 
  958     for (casadi_int k = 0, i = 0; i <= n; i++) {     
 
  968                               std::vector<casadi_int>& queue, 
const std::vector<casadi_int>& imatch,
 
  969                               const std::vector<casadi_int>& jmatch, casadi_int mark)
 const {
 
  975     casadi_int head = 0, tail = 0, j, i, p, j2 ;
 
  978     for (j=0; j<n; ++j) {
 
  980       if (imatch[j] >= 0) 
continue;
 
  990     if (tail == 0) 
return;
 
  993     const casadi_int *C_row, *C_colind;
 
 1000       C_colind = trans.
colind();
 
 1004     while (head < tail) {
 
 1008       for (p = C_colind[j] ; p < C_colind[j+1] ; p++) {
 
 1012         if (wi[i] >= 0) 
continue;
 
 1021         if (wj[j2] >= 0) 
continue;
 
 1033       const std::vector<casadi_int>& imatch, std::vector<casadi_int>& p,
 
 1034       std::vector<casadi_int>& q, std::vector<casadi_int>& cc, std::vector<casadi_int>& rr,
 
 1035       casadi_int set, casadi_int mark) {
 
 1041     casadi_int kc = cc[set];
 
 1042     casadi_int kr = rr[set-1] ;
 
 1043     for (casadi_int j=0; j<n; ++j) {
 
 1045       if (wj[j] != mark) 
continue;
 
 1047       p[kr++] = imatch[j] ;
 
 1056           std::vector<casadi_int>& p, std::vector<casadi_int>& rr, casadi_int set) {
 
 1062     casadi_int i, kr = rr[set] ;
 
 1076     std::vector<casadi_int> &rr = *
static_cast<std::vector<casadi_int> *
>(other);
 
 1077     return (i >= rr[1] && i < rr[2]) ;
 
 1081           std::vector<casadi_int>& w, casadi_int *js, casadi_int *is, casadi_int *ps)
 const {
 
 1088     const casadi_int* 
row = this->
row();
 
 1090     casadi_int found = 0, p, i = -1, head = 0, j ;
 
 1106         for (p = cheap[j] ; p < 
colind[j+1] && !found; ++p) {
 
 1108           found = (jmatch[i] == -1) ;
 
 1126       for (p = ps[head]; p<
colind[j+1]; ++p) {
 
 1132         if (w[jmatch[i]] == k) 
continue;
 
 1141         js[++head] = jmatch[i];
 
 1146       if (p == 
colind[j+1]) head--;
 
 1150       for (p = head; p>=0; --p)
 
 1151         jmatch[is[p]] = js[p];
 
 1155                                   Sparsity& trans, casadi_int seed)
 const {
 
 1162     const casadi_int* 
row = this->
row();
 
 1164     casadi_int n2 = 0, m2 = 0;
 
 1167     jmatch.resize(
size1());
 
 1168     imatch.resize(
size2());
 
 1173     for (casadi_int j=0; j<
size2(); ++j) {
 
 1186       for (i=0; i<k; ++i) jmatch[i] = i;
 
 1187       for (;    i<
size1(); ++i) jmatch[i] = -1;
 
 1190       for (j=0; j<k; ++j) imatch[j] = j;
 
 1191       for (;    j<
size2(); ++j) imatch[j] = -1;
 
 1194     for (casadi_int i=0; i<
size1(); ++i) m2 += w[i];
 
 1197     if (m2 < n2 && trans.
is_null())
 
 1201     const SparsityInternal* 
C = m2 < n2 ? static_cast<const SparsityInternal*>(trans.
get()) : 
this;
 
 1202     const casadi_int* C_colind = 
C->colind();
 
 1204     std::vector<casadi_int>& Cjmatch = m2 < n2 ? imatch : jmatch;
 
 1205     std::vector<casadi_int>& Cimatch = m2 < n2 ? jmatch : imatch;
 
 1208     w.resize(5 * 
C->size2());
 
 1210     casadi_int *cheap = &w.front() + 
C->size2();
 
 1211     casadi_int *js = &w.front() + 2*
C->size2();
 
 1212     casadi_int *is = &w.front() + 3*
C->size2();
 
 1213     casadi_int *ps = &w.front() + 4*
C->size2();
 
 1216     for (casadi_int j=0; j<
C->size2(); ++j)
 
 1217       cheap[j] = C_colind[j];
 
 1220     for (casadi_int j=0; j<
C->size2(); ++j)
 
 1224     for (casadi_int i=0; i<
C->size1(); ++i)
 
 1228     std::vector<casadi_int> q = 
randperm(
C->size2(), seed);
 
 1231     for (k=0; k<
C->size2(); ++k) {
 
 1232       C->augment(!q.empty() ? q[k]: k, Cjmatch, cheap, w, js, is, ps);
 
 1236     for (casadi_int j=0; j<
C->size2(); ++j)
 
 1239     for (casadi_int i = 0; i<
C->size1(); ++i)
 
 1240       if (Cjmatch[i] >= 0)
 
 1241         Cimatch[Cjmatch[i]] = i;
 
 1245                                 std::vector<casadi_int>& colperm,
 
 1246                                 std::vector<casadi_int>& rowblock,
 
 1247                                 std::vector<casadi_int>& colblock,
 
 1248                                 std::vector<casadi_int>& coarse_rowblock,
 
 1249                                 std::vector<casadi_int>& coarse_colblock)
 const {
 
 1255     casadi_int seed = 0;
 
 1266     colperm.resize(
size2());
 
 1269     rowblock.resize(
size1()+6);
 
 1272     colblock.resize(
size2()+6);
 
 1275     coarse_rowblock.resize(5);
 
 1276     std::fill(coarse_rowblock.begin(), coarse_rowblock.end(), 0);
 
 1279     coarse_colblock.resize(5);
 
 1280     std::fill(coarse_colblock.begin(), coarse_colblock.end(), 0);
 
 1283     std::vector<casadi_int> imatch, jmatch;
 
 1284     maxtrans(imatch, jmatch, trans, seed);
 
 1289     std::vector<casadi_int>& wi = rowblock;
 
 1290     std::vector<casadi_int>& wj = colblock;
 
 1293     for (casadi_int j=0; j<
size2(); ++j)
 
 1297     for (casadi_int i=0; i<
size1(); ++i)
 
 1301     bfs(
size2(), wi, wj, colperm, imatch, jmatch, 1);
 
 1304     bfs(
size1(), wj, wi, rowperm, jmatch, imatch, 3);
 
 1310     matched(
size2(), wj, imatch, rowperm, colperm, coarse_colblock, coarse_rowblock, 1, 1);
 
 1313     matched(
size2(), wj, imatch, rowperm, colperm, coarse_colblock, coarse_rowblock, 2, -1);
 
 1316     matched(
size2(), wj, imatch, rowperm, colperm, coarse_colblock, coarse_rowblock, 3, 3);
 
 1326     std::vector<casadi_int> colind_C, row_C;
 
 1327     permute(pinv, colperm, 0, colind_C, row_C);
 
 1330     casadi_int nc = coarse_colblock[3] - coarse_colblock[2];
 
 1331     if (coarse_colblock[2] > 0) {
 
 1332       for (casadi_int j = coarse_colblock[2]; j <= coarse_colblock[3]; ++j)
 
 1333         colind_C[j-coarse_colblock[2]] = colind_C[j];
 
 1335     casadi_int ncol_C = nc;
 
 1337     colind_C.resize(nc+1);
 
 1339     if (coarse_rowblock[2] - coarse_rowblock[1] < 
size1()) {
 
 1341       casadi_int cnz = colind_C[nc];
 
 1342       if (coarse_rowblock[1] > 0)
 
 1343         for (casadi_int k=0; k<cnz; ++k)
 
 1344           row_C[k] -= coarse_rowblock[1];
 
 1346     row_C.resize(colind_C.back());
 
 1347     casadi_int nrow_C = nc ;
 
 1348     Sparsity C(nrow_C, ncol_C, colind_C, row_C, 
true);
 
 1351     std::vector<casadi_int> scc_p, scc_r;
 
 1352     casadi_int scc_nb = 
C.scc(scc_p, scc_r);
 
 1357     std::vector<casadi_int> ps = scc_p;
 
 1360     std::vector<casadi_int> rs = scc_r;
 
 1363     casadi_int nb1 = scc_nb;
 
 1365     for (casadi_int k=0; k<nc; ++k)
 
 1366       wj[k] = colperm[ps[k] + coarse_colblock[2]];
 
 1368     for (casadi_int k=0; k<nc; ++k)
 
 1369       colperm[k + coarse_colblock[2]] = wj[k];
 
 1371     for (casadi_int k=0; k<nc; ++k)
 
 1372       wi[k] = rowperm[ps[k] + coarse_rowblock[1]];
 
 1374     for (casadi_int k=0; k<nc; ++k)
 
 1375       rowperm[k + coarse_rowblock[1]] = wi[k];
 
 1379     rowblock[0] = colblock[0] = 0;
 
 1382     if (coarse_colblock[2] > 0)
 
 1386     for (casadi_int k=0; k<nb1; ++k) {
 
 1388       rowblock[nb2] = rs[k] + coarse_rowblock[1];
 
 1389       colblock[nb2] = rs[k] + coarse_colblock[2] ;
 
 1393     if (coarse_rowblock[2] < 
size1()) {
 
 1395       rowblock[nb2] = coarse_rowblock[2];
 
 1396       colblock[nb2] = coarse_colblock[3];
 
 1400     rowblock[nb2] = 
size1();
 
 1401     colblock[nb2] = 
size2() ;
 
 1404     rowblock.resize(nb2+1);
 
 1405     colblock.resize(nb2+1);
 
 1415     std::vector<casadi_int> p;
 
 1418     if (seed==0) 
return p;
 
 1423     for (casadi_int k=0; k<n; ++k)
 
 1427     if (seed==-1) 
return p;
 
 1431     unsigned int seedu = 
static_cast<unsigned int>(seed);
 
 1434     for (casadi_int k=0; k<n; ++k) {
 
 1437       casadi_int j = k + (rand() % (n-k)); 
 
 1439       casadi_int j = k + (rand_r(&seedu) % (n-k));
 
 1442       casadi_int t = p[j];
 
 1451     std::vector<casadi_int> pinv(p.size());
 
 1452     for (casadi_int k=0; k<p.size(); ++k) pinv[p[k]] = k;
 
 1457                                      const std::vector<casadi_int>& q, casadi_int values)
 const {
 
 1458     std::vector<casadi_int> colind_C, row_C;
 
 1459     permute(pinv, q, values, colind_C, row_C);
 
 1464                                  const std::vector<casadi_int>& q, casadi_int values,
 
 1465                                  std::vector<casadi_int>& colind_C,
 
 1466                                  std::vector<casadi_int>& row_C)
 const {
 
 1473     const casadi_int* 
row = this->
row();
 
 1476     colind_C.resize(
size2()+1);
 
 1479     row_C.resize(
nnz());
 
 1481     for (casadi_int k = 0; k<
size2(); ++k) {
 
 1485       casadi_int j = !q.empty() ? (q[k]) : k;
 
 1488         row_C[nz++] = !pinv.empty() ? (pinv[
row[t]]) : 
row[t] ;
 
 1493     colind_C[
size2()] = nz;
 
 1497                              void *other, casadi_int nrow, casadi_int ncol,
 
 1498                              std::vector<casadi_int>& colind, std::vector<casadi_int>& row) {
 
 1506     for (casadi_int j = 0; j<ncol; ++j) {
 
 1508       casadi_int p = 
colind[j];
 
 1512       for ( ; p < 
colind[j+1] ; ++p) {
 
 1513         if (fkeep(
row[p], j, 1, other)) {
 
 1526       casadi_int *w, casadi_int n) {
 
 1532     if (mark < 2 || (mark + lemax < 0)) {
 
 1533       for (casadi_int k = 0; k<n; ++k) 
if (w[k] != 0) w[k] = 1;
 
 1550       casadi_int mark, casadi_int* Ci, casadi_int nz)
 const {
 
 1557     const casadi_int *Ap = 
colind();
 
 1558     const casadi_int *Ai = 
row();
 
 1560     for (p = Ap[j]; p<Ap[j+1]; ++p) {
 
 1582     casadi_assert(
size2() == B.
size1(), 
"Dimension mismatch.");
 
 1583     casadi_int m = 
size1();
 
 1584     casadi_int anz = 
nnz();
 
 1585     casadi_int n = B.
size2();
 
 1586     const casadi_int* Bp = B.
colind();
 
 1587     const casadi_int* Bi = B.
row();
 
 1588     casadi_int bnz = Bp[n];
 
 1591     std::vector<casadi_int> w(m);
 
 1594     std::vector<casadi_int> C_colind(n+1, 0), C_row;
 
 1596     C_colind.resize(anz + bnz);
 
 1598     casadi_int* Cp = &C_colind.front();
 
 1599     for (casadi_int j=0; j<n; ++j) {
 
 1600       if (nz+m > C_row.size()) {
 
 1601         C_row.resize(2*(C_row.size())+m);
 
 1606       for (casadi_int p = Bp[j] ; p<Bp[j+1] ; ++p) {
 
 1607         nz = 
scatter(Bi[p], w, j+1, &C_row.front(), nz);
 
 1616     return Sparsity(m, n, C_colind, C_row);
 
 1620     casadi_int nrow = this->
size1();
 
 1621     casadi_int ncol = this->
size2();
 
 1623     const casadi_int* 
row = this->
row();
 
 1630       casadi_int n = nrow * ncol;
 
 1631       std::vector<casadi_int> ret_colind(n+1, 0), ret_row;
 
 1635       for (casadi_int cc=0; cc<ncol; ++cc) {
 
 1637           casadi_int rr=
row[k];
 
 1638           casadi_int el=rr+nrow*cc; 
 
 1639           while (ret_i<=el) ret_colind[ret_i++]=ret_row.size();
 
 1640           ret_row.push_back(el);
 
 1641           mapping.push_back(k);
 
 1644       while (ret_i<=n) ret_colind[ret_i++]=ret_row.size();
 
 1647       return Sparsity(n, n, ret_colind, ret_row);
 
 1651       casadi_int n = std::min(nrow, ncol);
 
 1652       std::vector<casadi_int> ret_row, ret_colind(2, 0);
 
 1655       for (casadi_int cc=0; cc<n; ++cc) {
 
 1656         for (casadi_int el = 
colind[cc]; el<
colind[cc+1]; ++el) {
 
 1658             ret_row.push_back(
row[el]);
 
 1660             mapping.push_back(el);
 
 1666       return Sparsity(n, 1, ret_colind, ret_row);
 
 1671     casadi_int nrow = this->
size1();
 
 1672     casadi_int ncol = this->
size2();
 
 1674     const casadi_int* 
row = this->
row();
 
 1675     for (casadi_int c=0; c<ncol && c<nrow; ++c) {
 
 1677         if (
row[k]==c) 
return true;
 
 1684     casadi_int nrow = this->
size1();
 
 1685     casadi_int ncol = this->
size2();
 
 1687     const casadi_int* 
row = this->
row();
 
 1689     std::vector<casadi_int> ret_colind(ncol+1), ret_row;
 
 1691     ret_row.reserve(
nnz());
 
 1692     for (casadi_int c=0; c<ncol; ++c) {
 
 1695           ret_row.push_back(
row[k]);
 
 1698       ret_colind[c+1] = ret_row.size();
 
 1700     return Sparsity(nrow, ncol, ret_colind, ret_row);
 
 1705     if (with_nz) ret += 
"," + 
str(
nnz()) + 
"nz";
 
 1711     std::stringstream ss;
 
 1713       ss << 
"nonzero index " << k+start_index << 
" ";
 
 1715     casadi_int r = 
row()[k];
 
 1717     ss << 
"(row " << r+start_index << 
", col " << c+start_index << 
")";
 
 1724     casadi_int d1 = 
size1();
 
 1725     casadi_int d2 = y.
size2();
 
 1744     if (y.
is_diag()) 
return shared_from_this<Sparsity>();
 
 1747     const casadi_int* x_row = 
row();
 
 1748     const casadi_int* x_colind = 
colind();
 
 1749     const casadi_int* y_row = y.
row();
 
 1750     const casadi_int* y_colind = y.
colind();
 
 1753     std::vector<casadi_int> 
row, col;
 
 1756     std::vector<casadi_int> tmp(d1, -1);
 
 1759     for (casadi_int cc=0; cc<d2; ++cc) {
 
 1760       for (casadi_int kk=y_colind[cc]; kk<y_colind[cc+1]; ++kk) {
 
 1761         casadi_int rr = y_row[kk];
 
 1764         for (casadi_int kk1=x_colind[rr]; kk1<x_colind[rr+1]; ++kk1) {
 
 1765           casadi_int rr1 = x_row[kk1];
 
 1782     return size2()==1 && 
size1()==1 && (!scalar_and_dense || 
nnz()==1);
 
 1807     const casadi_int* 
row = this->
row();
 
 1813     if (
nnz() != 
size2()) 
return false;
 
 1816     for (casadi_int i=0; i<
nnz(); ++i) {
 
 1822     for (casadi_int i=0; i<
size2(); ++i) {
 
 1850     if (sum2(
sp).
nnz()!=
nnz()) 
return false;
 
 1851     if (sum1(
sp).
nnz()!=
nnz()) 
return false;
 
 1862     if (sum2(
sp).
nnz()!=
nnz()) 
return false;
 
 1863     if (sum1(
sp).
nnz()!=
nnz()) 
return false;
 
 1874     if (sum2(
sp).
nnz()!=
nnz()) 
return false;
 
 1875     if (sum1(
sp).
nnz()!=
nnz()) 
return false;
 
 1885     const casadi_int* 
row = this->
row();
 
 1887     for (casadi_int cc=0; cc<
size2(); ++cc) {
 
 1888       for (casadi_int el = 
colind[cc]; el<
colind[cc+1]; ++el) {
 
 1889         if (cc<
row[el] || (!strictly && cc==
row[el])) 
nnz++;
 
 1897     const casadi_int* 
row = this->
row();
 
 1899     for (casadi_int cc=0; cc<
size2(); ++cc) {
 
 1900       for (casadi_int el = 
colind[cc]; el < 
colind[cc+1]; ++el) {
 
 1909     const casadi_int* 
row = this->
row();
 
 1911     for (casadi_int cc=0; cc<
size2(); ++cc) {
 
 1912       for (casadi_int el = 
colind[cc]; el<
colind[cc+1]; ++el) {
 
 1913         if (cc>
row[el] || (!strictly && cc==
row[el])) 
nnz++;
 
 1920     return std::pair<casadi_int, casadi_int>(
size1(), 
size2());
 
 1924                                       std::vector<casadi_int>& mapping)
 const {
 
 1928       return shared_from_this<Sparsity>();
 
 1930     casadi_assert_in_range(rr, -
numel()+ind1, 
numel()+ind1);
 
 1934       std::vector<casadi_int> rr_mod = rr;
 
 1935       for (std::vector<casadi_int>::iterator i=rr_mod.begin(); i!=rr_mod.end(); ++i) {
 
 1937         if (*i<0) *i += 
numel();
 
 1939       return _erase(rr_mod, 
false, mapping); 
 
 1944       std::vector<casadi_int> rr_sorted = rr;
 
 1945       std::sort(rr_sorted.begin(), rr_sorted.end());
 
 1946       return _erase(rr_sorted, 
false, mapping);
 
 1953     if (
numel()==0) 
return shared_from_this<Sparsity>();
 
 1956     mapping.reserve(
nnz());
 
 1962     std::vector<casadi_int>::const_iterator next_rr = rr.begin();
 
 1968     casadi_int k_first, k_last=0;
 
 1971     for (casadi_int j=0; j<
size2(); ++j) {
 
 1974       k_last = ret_colind[j+1];
 
 1977       for (casadi_int k=k_first; k<k_last; ++k) {
 
 1979         casadi_int i=ret_row[k];
 
 1982         casadi_int el = i+j*
size1();
 
 1985         while (next_rr!=rr.end() && *next_rr<el) next_rr++;
 
 1988         if (next_rr!=rr.end() && *next_rr==el) {
 
 1994         mapping.push_back(k);
 
 2001       ret_colind[j+1] = nz;
 
 2011       const std::vector<casadi_int>& rr, 
const std::vector<casadi_int>& cc,
 
 2012       bool ind1, std::vector<casadi_int>& mapping)
 const {
 
 2013     casadi_assert_in_range(rr, -
size1()+ind1, 
size1()+ind1);
 
 2014     casadi_assert_in_range(cc, -
size2()+ind1, 
size2()+ind1);
 
 2020       std::vector<casadi_int> rr_mod = rr;
 
 2021       for (std::vector<casadi_int>::iterator i=rr_mod.begin(); i!=rr_mod.end(); ++i) {
 
 2023         if (*i<0) *i += 
size1();
 
 2025       std::sort(rr_mod.begin(), rr_mod.end());
 
 2028       std::vector<casadi_int> cc_mod = cc;
 
 2029       for (std::vector<casadi_int>::iterator i=cc_mod.begin(); i!=cc_mod.end(); ++i) {
 
 2031         if (*i<0) *i += 
size2();
 
 2033       std::sort(cc_mod.begin(), cc_mod.end());
 
 2036       return _erase(rr_mod, cc_mod, 
false, mapping);
 
 2043     if (
numel()==0) 
return shared_from_this<Sparsity>();
 
 2046     mapping.reserve(
nnz());
 
 2055     std::vector<casadi_int>::const_iterator ie = cc.begin();
 
 2058     casadi_int el_first=0, el_last=0;
 
 2061     for (casadi_int i=0; i<
size2(); ++i) {
 
 2064       el_last = ret_colind[i+1];
 
 2067       bool deletable_col = ie!=cc.end() && *ie==i;
 
 2068       if (deletable_col) {
 
 2072         std::vector<casadi_int>::const_iterator je = rr.begin();
 
 2075         for (casadi_int el=el_first; el<el_last; ++el) {
 
 2077           casadi_int j=ret_row[el];
 
 2080           for (; je!=rr.end() && *je<j; ++je) {}
 
 2083           if (je!=rr.end() && *je==j) {
 
 2089           mapping.push_back(el);
 
 2096         for (casadi_int el=el_first; el<el_last; ++el) {
 
 2098           casadi_int j=ret_row[el];
 
 2101           mapping.push_back(el);
 
 2119       const std::vector<casadi_int>& cc)
 const {
 
 2120     casadi_assert_bounded(rr, 
size1());
 
 2121     casadi_assert_bounded(cc, 
size2());
 
 2123     std::vector<casadi_int> rr_sorted;
 
 2124     std::vector<casadi_int> rr_sorted_index;
 
 2126     sort(rr, rr_sorted, rr_sorted_index);
 
 2128     std::vector<casadi_int> ret(cc.size()*rr.size());
 
 2130     casadi_int stride = rr.size();
 
 2132     const casadi_int* 
row = this->
row();
 
 2134     for (casadi_int i=0;i<cc.size();++i) {
 
 2135       casadi_int it = cc[i];
 
 2136       casadi_int el=
colind[it];
 
 2137       for (casadi_int j=0;j<rr_sorted.size();++j) {
 
 2138         casadi_int jt=rr_sorted[j];
 
 2140         for (; el<
colind[it+1] && 
row[el]<jt; ++el) {}
 
 2143           ret[i*stride+rr_sorted_index[j]] = el;
 
 2145           ret[i*stride+rr_sorted_index[j]] = -1;
 
 2153                                  std::vector<casadi_int>& mapping, 
bool ind1)
 const {
 
 2154     casadi_assert_dev(rr.size()==
sp.nnz());
 
 2157     casadi_assert_in_range(rr, -
numel()+ind1, 
numel()+ind1);
 
 2161       std::vector<casadi_int> rr_mod = rr;
 
 2162       for (std::vector<casadi_int>::iterator i=rr_mod.begin(); i!=rr_mod.end(); ++i) {
 
 2163         casadi_assert(!(ind1 && (*i)<=0),
 
 2164           "Matlab is 1-based, but requested index " + 
str(*i) +  
". " 
 2165           "Note that negative slices are disabled in the Matlab interface. " 
 2166           "Possibly you may want to use 'end'.");
 
 2168         if (*i<0) *i += 
numel();
 
 2170       return sub(rr_mod, 
sp, mapping, 
false); 
 
 2174     mapping.resize(rr.size());
 
 2175     std::copy(rr.begin(), rr.end(), mapping.begin());
 
 2179     std::vector<casadi_int> ret_colind(
sp.size2()+1), ret_row;
 
 2181     const casadi_int* sp_colind = 
sp.colind();
 
 2182     const casadi_int* sp_row = 
sp.row();
 
 2183     for (casadi_int c=0; c<
sp.size2(); ++c) {
 
 2184       for (casadi_int el=sp_colind[c]; el<sp_colind[c+1]; ++el) {
 
 2185         if (mapping[el]>=0) {
 
 2186           mapping[ret_row.size()] = mapping[el];
 
 2187           ret_row.push_back(sp_row[el]);
 
 2190       ret_colind[c+1] = ret_row.size();
 
 2192     mapping.resize(ret_row.size());
 
 2193     return Sparsity(
sp.size1(), 
sp.size2(), ret_colind, ret_row);
 
 2197       const std::vector<casadi_int>& rr, 
const std::vector<casadi_int>& cc,
 
 2198       std::vector<casadi_int>& mapping, 
bool ind1)
 const {
 
 2199     casadi_assert_in_range(rr, -
size1()+ind1, 
size1()+ind1);
 
 2200     casadi_assert_in_range(cc, -
size2()+ind1, 
size2()+ind1);
 
 2203     std::vector<casadi_int> tmp = rr;
 
 2204     for (std::vector<casadi_int>::iterator i=tmp.begin(); i!=tmp.end(); ++i) {
 
 2206       if (*i<0) *i += 
size1();
 
 2208     std::vector<casadi_int> rr_sorted, rr_sorted_index;
 
 2209     sort(tmp, rr_sorted, rr_sorted_index, 
false);
 
 2213     for (std::vector<casadi_int>::iterator i=tmp.begin(); i!=tmp.end(); ++i) {
 
 2215       if (*i<0) *i += 
size2();
 
 2217     std::vector<casadi_int> cc_sorted, cc_sorted_index;
 
 2218     sort(tmp, cc_sorted, cc_sorted_index, 
false);
 
 2219     std::vector<casadi_int> columns, rows;
 
 2222     bool with_lookup = 
static_cast<double>(cc.size())*
static_cast<double>(rr.size()) > 
nnz();
 
 2223     std::vector<casadi_int> rrlookup;
 
 2241     const casadi_int* 
row = this->
row();
 
 2242     for (casadi_int i=0; i<cc.size(); ++i) {
 
 2243       casadi_int it = cc_sorted[i];
 
 2246         for (casadi_int el=
colind[it]; el<
colind[it+1]; ++el) {
 
 2247           casadi_int j = 
row[el];
 
 2248           casadi_int ji = rrlookup[j];
 
 2250             casadi_int jv = rr_sorted[ji];
 
 2251             while (ji>=0 && jv == rr_sorted[ji--]) 
nnz++;
 
 2256         casadi_int el = 
colind[it];
 
 2257         for (casadi_int j=0; j<rr_sorted.size(); ++j) {
 
 2258           casadi_int jt=rr_sorted[j];
 
 2260           while (el<
colind[it+1] && 
row[el]<jt) el++;
 
 2267     mapping.resize(
nnz);
 
 2268     columns.resize(
nnz);
 
 2273     for (casadi_int i=0; i<cc.size(); ++i) {
 
 2274       casadi_int it = cc_sorted[i];
 
 2277         for (casadi_int el=
colind[it]; el<
colind[it+1]; ++el) {
 
 2278           casadi_int jt = 
row[el];
 
 2279           casadi_int ji = rrlookup[jt];
 
 2281             casadi_int jv = rr_sorted[ji];
 
 2282             while (ji>=0 && jv == rr_sorted[ji]) {
 
 2283               rows[k] = rr_sorted_index[ji];
 
 2284               columns[k] = cc_sorted_index[i];
 
 2293         casadi_int el = 
colind[it];
 
 2294         for (casadi_int j=0; j<rr_sorted.size(); ++j) {
 
 2295           casadi_int jt=rr_sorted[j];
 
 2297           while (el<
colind[it+1] && 
row[el]<jt) el++;
 
 2300             rows[k] = rr_sorted_index[j];
 
 2301             columns[k] = cc_sorted_index[i];
 
 2309     std::vector<casadi_int> sp_mapping;
 
 2310     std::vector<casadi_int> mapping_ = mapping;
 
 2313     for (casadi_int i=0; i<mapping.size(); ++i)
 
 2314       mapping[i] = mapping_[sp_mapping[i]];
 
 2321                                             bool function0_is_zero)
 const {
 
 2322     static std::vector<unsigned char> mapping;
 
 2323     return combineGen1<false>(y, f0x_is_zero, function0_is_zero, mapping);
 
 2327                                             bool function0_is_zero,
 
 2328                                             std::vector<unsigned char>& mapping)
 const {
 
 2329     return combineGen1<true>(y, f0x_is_zero, function0_is_zero, mapping);
 
 2334     std::vector<unsigned char> mapping;
 
 2335     shared_from_this<Sparsity>().unite(rhs, mapping);
 
 2336     for (
auto e : mapping) {
 
 2337       if (e==1) 
return false;
 
 2342   template<
bool with_mapping>
 
 2344                                                 bool function0_is_zero,
 
 2345                                                 std::vector<unsigned char>& mapping)
 const {
 
 2351         std::fill(mapping.begin(), mapping.end(), 1 | 2);
 
 2357       if (function0_is_zero) {
 
 2358         return combineGen<with_mapping, true, true>(y, mapping);
 
 2360         return combineGen<with_mapping, true, false>(y, mapping);
 
 2362     } 
else if (function0_is_zero) {
 
 2363       return combineGen<with_mapping, false, true>(y, mapping);
 
 2365       return combineGen<with_mapping, false, false>(y, mapping);
 
 2369   template<
bool with_mapping, 
bool f0x_is_zero, 
bool function0_is_zero>
 
 2371                                                std::vector<unsigned char>& mapping)
 const {
 
 2375       "Dimension mismatch : " + 
str(
size()) + 
" versus " + 
str(y.
size()) + 
".");
 
 2378     const casadi_int* y_colind = y.
colind();
 
 2379     const casadi_int* y_row = y.
row();
 
 2381     const casadi_int* 
row = this->
row();
 
 2384     std::vector<casadi_int> ret_colind(
size2()+1, 0);
 
 2385     std::vector<casadi_int> ret_row;
 
 2388     if (with_mapping) mapping.clear();
 
 2391     for (casadi_int i=0; i<
size2(); ++i) {
 
 2393       casadi_int el1 = 
colind[i];
 
 2394       casadi_int el2 = y_colind[i];
 
 2397       casadi_int el1_last = 
colind[i+1];
 
 2398       casadi_int el2_last = y_colind[i+1];
 
 2401       while (el1<el1_last || el2<el2_last) {
 
 2403         casadi_int row1 = el1<el1_last ? 
row[el1] : 
size1();
 
 2404         casadi_int row2 = el2<el2_last ? y_row[el2] : 
size1();
 
 2408           ret_row.push_back(row1);
 
 2409           if (with_mapping) mapping.push_back( 1 | 2);
 
 2411         } 
else if (row1<row2) { 
 
 2412           if (!function0_is_zero) {
 
 2413             ret_row.push_back(row1);
 
 2414             if (with_mapping) mapping.push_back(1);
 
 2416             if (with_mapping) mapping.push_back(1 | 4);
 
 2421             ret_row.push_back(row2);
 
 2422             if (with_mapping) mapping.push_back(2);
 
 2424             if (with_mapping) mapping.push_back(2 | 4);
 
 2431       ret_colind[i+1] = ret_row.size();
 
 2440     if (n==1 && 
is_equal(y)) 
return true;
 
 2445     const casadi_int* 
row = this->
row();
 
 2446     casadi_int y_size1 = y.
size1();
 
 2447     casadi_int y_size2 = y.
size2();
 
 2448     const casadi_int* y_colind = y.
colind();
 
 2449     const casadi_int* y_row = y.
row();
 
 2451     if (
size1!=y_size1 || 
size2!=n*y_size2) 
return false;
 
 2454     if (
nnz!=n*y_nnz) 
return false;
 
 2456     if (y_nnz==y_size1*y_size2) 
return true;
 
 2458     casadi_int offset = 0;
 
 2462     for (
int i=0; i<n; ++i) {
 
 2464       for (
int c=0; c<y_size2; ++c) 
if (y_colind[c+1]+offset != *
colind++) 
return false;
 
 2466       for (
int k=0; k<y_nnz; ++k) 
if (y_row[k] != *
row++) 
return false;
 
 2476     if (
this == y.
get()) 
return true;
 
 2488     std::vector<casadi_int> row_ret;
 
 2489     std::vector<casadi_int> colind_ret=
get_colind();
 
 2491     const casadi_int* 
row = this->
row();
 
 2494     for (casadi_int i=0;i<
size2();++i) {
 
 2507           row_ret.push_back(j);
 
 2513       while (j < 
size1())  {
 
 2514         row_ret.push_back(j);
 
 2525                                   const std::vector<casadi_int>& y_colind,
 
 2526                                   const std::vector<casadi_int>& y_row)
 const {
 
 2527     casadi_assert_dev(y_colind.size()==y_ncol+1);
 
 2528     casadi_assert_dev(y_row.size()==y_colind.back());
 
 2533                                  const casadi_int* y_colind, 
const casadi_int* y_row)
 const {
 
 2535     const casadi_int* 
row = this->
row();
 
 2538     casadi_int nz = y_colind[y_ncol];
 
 2541     if (
nnz()!=nz || 
size2()!=y_ncol || 
size1()!=y_nrow) 
return false;
 
 2550     if (!std::equal(
row, 
row+nz, y_row)) 
return false;
 
 2557     casadi_assert(
size2() == 1 && 
sp.size2() == 1,
 
 2558       "_appendVector(sp): Both arguments must be vectors but got " 
 2559        + 
str(
size2()) + 
" columns for lhs, and " + 
str(
sp.size2()) + 
" columns for rhs.");
 
 2562     casadi_int sz = 
nnz();
 
 2565     std::vector<casadi_int> new_row = 
get_row();
 
 2566     const casadi_int* sp_row = 
sp.row();
 
 2567     new_row.resize(sz + 
sp.nnz());
 
 2568     for (casadi_int i=sz; i<new_row.size(); ++i)
 
 2569       new_row[i] = sp_row[i-sz] + 
size1();
 
 2572     std::vector<casadi_int> new_colind(2, 0);
 
 2573     new_colind[1] = new_row.size();
 
 2578     casadi_assert(
size1()== 
sp.size1(),
 
 2579       "_appendColumns(sp): row sizes must match but got " + 
str(
size1())
 
 2580                           + 
" for lhs, and " + 
str(
sp.size1()) + 
" for rhs.");
 
 2583     std::vector<casadi_int> new_row = 
get_row();
 
 2584     const casadi_int* sp_row = 
sp.row();
 
 2585     new_row.insert(new_row.end(), sp_row, sp_row+
sp.nnz());
 
 2588     std::vector<casadi_int> new_colind = 
get_colind();
 
 2589     const casadi_int* sp_colind = 
sp.colind();
 
 2590     new_colind.resize(
size2() + 
sp.size2() + 1);
 
 2591     for (casadi_int i = 
size2()+1; i<new_colind.size(); ++i)
 
 2592       new_colind[i] = sp_colind[i-
size2()] + 
nnz();
 
 2599     casadi_assert_in_range(cc, -ncol+ind1, ncol+ind1);
 
 2603       std::vector<casadi_int> cc_mod = cc;
 
 2604       for (std::vector<casadi_int>::iterator i=cc_mod.begin(); i!=cc_mod.end(); ++i) {
 
 2606         if (*i<0) *i += ncol;
 
 2612     std::vector<casadi_int> new_colind = 
get_colind();
 
 2613     new_colind.resize(ncol+1, 
nnz());
 
 2615     casadi_int ik=cc.back(); 
 
 2616     casadi_int nz=
nnz(); 
 
 2617     for (casadi_int i=cc.size()-1; i>=0; --i) {
 
 2619       for (; ik>cc[i]; --ik) {
 
 2620         new_colind[ik] = nz;
 
 2627       new_colind[cc[i]] = nz;
 
 2631     for (; ik>=0; --ik) {
 
 2638       const std::vector<casadi_int>& rr, 
bool ind1)
 const {
 
 2639     casadi_assert_in_range(rr, -nrow+ind1, nrow+ind1);
 
 2643       std::vector<casadi_int> rr_mod = rr;
 
 2644       for (std::vector<casadi_int>::iterator i=rr_mod.begin(); i!=rr_mod.end(); ++i) {
 
 2646         if (*i<0) *i += nrow;
 
 2652     casadi_assert_dev(rr.size() == 
size1());
 
 2655     std::vector<casadi_int> new_row = 
get_row();
 
 2656     for (casadi_int k=0; k<
nnz(); ++k) {
 
 2657       new_row[k] = rr[new_row[k]];
 
 2664     const casadi_int* 
row = this->
row();
 
 2665     mapping.resize(
nnz());
 
 2666     for (casadi_int i=0; i<
size2(); ++i) {
 
 2668         casadi_int j = 
row[el];
 
 2669         mapping[el] = j + i*
size1();
 
 2678     if (rr<0) rr += 
size1();
 
 2679     if (cc<0) cc += 
size2();
 
 2681     const casadi_int* 
row = this->
row();
 
 2684     casadi_assert(rr>=0 && rr<
size1(), 
"Row index " + 
str(rr)
 
 2685                           + 
" out of bounds [0, " + 
str(
size1()) + 
")");
 
 2686     casadi_assert(cc>=0 && cc<
size2(), 
"Column index " + 
str(cc)
 
 2687                           + 
" out of bounds [0, " + 
str(
size2()) + 
")");
 
 2696     for (casadi_int ind=
colind[cc]; ind<
colind[cc+1]; ++ind) {
 
 2697       if (
row[ind] == rr) {
 
 2699       } 
else if (
row[ind] > rr) {
 
 2708     if (nrow<0 && ncol>0) {
 
 2710     } 
else if (nrow>0 && ncol<0) {
 
 2714     casadi_assert(
numel() == nrow*ncol,
 
 2715                           "reshape: number of elements must remain the same. Old shape is " 
 2716                           + 
dim() + 
". New shape is " + 
str(nrow) + 
"x" + 
str(ncol)
 
 2717                           + 
"=" + 
str(nrow*ncol) + 
".");
 
 2718     std::vector<casadi_int> ret_col(
nnz());
 
 2719     std::vector<casadi_int> ret_row(
nnz());
 
 2721     const casadi_int* 
row = this->
row();
 
 2722     for (casadi_int i=0; i<
size2(); ++i) {
 
 2724         casadi_int j = 
row[el];
 
 2727         casadi_int k_ret = j+i*
size1();
 
 2730         casadi_int i_ret = k_ret/nrow;
 
 2731         casadi_int j_ret = k_ret%nrow;
 
 2732         ret_col[el] = i_ret;
 
 2733         ret_row[el] = j_ret;
 
 2741     std::vector<casadi_int> row_new, colind_new(ncol+1, 0);
 
 2743     const casadi_int* 
row = this->
row();
 
 2747     for (i=0; i<
size2() && i<ncol; ++i) {
 
 2749       colind_new[i] = row_new.size();
 
 2753         row_new.push_back(
row[el]);
 
 2758     for (; i<ncol+1; ++i) {
 
 2759       colind_new[i] = row_new.size();
 
 2762     return Sparsity(nrow, ncol, colind_new, row_new);
 
 2767     const casadi_int* 
row = this->
row();
 
 2768     for (casadi_int i=0; i<
size2(); ++i) {
 
 2769       casadi_int lastrow = -1;
 
 2773         if (
row[k] < lastrow)
 
 2777         if (strictly && 
row[k] == lastrow)
 
 2790     casadi_assert_dev(mapping.size()==
nnz());
 
 2796     casadi_int k_strict=0;
 
 2799     for (casadi_int i=0; i<
size2(); ++i) {
 
 2802       casadi_int lastrow = -1;
 
 2805       casadi_int new_colind = k_strict;
 
 2808       for (casadi_int k=ret_colind[i]; k<ret_colind[i+1]; ++k) {
 
 2811         casadi_assert(ret_row[k] >= lastrow, 
"rows are not sequential");
 
 2814         if (ret_row[k] == lastrow) 
continue;
 
 2817         lastrow = ret_row[k];
 
 2820         mapping[k_strict] = mapping[k];
 
 2823         ret_row[k_strict] = ret_row[k];
 
 2830       ret_colind[i] = new_colind;
 
 2834     ret_colind[
size2()] = k_strict;
 
 2835     ret_row.resize(k_strict);
 
 2836     mapping.resize(k_strict);
 
 2847     const casadi_int* 
row = this->
row();
 
 2853     for (casadi_int cc=0; cc<
size2(); ++cc) {
 
 2856       for (casadi_int el=
colind[cc]; el<
colind[cc+1]; ++el) {
 
 2859         casadi_int rr = 
row[el];
 
 2862         loc[el] = rr+cc*
size1()+ind1;
 
 2869     if (indices.empty()) 
return;
 
 2873     const casadi_int* 
row = this->
row();
 
 2877     for (std::vector<casadi_int>::iterator it=indices.begin(); it!=indices.end(); ++it) {
 
 2879         casadi_int el = *it;
 
 2882           std::vector<casadi_int> indices_sorted, mapping;
 
 2883           sort(indices, indices_sorted, mapping, 
false);
 
 2885           for (
size_t i=0; i<indices.size(); ++i) {
 
 2886             indices[mapping[i]] = indices_sorted[i];
 
 2898     std::vector<casadi_int>::iterator it=indices.begin();
 
 2902     casadi_int cur_pos = -1;
 
 2904     casadi_int col_pos = 0;
 
 2907     for (casadi_int i=0; i<
size2(); ++i, col_pos+=
size1()) {
 
 2910       casadi_int last_pos = -1;
 
 2914         casadi_int el = 
colind[i+1] - 1;
 
 2915         casadi_int j = 
row[el];
 
 2916         last_pos = col_pos + j;
 
 2922       for (casadi_int el=
colind[i]; el<colind[i+1] && last_pos >= *it; ++el) {
 
 2924         casadi_int j = 
row[el];
 
 2926         cur_pos = col_pos + j;
 
 2929         while (*it < cur_pos) {
 
 2932           if (++it==indices.end()) 
return;
 
 2935         while (cur_pos == *it) {
 
 2941             if (++it==indices.end()) 
return;
 
 2948     std::fill(it, indices.end(), -1);
 
 2954     std::vector<casadi_int> forbiddenColors;
 
 2955     forbiddenColors.reserve(
size2());
 
 2956     std::vector<casadi_int> color(
size2(), 0);
 
 2959     const casadi_int* AT_colind = AT.
colind();
 
 2960     const casadi_int* AT_row = AT.
row();
 
 2962     const casadi_int* 
row = this->
row();
 
 2965     for (casadi_int i=0; i<
size2(); ++i) {
 
 2971         casadi_int c = 
row[el];
 
 2974         for (casadi_int el_prev=AT_colind[c]; el_prev<AT_colind[c+1]; ++el_prev) {
 
 2977           casadi_int i_prev = AT_row[el_prev];
 
 2984           casadi_int color_prev = color[i_prev];
 
 2987           forbiddenColors[color_prev] = i;
 
 2993       for (color_i=0; color_i<forbiddenColors.size(); ++color_i) {
 
 2995         if (forbiddenColors[color_i]!=i) 
break;
 
 3000       if (color_i==forbiddenColors.size()) {
 
 3001         forbiddenColors.push_back(0);
 
 3004         if (forbiddenColors.size()>cutoff) {
 
 3011     std::vector<casadi_int> ret_colind(forbiddenColors.size()+1, 0), ret_row;
 
 3014     for (casadi_int i=0; i<color.size(); ++i) {
 
 3015       ret_colind[color[i]+1]++;
 
 3019     for (casadi_int j=0; j<forbiddenColors.size(); ++j) {
 
 3020       ret_colind[j+1] += ret_colind[j];
 
 3024     ret_row.resize(color.size());
 
 3025     for (casadi_int j=0; j<ret_row.size(); ++j) {
 
 3026       ret_row[ret_colind[color[j]]++] = j;
 
 3030     for (casadi_int j=ret_colind.size()-2; j>=0; --j) {
 
 3031       ret_colind[j+1] = ret_colind[j];
 
 3036     return Sparsity(
size2(), forbiddenColors.size(), ret_colind, ret_row);
 
 3043       casadi_message(
"StarColoring requires a square matrix, got " + 
dim() + 
".");
 
 3049     const casadi_int* 
row = this->
row();
 
 3051       casadi_assert_dev(ordering==1);
 
 3063       return ret_permuted.
pmult(ord, 
true, 
false, 
false);
 
 3067     std::vector<casadi_int> forbiddenColors;
 
 3068     forbiddenColors.reserve(
size2());
 
 3069     std::vector<casadi_int> color(
size2(), -1);
 
 3071     std::vector<casadi_int> firstNeighborP(
size2(), -1);
 
 3072     std::vector<casadi_int> firstNeighborQ(
size2(), -1);
 
 3073     std::vector<casadi_int> firstNeighborQ_el(
size2(), -1);
 
 3075     std::vector<casadi_int> treated(
size2(), -1);
 
 3076     std::vector<casadi_int> hub(
nnz_upper(), -1);
 
 3078     std::vector<casadi_int> Tmapping;
 
 3081     std::vector<casadi_int> star(
nnz());
 
 3083     for (casadi_int i=0; i<
size2(); ++i) {
 
 3084       for (casadi_int j_el=
colind[i]; j_el<
colind[i+1]; ++j_el) {
 
 3085         casadi_int j = 
row[j_el];
 
 3088           star[Tmapping[j]] = k;
 
 3096     casadi_int starID = 0;
 
 3099     for (casadi_int v=0; v<
size2(); ++v) {
 
 3102       for (casadi_int w_el=
colind[v]; w_el<
colind[v+1]; ++w_el) {
 
 3103           casadi_int w = 
row[w_el];
 
 3104           casadi_int colorW = color[w];
 
 3105           if (colorW==-1) 
continue;
 
 3108           forbiddenColors[colorW] = v;
 
 3111           casadi_int p = firstNeighborP[colorW];
 
 3112           casadi_int q = firstNeighborQ[colorW];
 
 3118             if (treated[q]!=v) {
 
 3123                 for (casadi_int x_el=
colind[q]; x_el<
colind[q+1]; ++x_el) {
 
 3124                   casadi_int x = 
row[x_el];
 
 3125                   if (color[x]==-1) 
continue;
 
 3128                   forbiddenColors[color[x]] = v;
 
 3138               for (casadi_int x_el=
colind[w]; x_el<
colind[w+1]; ++x_el) {
 
 3139                 casadi_int x = 
row[x_el];
 
 3140                 if (color[x]==-1) 
continue;
 
 3143                 forbiddenColors[color[x]] = v;
 
 3153             firstNeighborP[colorW] = v;
 
 3154             firstNeighborQ[colorW] = w;
 
 3155             firstNeighborQ_el[colorW] = w_el;
 
 3158             casadi_int x_el_end = 
colind[w+1];
 
 3159             casadi_int x, colorx;
 
 3160             for (casadi_int x_el=
colind[w]; x_el < x_el_end; ++x_el) {
 
 3163               if (colorx==-1 || x==v) 
continue;
 
 3166               if (hub[star[x_el]]==x) {
 
 3169                 forbiddenColors[colorx] = v;
 
 3178       bool new_color = 
true;
 
 3179       for (casadi_int color_i=0; color_i<forbiddenColors.size(); ++color_i) {
 
 3181         if (forbiddenColors[color_i]!=v) {
 
 3190         color[v] = forbiddenColors.size();
 
 3191         forbiddenColors.push_back(-1);
 
 3194         if (forbiddenColors.size()>cutoff) {
 
 3202         for (casadi_int w_el=
colind[v]; w_el<
colind[v+1]; ++w_el) {
 
 3203             casadi_int w = 
row[w_el];
 
 3204             casadi_int colorW = color[w];
 
 3205             if (colorW==-1) 
continue;
 
 3213               if (x==v || color[x]!=color[v]) 
continue;
 
 3220               casadi_int starwx = star[x_el];
 
 3224               star[w_el]  = starwx;
 
 3225               star[Tmapping[w_el]] = starwx;
 
 3231               casadi_int p = firstNeighborP[colorW];
 
 3232               casadi_int q = firstNeighborQ[colorW];
 
 3233               casadi_int q_el = firstNeighborQ_el[colorW];
 
 3239                 casadi_int starvq = star[q_el];
 
 3243                 star[w_el]  = starvq;
 
 3244                 star[Tmapping[w_el]] = starvq;
 
 3253                 star[w_el] = starID;
 
 3254                 star[Tmapping[w_el]]= starID;
 
 3265     std::vector<casadi_int> ret_colind(forbiddenColors.size()+1, 0), ret_row;
 
 3268     for (casadi_int i=0; i<color.size(); ++i) {
 
 3269       ret_colind[color[i]+1]++;
 
 3273     for (casadi_int j=0; j<forbiddenColors.size(); ++j) {
 
 3274       ret_colind[j+1] += ret_colind[j];
 
 3278     ret_row.resize(color.size());
 
 3279     for (casadi_int j=0; j<ret_row.size(); ++j) {
 
 3280       ret_row[ret_colind[color[j]]++] = j;
 
 3284     for (casadi_int j=ret_colind.size()-2; j>=0; --j) {
 
 3285       ret_colind[j+1] = ret_colind[j];
 
 3290     return Sparsity(
size2(), forbiddenColors.size(), ret_colind, ret_row);
 
 3296       casadi_message(
"StarColoring requires a square matrix, got " + 
dim() + 
".");
 
 3301       casadi_assert_dev(ordering==1);
 
 3313       return ret_permuted.
pmult(ord, 
true, 
false, 
false);
 
 3318     const casadi_int* 
row = this->
row();
 
 3319     std::vector<casadi_int> forbiddenColors;
 
 3320     forbiddenColors.reserve(
size2());
 
 3321     std::vector<casadi_int> color(
size2(), -1);
 
 3324     for (casadi_int i=0; i<
size2(); ++i) {
 
 3327       for (casadi_int w_el=
colind[i]; w_el<
colind[i+1]; ++w_el) {
 
 3328         casadi_int w = 
row[w_el];
 
 3334           forbiddenColors[color[w]] = i;
 
 3339         for (casadi_int x_el=
colind[w]; x_el<
colind[w+1]; ++x_el) {
 
 3340           casadi_int x = 
row[x_el];
 
 3341           if (color[x]==-1) 
continue;
 
 3347             forbiddenColors[color[x]] = i;
 
 3352             for (casadi_int y_el=
colind[x]; y_el<
colind[x+1]; ++y_el) {
 
 3353               casadi_int y = 
row[y_el];
 
 3354               if (color[y]==-1 || y==w) 
continue;
 
 3357               if (color[y]==color[w]) {
 
 3360                 forbiddenColors[color[x]] = i;
 
 3376       bool new_color = 
true;
 
 3377       for (casadi_int color_i=0; color_i<forbiddenColors.size(); ++color_i) {
 
 3379         if (forbiddenColors[color_i]!=i) {
 
 3388         color[i] = forbiddenColors.size();
 
 3389         forbiddenColors.push_back(-1);
 
 3392         if (forbiddenColors.size()>cutoff) {
 
 3400     casadi_int num_colors = forbiddenColors.size();
 
 3407     std::vector<casadi_int> degree = 
get_colind();
 
 3408     casadi_int max_degree = 0;
 
 3409     for (casadi_int k=0; k<
size2(); ++k) {
 
 3410       degree[k] = degree[k+1]-degree[k];
 
 3411       max_degree = std::max(max_degree, 1+degree[k]);
 
 3413     degree.resize(
size2());
 
 3416     std::vector<casadi_int> degree_count(max_degree+1, 0);
 
 3417     for (std::vector<casadi_int>::const_iterator it=degree.begin(); it!=degree.end(); ++it) {
 
 3418       degree_count.at(*it+1)++;
 
 3422     for (casadi_int d=0; d<max_degree; ++d) {
 
 3423       degree_count[d+1] += degree_count[d];
 
 3427     std::vector<casadi_int> ordering(
size2());
 
 3428     for (casadi_int k=
size2()-1; k>=0; --k) {
 
 3429       ordering[degree_count[degree[k]]++] = k;
 
 3433     std::vector<casadi_int>& reverse_ordering = degree_count; 
 
 3434     reverse_ordering.resize(ordering.size());
 
 3435     std::copy(ordering.begin(), ordering.end(), reverse_ordering.rbegin());
 
 3438     return reverse_ordering;
 
 3444     std::vector<casadi_int> p_inv;
 
 3447       for (casadi_int k=0; k<p.size(); ++k) {
 
 3454     std::vector<casadi_int> col = 
get_col();
 
 3457     const casadi_int* 
row = this->
row();
 
 3460     std::vector<casadi_int> new_row(col.size()), new_col(col.size());
 
 3463     if (permute_columns) {
 
 3465       casadi_assert_dev(p.size()==
size2());
 
 3468       for (casadi_int k=0; k<col.size(); ++k) {
 
 3469         new_col[k] = pp[col[k]];
 
 3474       std::copy(col.begin(), col.end(), new_col.begin());
 
 3480       casadi_assert_dev(p.size()==
size1());
 
 3483       for (casadi_int k=0; k<
nnz(); ++k) {
 
 3484         new_row[k] = pp[
row[k]];
 
 3489       std::copy(
row, 
row+
nnz(), new_row.begin());
 
 3509     std::vector<casadi_int> y_col_count(y.
size2(), 0);
 
 3511     const casadi_int* 
row = this->
row();
 
 3512     const casadi_int* y_colind = y.
colind();
 
 3513     const casadi_int* y_row = y.
row();
 
 3516     for (casadi_int i=0; i<
size2(); ++i) {
 
 3522         casadi_int j=
row[el];
 
 3525         casadi_int el_y = y_colind[j] + y_col_count[j]++;
 
 3528         if (el_y>=y_colind[j+1]) 
return false;
 
 3531         casadi_int j_y = y_row[el_y];
 
 3534         if (j_y != i) 
return false;
 
 3544     if (
this==&y) 
return true;
 
 3554     const casadi_int* 
row = this->
row();
 
 3555     const casadi_int* y_colind = y.
colind();
 
 3556     const casadi_int* y_row = y.
row();
 
 3562     for (casadi_int cc=0; cc<
size2(); ++cc) {
 
 3563       for (casadi_int el=
colind[cc]; el<
colind[cc+1]; ++el) {
 
 3564         casadi_int rr=
row[el];
 
 3567         casadi_int loc = rr+
size1()*cc;
 
 3568         casadi_int rr_y = loc % y.
size1();
 
 3569         casadi_int cc_y = loc / y.
size1();
 
 3572         if (rr_y != y_row[el] || el<y_colind[cc_y] || el>=y_colind[cc_y+1])
 
 3586     const casadi_int* 
row = this->
row();
 
 3589     for (casadi_int rr=0; rr<
size1(); ++rr) {
 
 3592       for (casadi_int cc=0; cc<
size2(); ++cc) {
 
 3594         if (cind[cc]<
colind[cc+1] && 
row[cind[cc]]==rr) {
 
 3603       stream << std::endl;
 
 3608       std::ostream &stream, 
const Dict& options)
 const {
 
 3609     casadi_assert(lang==
"matlab", 
"Only matlab language supported for now.");
 
 3612     bool opt_inline = 
false;
 
 3613     std::string name = 
"sp";
 
 3614     bool as_matrix = 
true;
 
 3615     casadi_int indent_level = 0;
 
 3616     std::vector<std::string> nonzeros;
 
 3619     for (
auto&& op : options) {
 
 3620       if (op.first==
"inline") {
 
 3621         opt_inline = op.second;
 
 3622       } 
else if (op.first==
"name") {
 
 3623         name = op.second.to_string();
 
 3624       } 
else if (op.first==
"as_matrix") {
 
 3625         as_matrix = op.second;
 
 3626       } 
else if (op.first==
"indent_level") {
 
 3627         indent_level = op.second;
 
 3628       } 
else if (op.first==
"nonzeros") {
 
 3629         nonzeros = op.second;
 
 3631         casadi_error(
"Unknown option '" + op.first + 
"'.");
 
 3637     for (casadi_int i=0; i < indent_level; ++i) indent += 
"  ";
 
 3638     casadi_assert(!opt_inline, 
"Inline not supported for now.");
 
 3641     stream << indent << name << 
"_m = " << 
size1() << 
";\n";
 
 3642     stream << indent << name << 
"_n = " << 
size2() << 
";\n";
 
 3645     const casadi_int index_offset = 1;
 
 3649     const casadi_int* 
row = this->
row();
 
 3650     stream << indent << name<< 
"_j = [";
 
 3652     for (casadi_int i=0; i<
size2(); ++i) {
 
 3654         if (!first) stream << 
", ";
 
 3655         stream << (i+index_offset);
 
 3662     stream << indent << name << 
"_i = [";
 
 3664     casadi_int nz = 
nnz();
 
 3665     for (casadi_int i=0; i<nz; ++i) {
 
 3666       if (!first) stream << 
", ";
 
 3667       stream << (
row[i]+index_offset);
 
 3673     stream << indent << name << 
"_v = ";
 
 3674     if (nonzeros.empty()) {
 
 3675       stream << 
"ones(size(" << name << 
"_i));\n";
 
 3678       for (casadi_int i = 0; i < nonzeros.size(); ++i) {
 
 3679         if (i > 0) stream << 
", ";
 
 3680         stream << nonzeros.at(i);
 
 3687       stream << indent << name << 
" = sparse(" << name << 
"_i, " << name << 
"_j, ";
 
 3688       stream << name << 
"_v, " << name << 
"_m, " << name << 
"_n);\n";
 
 3696     std::ostream& mfile = *mfile_ptr;
 
 3699     mfile << 
"% This function was automatically generated by CasADi" << std::endl;
 
 3706     mfile << 
"spy(A);" << std::endl;
 
 3715     const casadi_int* 
row = this->
row();
 
 3717     for (casadi_int i=0; i<
size2(); ++i) {
 
 3722         if (strictly ? rr <= i : rr < i) 
return false;
 
 3731     const casadi_int* 
row = this->
row();
 
 3733     for (casadi_int i=0; i<
size2(); ++i) {
 
 3738         if (strictly ? rr >= i : rr > i) 
return false;
 
 3747     const casadi_int* 
row = this->
row();
 
 3748     std::vector<casadi_int> ret_colind, ret_row;
 
 3749     ret_colind.reserve(
size2()+1);
 
 3750     ret_colind.push_back(0);
 
 3751     for (casadi_int cc=0; cc<
size2(); ++cc) {
 
 3752       for (casadi_int el=
colind[cc]; el<
colind[cc+1]; ++el) {
 
 3753         casadi_int rr=
row[el];
 
 3754         if (rr>cc || (includeDiagonal && rr==cc)) {
 
 3755           ret_row.push_back(rr);
 
 3758       ret_colind.push_back(ret_row.size());
 
 3765     const casadi_int* 
row = this->
row();
 
 3766     std::vector<casadi_int> ret_colind, ret_row;
 
 3767     ret_colind.reserve(
size2()+1);
 
 3768     ret_colind.push_back(0);
 
 3769     for (casadi_int cc=0; cc<
size2(); ++cc) {
 
 3770       for (casadi_int el=
colind[cc]; el<
colind[cc+1]; ++el) {
 
 3771         casadi_int rr=
row[el];
 
 3772         if (rr<cc || (includeDiagonal && rr==cc)) {
 
 3773           ret_row.push_back(rr);
 
 3776       ret_colind.push_back(ret_row.size());
 
 3783     const casadi_int* 
row = this->
row();
 
 3784     std::vector<casadi_int> ret;
 
 3785     for (casadi_int cc=0; cc<
size2(); ++cc) {
 
 3786       for (casadi_int el = 
colind[cc]; el<
colind[cc+1]; ++el) {
 
 3797     const casadi_int* 
row = this->
row();
 
 3798     std::vector<casadi_int> ret;
 
 3799     for (casadi_int cc=0; cc<
size2(); ++cc) {
 
 3800       for (casadi_int el = 
colind[cc]; el<
colind[cc+1] && 
row[el]<=cc; ++el) {
 
 3810     const casadi_int* 
row = this->
row();
 
 3811     for (casadi_int cc=0; cc<
size2(); ++cc) {
 
 3814         bw = std::max(bw, cc-rr);
 
 3823     const casadi_int* 
row = this->
row();
 
 3824     for (casadi_int cc=0; cc<
size2(); ++cc) {
 
 3827         bw = std::max(bw, rr-cc);
 
 3839     const casadi_int* 
row = this->
row();
 
 3840     return std::vector<casadi_int>(
row, 
row+
nnz());
 
 3845     const Btf& 
btf = this->
btf();
 
 3847     const casadi_int* 
row = this->
row();
 
 3850       for (casadi_int b = 0; b < 
btf.nb; ++b) { 
 
 3854         for (casadi_int el=
btf.rowblock[b]; el<
btf.rowblock[b+1]; ++el) {
 
 3855           casadi_int rr = 
btf.rowperm[el];
 
 3860         for (casadi_int el=
btf.colblock[b]; el<
btf.colblock[b+1]; ++el) {
 
 3861           casadi_int cc = 
btf.colperm[el];
 
 3866         for (casadi_int el=
btf.colblock[b]; el<
btf.colblock[b+1]; ++el) {
 
 3867           casadi_int cc = 
btf.colperm[el];
 
 3874             casadi_int rr=
row[k];
 
 3881       for (casadi_int b = 
btf.nb; b-- > 0; ) { 
 
 3885         for (casadi_int el=
btf.colblock[b]; el<
btf.colblock[b+1]; ++el) {
 
 3886           casadi_int cc = 
btf.colperm[el];
 
 3893             casadi_int rr=
row[k];
 
 3899         for (casadi_int el=
btf.colblock[b]; el<
btf.colblock[b+1]; ++el) {
 
 3900           casadi_int cc = 
btf.colperm[el];
 
 3905         for (casadi_int el=
btf.rowblock[b]; el<
btf.rowblock[b+1]; ++el) {
 
 3906           casadi_int rr = 
btf.rowperm[el];
 
static std::unique_ptr< std::ostream > ofstream_ptr(const std::string &path, std::ios_base::openmode mode=std::ios_base::out)
bool is_null() const
Is a null pointer?
static casadi_int start_index
static casadi_int drop(casadi_int(*fkeep)(casadi_int, casadi_int, double, void *), void *other, casadi_int nrow, casadi_int ncol, std::vector< casadi_int > &colind, std::vector< casadi_int > &row)
drop entries for which fkeep(A(i, j)) is false; return nz if OK, else -1
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.
void bfs(casadi_int n, std::vector< casadi_int > &wi, std::vector< casadi_int > &wj, std::vector< casadi_int > &queue, const std::vector< casadi_int > &imatch, const std::vector< casadi_int > &jmatch, casadi_int mark) const
Breadth-first search for coarse decomposition.
Sparsity combineGen1(const Sparsity &y, bool f0x_is_zero, bool function0_is_zero, std::vector< unsigned char > &mapping) const
bool is_permutation() const
Is this a permutation matrix?
std::size_t hash() const
Hash the sparsity pattern.
void export_code(const std::string &lang, std::ostream &stream, const Dict &options) const
Export sparsity in Matlab format.
bool is_empty(bool both=false) const
Check if the sparsity is empty.
static casadi_int leaf(casadi_int i, casadi_int j, const casadi_int *first, casadi_int *maxfirst, casadi_int *prevleaf, casadi_int *ancestor, casadi_int *jleaf)
Needed by casadi_qr_colind.
static casadi_int wclear(casadi_int mark, casadi_int lemax, casadi_int *w, casadi_int n)
clear w
std::pair< casadi_int, casadi_int > size() const
Shape.
bool rowsSequential(bool strictly) const
Does the rows appear sequentially on each col.
Sparsity makeDense(std::vector< casadi_int > &mapping) const
Make a patten dense.
casadi_int numel() const
Number of elements.
bool is_orthonormal_rows(bool allow_empty=false) const
Are the rows of the pattern orthonormal ?
~SparsityInternal() override
Destructor.
bool is_square() const
Is square?
std::string repr_el(casadi_int k) const
Describe the nonzero location k as a string.
static void postorder(const casadi_int *parent, casadi_int n, casadi_int *post, casadi_int *w)
Calculate the postorder permuation.
Sparsity _enlargeColumns(casadi_int ncol, const std::vector< casadi_int > &cc, bool ind1) const
Enlarge the matrix along the second dimension (i.e. insert columns)
Sparsity _mtimes(const Sparsity &y) const
Sparsity pattern for a matrix-matrix product (details in public class)
bool has_diag() const
has diagonal entries?
static casadi_int postorder_dfs(casadi_int j, casadi_int k, casadi_int *head, const casadi_int *next, casadi_int *post, casadi_int *stack)
Traverse an elimination tree using depth first search.
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.
bool is_transpose(const SparsityInternal &y) const
Check if the sparsity is the transpose of another.
Sparsity _enlargeRows(casadi_int nrow, const std::vector< casadi_int > &rr, bool ind1) const
Enlarge the matrix along the first dimension (i.e. insert rows)
bool is_subset(const Sparsity &rhs) const
Is subset?
casadi_int nnz_lower(bool strictly=false) const
Number of non-zeros in the lower triangular half.
bool is_orthonormal_columns(bool allow_empty=false) const
Are the columns of the pattern orthonormal ?
bool is_column() const
Check if the pattern is a column vector (i.e. size2()==1)
void maxtrans(std::vector< casadi_int > &imatch, std::vector< casadi_int > &jmatch, Sparsity &trans, casadi_int seed) const
Compute the maximum transversal (maximum matching)
const std::vector< casadi_int > & sp() const
Get number of rows (see 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 _removeDuplicates(std::vector< casadi_int > &mapping) const
Remove duplicate entries.
void spy_matlab(const std::string &mfile) const
Generate a script for Matlab or Octave which visualizes the sparsity using the spy command.
std::vector< casadi_int > get_lower() const
Get nonzeros in lower triangular part.
casadi_int bw_lower() const
Lower half-bandwidth.
SparsityInternal(casadi_int nrow, casadi_int ncol, const casadi_int *colind, const casadi_int *row)
Construct a sparsity pattern from arrays.
Sparsity transpose(std::vector< casadi_int > &mapping, bool invert_mapping=false) const
Transpose the matrix and get the reordering of the non-zero entries,.
bool is_symmetric() const
Is symmetric?
std::vector< casadi_int > amd() const
Approximate minimal degree preordering.
static casadi_int qr_counts(const casadi_int *tr_sp, const casadi_int *parent, const casadi_int *post, casadi_int *counts, casadi_int *w)
Calculate the column offsets for the QR R matrix.
void disp(std::ostream &stream, bool more) const override
Print description.
bool is_reshape(const SparsityInternal &y) const
Check if the sparsity is a reshape of another.
void spsolve(bvec_t *X, bvec_t *B, bool tr) const
Propagate sparsity through a linear solve.
static casadi_int qr_nnz(const casadi_int *sp, casadi_int *pinv, casadi_int *leftmost, const casadi_int *parent, casadi_int *nrow_ext, casadi_int *w)
Calculate the number of nonzeros in the QR V matrix.
bool is_diag() const
Is diagonal?
bool is_selection(bool allow_empty=false) const
Is this a selection matrix.
bool is_tril(bool strictly) const
Is lower triangular?
void augment(casadi_int k, std::vector< casadi_int > &jmatch, casadi_int *cheap, std::vector< casadi_int > &w, casadi_int *js, casadi_int *is, casadi_int *ps) const
Find an augmenting path.
static void unmatched(casadi_int m, const std::vector< casadi_int > &wi, std::vector< casadi_int > &p, std::vector< casadi_int > &rr, casadi_int set)
Collect unmatched columns into the permutation vector p.
bool is_vector() const
Check if the pattern is a row or column vector.
casadi_int size1() const
Get number of rows (see public class)
const casadi_int * row() const
Get row indices (see public class)
Sparsity _appendColumns(const SparsityInternal &sp) const
Append another sparsity patten horizontally.
Sparsity _erase(const std::vector< casadi_int > &rr, const std::vector< casadi_int > &cc, bool ind1, std::vector< casadi_int > &mapping) const
Erase rows and/or columns - does bounds checking.
std::vector< casadi_int > get_upper() const
Get nonzeros in upper triangular part.
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.
std::vector< casadi_int > largest_first() const
Order the columns by decreasing degree.
Sparsity _resize(casadi_int nrow, casadi_int ncol) const
Resize.
casadi_int size2() const
Get number of columns (see public class)
bool is_stacked(const Sparsity &y, casadi_int n) const
Check if pattern is repeated.
Sparsity _tril(bool includeDiagonal) const
Get lower triangular part.
void dmperm(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
Compute the Dulmage-Mendelsohn decomposition.
casadi_int get_nz(casadi_int rr, casadi_int cc) const
Get the index of an existing non-zero element.
Sparsity _appendVector(const SparsityInternal &sp) const
Append another sparsity patten vertically (vectors only)
std::vector< casadi_int > get_colind() const
Get colind() as a vector.
casadi_int nnz_diag() const
Number of non-zeros on the diagonal.
Sparsity combineGen(const Sparsity &y, std::vector< unsigned char > &mapping) const
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.
casadi_int scatter(casadi_int j, std::vector< casadi_int > &w, casadi_int mark, casadi_int *Ci, casadi_int nz) const
x = x + beta * A(:, j), where x is a dense vector and A(:, j) is sparse
Sparsity _triu(bool includeDiagonal) const
Get upper triangular part.
static casadi_int rprune(casadi_int i, casadi_int j, double aij, void *other)
return 1 if column i is in R2
bool is_equal(const Sparsity &y) const
Check if two sparsity patterns are the same.
static std::vector< casadi_int > randperm(casadi_int n, casadi_int seed)
return a random permutation vector
Sparsity multiply(const Sparsity &B) const
C = A*B.
Sparsity drop_diag() const
Drop diagonal entries.
const casadi_int * colind() const
Get column offsets (see public class)
Sparsity uni_coloring(const Sparsity &AT, casadi_int cutoff) const
Perform a unidirectional coloring.
Sparsity T() const
Transpose the matrix.
Sparsity permute(const std::vector< casadi_int > &pinv, const std::vector< casadi_int > &q, casadi_int values) const
C = A(p, q) where p and q are permutations of 0..m-1 and 0..n-1.
static casadi_int diag(casadi_int i, casadi_int j, double aij, void *other)
keep off-diagonal entries; drop diagonal entries
Sparsity _reshape(casadi_int nrow, casadi_int ncol) const
Reshape a sparsity, order of nonzeros remains the same.
void find(std::vector< casadi_int > &loc, bool ind1) const
Get element index for each nonzero.
bool is_orthonormal(bool allow_empty=false) const
Are the rows and columns of the pattern orthonormal ?
bool is_row() const
Check if the pattern is a row vector (i.e. size1()==1)
static std::vector< casadi_int > invertPermutation(const std::vector< casadi_int > &p)
Invert a permutation vector.
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.
std::vector< casadi_int > get_row() const
Get row() as a vector.
std::vector< casadi_int > get_col() const
Get the column for each nonzero.
bool is_scalar(bool scalar_and_dense) const
Is scalar?
std::string dim(bool with_nz=false) const
Get the dimension as a string.
bool is_triu(bool strictly) const
is upper triangular?
bool is_dense() const
Is dense?
Sparsity combine(const Sparsity &y, bool f0x_is_zero, bool function0_is_zero, std::vector< unsigned char > &mapping) const
void spy(std::ostream &stream) const
Print a textual representation of sparsity.
static void matched(casadi_int n, const std::vector< casadi_int > &wj, const std::vector< casadi_int > &imatch, std::vector< casadi_int > &p, std::vector< casadi_int > &q, std::vector< casadi_int > &cc, std::vector< casadi_int > &rr, casadi_int set, casadi_int mark)
Collect matched columns and rows into p and q.
casadi_int bw_upper() const
Upper half-bandwidth.
casadi_int nnz() const
Number of structural non-zeros.
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.
casadi_int nnz_upper(bool strictly=false) const
Number of non-zeros in the upper triangular half.
casadi_int scc(std::vector< casadi_int > &p, std::vector< casadi_int > &r) const
Find the strongly connected components of a square matrix.
const Btf & btf() const
Get cached block triangular form.
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.
casadi_int size1() const
Get the number of rows.
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.
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 dense(casadi_int nrow, casadi_int ncol=1)
Create a dense rectangular sparsity pattern *.
SparsityInternal * get() const
bool is_scalar(bool scalar_and_dense=false) const
Is scalar?
bool is_diag() const
Is diagonal?
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,.
std::pair< casadi_int, casadi_int > size() const
Get the shape.
bool is_empty(bool both=false) const
Check if the sparsity is empty.
const casadi_int * colind() const
Get a reference to the colindex of all column element (see class description)
bool is_dense() const
Is dense?
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 *.
void resize(casadi_int nrow, casadi_int ncol)
Resize.
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:
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
bool has_negative(const std::vector< T > &v)
Check if the vector has negative entries.
void sort(const std::vector< T > &values, std::vector< T > &sorted_values, std::vector< casadi_int > &indices, bool invert_indices=false)
Sort the data in a vector.
std::string str(const T &v)
String representation, any type.
std::vector< casadi_int > lookupvector(const std::vector< casadi_int > &v, casadi_int size)
Returns a vector for quickly looking up entries of supplied list.
GenericType::Dict Dict
C++ equivalent of Python's dict or MATLAB's struct.
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_nondecreasing(const std::vector< T > &v)
Check if the vector is non-decreasing.
bool mul_overflows(const T &a, const T &b)