00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef CSparseMatrixTemplate_H
00029 #define CSparseMatrixTemplate_H
00030
00031 #include <mrpt/utils/utils_defs.h>
00032
00033 namespace mrpt {
00034 namespace math {
00035 using namespace std;
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 template<class T>
00052 class CSparseMatrixTemplate {
00053
00054 public:
00055
00056
00057
00058 typedef typename std::map<std::pair<size_t,size_t>,T> SparseMatrixMap;
00059
00060
00061
00062
00063 typedef typename SparseMatrixMap::const_iterator const_iterator;
00064
00065
00066
00067
00068 typedef typename SparseMatrixMap::const_reverse_iterator const_reverse_iterator;
00069 protected:
00070
00071
00072
00073 size_t mRows,mColumns;
00074
00075
00076
00077 SparseMatrixMap objectList;
00078 public:
00079
00080
00081
00082 CSparseMatrixTemplate():mRows(0),mColumns(0) {}
00083
00084
00085
00086 CSparseMatrixTemplate(size_t nR,size_t nC):mRows(nR),mColumns(nC) {}
00087
00088
00089
00090 inline T operator()(size_t r,size_t c) const {
00091 const_iterator it=objectList.find(make_pair(r,c));
00092 if (it==objectList.end()) return T();
00093 else return it->second;
00094 }
00095
00096
00097
00098 inline bool exists(size_t r,size_t c) const {
00099 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00100 if (r>=mRows||c>=mColumns) throw std::logic_error("Out of range");
00101 #endif
00102 return (objectList.find(make_pair(r,c)) != objectList.end());
00103 }
00104
00105
00106
00107
00108 inline T& operator()(size_t r,size_t c) {
00109 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00110 if (r>=mRows||c>=mColumns) throw std::logic_error("Out of range");
00111 #endif
00112 return objectList[make_pair(r,c)];
00113 }
00114
00115
00116
00117
00118 inline size_t getRowCount() const {
00119 return mRows;
00120 }
00121
00122
00123
00124
00125 inline size_t getColCount() const {
00126 return mColumns;
00127 }
00128
00129
00130
00131
00132
00133 void getRow(size_t nRow,std::vector<T> &vec) const {
00134 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00135 if (nRow>=mRows) throw std::logic_error("Out of range");
00136 #endif
00137 vec.resize(mColumns);
00138 size_t nextIndex=0;
00139 for (typename SparseMatrixMap::const_iterator it=objectList.begin();it!=objectList.end();++it) {
00140 const pair<size_t,size_t> &index=it->first;
00141 if (index.first<nRow) continue;
00142 else if (index.first==nRow) {
00143 for (size_t i=nextIndex;i<index.second;i++) vec[i]=T();
00144 vec[index.second]=it->second;
00145 nextIndex=index.second+1;
00146 } else {
00147 for (size_t i=nextIndex;i<mColumns;i++) vec[i]=T();
00148 break;
00149 }
00150 }
00151 }
00152
00153
00154
00155
00156
00157 void getColumn(size_t nCol,std::vector<T> &vec) const {
00158 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00159 if (nCol>=mColumns) throw std::logic_error("Out of range");
00160 #endif
00161 vec.resize(mRows);
00162 size_t nextIndex=0;
00163 for (typename SparseMatrixMap::const_iterator it=objectList.begin();it!=objectList.end();++it) {
00164 const pair<size_t,size_t> &index=it->first;
00165 if (index.second==nCol) {
00166 for (size_t i=nextIndex;i<index.first;i++) vec[i]=T();
00167 vec[index.first]=it->second;
00168 nextIndex=index.first+1;
00169 }
00170 }
00171 for (size_t i=nextIndex;i<mRows;i++) vec[i]=T();
00172 }
00173
00174
00175
00176
00177 inline void insert(size_t row,size_t column,const T& obj) {
00178 operator()(row,column)=obj;
00179 }
00180
00181
00182 template <class MATRIX_LIKE>
00183 inline void insertMatrix(size_t row,size_t column,const MATRIX_LIKE& mat)
00184 {
00185 for (size_t nr=0;nr<mat.getRowCount();nr++)
00186 for (size_t nc=0;nc<mat.getColCount();nc++)
00187 operator()(row+nr,column+nc)=mat(nr,nc);
00188 }
00189
00190
00191
00192
00193
00194
00195 inline const_iterator begin() const {
00196 return objectList.begin();
00197 }
00198
00199
00200
00201
00202 inline const_iterator end() const {
00203 return objectList.end();
00204 }
00205
00206
00207
00208
00209 inline const_reverse_iterator rbegin() const {
00210 return objectList.rbegin();
00211 }
00212
00213
00214
00215
00216 inline const_reverse_iterator rend() const {
00217 return objectList.rend();
00218 }
00219
00220
00221
00222
00223
00224 void setRow(size_t nRow,const std::vector<T> &vec,const T& nullObject=T()) {
00225 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00226 if (nRow>=mRows) throw std::logic_error("Out of range");
00227 #endif
00228 size_t N=vec.size();
00229 if (N!=mColumns) throw std::logic_error("Wrong-sized vector");
00230 for (size_t i=0;i<N;i++) {
00231 const T &obj=vec[i];
00232 pair<size_t,size_t> index=make_pair(nRow,i);
00233 if (obj==nullObject) objectList.erase(index);
00234 else objectList[index]=obj;
00235 }
00236 }
00237
00238
00239
00240
00241
00242 void setColumn(size_t nCol,const std::vector<T> &vec,const T& nullObject=T()) {
00243 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00244 if (nCol>=mColumns) throw std::logic_error("Out of range");
00245 #endif
00246 size_t N=vec.size();
00247 if (N!=mRows) throw std::logic_error("Wrong-sized vector");
00248 for (size_t i=0;i<N;i++) {
00249 const T &obj=vec[i];
00250 pair<size_t,size_t> index=make_pair(i,nCol);
00251 if (obj==nullObject) objectList.erase(index);
00252 else objectList[index]=obj;
00253 }
00254 }
00255
00256
00257
00258 void resize(size_t nRows,size_t nCols) {
00259
00260 if (mRows==nRows && mColumns==nCols) return;
00261 mRows=nRows;
00262 mColumns=nCols;
00263 std::vector<pair<size_t,size_t> > toErase;
00264 for (const_iterator it=objectList.begin();it!=objectList.end();++it) {
00265 const pair<size_t,size_t> &i=it->first;
00266 if (i.first>=nRows||i.second>=nCols) toErase.push_back(it->first);
00267 }
00268 for (std::vector<pair<size_t,size_t> >::const_iterator it=toErase.begin();it!=toErase.end();++it) objectList.erase(*it);
00269 }
00270
00271
00272
00273
00274
00275 CSparseMatrixTemplate<T> operator()(size_t firstRow,size_t lastRow,size_t firstColumn,size_t lastColumn) const {
00276 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00277 if (lastRow>=mRows||lastColumn>=mColumns) throw std::logic_error("Out of range");
00278 if (firstRow>lastRow||firstColumn>lastColumn) throw std::logic_error("Invalid size");
00279 #endif
00280 CSparseMatrixTemplate<T> res=CSparseMatrixTemplate<T>(lastRow+1-firstRow,lastColumn+1-firstColumn);
00281 for (typename SparseMatrixMap::const_iterator it=begin();it!=end();++it) {
00282 const pair<size_t,size_t> &i=it->first;
00283 if (i.first>=firstRow&&i.first<=lastRow&&i.second>=firstColumn&&i.second<=lastColumn) res(i.first-firstRow,i.second-firstColumn)=it->second;
00284 }
00285 return res;
00286 }
00287
00288
00289
00290 void getAsVector(std::vector<T> &vec) const {
00291 size_t N=objectList.size();
00292 vec.resize(0);
00293 vec.reserve(N);
00294 for (const_iterator it=objectList.begin();it!=objectList.end();++it) vec.push_back(it->second);
00295 }
00296
00297
00298
00299
00300 inline size_t getNonNullElements() const {
00301 return objectList.size();
00302 }
00303
00304
00305
00306 inline bool empty() const { return objectList.empty(); }
00307
00308
00309
00310
00311
00312 inline size_t getNullElements() const {
00313 return mRows*mColumns-getNonNullElements();
00314 }
00315
00316
00317
00318
00319
00320 inline bool isNull(size_t nRow,size_t nCol) const {
00321 if (nRow>=mRows||nCol>=mColumns) throw std::logic_error("Out of range");
00322 return objectList.count(make_pair(nRow,nCol))==0;
00323 }
00324
00325
00326
00327
00328 inline bool isNotNull(size_t nRow,size_t nCol) const {
00329 if (nRow>=mRows||nCol>=mColumns) throw std::logic_error("Out of range");
00330 return objectList.count(make_pair(nRow,nCol))>0;
00331 }
00332
00333
00334
00335 inline void clear() {
00336 objectList.clear();
00337 }
00338
00339
00340
00341 void purge(T nullObject=T()) {
00342 std::vector<std::pair<size_t,size_t> > nulls;
00343 for (const_iterator it=begin();it!=end();++it) if (it->second==nullObject) nulls.push_back(it->first);
00344 for (std::vector<std::pair<size_t,size_t> >::const_iterator it=nulls.begin();it!=nulls.end();++it) objectList.erase(*it);
00345 }
00346 };
00347
00348
00349
00350
00351
00352
00353 template<class T>
00354 class CSparseSymmetricalMatrix : public CSparseMatrixTemplate<T> {
00355 public:
00356 CSparseSymmetricalMatrix() : CSparseMatrixTemplate<T>() { }
00357 explicit CSparseSymmetricalMatrix(const CSparseSymmetricalMatrix &o) : CSparseMatrixTemplate<T>(o) { }
00358 explicit CSparseSymmetricalMatrix(const CSparseMatrixTemplate<T> &o) : CSparseMatrixTemplate<T>(o) { }
00359 virtual ~CSparseSymmetricalMatrix() { }
00360
00361 void resize(size_t matrixSize) {
00362 CSparseMatrixTemplate<T>::resize(matrixSize,matrixSize);
00363 }
00364
00365 inline T operator()(size_t r,size_t c) const {
00366 if (c<r) std::swap(r,c);
00367 typename CSparseMatrixTemplate<T>::const_iterator it=CSparseMatrixTemplate<T>::objectList.find(make_pair(r,c));
00368 if (it==CSparseMatrixTemplate<T>::objectList.end()) return T();
00369 else return it->second;
00370 }
00371 inline T& operator()(size_t r,size_t c) {
00372 if (c<r) std::swap(r,c);
00373 if (r>=CSparseMatrixTemplate<T>::mRows||c>=CSparseMatrixTemplate<T>::mColumns) throw std::logic_error("Out of range");
00374 return CSparseMatrixTemplate<T>::objectList[make_pair(r,c)];
00375 }
00376
00377 };
00378
00379 }
00380 }
00381 #endif