39template <
typename MatrixType>
40void pcg_axy(
const MatrixType& A,
const VectorX& x,
int xoff, VectorX& y,
42 y.segment(yoff, A.rows()) = A * x.segment(xoff, A.cols());
45template <
typename MatrixType>
46inline void pcg_axy(
const MatrixType& A,
const VectorX& x,
int xoff, VectorX& y,
48 y.segment<MatrixType::RowsAtCompileTime>(yoff) =
49 A * x.segment<MatrixType::ColsAtCompileTime>(xoff);
53inline void pcg_axy(
const MatrixX& A,
const VectorX& x,
int xoff, VectorX& y,
55 y.segment(yoff, A.rows()) = A * x.segment(xoff, A.cols());
59template <
typename MatrixType>
60inline void pcg_axpy(
const MatrixType& A,
const VectorX& x,
int xoff,
61 VectorX& y,
int yoff) {
62 y.segment<MatrixType::RowsAtCompileTime>(yoff) +=
63 A * x.segment<MatrixType::ColsAtCompileTime>(xoff);
67inline void pcg_axpy(
const MatrixX& A,
const VectorX& x,
int xoff, VectorX& y,
69 y.segment(yoff, A.rows()) += A * x.segment(xoff, A.cols());
72template <
typename MatrixType>
73inline void pcg_atxpy(
const MatrixType& A,
const VectorX& x,
int xoff,
74 VectorX& y,
int yoff) {
75 y.segment<MatrixType::ColsAtCompileTime>(yoff) +=
76 A.transpose() * x.segment<MatrixType::RowsAtCompileTime>(xoff);
80inline void pcg_atxpy(
const MatrixX& A,
const VectorX& x,
int xoff, VectorX& y,
82 y.segment(yoff, A.cols()) += A.transpose() * x.segment(xoff, A.rows());
87template <
typename MatrixType>
89 double* x,
double* b) {
90 const bool indexRequired = _indices.size() == 0;
96 for (
size_t i = 0; i < A.
blockCols().size(); ++i) {
101 for (it = col.begin(); it != col.end(); ++it) {
102 if (it->first == (
int)i) {
103 _diag.push_back(it->second);
104 _J.push_back(it->second->inverse());
108 _indices.push_back(std::make_pair(
110 _sparseMat.push_back(it->second);
118 assert(n > 0 &&
"Hessian has 0 rows/cols");
119 Eigen::Map<VectorX> xvec(x, A.
cols());
120 const Eigen::Map<VectorX> bvec(b, n);
130 double dn = r.dot(d);
131 double d0 = _tolerance * dn;
133 if (_absoluteTolerance) {
134 if (_residual > 0.0 && _residual > d0) d0 = _residual;
137 int maxIter = _maxIter < 0 ? A.
rows() : _maxIter;
140 for (iteration = 0; iteration < maxIter; ++iteration) {
141 G2O_DEBUG(
"residual [{}]: {}", iteration, dn);
144 double a = dn / d.dot(q);
151 double ba = dn / dold;
154 _residual = 0.5 * dn;
163template <
typename MatrixType>
165 const std::vector<int>& colBlockIndices,
MatrixVector& A,
168 for (
size_t i = 0; i < A.size(); ++i) {
170 row = colBlockIndices[i];
174template <
typename MatrixType>
179 for (
size_t i = 0; i < A.size(); ++i) {
181 row = colBlockIndices[i];
185template <
typename MatrixType>
189 multDiag(colBlockIndices, _diag, src, dest);
192 for (
size_t i = 0; i < _sparseMat.size(); ++i) {
193 const int& srcOffset = _indices[i].second;
194 const int& destOffsetT = srcOffset;
195 const int& destOffset = _indices[i].first;
196 const int& srcOffsetT = destOffset;
linear solver using PCG, pre-conditioner is block Jacobi
std::vector< MatrixType > MatrixVector
std::vector< const MatrixType * > MatrixPtrVector
Sparse matrix which uses blocks.
const std::vector< IntBlockMap > & blockCols() const
the block matrices per block-column
const std::vector< int > & colBlockIndices() const
indices of the column blocks
std::map< int, SparseMatrixBlock * > IntBlockMap
int rows() const
rows of the matrix
MatrixType SparseMatrixBlock
this is the type of the elementary block, it is an Eigen::Matrix.
int cols() const
columns of the matrix
const std::vector< int > & rowBlockIndices() const
indices of the row blocks
VectorN< Eigen::Dynamic > VectorX
void pcg_axpy(const MatrixType &A, const VectorX &x, int xoff, VectorX &y, int yoff)
void pcg_axy(const MatrixType &A, const VectorX &x, int xoff, VectorX &y, int yoff)
void pcg_atxpy(const MatrixType &A, const VectorX &x, int xoff, VectorX &y, int yoff)
statistics about the optimization
int iterationsLinearSolver