Main MRPT website > C++ reference for MRPT 1.9.9
CSparseMatrixTemplate.h
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2017, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 #ifndef CSparseMatrixTemplate_H
10 #define CSparseMatrixTemplate_H
11 
12 #include <mrpt/utils/utils_defs.h>
13 #include <map>
14 
15 namespace mrpt
16 {
17 namespace math
18 {
19 /** A sparse matrix container (with cells of any type), with iterators.
20  * This class stores only those elements created by assigning them a value,
21  * for example: "M(2,3)=8;".
22  *
23  * This class doesn't implement math operations since it's a generic sparse
24  * container, but it can be
25  * used to initialize the contents of a CSparse library-based matrix of type
26  * mrpt::math::CSparseMatrix.
27  *
28  * Note that reading non-existing cell elements will return the default value
29  * (0 for numbers)
30  * and that cell will remain non-created in the matrix.
31  *
32  * There is an additional method "exists(i,j)" to check whether a given
33  * element exists in the matrix.
34  *
35  * \sa mrpt::math::MatrixBlockSparseCols, mrpt::math::CSparseMatrix,
36  * CSparseSymmetricalMatrix
37  * \note Methods marked as "Doesn't check bounds" mean that if an access to an
38  * element out of the matrix size is tried, an empty element will be assumed,
39  * but this will not raise any invalid memory access.
40  * \ingroup mrpt_base_grp
41  */
42 template <class T>
44 {
45  // Public typedefs
46  public:
47  /**
48  * Internal map type, used to store the actual matrix.
49  */
50  typedef typename std::map<std::pair<size_t, size_t>, T> SparseMatrixMap;
51  /**
52  * Const iterator to move through the matrix.
53  * \sa CSparseMatrixTemplate::const_reverse_iterator
54  */
56  /**
57  * Const reverse iterator to move through the matrix.
58  * \sa CSparseMatrixTemplate::const_iterator
59  */
60  typedef
61  typename SparseMatrixMap::const_reverse_iterator const_reverse_iterator;
62 
63  protected:
64  /**
65  * Size of the matrix.
66  */
67  size_t mRows, mColumns;
68  /**
69  * Actual matrix.
70  */
72 
73  public:
74  /**
75  * Basic constructor with no data. Size is set to (0,0).
76  */
78  /**
79  * Constructor with default size.
80  */
81  CSparseMatrixTemplate(size_t nR, size_t nC) : mRows(nR), mColumns(nC) {}
82  /**
83  * Element access operator. Doesn't check bounds.
84  */
85  inline T operator()(size_t r, size_t c) const
86  {
87  const_iterator it = objectList.find(std::make_pair(r, c));
88  if (it == objectList.end())
89  return T();
90  else
91  return it->second;
92  }
93 
94  /** Element access operator. Checks bounds.
95  */
96  inline bool exists(size_t r, size_t c) const
97  {
98 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
99  if (r >= mRows || c >= mColumns) throw std::logic_error("Out of range");
100 #endif
101  return (objectList.find(std::make_pair(r, c)) != objectList.end());
102  }
103 
104  /**
105  * Reference access operator. Checks for bounds.
106  */
107  inline T& operator()(size_t r, size_t c)
108  { //-V659
109 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
110  if (r >= mRows || c >= mColumns) throw std::logic_error("Out of range");
111 #endif
112  return objectList[std::make_pair(r, c)];
113  }
114  /**
115  * Returns the amount of rows in this matrix.
116  * \sa getColCount,getRow
117  */
118  inline size_t getRowCount() const { return mRows; }
119  /**
120  * Returns the amount of columns in this matrix.
121  * \sa getRowCount
122  */
123  inline size_t getColCount() const { return mColumns; }
124  /**
125  * Extracts a full row from the matrix.
126  * \sa getRowCount,getColumn,setRow
127  * \throw std::logic_error on out of range.
128  */
129  void getRow(size_t nRow, std::vector<T>& vec) const
130  {
131 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
132  if (nRow >= mRows) throw std::logic_error("Out of range");
133 #endif
134  vec.resize(mColumns);
135  size_t nextIndex = 0;
136  for (typename SparseMatrixMap::const_iterator it = objectList.begin();
137  it != objectList.end(); ++it)
138  {
139  const std::pair<size_t, size_t>& index = it->first;
140  if (index.first < nRow)
141  continue;
142  else if (index.first == nRow)
143  {
144  for (size_t i = nextIndex; i < index.second; i++) vec[i] = T();
145  vec[index.second] = it->second;
146  nextIndex = index.second + 1;
147  }
148  else
149  {
150  for (size_t i = nextIndex; i < mColumns; i++) vec[i] = T();
151  break;
152  }
153  }
154  }
155  /**
156  * Extracts a full column from the matrix.
157  * \sa getColCount,getRow,setColumn
158  * \throw std::logic_error on out of range.
159  */
160  void getColumn(size_t nCol, std::vector<T>& vec) const
161  {
162 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
163  if (nCol >= mColumns) throw std::logic_error("Out of range");
164 #endif
165  vec.resize(mRows);
166  size_t nextIndex = 0;
167  for (typename SparseMatrixMap::const_iterator it = objectList.begin();
168  it != objectList.end(); ++it)
169  {
170  const std::pair<size_t, size_t>& index = it->first;
171  if (index.second == nCol)
172  {
173  for (size_t i = nextIndex; i < index.first; i++) vec[i] = T();
174  vec[index.first] = it->second;
175  nextIndex = index.first + 1;
176  }
177  }
178  for (size_t i = nextIndex; i < mRows; i++) vec[i] = T();
179  }
180  /**
181  * Inserts an element into the matrix.
182  * \sa operator()(size_t,size_t)
183  */
184  inline void insert(size_t row, size_t column, const T& obj)
185  {
186  operator()(row, column) = obj;
187  }
188 
189  /** Inserts submatrix at a given location */
190  template <class MATRIX_LIKE>
191  inline void insertMatrix(size_t row, size_t column, const MATRIX_LIKE& mat)
192  {
193  for (size_t nr = 0; nr < mat.getRowCount(); nr++)
194  for (size_t nc = 0; nc < mat.getColCount(); nc++)
195  operator()(row + nr, column + nc) = mat(nr, nc);
196  }
197 
198  // Public interface only supports const iterators. This way, no user of this
199  // class will be able to freely modify it contents.
200  /**
201  * Returns an iterator which points to the starting point of the matrix.
202  * It's a const_iterator, so that the usar isn't able to modify the matrix
203  * content into an invalid state.
204  * \sa end,rbegin,rend
205  */
206  inline const_iterator begin() const { return objectList.begin(); }
207  /**
208  * Returns an iterator which points to the end of the matrix. It's a
209  * const_iterator, so that the usar isn't able to modify the matrix content
210  * into an invalid state.
211  * \sa begin,rbegin,rend
212  */
213  inline const_iterator end() const { return objectList.end(); }
214  /**
215  * Returns an iterator which points to the end of the matrix, and can be
216  * used to move backwards. It's a const_reverse_iterator, so that the usar
217  * isn't able to modify the matrix content into an invalid state.
218  * \sa begin,end,rend
219  */
220  inline const_reverse_iterator rbegin() const { return objectList.rbegin(); }
221  /**
222  * Returns an iterator which points to the starting point of the matrix,
223  * although it's the upper limit of the matrix since it's a reverse
224  * iterator. Also, it's a const_reverse_iterator, so that the usar isn't
225  * able to modify the matrix content into an invalid state.
226  * \sa begin,end,rbegin
227  */
228  inline const_reverse_iterator rend() const { return objectList.rend(); }
229  /**
230  * Inserts a full row into the matrix. The third argument is used to
231  * specify a null object (which won't be inserted, since the matrix is
232  * sparse).
233  * \sa getRow
234  * \throw std::logic_error on out of range or wrong sized vector.
235  */
236  void setRow(
237  size_t nRow, const std::vector<T>& vec, const T& nullObject = T())
238  {
239 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
240  if (nRow >= mRows) throw std::logic_error("Out of range");
241 #endif
242  size_t N = vec.size();
243  if (N != mColumns) throw std::logic_error("Wrong-sized vector");
244  for (size_t i = 0; i < N; i++)
245  {
246  const T& obj = vec[i];
247  std::pair<size_t, size_t> index = std::make_pair(nRow, i);
248  if (obj == nullObject)
249  objectList.erase(index);
250  else
251  objectList[index] = obj;
252  }
253  }
254  /**
255  * Inserts a full column into the matrix. The third argument is used to
256  * specify a null object (which won't be inserted, since the matrix is
257  * sparse).
258  * \sa getColumn
259  * \throw std::logic_error on out of range or wrong sized vector.
260  */
261  void setColumn(
262  size_t nCol, const std::vector<T>& vec, const T& nullObject = T())
263  {
264 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
265  if (nCol >= mColumns) throw std::logic_error("Out of range");
266 #endif
267  size_t N = vec.size();
268  if (N != mRows) throw std::logic_error("Wrong-sized vector");
269  for (size_t i = 0; i < N; i++)
270  {
271  const T& obj = vec[i];
272  std::pair<size_t, size_t> index = std::make_pair(i, nCol);
273  if (obj == nullObject)
274  objectList.erase(index);
275  else
276  objectList[index] = obj;
277  }
278  }
279  /**
280  * Changes the size of the matrix.
281  */
282  void resize(size_t nRows, size_t nCols)
283  {
284  // if (mRows<0||mColumns<0) throw std::logic_error("Invalid range"); //
285  // This case never happens!
286  if (mRows == nRows && mColumns == nCols) return;
287  mRows = nRows;
288  mColumns = nCols;
289  std::vector<std::pair<size_t, size_t>> toErase;
290  for (const_iterator it = objectList.begin(); it != objectList.end();
291  ++it)
292  {
293  const std::pair<size_t, size_t>& i = it->first;
294  if (i.first >= nRows || i.second >= nCols)
295  toErase.push_back(it->first);
296  }
297  for (std::vector<std::pair<size_t, size_t>>::const_iterator it =
298  toErase.begin();
299  it != toErase.end(); ++it)
300  objectList.erase(*it);
301  }
302  /**
303  * Extracts a submatrix form the matrix.
304  * \sa operator()(size_t,size_t)
305  * \throw std::logic_error on invalid bounds.
306  */
308  size_t firstRow, size_t lastRow, size_t firstColumn,
309  size_t lastColumn) const
310  {
311 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
312  if (lastRow >= mRows || lastColumn >= mColumns)
313  throw std::logic_error("Out of range");
314  if (firstRow > lastRow || firstColumn > lastColumn)
315  throw std::logic_error("Invalid size");
316 #endif
318  lastRow + 1 - firstRow, lastColumn + 1 - firstColumn);
319  for (typename SparseMatrixMap::const_iterator it = begin(); it != end();
320  ++it)
321  {
322  const std::pair<size_t, size_t>& i = it->first;
323  if (i.first >= firstRow && i.first <= lastRow &&
324  i.second >= firstColumn && i.second <= lastColumn)
325  res(i.first - firstRow, i.second - firstColumn) = it->second;
326  }
327  return res;
328  }
329  /**
330  * Gets a vector containing all the elements of the matrix, ignoring their
331  * position.
332  */
333  void getAsVector(std::vector<T>& vec) const
334  {
335  size_t N = objectList.size();
336  vec.resize(0);
337  vec.reserve(N);
338  for (const_iterator it = objectList.begin(); it != objectList.end();
339  ++it)
340  vec.push_back(it->second);
341  }
342  /**
343  * Gets the amount of non-null elements inside the matrix.
344  * \sa getNullElements,isNull,isNotNull
345  */
346  inline size_t getNonNullElements() const { return objectList.size(); }
347  /** Are there no elements set to !=0 ?
348  * \sa getNullElements,isNull,isNotNull
349  */
350  inline bool empty() const { return objectList.empty(); }
351  /**
352  * Gets the amount of null elements inside the matrix.
353  * \sa getNonNullElements,isNull,isNotNull
354  */
355  inline size_t getNullElements() const
356  {
357  return mRows * mColumns - getNonNullElements();
358  }
359  /**
360  * Checks whether an element of the matrix is the default object.
361  * \sa getNonNullElements,getNullElements,isNotNull
362  * \throw std::logic_error on out of range
363  */
364  inline bool isNull(size_t nRow, size_t nCol) const
365  {
366  if (nRow >= mRows || nCol >= mColumns)
367  throw std::logic_error("Out of range");
368  return objectList.count(std::make_pair(nRow, nCol)) == 0;
369  }
370  /**
371  * Checks whether an element of the matrix is not the default object.
372  * \sa getNonNullElements,getNullElements,isNull
373  */
374  inline bool isNotNull(size_t nRow, size_t nCol) const
375  {
376  if (nRow >= mRows || nCol >= mColumns)
377  throw std::logic_error("Out of range");
378  return objectList.count(std::make_pair(nRow, nCol)) > 0;
379  }
380  /**
381  * Completely removes all elements, although maintaining the matrix's size.
382  */
383  inline void clear() { objectList.clear(); }
384  /**
385  * Checks each non-null elements against the basic objects, erasing
386  * unnecesary references to it.
387  */
388  void purge(T nullObject = T())
389  {
390  std::vector<std::pair<size_t, size_t>> nulls;
391  for (const_iterator it = begin(); it != end(); ++it)
392  if (it->second == nullObject) nulls.push_back(it->first);
393  for (std::vector<std::pair<size_t, size_t>>::const_iterator it =
394  nulls.begin();
395  it != nulls.end(); ++it)
396  objectList.erase(*it);
397  }
398 }; // end of sparse matrix
399 
400 /** A sparse matrix container for square symmetrical content around the main
401  * diagonal.
402  * This class saves half of the space with respect to CSparseMatrixTemplate
403  * since only those entries (c,r) such as c>=r are really stored,
404  * but both (c,r) and (r,c) can be retrieved or set and both redirect to the
405  * same internal cell container.
406  * \sa CSparseMatrixTemplate
407  */
408 template <class T>
410 {
411  public:
414  : CSparseMatrixTemplate<T>(o)
415  {
416  }
418  : CSparseMatrixTemplate<T>(o)
419  {
420  }
422  void resize(size_t matrixSize)
423  {
424  CSparseMatrixTemplate<T>::resize(matrixSize, matrixSize);
425  }
426 
427  inline T operator()(size_t r, size_t c) const
428  {
429  if (c < r) std::swap(r, c); // Symmetrical matrix
431  CSparseMatrixTemplate<T>::objectList.find(std::make_pair(r, c));
433  return T();
434  else
435  return it->second;
436  }
437  inline T& operator()(size_t r, size_t c)
438  { //-V659
439  if (c < r) std::swap(r, c); // Symmetrical matrix
442  throw std::logic_error("Out of range");
443  return CSparseMatrixTemplate<T>::objectList[std::make_pair(r, c)];
444  }
445 
446 }; // end of CSparseSymmetricalMatrix
447 }
448 }
449 #endif
void insertMatrix(size_t row, size_t column, const MATRIX_LIKE &mat)
Inserts submatrix at a given location.
const_iterator begin() const
Returns an iterator which points to the starting point of the matrix.
bool isNotNull(size_t nRow, size_t nCol) const
Checks whether an element of the matrix is not the default object.
size_t getNullElements() const
Gets the amount of null elements inside the matrix.
size_t getNonNullElements() const
Gets the amount of non-null elements inside the matrix.
size_t getColCount() const
Returns the amount of columns in this matrix.
void setColumn(size_t nCol, const std::vector< T > &vec, const T &nullObject=T())
Inserts a full column into the matrix.
void insert(size_t row, size_t column, const T &obj)
Inserts an element into the matrix.
const Scalar * const_iterator
Definition: eigen_plugins.h:27
SparseMatrixMap::const_iterator const_iterator
Const iterator to move through the matrix.
T & operator()(size_t r, size_t c)
Reference access operator.
GLsizei GLsizei GLuint * obj
Definition: glext.h:4070
CSparseSymmetricalMatrix(const CSparseSymmetricalMatrix &o)
A sparse matrix container (with cells of any type), with iterators.
bool empty() const
Are there no elements set to !=0 ?
void purge(T nullObject=T())
Checks each non-null elements against the basic objects, erasing unnecesary references to it...
size_t getRowCount() const
Returns the amount of rows in this matrix.
CSparseMatrixTemplate(size_t nR, size_t nC)
Constructor with default size.
T operator()(size_t r, size_t c) const
Element access operator.
GLuint index
Definition: glext.h:4054
const GLubyte * c
Definition: glext.h:6313
SparseMatrixMap::const_reverse_iterator const_reverse_iterator
Const reverse iterator to move through the matrix.
void getColumn(size_t nCol, std::vector< T > &vec) const
Extracts a full column from the matrix.
CSparseMatrixTemplate()
Basic constructor with no data.
size_t mRows
Size of the matrix.
const_reverse_iterator rend() const
Returns an iterator which points to the starting point of the matrix, although it&#39;s the upper limit o...
void clear()
Completely removes all elements, although maintaining the matrix&#39;s size.
CSparseSymmetricalMatrix(const CSparseMatrixTemplate< T > &o)
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
const_iterator end() const
Returns an iterator which points to the end of the matrix.
bool isNull(size_t nRow, size_t nCol) const
Checks whether an element of the matrix is the default object.
GLdouble GLdouble GLdouble r
Definition: glext.h:3705
T operator()(size_t r, size_t c) const
CSparseMatrixTemplate< T > operator()(size_t firstRow, size_t lastRow, size_t firstColumn, size_t lastColumn) const
Extracts a submatrix form the matrix.
SparseMatrixMap objectList
Actual matrix.
GLenum GLenum GLvoid * row
Definition: glext.h:3576
void resize(size_t nRows, size_t nCols)
Changes the size of the matrix.
bool exists(size_t r, size_t c) const
Element access operator.
GLuint res
Definition: glext.h:7268
const_reverse_iterator rbegin() const
Returns an iterator which points to the end of the matrix, and can be used to move backwards...
std::map< std::pair< size_t, size_t >, T > SparseMatrixMap
Internal map type, used to store the actual matrix.
void getAsVector(std::vector< T > &vec) const
Gets a vector containing all the elements of the matrix, ignoring their position. ...
GLenum GLenum GLvoid GLvoid * column
Definition: glext.h:3576
void getRow(size_t nRow, std::vector< T > &vec) const
Extracts a full row from the matrix.
void setRow(size_t nRow, const std::vector< T > &vec, const T &nullObject=T())
Inserts a full row into the matrix.
A sparse matrix container for square symmetrical content around the main diagonal.



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: ae4571287 Thu Nov 23 00:06:53 2017 +0100 at dom oct 27 23:51:55 CET 2019