sparse_block_matrix.hpp
Go to the documentation of this file.
00001 // g2o - General Graph Optimization
00002 // Copyright (C) 2011 R. Kuemmerle, G. Grisetti, W. Burgard
00003 // 
00004 // g2o is free software: you can redistribute it and/or modify
00005 // it under the terms of the GNU Lesser General Public License as published
00006 // by the Free Software Foundation, either version 3 of the License, or
00007 // (at your option) any later version.
00008 // 
00009 // g2o is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 // GNU Lesser General Public License for more details.
00013 // 
00014 // You should have received a copy of the GNU Lesser General Public License
00015 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
00016 
00017 #include <assert.h>
00018 #include "sparse_block_matrix.h"
00019 
00020 namespace g2o {
00021   using namespace Eigen;
00022 
00023   namespace {
00024     struct TripletEntry
00025     {
00026       int r, c;
00027       double x;
00028       TripletEntry(int r_, int c_, double x_) : r(r_), c(c_), x(x_) {}
00029     };
00030 
00031 /******************************************************************************/
00032 
00033     struct TripletColSort
00034     {
00035       bool operator()(const TripletEntry& e1, const TripletEntry& e2) const
00036       {
00037         return e1.c < e2.c || (e1.c == e2.c && e1.r < e2.r);
00038       }
00039     };
00040   }
00041 
00042 /******************************************************************************/
00043 
00044 // Constructor de la matriz dispersa. No se reserva memoria, solo se asignan
00045 // los indices de la matriz que contienen datos
00046   template <class MatrixType>
00047   SparseBlockMatrix<MatrixType>::SparseBlockMatrix
00048   (
00049      const int *rbi, const int *cbi,
00050      int rb, int cb, bool hasStorage
00051   ):
00052     _rowBlockIndices(rbi, rbi+rb),
00053     _colBlockIndices(cbi, cbi+cb),
00054     _blockCols(cb), _hasStorage(hasStorage) 
00055   {}
00056 
00057 /******************************************************************************/
00058 
00059   template <class MatrixType>
00060   SparseBlockMatrix<MatrixType>::SparseBlockMatrix():
00061     _blockCols(0), _hasStorage(true) 
00062   {}
00063 
00064 /******************************************************************************/
00065 
00066 // Limpia la matriz dispersa
00067   template <class MatrixType>
00068   void SparseBlockMatrix<MatrixType>::clear(bool dealloc)
00069   {
00070 #   ifdef G2O_OPENMP
00071 #   pragma omp parallel for default (shared) if (_blockCols.size() > 100)
00072 #   endif
00073     for (int i=0; i < static_cast<int>(_blockCols.size()); ++i)
00074     {
00075       for (typename SparseBlockMatrix<MatrixType>::IntBlockMap::const_iterator 
00076            it  = _blockCols[i].begin();
00077            it != _blockCols[i].end();
00078            it++)
00079       {
00080         typename SparseBlockMatrix<MatrixType>::SparseMatrixBlock* b=it->second;
00081         if (_hasStorage && dealloc)   delete b;
00082         else   b->setZero();
00083       }
00084       if (_hasStorage && dealloc)   _blockCols[i].clear();
00085     }
00086   }
00087 
00088 /******************************************************************************/
00089 
00090   template <class MatrixType>
00091   SparseBlockMatrix<MatrixType>::~SparseBlockMatrix()
00092   {
00093     if (_hasStorage)   clear(true);
00094   }
00095 
00096 /******************************************************************************/
00097 
00098 // Devuelve la direccion de memoria del bloque solicitado.
00099 // Si ese bloque no existe y alloc == 0 y hasStorage devuelve un NULL.
00100 // Si no Si el bloque no existe, se crea.
00101   template <class MatrixType>
00102   typename SparseBlockMatrix<MatrixType>::SparseMatrixBlock* 
00103      SparseBlockMatrix<MatrixType>::block(int r, int c, bool alloc)
00104   {
00105     typename SparseBlockMatrix<MatrixType>::IntBlockMap::iterator it =
00106        _blockCols[c].find(r);
00107 
00108     typename SparseBlockMatrix<MatrixType>::SparseMatrixBlock* _block = 0;
00109 
00110     if (it == _blockCols[c].end())
00111     {
00112       if (!_hasStorage && ! alloc )   return 0;
00113       else 
00114       {
00115         int rb = rowsOfBlock(r);
00116         int cb = colsOfBlock(c);
00117         _block = 
00118            new typename SparseBlockMatrix<MatrixType>::SparseMatrixBlock(rb,cb);
00119         _block->setZero();
00120         std::pair 
00121         <
00122            typename SparseBlockMatrix<MatrixType>::IntBlockMap::iterator,
00123            bool
00124         > result =_blockCols[c].insert(std::make_pair(r,_block));
00125         (void) result;
00126         assert (result.second);
00127       }
00128     }else   _block = it->second;
00129 
00130     return _block;
00131   }
00132 
00133 /******************************************************************************/
00134 
00135   template <class MatrixType>
00136   const typename SparseBlockMatrix<MatrixType>::SparseMatrixBlock* 
00137      SparseBlockMatrix<MatrixType>::block(int r, int c) const
00138   {
00139     typename SparseBlockMatrix<MatrixType>::IntBlockMap::const_iterator it =
00140        _blockCols[c].find(r);
00141     if (it==_blockCols[c].end())   return 0;
00142     return it->second;
00143   }
00144 
00145 /******************************************************************************/
00146 
00147   template <class MatrixType>
00148   SparseBlockMatrix<MatrixType>* SparseBlockMatrix<MatrixType>::clone() const
00149   {
00150     SparseBlockMatrix* ret =
00151        new SparseBlockMatrix
00152        (
00153           &_rowBlockIndices[0], &_colBlockIndices[0],
00154           _rowBlockIndices.size(), _colBlockIndices.size()
00155        );
00156     for (size_t i=0; i<_blockCols.size(); i++)
00157     {
00158       for (typename SparseBlockMatrix<MatrixType>::IntBlockMap::const_iterator
00159            it  = _blockCols[i].begin();
00160            it != _blockCols[i].end();
00161            it++)
00162       {
00163         typename SparseBlockMatrix<MatrixType>::SparseMatrixBlock* b =
00164            new typename 
00165               SparseBlockMatrix<MatrixType>::SparseMatrixBlock(*it->second);
00166 
00167         ret->_blockCols[i].insert(std::make_pair(it->first, b));
00168       }
00169     }
00170     ret->_hasStorage = true;
00171     return ret;
00172   }
00173 
00174 /******************************************************************************/
00175 
00176   template <class MatrixType>
00177   template <class MatrixTransposedType>
00178   bool SparseBlockMatrix<MatrixType>::transpose
00179      (SparseBlockMatrix<MatrixTransposedType>*& dest) const
00180   {
00181     if (! dest)
00182     {
00183       dest = 
00184          new SparseBlockMatrix<MatrixTransposedType>
00185          (
00186             &_colBlockIndices[0], &_rowBlockIndices[0],
00187             _colBlockIndices.size(), _rowBlockIndices.size()
00188          );
00189     }else
00190     {
00191       if(! dest->_hasStorage)   return false;
00192       if(_rowBlockIndices.size()!=dest->_colBlockIndices.size())   return false;
00193       if(_colBlockIndices.size()!=dest->_rowBlockIndices.size())   return false;
00194 
00195       for (size_t i=0; i<_rowBlockIndices.size(); i++)
00196       {
00197         if(_rowBlockIndices[i]!=dest->_colBlockIndices[i])   return false;
00198       }
00199 
00200       for (size_t i=0; i<_colBlockIndices.size(); i++)
00201         if(_colBlockIndices[i]!=dest->_rowBlockIndices[i])   return false;
00202     }
00203 
00204     for (size_t i=0; i<_blockCols.size(); i++)
00205     {
00206       for (typename SparseBlockMatrix<MatrixType>::IntBlockMap::const_iterator
00207            it  = _blockCols[i].begin();
00208            it != _blockCols[i].end();
00209            it++)
00210       {
00211         typename SparseBlockMatrix<MatrixType>::SparseMatrixBlock* s = 
00212            it->second;
00213         typename SparseBlockMatrix<MatrixTransposedType>::SparseMatrixBlock* d =
00214            dest->block(i,it->first,true);
00215         *d = s->transpose();
00216       }
00217     }
00218     return true;
00219   }
00220 
00221 /******************************************************************************/
00222 
00223   template <class MatrixType>
00224   bool SparseBlockMatrix<MatrixType>::add(SparseBlockMatrix*& dest) const
00225   {
00226     if (! dest)
00227     {
00228       dest = 
00229          new SparseBlockMatrix
00230          (
00231             &_rowBlockIndices[0], &_colBlockIndices[0],
00232             _rowBlockIndices.size(), _colBlockIndices.size()
00233          );
00234     }else
00235     {
00236       if(! dest->_hasStorage)   return false;
00237 
00238       if(_rowBlockIndices.size()!=dest->_rowBlockIndices.size())   return false;
00239       if(_colBlockIndices.size()!=dest->_colBlockIndices.size())   return false;
00240       for (size_t i=0; i<_rowBlockIndices.size(); i++)
00241       {
00242         if(_rowBlockIndices[i]!=dest->_rowBlockIndices[i])   return false;
00243       }
00244       for (size_t i=0; i<_colBlockIndices.size(); i++)
00245       {
00246         if(_colBlockIndices[i]!=dest->_colBlockIndices[i])   return false;
00247       }
00248     }
00249 
00250     for (size_t i=0; i<_blockCols.size(); i++)
00251     {
00252       for (typename SparseBlockMatrix<MatrixType>::IntBlockMap::const_iterator 
00253            it  = _blockCols[i].begin();
00254            it != _blockCols[i].end();
00255            it++)
00256       {
00257         typename SparseBlockMatrix<MatrixType>::SparseMatrixBlock* s =
00258            it->second;
00259         typename SparseBlockMatrix<MatrixType>::SparseMatrixBlock* d =
00260            dest->block(it->first,i,true);
00261         (*d) += *s;
00262       }
00263     }
00264     return true;
00265   }
00266 
00267 /******************************************************************************/
00268 
00269   template <class MatrixType>
00270   template < class MatrixResultType, class MatrixFactorType >
00271   bool SparseBlockMatrix<MatrixType>::multiply
00272   (
00273      SparseBlockMatrix<MatrixResultType>*& dest,
00274     const SparseBlockMatrix<MatrixFactorType> * M
00275   ) const
00276   {
00277     // sanity check
00278     if(_colBlockIndices.size()!=M->_rowBlockIndices.size())   return false;
00279     for (size_t i=0; i<_colBlockIndices.size(); i++)
00280       if(_colBlockIndices[i]!=M->_rowBlockIndices[i])   return false;
00281 
00282     if (! dest)
00283     {
00284       dest = 
00285          new SparseBlockMatrix<MatrixResultType>
00286          (
00287             &_rowBlockIndices[0], &(M->_colBlockIndices[0]),
00288             _rowBlockIndices.size(), M->_colBlockIndices.size()
00289          );
00290     }
00291 
00292     if (! dest->_hasStorage)   return false;
00293 
00294     for (size_t i=0; i<M->_blockCols.size(); i++)
00295     {
00296       for (typename SparseBlockMatrix<MatrixFactorType>::IntBlockMap::
00297            const_iterator it  = M->_blockCols[i].begin();
00298            it != M->_blockCols[i].end();
00299            it++)
00300       {
00301         // look for a non-zero block in a row of column it
00302         int colM = i;
00303         const typename SparseBlockMatrix<MatrixFactorType>::
00304            SparseMatrixBlock *b = it->second;
00305 
00306         typename SparseBlockMatrix<MatrixType>::IntBlockMap::const_iterator 
00307            rbt = _blockCols[it->first].begin();
00308 
00309         while(rbt!=_blockCols[it->first].end())
00310         {
00311           //int colA=it->first;
00312           int rowA = rbt->first;
00313           typename SparseBlockMatrix<MatrixType>::SparseMatrixBlock *a =
00314              rbt->second;
00315           typename SparseBlockMatrix<MatrixResultType>::SparseMatrixBlock *c =
00316              dest->block(rowA,colM,true);
00317           assert (c->rows()==a->rows());
00318           assert (c->cols()==b->cols());
00319           rbt++;
00320           (*c) += (*a)*(*b);
00321         }
00322       }
00323     }
00324     return false;
00325   }
00326 
00327 /******************************************************************************/
00328 
00329   template<typename MatrixType>
00330   inline void axpy
00331   (
00332      const MatrixType& A, const Map<VectorXd>& x,
00333      int xoff, Map<VectorXd>& y, int yoff
00334   )
00335   {
00336     y.segment<MatrixType::RowsAtCompileTime>(yoff) += 
00337        A * x.segment<MatrixType::ColsAtCompileTime>(xoff);
00338   }
00339 
00340 /******************************************************************************/
00341 
00342   template<>
00343   inline void axpy
00344   (
00345      const MatrixXd& A, const Map<VectorXd>& x,
00346      int xoff, Map<VectorXd>& y, int yoff
00347   )
00348   {
00349     y.segment(yoff, A.rows()) += A * x.segment(xoff, A.cols());
00350   }
00351 
00352 /******************************************************************************/
00353 
00354   template<typename MatrixType>
00355   inline void atxpy
00356   (
00357      const MatrixType& A, Map<const VectorXd>& x,
00358      int xoff, Map<VectorXd>& y, int yoff
00359   )
00360   {
00361     y.segment<MatrixType::ColsAtCompileTime>(yoff) +=
00362        A.transpose() * x.segment<MatrixType::RowsAtCompileTime>(xoff);
00363   }
00364 
00365 /******************************************************************************/
00366 
00367   template<>
00368   inline void atxpy
00369   (
00370      const MatrixXd& A, Map<const VectorXd>& x,
00371      int xoff, Map<VectorXd>& y, int yoff
00372   )
00373   {
00374     y.segment(yoff, A.cols()) += A.transpose() * x.segment(xoff, A.rows());
00375   }
00376 
00377 /******************************************************************************/
00378 
00379   template <class MatrixType>
00380   void SparseBlockMatrix<MatrixType>::multiply(double*& dest, const double* src)
00381   const 
00382   {
00383     if (! dest)
00384     {
00385       dest = new double [_rowBlockIndices[_rowBlockIndices.size()-1] ];
00386       memset
00387          (dest, 0, _rowBlockIndices[_rowBlockIndices.size()-1]*sizeof(double));
00388     }
00389 
00390     // map the memory by Eigen
00391     Map<VectorXd> destVec(dest, rows());
00392     const Map<VectorXd> srcVec(src, cols());
00393 
00394     for (size_t i=0; i<_blockCols.size(); i++)
00395     {
00396       int srcOffset = i ? _colBlockIndices[i-1] : 0;
00397 
00398       for (typename SparseBlockMatrix<MatrixType>::IntBlockMap::const_iterator
00399            it  = _blockCols[i].begin();
00400            it != _blockCols[i].end();
00401            ++it)
00402       {
00403         const typename SparseBlockMatrix<MatrixType>::SparseMatrixBlock* a =
00404            it->second;
00405         int destOffset = it->first ? _rowBlockIndices[it->first - 1] : 0;
00406         // destVec += *a * srcVec (according to the sub-vector parts)
00407         axpy(*a, srcVec, srcOffset, destVec, destOffset);
00408       }
00409     }
00410   }
00411 
00412 /******************************************************************************/
00413 
00414   template <class MatrixType>
00415   void SparseBlockMatrix<MatrixType>::rightMultiply
00416      (double*& dest, const double* src) const
00417   {
00418     int destSize=cols();
00419 
00420     if (! dest)
00421     {
00422       dest=new double [ destSize ];
00423       memset(dest,0, destSize*sizeof(double));
00424     }
00425 
00426     // map the memory by Eigen
00427     Map<VectorXd> destVec(dest, destSize);
00428     Map<const VectorXd> srcVec(src, rows());
00429 
00430 #   ifdef G2O_OPENMP
00431 #   pragma omp parallel for default (shared)
00432 #   endif
00433     for (int i=0; i < static_cast<int>(_blockCols.size()); i++)
00434     {
00435       int destOffset = colBaseOfBlock(i);
00436       for (typename SparseBlockMatrix<MatrixType>::IntBlockMap::const_iterator 
00437            it  = _blockCols[i].begin(); 
00438            it != _blockCols[i].end(); 
00439            ++it)
00440       {
00441         const typename SparseBlockMatrix<MatrixType>::SparseMatrixBlock* a =
00442            it->second;
00443         int srcOffset = rowBaseOfBlock(it->first);
00444         //destVec += *a.transpose() * srcVec (according to the sub-vector parts)
00445         atxpy(*a, srcVec, srcOffset, destVec, destOffset);
00446       }
00447     }
00448     
00449   }
00450 
00451 /******************************************************************************/
00452 
00453   template <class MatrixType>
00454   void SparseBlockMatrix<MatrixType>::scale(double a_)
00455   {
00456     for (size_t i=0; i<_blockCols.size(); i++)
00457     {
00458       for (typename SparseBlockMatrix<MatrixType>::IntBlockMap::const_iterator
00459            it  = _blockCols[i].begin();
00460            it != _blockCols[i].end();
00461            ++it)
00462       {
00463         typename SparseBlockMatrix<MatrixType>::SparseMatrixBlock* a=it->second;
00464         *a *= a_;
00465       }
00466     }
00467   }
00468 
00469 /******************************************************************************/
00470 
00471   template <class MatrixType>
00472   SparseBlockMatrix<MatrixType>*  SparseBlockMatrix<MatrixType>::slice
00473      (int rmin, int rmax, int cmin, int cmax, bool alloc) const 
00474   {
00475     int m = rmax-rmin;
00476     int n = cmax-cmin;
00477     int rowIdx [m];
00478     rowIdx[0] = rowsOfBlock(rmin);
00479     for (int i = 1; i<m; i++)
00480        rowIdx[i]=rowIdx[i-1]+rowsOfBlock(rmin+i);
00481 
00482     int colIdx [n];
00483     colIdx[0] = colsOfBlock(cmin);
00484     for (int i=1; i<n; i++)
00485        colIdx[i]=colIdx[i-1]+colsOfBlock(cmin+i);
00486 
00487     typename SparseBlockMatrix<MatrixType>::SparseBlockMatrix* s =
00488        new SparseBlockMatrix(rowIdx, colIdx, m, n, true);
00489 
00490     for (int i=0; i<n; i++)
00491     {
00492       int mc=cmin+i;
00493       for (typename SparseBlockMatrix<MatrixType>::IntBlockMap::const_iterator
00494            it  = _blockCols[mc].begin();
00495            it != _blockCols[mc].end();
00496            it++)
00497       {
00498         if (it->first >= rmin && it->first < rmax)
00499         {
00500           typename SparseBlockMatrix<MatrixType>::SparseMatrixBlock* b = 
00501              alloc 
00502               ? new typename 
00503                 SparseBlockMatrix<MatrixType>::SparseMatrixBlock (*(it->second))
00504               : it->second;
00505 
00506           s->_blockCols[i].insert(std::make_pair(it->first-rmin, b));
00507         }
00508       }
00509     }
00510     s->_hasStorage=alloc;
00511     return s;
00512   }
00513 
00514 /******************************************************************************/
00515 
00516   template <class MatrixType>
00517   size_t SparseBlockMatrix<MatrixType>::nonZeroBlocks() const
00518   {
00519     size_t count=0;
00520     for (size_t i=0; i<_blockCols.size(); i++)
00521       count+=_blockCols[i].size();
00522     return count;
00523   }
00524 
00525 /******************************************************************************/
00526 
00527   template <class MatrixType>
00528   size_t SparseBlockMatrix<MatrixType>::nonZeros() const
00529   {
00530     if (MatrixType::SizeAtCompileTime != Eigen::Dynamic)
00531     {
00532       size_t nnz = nonZeroBlocks() * MatrixType::SizeAtCompileTime;
00533       return nnz;
00534     }else
00535     {
00536       size_t count=0;
00537       for (size_t i=0; i<_blockCols.size(); i++)
00538       {
00539         for (typename SparseBlockMatrix<MatrixType>::IntBlockMap::const_iterator
00540              it  = _blockCols[i].begin();
00541              it != _blockCols[i].end();
00542              it++)
00543         {
00544           const typename SparseBlockMatrix<MatrixType>::SparseMatrixBlock* a =
00545              it->second;
00546           count += a->cols()*a->rows();
00547         }
00548       }
00549       return count;
00550     }
00551   }
00552 
00553 /******************************************************************************/
00554 
00555   template <class MatrixType>
00556   std::ostream& operator << 
00557      (std::ostream& os, const SparseBlockMatrix<MatrixType>& m)
00558   {
00559     os << "RBI: " << m.rowBlockIndices().size();
00560     for (size_t i=0; i<m.rowBlockIndices().size(); i++)
00561       os << " " << m.rowBlockIndices()[i];
00562     os << std::endl;
00563 
00564     os << "CBI: " << m.colBlockIndices().size();
00565     for (size_t i=0; i<m.colBlockIndices().size(); i++)
00566       os << " " << m.colBlockIndices()[i];
00567     os << std::endl;
00568 
00569     for (size_t i=0; i<m.blockCols().size(); i++)
00570     {
00571       for (typename SparseBlockMatrix<MatrixType>::IntBlockMap::const_iterator 
00572            it  = m.blockCols()[i].begin();
00573            it != m.blockCols()[i].end();
00574            it++)
00575       {
00576         const typename SparseBlockMatrix<MatrixType>::SparseMatrixBlock* b =
00577            it->second;
00578         os << "BLOCK: " << it->first << " " << i << std::endl
00579            << *b << std::endl;
00580       }
00581     }
00582     return os;
00583   }
00584 
00585 /******************************************************************************/
00586 
00587   template <class MatrixType>
00588   bool SparseBlockMatrix<MatrixType>::symmPermutation
00589      (SparseBlockMatrix<MatrixType>*& dest, const int* pinv, bool upperTriangle)
00590   const
00591   {
00592     // compute the permuted version of the new row/column layout
00593     size_t n=_rowBlockIndices.size();
00594 
00595     // computed the block sizes
00596     int blockSizes[_rowBlockIndices.size()];
00597     blockSizes[0]=_rowBlockIndices[0];
00598     for (size_t i=1; i<n; i++)
00599       blockSizes[i]=_rowBlockIndices[i]-_rowBlockIndices[i-1];
00600 
00601     // permute them
00602     int pBlockIndices[_rowBlockIndices.size()];
00603     for (size_t i=0; i<n; i++)
00604       pBlockIndices[pinv[i]]=blockSizes[i];
00605 
00606     for (size_t i=1; i<n; i++)
00607       pBlockIndices[i] += pBlockIndices[i-1];
00608 
00609     // allocate C, or check the structure;
00610     if(! dest)
00611     {
00612       dest =
00613          new SparseBlockMatrix(pBlockIndices, pBlockIndices, n, n);
00614     }else
00615     {
00616       if(dest->_rowBlockIndices.size()!=n)   return false;
00617       if(dest->_colBlockIndices.size()!=n)   return false;
00618       for (size_t i=0; i<n; i++)
00619       {
00620         if(dest->_rowBlockIndices[i]!=pBlockIndices[i])   return false;
00621         if(dest->_colBlockIndices[i]!=pBlockIndices[i])   return false;
00622       }
00623       dest->clear();
00624     }
00625 
00626     // now ready to permute the columns
00627     for (size_t i=0; i<n; i++)
00628     {
00629       //cerr << PVAR(i) <<  " ";
00630       int pi = pinv[i];
00631       for (typename SparseBlockMatrix<MatrixType>::IntBlockMap::const_iterator
00632            it  = _blockCols[i].begin(); 
00633            it!=_blockCols[i].end();
00634            it++)
00635       {
00636         int pj=pinv[it->first];
00637 
00638         const typename SparseBlockMatrix<MatrixType>::SparseMatrixBlock* s =
00639            it->second;
00640 
00641         typename SparseBlockMatrix<MatrixType>::SparseMatrixBlock* b = 0;
00642         if (! upperTriangle || pj<=pi)
00643         {
00644           b = dest->block(pj,pi,true);
00645           assert(b->cols() == s->cols());
00646           assert(b->rows() == s->rows());
00647           *b = *s;
00648         }else
00649         {
00650           b = dest->block(pi,pj,true);
00651           assert(b);
00652           assert(b->rows() == s->cols());
00653           assert(b->cols() == s->rows());
00654           *b = s->transpose();
00655         }
00656       }
00657       //cerr << endl;
00658       // within each row, 
00659     }
00660     return true;
00661   }
00662 
00663 /******************************************************************************/
00664 
00665   template <class MatrixType>
00666   int SparseBlockMatrix<MatrixType>::fillCCS(double* Cx, bool upperTriangle)
00667   const
00668   {
00669     double* CxStart = Cx;
00670     for (size_t i=0; i<_blockCols.size(); ++i)
00671     {
00672       int cstart=i ? _colBlockIndices[i-1] : 0;
00673       int csize=colsOfBlock(i);
00674       for (int c=0; c<csize; c++)
00675       {
00676         for (typename SparseBlockMatrix<MatrixType>::IntBlockMap::const_iterator
00677              it  = _blockCols[i].begin();
00678              it != _blockCols[i].end();
00679              ++it)
00680         {
00681           const typename SparseBlockMatrix<MatrixType>::SparseMatrixBlock* b =
00682              it->second;
00683           int rstart = it->first ? _rowBlockIndices[it->first-1] : 0;
00684 
00685           int elemsToCopy = b->rows();
00686           if (upperTriangle && rstart == cstart)   elemsToCopy = c + 1;
00687 
00688           memcpy(Cx, b->data() + c*b->rows(), elemsToCopy * sizeof(double));
00689           Cx += elemsToCopy;
00690         }
00691       }
00692     }
00693     return Cx - CxStart;
00694   }
00695 
00696 /******************************************************************************/
00697 
00698   template <class MatrixType>
00699   int SparseBlockMatrix<MatrixType>::fillCCS
00700      (int* Cp, int* Ci, double* Cx, bool upperTriangle) const
00701   {
00702     int nz=0;
00703     for (size_t i=0; i<_blockCols.size(); ++i)
00704     {
00705       int cstart = i ? _colBlockIndices[i-1] : 0;
00706       int csize = colsOfBlock(i);
00707       for (int c = 0; c<csize; c++)
00708       {
00709         *Cp = nz;
00710         for (typename SparseBlockMatrix<MatrixType>::IntBlockMap::const_iterator
00711              it  = _blockCols[i].begin();
00712              it != _blockCols[i].end();
00713              ++it)
00714         {
00715           const typename SparseBlockMatrix<MatrixType>::SparseMatrixBlock* b =
00716              it->second;
00717           int rstart=it->first ? _rowBlockIndices[it->first-1] : 0;
00718 
00719           int elemsToCopy = b->rows();
00720           if (upperTriangle && rstart == cstart)   elemsToCopy = c + 1;
00721 
00722           for (int r=0; r<elemsToCopy; ++r)
00723           {
00724             *Cx++ = (*b)(r,c);
00725             *Ci++ = rstart++;
00726             ++nz;
00727           }
00728         }
00729         ++Cp;
00730       }
00731     }
00732     *Cp = nz;
00733     return nz;
00734   }
00735 
00736 /******************************************************************************/
00737 
00738   template <class MatrixType>
00739   void SparseBlockMatrix<MatrixType>::fillBlockStructure(MatrixStructure& ms)
00740   const
00741   {
00742     int n     = _colBlockIndices.size();
00743     int nzMax = (int)nonZeroBlocks();
00744 
00745     ms.alloc(n, nzMax);
00746     ms.m = _rowBlockIndices.size();
00747 
00748     int nz = 0;
00749     int* Cp = ms.Ap;
00750     int* Ci = ms.Aii;
00751     for (size_t i = 0; i<_blockCols.size(); ++i)
00752     {
00753       *Cp = nz;
00754       const int& c = i;
00755       for (typename SparseBlockMatrix<MatrixType>::IntBlockMap::const_iterator 
00756            it  = _blockCols[i].begin();
00757            it != _blockCols[i].end();
00758            ++it) 
00759       {
00760         const int& r = it->first;
00761         if (r <= c)
00762         {
00763           *Ci++ = r;
00764           ++nz;
00765         }
00766       }
00767       Cp++;
00768     }
00769     *Cp = nz;
00770     assert(nz <= nzMax);
00771   }
00772 
00773 /******************************************************************************/
00774 
00775   template <class MatrixType>
00776   bool SparseBlockMatrix<MatrixType>::writeOctave
00777      (const char* filename, bool upperTriangle) const
00778   {
00779     std::string name = filename;
00780     std::string::size_type lastDot = name.find_last_of('.');
00781     if(lastDot != std::string::npos)   name = name.substr(0, lastDot);
00782 
00783     std::vector<TripletEntry> entries;
00784     for (size_t i = 0; i<_blockCols.size(); ++i)
00785     {
00786       const int& c = i;
00787       for (typename SparseBlockMatrix<MatrixType>::IntBlockMap::const_iterator 
00788            it  = _blockCols[i].begin();
00789            it != _blockCols[i].end();
00790            ++it)
00791       {
00792         const int& r = it->first;
00793         const MatrixType& m = *(it->second);
00794         for (int cc = 0; cc < m.cols(); ++cc)
00795           for (int rr = 0; rr < m.rows(); ++rr)
00796           {
00797             int aux_r = rowBaseOfBlock(r) + rr;
00798             int aux_c = colBaseOfBlock(c) + cc;
00799             entries.push_back(TripletEntry(aux_r, aux_c, m(rr, cc)));
00800             if (upperTriangle && r != c)
00801             {
00802               entries.push_back(TripletEntry(aux_c, aux_r, m(rr, cc)));
00803             }
00804           }
00805       }
00806     }
00807 
00808     int nz = entries.size();
00809     std::sort(entries.begin(), entries.end(), TripletColSort());
00810 
00811     std::ofstream fout(filename);
00812     fout << "# name: " << name << std::endl;
00813     fout << "# type: sparse matrix" << std::endl;
00814     fout << "# nnz: " << nz << std::endl;
00815     fout << "# rows: " << rows() << std::endl;
00816     fout << "# columns: " << cols() << std::endl;
00817     fout << std::setprecision(9) << std::endl;
00818 
00819     for (std::vector<TripletEntry>::const_iterator
00820          it  = entries.begin();
00821          it != entries.end();
00822          ++it)
00823     {
00824       const TripletEntry& entry = *it;
00825       fout << entry.r+1 << " " << entry.c+1 << " " << entry.x << std::endl;
00826     }
00827     return fout.good();
00828   }
00829 
00830 }// end namespace


re_vision
Author(s): Dorian Galvez-Lopez
autogenerated on Sun Jan 5 2014 11:32:45