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



Page generated by Doxygen 1.8.17 for MRPT 1.9.9 Git: ad3a9d8ae Tue May 1 23:10:22 2018 -0700 at miƩ 12 jul 2023 10:03:34 CEST