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