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>
88bool LinearSolverPCG<MatrixType>::solve(
const SparseBlockMatrix<MatrixType>& A,
89 double* x,
double* b) {
90 const bool indexRequired = _indices.size() == 0;
96 for (
size_t i = 0; i < A.blockCols().size(); ++i) {
97 const typename SparseBlockMatrix<MatrixType>::IntBlockMap& col =
100 typename SparseBlockMatrix<MatrixType>::IntBlockMap::const_iterator it;
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(
109 it->first > 0 ? A.rowBlockIndices()[it->first - 1] : 0, colIdx));
110 _sparseMat.push_back(it->second);
114 colIdx = A.colBlockIndices()[i];
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);
129 multDiag(A.colBlockIndices(), _J, r, d);
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);
143 mult(A.colBlockIndices(), d, q);
144 double a = dn / d.dot(q);
148 multDiag(A.colBlockIndices(), _J, r, s);
151 double ba = dn / dold;
154 _residual = 0.5 * dn;
155 G2OBatchStatistics* globalStats = G2OBatchStatistics::globalStats();
157 globalStats->iterationsLinearSolver = iteration;
163template <
typename MatrixType>
164void LinearSolverPCG<MatrixType>::multDiag(
165 const std::vector<int>& colBlockIndices, MatrixVector& A,
166 const VectorX& src, VectorX& dest) {
168 for (
size_t i = 0; i < A.size(); ++i) {
170 row = colBlockIndices[i];
174template <
typename MatrixType>
175void LinearSolverPCG<MatrixType>::multDiag(
176 const std::vector<int>& colBlockIndices, MatrixPtrVector& A,
177 const VectorX& src, VectorX& dest) {
179 for (
size_t i = 0; i < A.size(); ++i) {
181 row = colBlockIndices[i];
185template <
typename MatrixType>
186void LinearSolverPCG<MatrixType>::mult(
const std::vector<int>& colBlockIndices,
187 const VectorX& src, VectorX& dest) {
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;
198 const typename SparseBlockMatrix<MatrixType>::SparseMatrixBlock* a =
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)