NDEVR
API Documentation
sparse_block_matrix.hpp
1namespace NDEVR
2{
3 using namespace Eigen;
4
5 namespace
6 {
7 struct TripletEntry
8 {
9 int r, c;
10 g_type x;
11 TripletEntry(int r_, int c_, g_type x_) : r(r_), c(c_), x(x_) {}
12 };
13 struct TripletColSort
14 {
15 bool operator()(const TripletEntry& e1, const TripletEntry& e2) const
16 {
17 return e1.c < e2.c || (e1.c == e2.c && e1.r < e2.r);
18 }
19 };
21 template<class T1, class T2, class Pred = std::less<T1> >
22 struct CmpPairFirst {
23 bool operator()(const std::pair<T1,T2>& left, const std::pair<T1,T2>& right) {
24 return Pred()(left.first, right.first);
25 }
26 };
27 }
28
29 template <class MatrixType>
30 SparseBlockMatrix<MatrixType>::SparseBlockMatrix( const int * rbi, const int* cbi, int rb, int cb, bool hasStorage)
31 : _rowBlockIndices(rbi,rb)
32 , _colBlockIndices(cbi,cb)
33 , _blockCols(cast<uint04>(cb), IntBlockMap())
34 , _hasStorage(hasStorage)
35 {
36 }
37
38 template <class MatrixType>
40 _blockCols(0), _hasStorage(true)
41 {
42 }
43
44 template <class MatrixType>
46 {
47# ifdef G2O_OPENMP
48//# pragma omp parallel for default (shared) if (_blockCols.size() > 100)
49# endif
50 for (int i=0; i < static_cast<int>(_blockCols.size()); ++i)
51 {
52 if (!_hasStorage || !dealloc)
53 {
54 if (_blockCols[i].size() == 0)
55 continue;
56 for (auto it = _blockCols[i].begin(); it != _blockCols[i].end(); ++it)
57 {
58 it->second.setZero();
59 }
60 }
61 if (_hasStorage && dealloc)
62 _blockCols[i].clear();
63 }
64 //_blockCols.clear();
65 }
66
67 template <class MatrixType>
68 SparseBlockMatrix<MatrixType>::~SparseBlockMatrix(){
69 if (_hasStorage)
70 clear(true);
71 }
72
73 template <class MatrixType>
75 {
76 auto it = _blockCols[c].find(r);
78 if (it==_blockCols[c].end())
79 {
80 if (!_hasStorage && ! alloc )
81 return nullptr;
82 else
83 {
84 int rb=rowsOfBlock(r);
85 int cb=colsOfBlock(c);
87 block.setZero();
88 _blockCols[c].insert(std::make_pair(r, block));
89 _block = &_blockCols[c][r];
90 }
91 }
92 else
93 {
94 _block = &_blockCols[c][r];
95 }
96 return _block;
97 }
98
99 template <class MatrixType>
101 typename SparseBlockMatrix<MatrixType>::IntBlockMap::const_iterator it =_blockCols[c].find(r);
102 if (it==_blockCols[c].end())
103 return nullptr;
104 return &(it->second);
105 }
106
107
108
109
110 template <class MatrixType>
111 template <class MatrixTransposedType>
113 if (! dest){
115 } else {
116 if (! dest->_hasStorage)
117 return false;
118 if(_rowBlockIndices.size()!=dest->_colBlockIndices.size())
119 return false;
120 if (_colBlockIndices.size()!=dest->_rowBlockIndices.size())
121 return false;
122 for (uint04 i=0; i<_rowBlockIndices.size(); ++i){
123 if(_rowBlockIndices[i]!=dest->_colBlockIndices[i])
124 return false;
125 }
126 for (uint04 i=0; i<_colBlockIndices.size(); ++i){
127 if(_colBlockIndices[i]!=dest->_rowBlockIndices[i])
128 return false;
129 }
130 }
131
132 for (uint04 i=0; i<_blockCols.size(); ++i)
133 {
134 for (auto it = _blockCols[i].begin(); it!=_blockCols[i].end(); ++it){
135 const typename SparseBlockMatrix<MatrixType>::SparseMatrixBlock& s=it->second;
136 typename SparseBlockMatrix<MatrixTransposedType>::SparseMatrixBlock* d=dest->block(i,it->first,true);
137 *d = s.transpose();
138 }
139 }
140 return true;
141 }
142
143 template <class MatrixType>
145 {
146 if (!dest._hasStorage)
147 return false;
148 if (_rowBlockIndices.size() != dest._rowBlockIndices.size())
149 return false;
150 if (_colBlockIndices.size() != dest._colBlockIndices.size())
151 return false;
152 for (uint04 i = 0; i < _rowBlockIndices.size(); ++i)
153 {
154 if (_rowBlockIndices[i] != dest._rowBlockIndices[i])
155 return false;
156 }
157 for (uint04 i = 0; i < _colBlockIndices.size(); ++i)
158 {
159 if (_colBlockIndices[i] != dest._colBlockIndices[i])
160 return false;
161 }
162 for (uint04 i = 0; i < _blockCols.size(); ++i)
163 {
164 for (auto it = _blockCols[i].begin(); it != _blockCols[i].end(); ++it)
165 {
167 typename SparseBlockMatrix<MatrixType>::SparseMatrixBlock* d = dest.block(it->first, i, true);
168 (*d) += s;
169 }
170 }
171 return true;
172 }
173
174 template <class MatrixType>
175 template < class MatrixResultType, class MatrixFactorType >
177 // sanity check
178 if (_colBlockIndices.size()!=M->_rowBlockIndices.size())
179 return false;
180 for (uint04 i=0; i<_colBlockIndices.size(); ++i){
182 return false;
183 }
184 if (! dest) {
186 }
187 if (! dest->_hasStorage)
188 return false;
189 for (uint04 i=0; i<M->_blockCols.size(); ++i)
190 {
191 for (auto it=M->_blockCols[i].begin(); it!=M->_blockCols[i].end(); ++it){
192 // look for a non-zero block in a row of column it
193 int colM=i;
195 typename SparseBlockMatrix<MatrixType>::IntBlockMap::const_iterator rbt=_blockCols[it->first].begin();
196 while(rbt!=_blockCols[it->first].end()){
197 //int colA=it->first;
198 int rowA=rbt->first;
199 const typename SparseBlockMatrix<MatrixType>::SparseMatrixBlock& a=rbt->second;
200 typename SparseBlockMatrix<MatrixResultType>::SparseMatrixBlock *c=dest->block(rowA,colM,true);
201 assert (c->rows()==a.rows());
202 assert (c->cols()==b.cols());
203 ++rbt;
204 (*c)+=a*b;
205 }
206 }
207 }
208 return true;
209 }
210
211 template <class MatrixType>
212 void SparseBlockMatrix<MatrixType>::multiply(g_type*& dest, const g_type* src) const {
213 if (! dest){
214 dest=new g_type [_rowBlockIndices[_rowBlockIndices.size()-1] ];
215 memset(dest,0, _rowBlockIndices[_rowBlockIndices.size()-1]*sizeof(g_type));
216 }
217
218 // map the memory by Eigen
219 Eigen::Map<VectorX<g_type>> destVec(dest, rows());
220 const Eigen::Map<const VectorX<g_type>> srcVec(src, cols());
221
222 for (uint04 i=0; i<_blockCols.size(); ++i)
223 {
224 int srcOffset = i ? _colBlockIndices[i-1] : 0;
225
226 for (auto it=_blockCols[i].begin(); it!=_blockCols[i].end(); ++it){
227 const typename SparseBlockMatrix<MatrixType>::SparseMatrixBlock& a=it->second;
228 int destOffset = it->first ? _rowBlockIndices[it->first - 1] : 0;
229 // destVec += *a * srcVec (according to the sub-vector parts)
230 internal::axpy(a, srcVec, srcOffset, destVec, destOffset);
231 }
232 }
233 }
234
235 template <class MatrixType>
236 void SparseBlockMatrix<MatrixType>::multiplySymmetricUpperTriangle(g_type*& dest, const g_type* src) const
237 {
238 if (! dest){
239 dest=new g_type [_rowBlockIndices[_rowBlockIndices.size()-1] ];
240 memset(dest,0, _rowBlockIndices[_rowBlockIndices.size()-1]*sizeof(g_type));
241 }
242
243 // map the memory by Eigen
244 Eigen::Map<VectorX<g_type>> destVec(dest, rows());
245 const Eigen::Map<const VectorX<g_type>> srcVec(src, cols());
246
247 for (uint04 i=0; i<_blockCols.size(); ++i){
248 int srcOffset = colBaseOfBlock(i);
249 for (typename SparseBlockMatrix<MatrixType>::IntBlockMap::const_iterator it=_blockCols[i].begin(); it!=_blockCols[i].end(); ++it){
250 const auto& a = it->second;
251 int destOffset = rowBaseOfBlock(it->first);
252 if (destOffset > srcOffset) // only upper triangle
253 break;
254 // destVec += *a * srcVec (according to the sub-vector parts)
255 internal::axpy(a, srcVec, srcOffset, destVec, destOffset);
256 if (destOffset < srcOffset)
257 internal::atxpy(a, srcVec, destOffset, destVec, srcOffset);
258 }
259 }
260 }
261
262 template <class MatrixType>
263 void SparseBlockMatrix<MatrixType>::rightMultiply(g_type*& dest, const g_type* src) const {
264 int destSize=cols();
265
266 if (! dest){
267 dest=new g_type [ destSize ];
268 memset(dest,0, destSize*sizeof(g_type));
269 }
270
271 // map the memory by Eigen
272 Eigen::Map<VectorX<g_type>> destVec(dest, destSize);
273 Eigen::Map<const VectorX<g_type>> srcVec(src, rows());
274
275# ifdef G2O_OPENMP
276# pragma omp parallel for default (shared) schedule(dynamic, 10)
277# endif
278 for (int i=0; i < static_cast<int>(_blockCols.size()); ++i){
279 int destOffset = colBaseOfBlock(i);
280 for (typename SparseBlockMatrix<MatrixType>::IntBlockMap::const_iterator it=_blockCols[i].begin();
281 it!=_blockCols[i].end();
282 ++it){
283 const typename SparseBlockMatrix<MatrixType>::SparseMatrixBlock& a=it->second;
284 int srcOffset = rowBaseOfBlock(it->first);
285 // destVec += *a.transpose() * srcVec (according to the sub-vector parts)
286 internal::atxpy(a, srcVec, srcOffset, destVec, destOffset);
287 }
288 }
289
290 }
291
292 template <class MatrixType>
294 {
295 lib_assert(a_ > -200.0f && a_ < 200.0f, "Bad scale");
296 for (uint04 i=0; i<_blockCols.size(); ++i){
297 for (auto it=_blockCols[i].begin(); it!=_blockCols[i].end(); ++it){
298 it->second *= a_;
299 }
300 }
301 }
302
303 template <class MatrixType>
304 SparseBlockMatrix<MatrixType>* SparseBlockMatrix<MatrixType>::slice(int rmin, int rmax, int cmin, int cmax, bool alloc) const {
305 int m=rmax-rmin;
306 int n=cmax-cmin;
307 Buffer<int> rowIdx(m);
308 rowIdx[0] = rowsOfBlock(rmin);
309 for (int i=1; i<m; ++i){
310 rowIdx[i]=rowIdx[i-1]+rowsOfBlock(rmin+i);
311 }
312
313 Buffer<int> colIdx(n);
314 colIdx[0] = colsOfBlock(cmin);
315 for (int i=1; i<n; ++i)
316 {
317 colIdx[i]=colIdx[i-1]+colsOfBlock(cmin+i);
318 }
319 SparseBlockMatrix* s=new SparseBlockMatrix(rowIdx, colIdx, m, n, true);
320 for (int i=0; i<n; ++i){
321 int mc=cmin+i;
322 for (typename SparseBlockMatrix<MatrixType>::IntBlockMap::const_iterator it=_blockCols[mc].begin(); it!=_blockCols[mc].end(); ++it){
323 if (it->first >= rmin && it->first < rmax){
324 s->_blockCols[i].insert(std::make_pair(it->first-rmin, it->second));
325 }
326 }
327 }
328 s->_hasStorage=alloc;
329 return s;
330 }
331
332 template <class MatrixType>
334 uint04 count=0;
335 for (uint04 i=0; i<_blockCols.size(); ++i)
336 count+=cast<uint04>(_blockCols[i].size());
337 return count;
338 }
339
340 template <class MatrixType>
342 {
343 if constexpr (MatrixType::SizeAtCompileTime != Eigen::Dynamic)
344 {
345 uint04 nnz = nonZeroBlocks() * MatrixType::SizeAtCompileTime;
346 return nnz;
347 }
348 else
349 {
350 uint04 count=0;
351 for (uint04 i=0; i<_blockCols.size(); ++i)
352 {
353 for (auto it=_blockCols[i].begin(); it!=_blockCols[i].end(); ++it)
354 {
356 count += cast<uint04>(a.cols() * a.rows());
357 }
358 }
359 return count;
360 }
361 }
362
363 template <class MatrixType>
364 std::ostream& operator << (std::ostream& os, const SparseBlockMatrix<MatrixType>& m){
365 os << "RBI: " << m.rowBlockIndices().size();
366 for (uint04 i=0; i<m.rowBlockIndices().size(); ++i)
367 os << " " << m.rowBlockIndices()[i];
368 os << std::endl;
369 os << "CBI: " << m.colBlockIndices().size();
370 for (uint04 i=0; i<m.colBlockIndices().size(); ++i)
371 os << " " << m.colBlockIndices()[i];
372 os << std::endl;
373
374 for (uint04 i=0; i<m.blockCols().size(); ++i){
375 for (typename SparseBlockMatrix<MatrixType>::IntBlockMap::const_iterator it=m.blockCols()[i].begin(); it!=m.blockCols()[i].end(); ++it){
376 const typename SparseBlockMatrix<MatrixType>::SparseMatrixBlock& b=it->second;
377 os << "BLOCK: " << it->first << " " << i << std::endl;
378 os << b << std::endl;
379 }
380 }
381 return os;
382 }
383
384 template <class MatrixType>
385 bool SparseBlockMatrix<MatrixType>::symmPermutation(SparseBlockMatrix<MatrixType>*& dest, const int* pinv, bool upperTriangle) const{
386 // compute the permuted version of the new row/column layout
387 uint04 n=_rowBlockIndices.size();
388 // computed the block sizes
389 Buffer<int> blockSizes;
390 blockSizes.resize(_rowBlockIndices.size());
391 blockSizes[0]=_rowBlockIndices[0];
392 for (uint04 i=1; i<n; ++i){
393 blockSizes[i]=_rowBlockIndices[i]-_rowBlockIndices[i-1];
394 }
395 // permute them
396 Buffer<int> pBlockIndices;
397 pBlockIndices.resize(_rowBlockIndices.size());
398 for (uint04 i=0; i<n; ++i){
399 pBlockIndices[pinv[i]]=blockSizes[i];
400 }
401 for (uint04 i=1; i<n; ++i){
402 pBlockIndices[i]+=pBlockIndices[i-1];
403 }
404 // allocate C, or check the structure;
405 if (! dest){
406 dest=new SparseBlockMatrix(&pBlockIndices[0], &pBlockIndices[0], n, n);
407 } else {
408 if (dest->_rowBlockIndices.size()!=n)
409 return false;
410 if (dest->_colBlockIndices.size()!=n)
411 return false;
412 for (uint04 i=0; i<n; ++i){
413 if (dest->_rowBlockIndices[i]!=pBlockIndices[i])
414 return false;
415 if (dest->_colBlockIndices[i]!=pBlockIndices[i])
416 return false;
417 }
418 dest->clear();
419 }
420 // now ready to permute the columns
421 for (uint04 i=0; i<n; ++i){
422 //cerr << PVAR(i) << " ";
423 int pi=pinv[i];
424 for (typename SparseBlockMatrix<MatrixType>::IntBlockMap::const_iterator it=_blockCols[i].begin();
425 it!=_blockCols[i].end(); ++it){
426 int pj=pinv[it->first];
427
428 const typename SparseBlockMatrix<MatrixType>::SparseMatrixBlock& s=it->second;
429
431 if (! upperTriangle || pj<=pi) {
432 b=dest->block(pj,pi,true);
433 assert(b->cols()==s.cols());
434 assert(b->rows()==s.rows());
435 *b=s;
436 } else {
437 b=dest->block(pi,pj,true);
438 assert(b);
439 assert(b->rows()==s.cols());
440 assert(b->cols()==s.rows());
441 *b=s.transpose();
442 }
443 }
444 //cerr << endl;
445 // within each row,
446 }
447 return true;
448
449 }
450
451 template <class MatrixType>
452 int SparseBlockMatrix<MatrixType>::fillCCS(g_type* Cx, bool upperTriangle) const
453 {
454 assert(Cx && "Target destination is NULL");
455 g_type* CxStart = Cx;
456 for (uint04 i=0; i<_blockCols.size(); ++i){
457 int cstart=i ? _colBlockIndices[i-1] : 0;
458 int csize=colsOfBlock(i);
459 for (int c=0; c<csize; ++c) {
460 for (typename SparseBlockMatrix<MatrixType>::IntBlockMap::const_iterator it=_blockCols[i].begin(); it!=_blockCols[i].end(); ++it){
461 const auto& b=it->second;
462 int rstart=it->first ? _rowBlockIndices[it->first-1] : 0;
463
464 int elemsToCopy = cast<int>(b.rows());
465 if (upperTriangle && rstart == cstart)
466 elemsToCopy = c + 1;
467 memcpy(Cx, b.data() + c * b.rows(), elemsToCopy * sizeof(g_type));
468 Cx += cast<size_t>(elemsToCopy);
469
470 }
471 }
472 }
473 return cast<int>(Cx - CxStart);
474 }
475
476 template <class MatrixType>
477 int SparseBlockMatrix<MatrixType>::fillCCS(int* Cp, int* Ci, g_type* Cx, bool upperTriangle) const
478 {
479 assert(Cp && Ci && Cx && "Target destination is NULL");
480 int nz=0;
481 for (uint04 i=0; i<_blockCols.size(); ++i){
482 int cstart=i ? _colBlockIndices[i-1] : 0;
483 int csize=colsOfBlock(i);
484 for (int c=0; c<csize; ++c) {
485 *Cp=nz;
486 for (typename SparseBlockMatrix<MatrixType>::IntBlockMap::const_iterator it=_blockCols[i].begin(); it!=_blockCols[i].end(); ++it){
487 const typename SparseBlockMatrix<MatrixType>::SparseMatrixBlock& b=it->second;
488 int rstart=it->first ? _rowBlockIndices[it->first-1] : 0;
489
490 int elemsToCopy = b.rows();
491 if (upperTriangle && rstart == cstart)
492 elemsToCopy = c + 1;
493 for (int r=0; r<elemsToCopy; ++r){
494 *Cx++ = b(r,c);
495 *Ci++ = rstart++;
496 ++nz;
497 }
498 }
499 ++Cp;
500 }
501 }
502 *Cp=nz;
503 return nz;
504 }
505
506 template <class MatrixType>
508 {
509 int n = _colBlockIndices.size();
510 int nzMax = (int)nonZeroBlocks();
511
512 ms.alloc(n, nzMax);
513 ms.m = _rowBlockIndices.size();
514
515 int nz = 0;
516 int* Cp = ms.Ap;
517 int* Ci = ms.Aii;
518 for (int i = 0; i < static_cast<int>(_blockCols.size()); ++i){
519 *Cp = nz;
520 const int& c = i;
521 for (typename SparseBlockMatrix<MatrixType>::IntBlockMap::const_iterator it=_blockCols[i].begin(); it!=_blockCols[i].end(); ++it) {
522 const int& r = it->first;
523 if (r <= c) {
524 *Ci++ = r;
525 ++nz;
526 }
527 }
528 Cp++;
529 }
530 *Cp=nz;
531 assert(nz <= nzMax);
532 }
533
534 template <class MatrixType>
536 {
537 blockCCS.columns().resize(blockCols().size());
538 uint04 numblocks = 0;
539 for (uint04 i = 0; i < blockCols().size(); ++i)
540 {
541 const IntBlockMap& row = blockCols()[i];
542 auto& dest = blockCCS.columns()[i];
543 dest.clear();
544 dest.setSize(cast<uint04>(row.size()));
545 uint04 index = 0;
546 for (auto it = row.begin(); it != row.end(); ++it)
547 {
548 dest[index++] = typename SparseBlockMatrixCCS<MatrixType>::RowBlock(it->first, it->second);
549 }
550 numblocks += cast<uint04>(row.size());
551 }
552 return numblocks;
553 }
554
555 template <class MatrixType>
557 {
558 blockCCS.columns().clear();
559 blockCCS.columns().resize(_rowBlockIndices.size());
560 int numblocks = 0;
561 for (uint04 i = 0; i < blockCols().size(); ++i)
562 {
563 const IntBlockMap& row = blockCols()[i];
564 for (auto it = row.begin(); it != row.end(); ++it)
565 {
566 auto& dest = blockCCS.columns()[it->first];
567 dest.add(typename SparseBlockMatrixCCS<MatrixType>::RowBlock(i, it->second));
568 ++numblocks;
569 }
570 }
571 return numblocks;
572 }
573
574 template <class MatrixType>
576 {
577 // sort the sparse columns and add them to the map structures by
578 // exploiting that we are inserting a sorted structure
579 typedef std::pair<int, MatrixType> SparseColumnPair;
580 typedef typename SparseBlockMatrixHashMap<MatrixType>::SparseColumn HashSparseColumn;
581 for (uint04 i = 0; i < hashMatrix.columns().size(); ++i) {
582 // prepare a temporary vector for sorting
583 HashSparseColumn& column = hashMatrix.columns()[i];
584 if (column.size() == 0)
585 continue;
586 Buffer<SparseColumnPair> sparseRowSorted; // temporary structure
587 sparseRowSorted.ensureCapacity(column.size());
588 for (auto it = column.begin(); it != column.end(); ++it)
589 sparseRowSorted.add(*it);
590 std::sort(sparseRowSorted.begin(), sparseRowSorted.end(), CmpPairFirst<int, MatrixType>());
591 // try to free some memory early
592 column.clear();
593 // now insert sorted vector to the std::map structure
594 IntBlockMap& destColumnMap = blockCols()[i];
595 //destColumnMap.insert(sparseRowSorted[0]);
596 for (uint04 j = 0; j < sparseRowSorted.size(); ++j)
597 {
598 //typename SparseBlockMatrix<MatrixType>::IntBlockMap::iterator hint = destColumnMap.end();
599 //--hint; // cppreference says the element goes after the hint (until C++11)
600 destColumnMap.insert(sparseRowSorted[j]);
601 }
602 }
603 }
604
605}// end namespace
The equivelent of std::vector but with a bit more control.
Definition Buffer.hpp:58
void add(t_type &&object)
Adds object to the end of the buffer.
Definition Buffer.hpp:190
void insert(t_index_type location, const t_type &object)
Adds an object to a specific location.
Definition Buffer.hpp:233
representing the structure of a matrix in column compressed structure (only the upper triangular part...
int * Aii
row indices of A, of size nz = Ap [n]
int * Ap
column pointers for A, of size n+1
int m
A is m-by-n. m must be >= 0.
void alloc(int n_, int nz)
allocate space for the Matrix Structure.
Sparse matrix which uses blocks.
const Buffer< SparseColumn > & columns() const
the block matrices per block-column
Sparse matrix which uses blocks based on hash structures.
const Buffer< SparseColumn > & columns() const
the block matrices per block-column
Sparse matrix which uses blocks.
const Buffer< int > & rowBlockIndices() const
indices of the row blocks
void scale(g_type a)
*this *= a
int cols() const
columns of the matrix
int fillSparseBlockMatrixCCS(SparseBlockMatrixCCS< MatrixType > &blockCCS) const
copy into CCS structure
bool symmPermutation(SparseBlockMatrix< MatrixType > *&dest, const int *pinv, bool onlyUpper=false) const
writes in dest a block permutaton specified by pinv.
int fillCCS(int *Cp, int *Ci, g_type *Cx, bool upperTriangle=false) const
fill the CCS arrays of a matrix, arrays have to be allocated beforehand
SparseBlockMatrix * slice(int rmin, int rmax, int cmin, int cmax, bool alloc=true) const
returns a view or a copy of the block matrix
Buffer< IntBlockMap > _blockCols
array of maps of blocks.
const Buffer< IntBlockMap > & blockCols() const
the block matrices per block-column
int rows() const
rows of the matrix
void multiplySymmetricUpperTriangle(g_type *&dest, const g_type *src) const
compute dest = (*this) * src However, assuming that this is a symmetric matrix where only the upper t...
bool _hasStorage
Whether this matrix owns its block storage (true) or is a view (false).
Buffer< int > _rowBlockIndices
vector of the indices of the blocks along the rows.
bool add(SparseBlockMatrix< MatrixType > &dest) const
adds the current matrix to the destination
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
uint04 nonZeroBlocks() const
number of allocated blocks
void fillBlockStructure(MatrixStructure &ms) const
exports the non zero blocks in the structure matrix ms
bool multiply(SparseBlockMatrix< MatrixResultType > *&dest, const SparseBlockMatrix< MatrixFactorType > *M) const
dest = (*this) * M
void rightMultiply(g_type *&dest, const g_type *src) const
dest = M * (*this)
const Buffer< int > & colBlockIndices() const
indices of the column blocks
void takePatternFromHash(SparseBlockMatrixHashMap< MatrixType > &hashMatrix)
take over the memory and matrix pattern from a hash matrix.
uint04 nonZeros() const
number of non-zero elements
int rowsOfBlock(int r) const
how many rows does the block at block-row r has?
int fillSparseBlockMatrixCCSTransposed(SparseBlockMatrixCCS< MatrixType > &blockCCS) const
copy as transposed into a CCS structure
bool transpose(SparseBlockMatrix< MatrixTransposedType > *&dest) const
transposes a block matrix, The transposed type should match the argument false on failure
MatrixType SparseMatrixBlock
this is the type of the elementary block, it is an Eigen::Matrix.
SparseBlockMatrix(const int *rbi, const int *cbi, int rb, int cb, bool hasStorage=true)
constructs a sparse block matrix having a specific layout
int rowBaseOfBlock(int r) const
where does the row at block-row r starts?
void clear(bool dealloc=false)
this zeroes all the blocks. If dealloc=true the blocks are removed from memory
int colsOfBlock(int c) const
how many cols does the block at block-col c has?
int colBaseOfBlock(int c) const
where does the col at block-col r starts?
Buffer< int > _colBlockIndices
vector of the indices of the blocks along the cols
void axpy(const MatrixType &A, const Eigen::Map< const Eigen::VectorX< g_type > > &x, int xoff, Eigen::Map< Eigen::VectorX< g_type > > &y, int yoff)
Computes y[yoff..] += A * x[xoff..] for fixed-size blocks.
The primary namespace for the NDEVR SDK.
uint32_t uint04
-Defines an alias representing a 4 byte, unsigned integer -Can represent exact integer values 0 throu...
constexpr t_to cast(const Angle< t_from > &value)
Casts an Angle from one backing type to another.
Definition Angle.h:408