34template <
int p,
int l>
35std::unique_ptr<g2o::Solver> AllocateCholmodSolver() {
36 std::cerr <<
"# Using CHOLMOD online poseDim " << p <<
" landMarkDim " << l
37 <<
" blockordering 1" << std::endl;
39 return std::make_unique<BlockSolverPL<p, l>>(
40 std::make_unique<LinearSolverCholmodOnline<
41 typename BlockSolverPL<p, l>::PoseMatrixType>>());
49 OptimizableGraph::Vertex* vertex;
51 bool operator<(
const VertexBackup& other)
const {
52 return hessianIndex < other.hessianIndex;
68 _permutedUpdate = cholmod_allocate_triplet(1000, 1000, 1024, 0, CHOLMOD_REAL,
125 int numBlocksRequired =
_ivMap.size();
126 if (
_cmember.size() < numBlocksRequired) {
127 _cmember.resize(2 * numBlocksRequired);
129 memset(
_cmember.data(), 0, numBlocksRequired *
sizeof(
int));
130 if (
_ivMap.size() > 100) {
131 for (
size_t i =
_ivMap.size() - 20; i <
_ivMap.size(); ++i) {
133 for (HyperGraph::EdgeSet::const_iterator it = eset.begin();
134 it != eset.end(); ++it) {
153 int* p =
static_cast<int*
>(
_L->Perm);
154 for (
size_t i = 0; i <
_L->n; ++i)
_perm[p[i]] = i;
171 cerr <<
"nodes = " <<
vertices().size()
173 <<
"\t chi2= " << FIXED(
activeChi2()) << endl;
188 for (HyperGraph::VertexSet::iterator it = vset.begin(); it != vset.end();
196 for (HyperGraph::EdgeSet::iterator it = eset.begin(); it != eset.end();
209 std::vector<HyperGraph::Vertex*> newVertices;
210 newVertices.reserve(vset.size());
213 for (HyperGraph::EdgeSet::iterator it = eset.begin(); it != eset.end(); ++it)
218 size_t next =
_ivMap.size();
219 for (HyperGraph::VertexSet::iterator it = vset.begin(); it != vset.end();
226 newVertices.push_back(v);
249 backupIdx[idx].vertex = v;
258 for (
int i = 0; i < idx; ++i) {
259 backupIdx[i].vertex->setHessianIndex(i);
270 MatrixXd* lastBlock = 0;
272 for (
int i = 0; i < idx; ++i) {
289 lastBlock->diagonal().array() += 1e-6;
292 for (HyperGraph::EdgeSet::const_iterator it = eset.begin(); it != eset.end();
299 if (ind1 == -1)
continue;
301 if (ind2 == -1)
continue;
302 bool transposedBlock = ind1 > ind2;
311 for (HyperGraph::EdgeSet::iterator it = eset.begin(); it != eset.end();
316 for (HyperGraph::EdgeSet::iterator it = eset.begin(); it != eset.end();
324 for (
int i = 0; i < idx; ++i) {
325 backupIdx[i].vertex->setHessianIndex(backupIdx[i].hessianIndex);
326 if (backupIdx[i].hessianData)
327 backupIdx[i].vertex->mapHessianMemory(backupIdx[i].hessianData);
335 cerr <<
"Error while computing update" << endl;
338 cholmod_sparse* updateAsSparseFactor =
344 cholmod_reallocate_triplet(updateAsSparseFactor->nzmax,
_permutedUpdate,
350 int* Ap =
static_cast<int*
>(updateAsSparseFactor->p);
351 int* Ai =
static_cast<int*
>(updateAsSparseFactor->i);
352 double* Ax =
static_cast<double*
>(updateAsSparseFactor->x);
356 for (
size_t c = 0; c < updateAsSparseFactor->ncol; ++c) {
357 const int& rbeg = Ap[c];
358 const int& rend = Ap[c + 1];
361 const int& cbase = backupIdx[cc].vertex->colInHessian();
362 const int& ccol =
_perm(cbase + coff);
363 for (
int j = rbeg; j < rend; j++) {
364 const int& r = Ai[j];
365 const double& val = Ax[j];
369 const int& rbase = backupIdx[rr].vertex->colInHessian();
371 int row =
_perm(rbase + roff);
448 for (
int i = 0; i < (int)n; ++i)
450 cerr <<
"wrong permutation" << i <<
" -> " << p[i] << endl;
462 int change_status = cholmod_change_factor(CHOLMOD_REAL, 1, 0, 1, 1,
464 if (!change_status) {
472 std::unique_ptr<g2o::Solver> s;
474 if (solverName ==
"fix3_2_cholmod") {
475 s = AllocateCholmodSolver<3, 2>();
476 }
else if (solverName ==
"fix6_3_cholmod") {
477 s = AllocateCholmodSolver<6, 3>();
488 if (dimension == 3) {
496 assert(bs &&
"Unable to get internal block solver");
511 assert(bs &&
"Unable to get internal block solver");
523 cerr <<
"Error allocating solver. Allocating CHOLMOD solver failed!"
572 for (
int i = 0; i < n; i++) {
void setEstimate(const EstimateType &et)
set the estimate for the vertex also calls updateCache()
Implementation of a solver operating on the blocks of the Hessian.
virtual void setSchur(bool s)
LinearSolver< PoseMatrixType > & linearSolver() const
const VertexContainer & vertices() const
std::set< Edge * > EdgeSet
std::set< Vertex * > VertexSet
const VertexIDMap & vertices() const
virtual cholmod_factor * L() const =0
virtual bool solve(double *x, double *b)=0
virtual int choleskyUpdate(cholmod_sparse *update)=0
Eigen::VectorXi * cmember
linear solver which allows to update the cholesky factor
VertexSE2::EstimateType updatedEstimate
VertexSE3::EstimateType updatedEstimate
virtual void linearizeOplus(JacobianWorkspace &jacobianWorkspace)=0
virtual void computeError()=0
virtual void mapHessianMemory(double *d, int i, int j, bool rowMajor)=0
virtual void constructQuadraticForm()=0
A general case Vertex for optimization.
virtual void mapHessianMemory(double *d)=0
bool marginalized() const
true => this node is marginalized out during the optimization
void setHessianIndex(int ti)
set the temporary index of the vertex in the parameter blocks
int colInHessian() const
get the row of this vertex in the Hessian
virtual void clearQuadraticForm()=0
int dimension() const
dimension of the estimated state belonging to this node
bool fixed() const
true => this node is fixed during the optimization
virtual double * hessianData()=0
virtual int copyB(double *b_) const =0
Implementation of the Gauss Newton Algorithm.
Solver & solver()
return the underlying solver used to solve the linear system
Generic interface for a non-linear solver operating on a graph.
virtual bool updateStructure(const std::vector< HyperGraph::Vertex * > &vset, const HyperGraph::EdgeSet &edges)=0
virtual bool init(bool online=false)=0
double * b()
return b, the right hand side of the system
virtual bool buildStructure(bool zeroBlocks=false)=0
double * x()
return x, the solution vector
virtual bool buildSystem()=0
void setAdditionalVectorSpace(size_t s)
Sparse matrix which uses blocks.
size_t nonZeros() const
number of non-zero elements
int fillCCS(int *Cp, int *Ci, double *Cx, bool upperTriangle=false) const
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
SparseMatrixBlock * block(int r, int c, bool alloc=false)
int cols() const
columns of the matrix
const std::vector< int > & rowBlockIndices() const
indices of the row blocks
void clear(bool dealloc=false)
SparseBlockMatrix< Eigen::MatrixXd > _updateMat
cholmod::CholmodExt * _permutedUpdateAsSparse
cholmod_common _cholmodCommon
cholmod_triplet * _permutedUpdate
cholmod_factor * _cholmodFactor
void convertTripletUpdateToSparse()
Eigen::VectorXi _tripletWorkspace
int optimize(int iterations, bool online=false)
LinearSolverCholmodOnlineInterface * _solverInterface
SparseOptimizerIncremental()
bool computeCholeskyUpdate()
virtual bool initSolver(int dimension, int batchEveryN)
HyperGraph::VertexSet _touchedVertices
virtual bool updateInitialization(HyperGraph::VertexSet &vset, HyperGraph::EdgeSet &eset)
~SparseOptimizerIncremental()
cholmod::CholmodExt * _cholmodSparse
void update(double *update)
virtual void gnuplotVisualization()
Solver * _underlyingSolver
virtual bool updateInitialization(HyperGraph::VertexSet &vset, HyperGraph::EdgeSet &eset)
void computeActiveErrors()
EdgeContainer _activeEdges
sorted according to EdgeIDCompare
void setAlgorithm(OptimizationAlgorithm *algorithm)
OptimizationAlgorithm * _algorithm
VertexContainer _activeVertices
sorted according to VertexIDCompare
bool verbose() const
verbose information during optimization
const VertexContainer & indexMapping() const
the index mapping of the vertices
double activeChi2() const
OptimizationAlgorithm * solver()
#define __PRETTY_FUNCTION__
bool operator<(const HyperDijkstra::AdjacencyMapEntry &a, const HyperDijkstra::AdjacencyMapEntry &b)
static OptimizationAlgorithm * createSolver(const std::string &solverName)
JacobianWorkspace & jacobianWorkspace()
the workspace for storing the Jacobians of the graph
Our extension of the CHOLMOD matrix struct.