27 #ifndef G2O_LINEAR_SOLVER_EIGEN_H 28 #define G2O_LINEAR_SOLVER_EIGEN_H 30 #include <Eigen/Sparse> 31 #include <Eigen/SparseCholesky> 48 template <
typename MatrixType>
62 using Eigen::SimplicialLDLT< SparseMatrix, Eigen::Upper>::analyzePattern_preordered;
67 m_P = permutation.inverse();
69 SparseMatrix ap(size, size);
70 ap.selfadjointView<Eigen::Upper>() = a.selfadjointView<UpLo>().twistedBy(m_P);
71 analyzePattern_preordered(ap,
true);
103 if (
_cholesky.info() != Eigen::Success) {
105 std::cerr <<
"Cholesky failure, writing debug.txt (Hessian loadable by Octave)" << std::endl;
148 if (! _blockOrdering) {
149 _cholesky.analyzePattern(_sparseMatrix);
154 Eigen::PermutationMatrix<Eigen::Dynamic,Eigen::Dynamic> blockP;
157 std::vector<Triplet> triplets;
158 for (
size_t c = 0; c < A.
blockCols().size(); ++c){
161 const int& r = it->first;
162 if (r > static_cast<int>(c))
164 triplets.push_back(
Triplet(r, c, 0.));
171 auxBlockMatrix.setFromTriplets(triplets.begin(), triplets.end());
172 typename CholeskyDecomposition::CholMatrixType C;
173 C = auxBlockMatrix.selfadjointView<Eigen::Upper>();
174 Eigen::internal::minimum_degree_ordering(C, blockP);
178 assert(rows == A.
cols() &&
"Matrix A is not square");
181 PermutationMatrix scalarP;
182 scalarP.resize(rows);
184 for (
int i = 0; i < blockP.size(); ++i) {
185 const int& p = blockP.indices()(i);
188 for (
int j = 0; j < nCols; ++j)
189 scalarP.indices()(scalarIdx++) = base++;
191 assert(scalarIdx == rows &&
"did not completely fill the permutation matrix");
204 A.
fillCCS(_sparseMatrix.valuePtr(),
true);
208 std::vector<Triplet> triplets;
210 for (
size_t c = 0; c < A.
blockCols().size(); ++c) {
215 const MatrixType& m = *(it->second);
216 for (
int cc = 0; cc < m.cols(); ++cc) {
217 int aux_c = colBaseOfBlock + cc;
218 for (
int rr = 0; rr < m.rows(); ++rr) {
219 int aux_r = rowBaseOfBlock + rr;
222 triplets.push_back(
Triplet(aux_r, aux_c, m(rr, cc)));
227 _sparseMatrix.setFromTriplets(triplets.begin(), triplets.end());
virtual ~LinearSolverEigen()
double get_monotonic_time()
statistics about the optimization
int cols() const
columns of the matrix
Eigen::SparseMatrix< double, Eigen::ColMajor > SparseMatrix
bool writeOctave(const char *filename, bool upperTriangle=true) const
int rows() const
rows of the matrix
Sub-classing Eigen's SimplicialLDLT to perform ordering with a given ordering.
void computeSymbolicDecomposition(const SparseBlockMatrix< MatrixType > &A)
int colsOfBlock(int c) const
how many cols does the block at block-col c has?
Eigen::Triplet< double > Triplet
size_t nonZeros() const
number of non-zero elements
Eigen::PermutationMatrix< Eigen::Dynamic, Eigen::Dynamic > PermutationMatrix
size_t choleskyNNZ
number of non-zeros in the cholesky factor
utility functions for handling time related stuff
bool blockOrdering() const
do the AMD ordering on the blocks or on the scalar matrix
linear solver which uses the sparse Cholesky solver from Eigen
static G2OBatchStatistics * globalStats()
double timeNumericDecomposition
numeric decomposition (0 if not done)
std::map< int, SparseMatrixBlock * > IntBlockMap
int colBaseOfBlock(int c) const
where does the col at block-col r starts?
const std::vector< IntBlockMap > & blockCols() const
the block matrices per block-column
void fillSparseMatrix(const SparseBlockMatrix< MatrixType > &A, bool onlyValues)
bool solve(const SparseBlockMatrix< MatrixType > &A, double *x, double *b)
double timeSymbolicDecomposition
symbolic decomposition (0 if not done)
virtual bool writeDebug() const
write a debug dump of the system matrix if it is not SPD in solve
void setBlockOrdering(bool blockOrdering)
CholeskyDecomposition _cholesky
int rowBaseOfBlock(int r) const
where does the row at block-row r starts?
Sparse matrix which uses blocks.
SparseMatrix _sparseMatrix
int fillCCS(int *Cp, int *Ci, double *Cx, bool upperTriangle=false) const
void analyzePatternWithPermutation(SparseMatrix &a, const PermutationMatrix &permutation)
virtual void setWriteDebug(bool b)