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