CRSSparsity reshape(const CRSSparsity& a, int n, int m){
  casadi_assert_message(a.numel() == n*m,
     "reshape: number of elements must remain the same." << endl <<
     "Input argument has shape " << a.size1() << " x " << a.size2() << " =  " << a.numel() << ", while you request a reshape to " <<
     n << " x " << m << " =  " << n*m
  );

  // our strategy is: (col,rowind) -> (col,row) -> modulus calculus -> (col_new, row_new) -> sp_NZ
  std::vector<int> row = a.getRow();
  const std::vector<int> &col = a.col();

  std::vector<int> row_new(a.size());
  std::vector<int> col_new(a.size());
  
//  int i=0;int j=0; int z =0;
  for(int k=0; k<a.size(); ++k){
    int i = row[k];
    int j = col[k];
    int z = j+i*a.size2();
    row_new[k] = z/m;
    col_new[k] = z%m;
  }
  
  return  sp_triplet(n,m,row_new,col_new);
}
CRSSparsity lowerSparsity(const CRSSparsity& a, bool includeDiagonal) {
  const std::vector<int> & col= a.col();
  std::vector<int> row = a.getRow();
  

  std::vector<int> new_col;   // new col
  std::vector<int> new_row;   // new row
  
  int offset = (includeDiagonal ? 1 : 0);
  
  // Find size
  int n=0;
  for (int k=0;k<row.size();k++) n+= row[k] + offset > col[k];
  new_col.resize(n);
  new_row.resize(n);
  
  // populate return vector
  int cnt=0;
  for (int k=0;k<row.size();k++) {
    if (row[k] + offset > col[k]) {
      new_col[cnt]=col[k];
      new_row[cnt]=row[k];
      cnt++;
    }
  }
  return sp_triplet(a.size1(), a.size2(), new_row, new_col);
  
}
std::vector<int> getNZDense(const CRSSparsity &sp) {
  std::vector<int> ret(sp.size());
  std::vector<int> row = sp.getRow();
  const std::vector<int> &col = sp.col();
  int s2 = sp.size2();
  for(int k=0;k<sp.size();k++) {
    ret[k] = col[k]+row[k]*s2;
  }
  return ret;
}
std::vector<int> lowerNZ(const CRSSparsity& a) {
  const std::vector<int> & col= a.col();
  std::vector<int> row = a.getRow();
  
  // Return vector
  std::vector<int> ret;
  
  // Find size of return vector
  int n=0;
  for (int k=0;k<row.size();k++) n+= (row[k] >= col[k]);
  ret.resize(n);
  
  // populate return vector
  int cnt=0;
  for (int k=0;k<row.size();k++) {
    if (row[k] >= col[k]) ret[cnt++]=k;
  }
  
  return ret;
}