Main MRPT website > C++ reference for MRPT 1.4.0
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-2016, 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
16namespace 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() */
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
A STL-like container which looks and behaves (almost exactly) like a std::map<> but is implemented as...
Definition: map_as_vector.h:48
Scalar * iterator
Definition: eigen_plugins.h:23
const Scalar * const_iterator
Definition: eigen_plugins.h:24
EIGEN_STRONG_INLINE iterator begin()
Definition: eigen_plugins.h:26
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: bits.h:145
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
std::map< TYPE1, TYPE2, std::less< TYPE1 >, Eigen::aligned_allocator< std::pair< const TYPE1, TYPE2 > > > map_t
matrix_t num
Numeric matrix.
symbolic_t sym
Extra symbolic info.
A templated column-indexed efficient storage of block-sparse Jacobian or Hessian matrices,...
void getBinaryBlocksRepresentation(MATRIX &out) const
Builds a binary matrix with 1s where an elementary matrix is stored, 0s elsewhere.
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.
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.
size_t findCurrentNumberOfRows() const
Goes over all the columns and keep the largest column length.
void clearColEntries()
Clear all the entries in each column (do not change the number of columns, though!...
const col_t & getCol(const size_t idx) const
col_t & appendCol(const size_t remapIndex)
Append one column, returning a ref to the new col_t data.
void setColCount(const size_t nCols)
Change the number of columns (keep old contents)
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...
Eigen::Matrix< Scalar, NROWS, NCOLS > matrix_t
const mrpt::utils::map_as_vector< size_t, size_t > & getColInverseRemappedIndices() const
std::deque< col_t > cols
-> cols[i]: i'th column.
std::vector< size_t > col_remapped_indices
mrpt::aligned_containers< size_t, TEntry >::map_t col_t
Each compressed sparse column.
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...
void clearAll()
Clear all the entries in each column (do not change the number of columns, though!...
size_t getColCount() const
Get current number of cols.
const std::vector< size_t > & getColRemappedIndices() const



Page generated by Doxygen 1.9.2 for MRPT 1.4.0 SVN: at Mon Sep 20 00:36:32 UTC 2021