Main MRPT website > C++ reference for MRPT 1.5.7
MatrixBlockSparseCols.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 
10 #ifndef _mrpt_math_MatrixBlockSparseCols_H
11 #define _mrpt_math_MatrixBlockSparseCols_H
12 
14 #include <mrpt/math/CMatrixTemplateNumeric.h> // For mrpt::math::CMatrixDouble
15 
16 namespace mrpt
17 {
18  namespace math
19  {
20 
21  /** A templated column-indexed efficient storage of block-sparse Jacobian or Hessian matrices, together with other arbitrary information.
22  * Columns are stored in a non-associative container, but the contents of each column are kept within an std::map<> indexed by row.
23  * All submatrix blocks have the same size, which allows dense storage of them in fixed-size matrices, avoiding costly memory allocations.
24  *
25  * \tparam NROWS Rows in each elementary matrix.
26  * \tparam NCOLS Cols in each elementary matrix.
27  * \tparam INFO Type of the extra data fields within each block
28  * \tparam HAS_REMAP Is true, an inverse mapping between column indices and "user IDs" is kept.
29  * \tparam INDEX_REMAP_MAP_IMPL Ignore if HAS_REMAP=false. Defaults to "mrpt::utils::map_as_vector<size_t,size_t>" for amortized O(1). Can be set to "std::map<size_t,size_t>" in very sparse systems to save memory at the cost of a O(log N) access time when using the remap indices.
30  *
31  * \ingroup mrpt_base_grp
32  */
33  template <
34  typename Scalar,
35  int NROWS,
36  int NCOLS,
37  typename INFO,
38  bool HAS_REMAP,
39  typename INDEX_REMAP_MAP_IMPL = mrpt::utils::map_as_vector<size_t,size_t>
40  >
42  {
43  typedef Eigen::Matrix<Scalar,NROWS,NCOLS> matrix_t;
44  typedef INFO symbolic_t;
45 
46  struct TEntry
47  {
48  matrix_t num; //!< Numeric matrix
49  symbolic_t sym; //!< Extra symbolic info
50  };
51 
52  typedef typename mrpt::aligned_containers<size_t,TEntry>::map_t col_t; //!< Each compressed sparse column
53 
54  private:
55  /** -> cols[i]: i'th column.
56  * -> Each column is a map [row] -> TEntry
57  */
58  std::deque<col_t> cols;
59  /** "remapped index" is the index of some global variable, interpreted by the external user of this class. */
60  //map<size_t,size_t> col_inverse_remapped_indices;
62  std::vector<size_t> col_remapped_indices;
63 
64  public:
65  inline MatrixBlockSparseCols() : cols(0) { }
66 
67  inline col_t & getCol(const size_t idx) { return cols[idx]; }
68  inline const col_t & getCol(const size_t idx) const { return cols[idx]; }
69 
70  inline const mrpt::utils::map_as_vector<size_t,size_t> & getColInverseRemappedIndices() const { if (!HAS_REMAP) assert(false); return col_inverse_remapped_indices; }
71  inline const std::vector<size_t> & getColRemappedIndices() const { if (!HAS_REMAP) assert(false); return col_remapped_indices; }
72 
73  /** Append one column, returning a ref to the new col_t data */
74  inline col_t & appendCol(const size_t remapIndex) {
75  const size_t idx = cols.size();
76  cols.push_back( col_t() );
77 
78  if (HAS_REMAP)
79  {
80  col_remapped_indices.resize(idx+1);
81  col_remapped_indices[idx] = remapIndex;
82 
83  col_inverse_remapped_indices[remapIndex] = idx;
84  }
85 
86  return *cols.rbegin();
87  }
88 
89  /** Change the number of columns (keep old contents) */
90  inline void setColCount(const size_t nCols) { cols.resize(nCols); }
91 
92  /** Get current number of cols. \sa findCurrentNumberOfRows */
93  inline size_t getColCount() const { return cols.size(); }
94 
95  /** Clear all the entries in each column (do not change the number of columns, though!) \sa getColCount */
96  inline void clearColEntries() {
97  for (size_t i=0;i<cols.size();i++) cols[i].clear();
98  }
99 
100  /** Clear all the entries in each column (do not change the number of columns, though!) \sa getColCount */
101  inline void clearAll() {
102  cols.clear();
103  if (HAS_REMAP)
104  {
105  col_remapped_indices.clear();
107  }
108  }
109 
110  /** Builds a dense representation of the matrix and saves to a text file. */
112  const std::string &filename,
113  const bool force_symmetry=false,
114  const bool is_col_compressed = true ) const
115  {
117  getAsDense(D,force_symmetry,is_col_compressed);
118  return D.saveToTextFile(filename);
119  }
120 
121  /** Builds a dense representation of the matrix and saves to a text file.
122  * \param is_col_compressed true: interpret this object as compressed by cols; false: compressed by rows
123  */
126  const bool force_symmetry=false,
127  const bool is_col_compressed = true ) const
128  {
129  const size_t nCols = cols.size();
130  const size_t nRows = findCurrentNumberOfRows();
131 
132  if (is_col_compressed)
133  D.setSize(nRows*NROWS,nCols*NCOLS);
134  else D.setSize(nCols*NROWS,nRows*NCOLS);
135 
136  for (size_t j=0;j<nCols;j++)
137  {
138  for (typename col_t::const_iterator itRow=cols[j].begin();itRow!=cols[j].end();++itRow)
139  {
140  const size_t row = itRow->first;
141  const size_t row_idx = is_col_compressed ? row*NROWS : j*NROWS;
142  const size_t col_idx = is_col_compressed ? j*NCOLS : row*NCOLS;
143  D.block(row_idx,col_idx, NROWS,NCOLS) = itRow->second.num;
144  if (force_symmetry && row_idx!=col_idx)
145  D.block(col_idx,row_idx, NCOLS,NROWS) = itRow->second.num.transpose();
146  }
147  }
148  }
149 
150  /** Goes over all the columns and keep the largest column length. \sa getColCount() */
151  size_t findCurrentNumberOfRows() const
152  {
153  size_t nRows = 0;
154  const size_t nCols = cols.size();
155  for (size_t j=0;j<nCols;j++)
156  for (typename col_t::const_iterator itRow=cols[j].begin();itRow!=cols[j].end();++itRow)
157  mrpt::utils::keep_max(nRows, itRow->first);
158  return nRows+1; // nRows was the max. row index, now it's the row count.
159  }
160 
161  /** Builds a binary matrix with 1s where an elementary matrix is stored, 0s elsewhere. */
162  template <class MATRIX>
163  void getBinaryBlocksRepresentation( MATRIX &out ) const
164  {
165  const size_t nCols = cols.size();
166  const size_t nRows = findCurrentNumberOfRows();
167  out.zeros(nRows,nCols);
168  for (size_t j=0;j<nCols;j++)
169  for (typename col_t::const_iterator itRow=cols[j].begin();itRow!=cols[j].end();++itRow)
170  {
171  const size_t row = itRow->first;
172  out(row,j) = 1;
173  }
174  }
175 
176  /** Clear the current contents of this objects and replicates the sparse structure and numerical values of \a o */
178  {
179  const size_t nC = o.cols.size();
180  if (cols.size()!=nC)
181  {
182  // Just create an empty structure with the numerical matrices:
183  cols.resize(nC);
184  for (size_t i=0;i<nC;i++)
185  {
186  cols[i].clear();
187  for (typename col_t::const_iterator it=o.cols[i].begin();it!=o.cols[i].end();++it)
188  cols[i][it->first].num = it->second.num;
189  }
190  }
191  else
192  {
193  // It might be that we're overwriting an existing data structure:
194  for (size_t i=0;i<nC;i++)
195  {
196  //ASSERTMSG_(cols[i].size()>=o.cols[i].size(), "copyNumericalValuesFrom() invoked on dissimilar structures")
197  typename col_t::iterator it_dst = cols[i].begin();
198  typename col_t::const_iterator it_src = o.cols[i].begin();
199  while (it_src!=o.cols[i].end())
200  {
201  if (it_dst->first < it_src->first)
202  {
203  it_dst->second.num.setZero();
204  it_dst++;
205  }
206  else if (it_dst->first > it_src->first)
207  {
208  cols[i][it_src->first].num = it_src->second.num;
209  it_src++;
210  }
211  else
212  {
213  it_dst->second.num = it_src->second.num;
214  ++it_dst;
215  ++it_src;
216  }
217  }
218  }
219  }
220  } // end copyNumericalValuesFrom()
221 
222  }; // end of MatrixBlockSparseCols
223 
224  } // end NS
225 }// end NS
226 
227 #endif //_mrpt_math_MatrixBlockSparseCols_H
mrpt::aligned_containers< size_t, TEntry >::map_t col_t
Each compressed sparse column.
void getAsDense(mrpt::math::CMatrixDouble &D, const bool force_symmetry=false, const bool is_col_compressed=true) const
Builds a dense representation of the matrix and saves to a text file.
symbolic_t sym
Extra symbolic info.
void getBinaryBlocksRepresentation(MATRIX &out) const
Builds a binary matrix with 1s where an elementary matrix is stored, 0s elsewhere.
Scalar * iterator
Definition: eigen_plugins.h:23
const col_t & getCol(const size_t idx) const
EIGEN_STRONG_INLINE iterator begin()
Definition: eigen_plugins.h:26
std::map< TYPE1, TYPE2, std::less< TYPE1 >, Eigen::aligned_allocator< std::pair< const TYPE1, TYPE2 > > > map_t
col_t & appendCol(const size_t remapIndex)
Append one column, returning a ref to the new col_t data.
const Scalar * const_iterator
Definition: eigen_plugins.h:24
void clear()
Clear the contents of this container.
Definition: map_as_vector.h:94
void clear()
Clear the contents of this container.
Definition: ts_hash_map.h:113
matrix_t num
Numeric matrix.
void saveToTextFileAsDense(const std::string &filename, const bool force_symmetry=false, const bool is_col_compressed=true) const
Builds a dense representation of the matrix and saves to a text file.
mrpt::utils::map_as_vector< size_t, size_t > col_inverse_remapped_indices
"remapped index" is the index of some global variable, interpreted by the external user of this class...
const mrpt::utils::map_as_vector< size_t, size_t > & getColInverseRemappedIndices() const
void setColCount(const size_t nCols)
Change the number of columns (keep old contents)
GLsizei const GLchar ** string
Definition: glext.h:3919
std::deque< col_t > cols
-> cols[i]: i&#39;th column.
A templated column-indexed efficient storage of block-sparse Jacobian or Hessian matrices, together with other arbitrary information.
size_t findCurrentNumberOfRows() const
Goes over all the columns and keep the largest column length.
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
void clearColEntries()
Clear all the entries in each column (do not change the number of columns, though!) ...
const std::vector< size_t > & getColRemappedIndices() const
GLenum GLenum GLvoid * row
Definition: glext.h:3533
Eigen::Matrix< Scalar, NROWS, NCOLS > matrix_t
void clearAll()
Clear all the entries in each column (do not change the number of columns, though!) ...
void copyNumericalValuesFrom(const MatrixBlockSparseCols< Scalar, NROWS, NCOLS, INFO, HAS_REMAP > &o)
Clear the current contents of this objects and replicates the sparse structure and numerical values o...
std::vector< size_t > col_remapped_indices
double Scalar
Definition: KmUtils.h:41
size_t getColCount() const
Get current number of cols.
void keep_max(T &var, const K test_val)
If the second argument is above the first one, set the first argument to this higher value...



Page generated by Doxygen 1.8.14 for MRPT 1.5.7 Git: 5902e14cc Wed Apr 24 15:04:01 2019 +0200 at lun oct 28 01:39:17 CET 2019