34 template<
typename MatrixType>
37 y.segment(yoff, A.rows()) = A * x.segment(xoff, A.cols());
40 template<
typename MatrixType>
43 y.segment<MatrixType::RowsAtCompileTime>(yoff) = A * x.segment<MatrixType::ColsAtCompileTime>(xoff);
49 y.segment(yoff, A.rows()) = A * x.segment(xoff, A.cols());
53 template<
typename MatrixType>
56 y.segment<MatrixType::RowsAtCompileTime>(yoff) += A * x.segment<MatrixType::ColsAtCompileTime>(xoff);
62 y.segment(yoff, A.rows()) += A * x.segment(xoff, A.cols());
65 template<
typename MatrixType>
68 y.segment<MatrixType::ColsAtCompileTime>(yoff) += A.transpose() * x.segment<MatrixType::RowsAtCompileTime>(xoff);
74 y.segment(yoff, A.cols()) += A.transpose() * x.segment(xoff, A.rows());
79 template <
typename MatrixType>
80 bool LinearSolverPCG<MatrixType>::solve(
const SparseBlockMatrix<MatrixType>& A,
double* x,
double* b)
82 const bool indexRequired = _indices.size() == 0;
88 for (
size_t i = 0; i < A.blockCols().size(); ++i){
89 const typename SparseBlockMatrix<MatrixType>::IntBlockMap& col = A.blockCols()[i];
91 typename SparseBlockMatrix<MatrixType>::IntBlockMap::const_iterator it;
92 for (it = col.begin(); it != col.end(); ++it) {
93 if (it->first == (
int)i) {
94 _diag.push_back(it->second);
95 _J.push_back(it->second->inverse());
99 _indices.push_back(std::make_pair(it->first > 0 ? A.rowBlockIndices()[it->first-1] : 0, colIdx));
100 _sparseMat.push_back(it->second);
105 colIdx = A.colBlockIndices()[i];
109 assert(n > 0 &&
"Hessian has 0 rows/cols");
110 Eigen::Map<VectorXD> xvec(x, A.cols());
111 const Eigen::Map<VectorXD> bvec(b, n);
120 multDiag(A.colBlockIndices(), _J, r, d);
121 double dn = r.dot(d);
122 double d0 = _tolerance * dn;
124 if (_absoluteTolerance) {
125 if (_residual > 0.0 && _residual > d0)
129 int maxIter = _maxIter < 0 ? A.rows() : _maxIter;
132 for (iteration = 0; iteration < maxIter; ++iteration) {
134 std::cerr <<
"residual[" << iteration <<
"]: " << dn << std::endl;
137 mult(A.colBlockIndices(), d, q);
138 double a = dn / d.dot(q);
142 multDiag(A.colBlockIndices(), _J, r, s);
145 double ba = dn / dold;
149 _residual = 0.5 * dn;
150 G2OBatchStatistics* globalStats = G2OBatchStatistics::globalStats();
152 globalStats->iterationsLinearSolver = iteration;
158 template <
typename MatrixType>
159 void LinearSolverPCG<MatrixType>::multDiag(
const std::vector<int>& colBlockIndices, MatrixVector& A,
const VectorXD& src,
VectorXD& dest)
162 for (
size_t i = 0; i < A.size(); ++i) {
164 row = colBlockIndices[i];
168 template <
typename MatrixType>
169 void LinearSolverPCG<MatrixType>::multDiag(
const std::vector<int>& colBlockIndices, MatrixPtrVector& A,
const VectorXD& src,
VectorXD& dest)
172 for (
size_t i = 0; i < A.size(); ++i) {
174 row = colBlockIndices[i];
178 template <
typename MatrixType>
179 void LinearSolverPCG<MatrixType>::mult(
const std::vector<int>& colBlockIndices,
const VectorXD& src,
VectorXD& dest)
182 multDiag(colBlockIndices, _diag, src, dest);
185 for (
size_t i = 0; i < _sparseMat.size(); ++i) {
186 const int& srcOffset = _indices[i].second;
187 const int& destOffsetT = srcOffset;
188 const int& destOffset = _indices[i].first;
189 const int& srcOffsetT = destOffset;
191 const typename SparseBlockMatrix<MatrixType>::SparseMatrixBlock* a = _sparseMat[i];
void pcg_axpy(const MatrixType &A, const VectorXD &x, int xoff, VectorXD &y, int yoff)
Eigen::Matrix< double, Eigen::Dynamic, 1, Eigen::ColMajor > VectorXD
void pcg_atxpy(const MatrixType &A, const VectorXD &x, int xoff, VectorXD &y, int yoff)
void pcg_axy(const MatrixType &A, const VectorXD &x, int xoff, VectorXD &y, int yoff)
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor > MatrixXD