34 TripletEntry(
int r_,
int c_,
double x_) : r(r_), c(c_), x(x_) {}
38 bool operator()(
const TripletEntry& e1,
const TripletEntry& e2)
const 40 return e1.c < e2.c || (e1.c == e2.c && e1.r < e2.r);
44 template<
class T1,
class T2,
class Pred = std::less<T1> >
46 bool operator()(
const std::pair<T1,T2>& left,
const std::pair<T1,T2>& right) {
47 return Pred()(left.first, right.first);
52 template <
class MatrixType>
54 _rowBlockIndices(rbi,rbi+rb),
55 _colBlockIndices(cbi,cbi+cb),
56 _blockCols(cb), _hasStorage(hasStorage)
60 template <
class MatrixType>
66 template <
class MatrixType>
69 # pragma omp parallel for default (shared) if (_blockCols.size() > 100) 71 for (
int i=0; i < static_cast<int>(
_blockCols.size()); ++i) {
84 template <
class MatrixType>
90 template <
class MatrixType>
102 std::pair < typename SparseBlockMatrix<MatrixType>::IntBlockMap::iterator,
bool> result
103 =
_blockCols[c].insert(std::make_pair(r,_block)); (void) result;
104 assert (result.second);
112 template <
class MatrixType>
121 template <
class MatrixType>
127 ret->
_blockCols[i].insert(std::make_pair(it->first, b));
135 template <
class MatrixType>
136 template <
class MatrixTransposedType>
167 template <
class MatrixType>
197 template <
class MatrixType>
198 template <
class MatrixResultType,
class MatrixFactorType >
212 for (
size_t i=0; i<M->
_blockCols.size(); ++i){
233 template <
class MatrixType>
237 memset(dest,0, _rowBlockIndices[_rowBlockIndices.size()-1]*
sizeof(double));
241 Eigen::Map<VectorXD> destVec(dest,
rows());
242 const Eigen::Map<const VectorXD> srcVec(src,
cols());
251 internal::template axpy<typename SparseBlockMatrix<MatrixType>::SparseMatrixBlock>(*a, srcVec, srcOffset, destVec, destOffset);
256 template <
class MatrixType>
261 memset(dest,0, _rowBlockIndices[_rowBlockIndices.size()-1]*
sizeof(double));
265 Eigen::Map<VectorXD> destVec(dest,
rows());
266 const Eigen::Map<const VectorXD> srcVec(src,
cols());
273 if (destOffset > srcOffset)
276 internal::template axpy<typename SparseBlockMatrix<MatrixType>::SparseMatrixBlock>(*a, srcVec, srcOffset, destVec, destOffset);
277 if (destOffset < srcOffset)
278 internal::template atxpy<typename SparseBlockMatrix<MatrixType>::SparseMatrixBlock>(*a, srcVec, destOffset, destVec, srcOffset);
283 template <
class MatrixType>
288 dest=
new double [ destSize ];
289 memset(dest,0, destSize*
sizeof(
double));
293 Eigen::Map<VectorXD> destVec(dest, destSize);
294 Eigen::Map<const VectorXD> srcVec(src,
rows());
297 # pragma omp parallel for default (shared) schedule(dynamic, 10) 299 for (
int i=0; i < static_cast<int>(
_blockCols.size()); ++i){
307 internal::template atxpy<typename SparseBlockMatrix<MatrixType>::SparseMatrixBlock>(*a, srcVec, srcOffset, destVec, destOffset);
313 template <
class MatrixType>
323 template <
class MatrixType>
329 for (
int i=1; i<m; ++i){
335 for (
int i=1; i<n; ++i){
339 for (
int i=0; i<n; ++i){
342 if (it->first >= rmin && it->first < rmax){
344 s->
_blockCols[i].insert(std::make_pair(it->first-rmin, b));
352 template <
class MatrixType>
360 template <
class MatrixType>
362 if (MatrixType::SizeAtCompileTime != Eigen::Dynamic) {
363 size_t nnz =
nonZeroBlocks() * MatrixType::SizeAtCompileTime;
377 template <
class MatrixType>
378 std::ostream& operator << (std::ostream& os, const SparseBlockMatrix<MatrixType>& m){
379 os <<
"RBI: " << m.rowBlockIndices().size();
380 for (
size_t i=0; i<m.rowBlockIndices().size(); ++i)
381 os <<
" " << m.rowBlockIndices()[i];
383 os <<
"CBI: " << m.colBlockIndices().size();
384 for (
size_t i=0; i<m.colBlockIndices().size(); ++i)
385 os <<
" " << m.colBlockIndices()[i];
388 for (
size_t i=0; i<m.blockCols().size(); ++i){
391 os <<
"BLOCK: " << it->first <<
" " << i << std::endl;
392 os << *b << std::endl;
398 template <
class MatrixType>
405 for (
size_t i=1; i<n; ++i){
410 for (
size_t i=0; i<n; ++i){
411 pBlockIndices[pinv[i]]=blockSizes[i];
413 for (
size_t i=1; i<n; ++i){
414 pBlockIndices[i]+=pBlockIndices[i-1];
424 for (
size_t i=0; i<n; ++i){
433 for (
size_t i=0; i<n; ++i){
438 int pj=pinv[it->first];
443 if (! upperTriangle || pj<=pi) {
444 b=dest->
block(pj,pi,
true);
449 b=dest->
block(pi,pj,
true);
463 template <
class MatrixType>
466 assert(Cx &&
"Target destination is NULL");
467 double* CxStart = Cx;
471 for (
int c=0; c<csize; ++c) {
476 int elemsToCopy = b->
rows();
477 if (upperTriangle && rstart == cstart)
479 memcpy(Cx, b->data() + c*b->
rows(), elemsToCopy *
sizeof(double));
488 template <
class MatrixType>
491 assert(Cp && Ci && Cx &&
"Target destination is NULL");
496 for (
int c=0; c<csize; ++c) {
502 int elemsToCopy = b->
rows();
503 if (upperTriangle && rstart == cstart)
505 for (
int r=0; r<elemsToCopy; ++r){
518 template <
class MatrixType>
530 for (
int i = 0; i < static_cast<int>(
_blockCols.size()); ++i){
534 const int& r = it->first;
546 template <
class MatrixType>
549 std::string name = filename;
550 std::string::size_type lastDot = name.find_last_of(
'.');
551 if (lastDot != std::string::npos)
552 name = name.substr(0, lastDot);
554 std::vector<TripletEntry> entries;
558 const int& r = it->first;
559 const MatrixType& m = *(it->second);
560 for (
int cc = 0; cc < m.cols(); ++cc)
561 for (
int rr = 0; rr < m.rows(); ++rr) {
564 entries.push_back(TripletEntry(aux_r, aux_c, m(rr, cc)));
565 if (upperTriangle && r != c) {
566 entries.push_back(TripletEntry(aux_c, aux_r, m(rr, cc)));
572 int nz = entries.size();
573 std::sort(entries.begin(), entries.end(), TripletColSort());
575 std::ofstream fout(filename);
576 fout <<
"# name: " << name << std::endl;
577 fout <<
"# type: sparse matrix" << std::endl;
578 fout <<
"# nnz: " << nz << std::endl;
579 fout <<
"# rows: " <<
rows() << std::endl;
580 fout <<
"# columns: " <<
cols() << std::endl;
581 fout << std::setprecision(9) << std::fixed << std::endl;
583 for (std::vector<TripletEntry>::const_iterator it = entries.begin(); it != entries.end(); ++it) {
584 const TripletEntry& entry = *it;
585 fout << entry.r+1 <<
" " << entry.c+1 <<
" " << entry.x << std::endl;
590 template <
class MatrixType>
595 for (
size_t i = 0; i <
blockCols().size(); ++i) {
599 dest.reserve(row.size());
600 for (
typename IntBlockMap::const_iterator it = row.begin(); it != row.end(); ++it) {
608 template <
class MatrixType>
614 for (
size_t i = 0; i <
blockCols().size(); ++i) {
616 for (
typename IntBlockMap::const_iterator it = row.begin(); it != row.end(); ++it) {
625 template <
class MatrixType>
630 typedef std::pair<int, MatrixType*> SparseColumnPair;
632 for (
size_t i = 0; i < hashMatrix.
blockCols().size(); ++i) {
634 HashSparseColumn& column = hashMatrix.
blockCols()[i];
635 if (column.size() == 0)
637 std::vector<SparseColumnPair> sparseRowSorted;
638 sparseRowSorted.reserve(column.size());
639 for (
typename HashSparseColumn::const_iterator it = column.begin(); it != column.end(); ++it)
640 sparseRowSorted.push_back(*it);
641 std::sort(sparseRowSorted.begin(), sparseRowSorted.end(), CmpPairFirst<int, MatrixType*>());
643 HashSparseColumn aux;
644 std::swap(aux, column);
647 destColumnMap.insert(sparseRowSorted[0]);
648 for (
size_t j = 1; j < sparseRowSorted.size(); ++j) {
651 destColumnMap.insert(hint, sparseRowSorted[j]);
std::vector< int > _rowBlockIndices
vector of the indices of the blocks along the rows.
std::vector< int > _colBlockIndices
int fillSparseBlockMatrixCCS(SparseBlockMatrixCCS< MatrixType > &blockCCS) const
bool transpose(SparseBlockMatrix< MatrixTransposedType > *&dest) const
transposes a block matrix, The transposed type should match the argument false on failure ...
int rowsOfBlock(int r) const
how many rows does the block at block-row r has?
int cols() const
columns of the matrix
int * Ap
column pointers for A, of size n+1
std::unordered_map< int, MatrixType * > SparseColumn
bool writeOctave(const char *filename, bool upperTriangle=true) const
int rows() const
rows of the matrix
SparseMatrixBlock * block(int r, int c, bool alloc=false)
returns the block at location r,c. if alloc=true he block is created if it does not exist ...
representing the structure of a matrix in column compressed structure (only the upper triangular part...
size_t nonZeroBlocks() const
number of allocated blocks
int colsOfBlock(int c) const
how many cols does the block at block-col c has?
void clear(bool dealloc=false)
this zeroes all the blocks. If dealloc=true the blocks are removed from memory
MatrixType SparseMatrixBlock
this is the type of the elementary block, it is an Eigen::Matrix.
size_t nonZeros() const
number of non-zero elements
std::vector< RowBlock > SparseColumn
void fillBlockStructure(MatrixStructure &ms) const
exports the non zero blocks in the structure matrix ms
std::vector< IntBlockMap > _blockCols
SparseBlockMatrix * slice(int rmin, int rmax, int cmin, int cmax, bool alloc=true) const
void takePatternFromHash(SparseBlockMatrixHashMap< MatrixType > &hashMatrix)
int m
A is m-by-n. m must be >= 0.
void multiplySymmetricUpperTriangle(double *&dest, const double *src) const
const std::vector< SparseColumn > & blockCols() const
the block matrices per block-column
Sparse matrix which uses blocks.
int fillSparseBlockMatrixCCSTransposed(SparseBlockMatrixCCS< MatrixType > &blockCCS) const
void rightMultiply(double *&dest, const double *src) const
dest = M * (*this)
bool symmPermutation(SparseBlockMatrix< MatrixType > *&dest, const int *pinv, bool onlyUpper=false) const
std::map< int, SparseMatrixBlock * > IntBlockMap
void alloc(int n_, int nz)
int colBaseOfBlock(int c) const
where does the col at block-col r starts?
const std::vector< IntBlockMap > & blockCols() const
the block matrices per block-column
bool multiply(SparseBlockMatrix< MatrixResultType > *&dest, const SparseBlockMatrix< MatrixFactorType > *M) const
dest = (*this) * M
int * Aii
row indices of A, of size nz = Ap [n]
void scale(double a)
*this *= a
SparseBlockMatrix * clone() const
deep copy of a sparse-block-matrix;
Sparse matrix which uses blocks based on hash structures.
bool add(SparseBlockMatrix< MatrixType > *&dest) const
adds the current matrix to the destination
const std::vector< SparseColumn > & blockCols() const
the block matrices per block-column
int rowBaseOfBlock(int r) const
where does the row at block-row r starts?
Sparse matrix which uses blocks.
int fillCCS(int *Cp, int *Ci, double *Cx, bool upperTriangle=false) const