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