g2o
Loading...
Searching...
No Matches
Public Member Functions | Protected Member Functions | Protected Attributes | List of all members
g2o::SparseOptimizerIncremental Class Reference

#include <graph_optimizer_sparse_incremental.h>

Inheritance diagram for g2o::SparseOptimizerIncremental:
Inheritance graph
[legend]
Collaboration diagram for g2o::SparseOptimizerIncremental:
Collaboration graph
[legend]

Public Member Functions

 SparseOptimizerIncremental ()
 
 ~SparseOptimizerIncremental ()
 
int optimize (int iterations, bool online=false)
 
virtual bool updateInitialization (HyperGraph::VertexSet &vset, HyperGraph::EdgeSet &eset)
 
virtual bool initSolver (int dimension, int batchEveryN)
 
- Public Member Functions inherited from g2o::SparseOptimizerOnline
 SparseOptimizerOnline (bool pcg=false)
 
virtual ~SparseOptimizerOnline ()
 
int optimize (int iterations, bool online=false)
 
void update (double *update)
 
virtual void gnuplotVisualization ()
 
- Public Member Functions inherited from g2o::SparseOptimizer
 SparseOptimizer ()
 
virtual ~SparseOptimizer ()
 
virtual bool initializeOptimization (HyperGraph::EdgeSet &eset)
 
virtual bool initializeOptimization (HyperGraph::VertexSet &vset, int level=0)
 
virtual bool initializeOptimization (int level=0)
 
virtual void computeInitialGuess ()
 
virtual void computeInitialGuess (EstimatePropagatorCost &propagator)
 
virtual void setToOrigin ()
 
bool computeMarginals (SparseBlockMatrix< MatrixX > &spinv, const std::vector< std::pair< int, int > > &blockIndices)
 
bool computeMarginals (SparseBlockMatrix< MatrixX > &spinv, const Vertex *vertex)
 
bool computeMarginals (SparseBlockMatrix< MatrixX > &spinv, const VertexContainer &vertices)
 
virtual VertexfindGauge ()
 finds a gauge in the graph to remove the undefined dof.
 
bool gaugeFreedom ()
 
double activeChi2 () const
 
double activeRobustChi2 () const
 
bool verbose () const
 verbose information during optimization
 
void setVerbose (bool verbose)
 
void setForceStopFlag (bool *flag)
 
bool * forceStopFlag () const
 
bool terminate ()
 if external stop flag is given, return its state. False otherwise
 
const VertexContainerindexMapping () const
 the index mapping of the vertices
 
const VertexContaineractiveVertices () const
 the vertices active in the current optimization
 
const EdgeContaineractiveEdges () const
 the edges active in the current optimization
 
virtual bool removeVertex (HyperGraph::Vertex *v, bool detach=false)
 
VertexContainer::const_iterator findActiveVertex (const OptimizableGraph::Vertex *v) const
 
EdgeContainer::const_iterator findActiveEdge (const OptimizableGraph::Edge *e) const
 
const OptimizationAlgorithmalgorithm () const
 the solver used by the optimizer
 
OptimizationAlgorithmsolver ()
 
void setAlgorithm (OptimizationAlgorithm *algorithm)
 
void push (SparseOptimizer::VertexContainer &vlist)
 push the estimate of a subset of the variables onto a stack
 
void push (HyperGraph::VertexSet &vlist)
 push the estimate of a subset of the variables onto a stack
 
void push ()
 push all the active vertices onto a stack
 
void pop (SparseOptimizer::VertexContainer &vlist)
 pop (restore) the estimate a subset of the variables from the stack
 
void pop (HyperGraph::VertexSet &vlist)
 pop (restore) the estimate a subset of the variables from the stack
 
void pop ()
 pop (restore) the estimate of the active vertices from the stack
 
void discardTop (SparseOptimizer::VertexContainer &vlist)
 
void discardTop ()
 same as above, but for the active vertices
 
virtual void clear ()
 
void computeActiveErrors ()
 
 G2O_ATTRIBUTE_DEPRECATED (void linearizeSystem())
 
void update (const double *update)
 
const BatchStatisticsContainerbatchStatistics () const
 
BatchStatisticsContainerbatchStatistics ()
 
void setComputeBatchStatistics (bool computeBatchStatistics)
 
bool computeBatchStatistics () const
 
bool addComputeErrorAction (HyperGraphAction *action)
 add an action to be executed before the error vectors are computed
 
bool removeComputeErrorAction (HyperGraphAction *action)
 
virtual void discardTop ()
 
virtual void discardTop (HyperGraph::VertexSet &vset)
 
- Public Member Functions inherited from g2o::OptimizableGraph
Vertexvertex (int id)
 returns the vertex number id appropriately casted
 
const Vertexvertex (int id) const
 returns the vertex number id appropriately casted
 
 OptimizableGraph ()
 empty constructor
 
virtual ~OptimizableGraph ()
 
virtual bool addVertex (HyperGraph::Vertex *v, Data *userData)
 
virtual bool addVertex (HyperGraph::Vertex *v)
 
bool addVertex (OptimizableGraph::Vertex *v, Data *userData)
 
bool addVertex (OptimizableGraph::Vertex *v)
 
virtual bool addEdge (HyperGraph::Edge *e)
 
bool addEdge (OptimizableGraph::Edge *e)
 
virtual bool setEdgeVertex (HyperGraph::Edge *e, int pos, HyperGraph::Vertex *v)
 
double chi2 () const
 returns the chi2 of the current configuration
 
int maxDimension () const
 return the maximum dimension of all vertices in the graph
 
void recomputeJacobianWorkspaceSize ()
 
std::set< int > dimensions () const
 
virtual void preIteration (int)
 
virtual void postIteration (int)
 
bool addPreIterationAction (HyperGraphAction *action)
 add an action to be executed before each iteration
 
bool addPostIterationAction (HyperGraphAction *action)
 add an action to be executed after each iteration
 
bool removePreIterationAction (HyperGraphAction *action)
 remove an action that should no longer be executed before each iteration
 
bool removePostIterationAction (HyperGraphAction *action)
 remove an action that should no longer be executed after each iteration
 
virtual bool load (std::istream &is)
 
bool load (const char *filename)
 
virtual bool save (std::ostream &os, int level=0) const
 save the graph to a stream. Again uses the Factory system.
 
bool save (const char *filename, int level=0) const
 function provided for convenience, see save() above
 
bool saveSubset (std::ostream &os, HyperGraph::VertexSet &vset, int level=0)
 save a subgraph to a stream. Again uses the Factory system.
 
bool saveSubset (std::ostream &os, HyperGraph::EdgeSet &eset)
 save a subgraph to a stream. Again uses the Factory system.
 
virtual void setFixed (HyperGraph::VertexSet &vset, bool fixed)
 fixes/releases a set of vertices
 
void setRenamedTypesFromString (const std::string &types)
 
bool isSolverSuitable (const OptimizationAlgorithmProperty &solverProperty, const std::set< int > &vertDims=std::set< int >()) const
 
virtual void clearParameters ()
 
bool addParameter (Parameter *p)
 
Parameterparameter (int id)
 
bool verifyInformationMatrices (bool verbose=false) const
 
bool saveVertex (std::ostream &os, Vertex *v) const
 
bool saveParameter (std::ostream &os, Parameter *v) const
 
bool saveEdge (std::ostream &os, Edge *e) const
 
bool saveUserData (std::ostream &os, HyperGraph::Data *v) const
 
JacobianWorkspacejacobianWorkspace ()
 the workspace for storing the Jacobians of the graph
 
const JacobianWorkspacejacobianWorkspace () const
 
ParameterContainerparameters ()
 
const ParameterContainerparameters () const
 
void forEachVertex (std::function< void(OptimizableGraph::Vertex *)> fn)
 apply a unary function to all vertices
 
void forEachVertex (HyperGraph::VertexSet &vset, std::function< void(OptimizableGraph::Vertex *)> fn)
 apply a unary function to the vertices in vset
 
- Public Member Functions inherited from g2o::HyperGraph
 HyperGraph ()
 constructs an empty hyper graph
 
virtual ~HyperGraph ()
 destroys the hyper-graph and all the vertices of the graph
 
Vertexvertex (int id)
 
const Vertexvertex (int id) const
 
virtual bool removeEdge (Edge *e)
 
const VertexIDMapvertices () const
 
VertexIDMapvertices ()
 
const EdgeSetedges () const
 
EdgeSetedges ()
 
virtual bool mergeVertices (Vertex *vBig, Vertex *vSmall, bool erase)
 
virtual bool detachVertex (Vertex *v)
 
virtual bool changeId (Vertex *v, int newId)
 

Protected Member Functions

bool computeCholeskyUpdate ()
 
void convertTripletUpdateToSparse ()
 
- Protected Member Functions inherited from g2o::SparseOptimizer
void sortVectorContainers ()
 
bool buildIndexMapping (SparseOptimizer::VertexContainer &vlist)
 
void clearIndexMapping ()
 
- Protected Member Functions inherited from g2o::OptimizableGraph
void performActions (int iter, HyperGraphActionSet &actions)
 

Protected Attributes

SparseBlockMatrix< Eigen::MatrixXd > _updateMat
 
cholmod_common _cholmodCommon
 
cholmod::CholmodExt_cholmodSparse
 
cholmod_factor * _cholmodFactor
 
cholmod_triplet * _permutedUpdate
 
cholmod_factor * _L
 
LinearSolverCholmodOnlineInterface_solverInterface
 
HyperGraph::VertexSet _touchedVertices
 
Eigen::VectorXi _perm
 
Eigen::VectorXi _cmember
 
Eigen::VectorXi _tripletWorkspace
 
cholmod::CholmodExt_permutedUpdateAsSparse
 
- Protected Attributes inherited from g2o::SparseOptimizerOnline
FILE * _gnuplot
 
bool _usePcg
 
Solver_underlyingSolver
 
- Protected Attributes inherited from g2o::SparseOptimizer
bool * _forceStopFlag
 
bool _verbose
 
VertexContainer _ivMap
 
VertexContainer _activeVertices
 sorted according to VertexIDCompare
 
EdgeContainer _activeEdges
 sorted according to EdgeIDCompare
 
OptimizationAlgorithm_algorithm
 
BatchStatisticsContainer _batchStatistics
 
bool _computeBatchStatistics
 
- Protected Attributes inherited from g2o::OptimizableGraph
std::map< std::string, std::string > _renamedTypesLookup
 
long long _nextEdgeId
 
std::vector< HyperGraphActionSet_graphActions
 
ParameterContainer _parameters
 
JacobianWorkspace _jacobianWorkspace
 
- Protected Attributes inherited from g2o::HyperGraph
VertexIDMap _vertices
 
EdgeSet _edges
 

Additional Inherited Members

- Public Types inherited from g2o::SparseOptimizer
enum  { AT_COMPUTEACTIVERROR = OptimizableGraph::AT_NUM_ELEMENTS , AT_NUM_ELEMENTS }
 
- Public Types inherited from g2o::OptimizableGraph
enum  ActionType { AT_PREITERATION , AT_POSTITERATION , AT_NUM_ELEMENTS }
 
typedef std::set< HyperGraphAction * > HyperGraphActionSet
 
typedef std::vector< OptimizableGraph::Vertex * > VertexContainer
 vector container for vertices
 
typedef std::vector< OptimizableGraph::Edge * > EdgeContainer
 vector container for edges
 
- Public Types inherited from g2o::HyperGraph
typedef std::bitset< HyperGraph::HGET_NUM_ELEMS > GraphElemBitset
 
typedef std::set< Edge * > EdgeSet
 
typedef std::set< Vertex * > VertexSet
 
typedef std::unordered_map< int, Vertex * > VertexIDMap
 
typedef std::vector< Vertex * > VertexContainer
 
- Static Public Member Functions inherited from g2o::OptimizableGraph
static bool initMultiThreading ()
 
- Public Attributes inherited from g2o::SparseOptimizerOnline
int slamDimension
 
HyperGraph::EdgeSetnewEdges
 
bool batchStep
 
bool vizWithGnuplot
 
- Public Attributes inherited from g2o::OptimizableGraph
class G2O_CORE_API Vertex
 
class G2O_CORE_API Edge
 
- Public Attributes inherited from g2o::HyperGraph
class G2O_CORE_API Data
 
class G2O_CORE_API DataContainer
 
class G2O_CORE_API Vertex
 
class G2O_CORE_API Edge
 
- Static Public Attributes inherited from g2o::HyperGraph
static const int UnassignedId = -1
 
static const int InvalidId = -2
 

Detailed Description

Definition at line 31 of file graph_optimizer_sparse_incremental.h.

Constructor & Destructor Documentation

◆ SparseOptimizerIncremental()

g2o::SparseOptimizerIncremental::SparseOptimizerIncremental ( )

Definition at line 57 of file graph_optimizer_sparse_incremental.cpp.

57 {
58 _cholmodSparse = new cholmod::CholmodExt();
60 cholmod_start(&_cholmodCommon);
61
62 // setup ordering strategy to not permute the matrix
63 _cholmodCommon.nmethods = 1;
64 _cholmodCommon.method[0].ordering = CHOLMOD_NATURAL;
65 _cholmodCommon.postorder = 0;
66 _cholmodCommon.supernodal = CHOLMOD_SIMPLICIAL;
67
68 _permutedUpdate = cholmod_allocate_triplet(1000, 1000, 1024, 0, CHOLMOD_REAL,
70 _L = 0;
73
74 _permutedUpdateAsSparse = new cholmod::CholmodExt;
75}
LinearSolverCholmodOnlineInterface * _solverInterface

References _cholmodCommon, _cholmodFactor, _cholmodSparse, _L, _permutedUpdate, _permutedUpdateAsSparse, and _solverInterface.

◆ ~SparseOptimizerIncremental()

g2o::SparseOptimizerIncremental::~SparseOptimizerIncremental ( )

Definition at line 77 of file graph_optimizer_sparse_incremental.cpp.

77 {
79 _updateMat.clear(true);
80 delete _cholmodSparse;
81 if (_cholmodFactor) {
82 cholmod_free_factor(&_cholmodFactor, &_cholmodCommon);
84 }
85 cholmod_free_triplet(&_permutedUpdate, &_cholmodCommon);
86 cholmod_finish(&_cholmodCommon);
87}
void clear(bool dealloc=false)
SparseBlockMatrix< Eigen::MatrixXd > _updateMat

References _cholmodCommon, _cholmodFactor, _cholmodSparse, _permutedUpdate, _permutedUpdateAsSparse, _updateMat, and g2o::SparseBlockMatrix< MatrixType >::clear().

Member Function Documentation

◆ computeCholeskyUpdate()

bool g2o::SparseOptimizerIncremental::computeCholeskyUpdate ( )
protected

Definition at line 400 of file graph_optimizer_sparse_incremental.cpp.

400 {
401 if (_cholmodFactor) {
402 cholmod_free_factor(&_cholmodFactor, &_cholmodCommon);
403 _cholmodFactor = 0;
404 }
405
406 const SparseBlockMatrix<MatrixXd>& A = _updateMat;
407 size_t m = A.rows();
408 size_t n = A.cols();
409
411 // std::cerr << __PRETTY_FUNCTION__ << ": reallocating columns" <<
412 // std::endl;
415 ? n
416 : 2 * n; // pre-allocate more space if re-allocating
417 delete[] static_cast<int*>(_cholmodSparse->p);
419 }
420 size_t nzmax = A.nonZeros();
421 if (_cholmodSparse->nzmax < nzmax) {
422 // std::cerr << __PRETTY_FUNCTION__ << ": reallocating row + values" <<
423 // std::endl;
424 _cholmodSparse->nzmax =
425 _cholmodSparse->nzmax == 0
426 ? nzmax
427 : 2 * nzmax; // pre-allocate more space if re-allocating
428 delete[] static_cast<double*>(_cholmodSparse->x);
429 delete[] static_cast<int*>(_cholmodSparse->i);
430 _cholmodSparse->i = new int[_cholmodSparse->nzmax];
431 _cholmodSparse->x = new double[_cholmodSparse->nzmax];
432 }
433 _cholmodSparse->ncol = n;
434 _cholmodSparse->nrow = m;
435
436 A.fillCCS(static_cast<int*>(_cholmodSparse->p),
437 static_cast<int*>(_cholmodSparse->i),
438 static_cast<double*>(_cholmodSparse->x), true);
439 // writeCCSMatrix("updatesparse.txt", _cholmodSparse->nrow,
440 // _cholmodSparse->ncol, (int*)_cholmodSparse->p, (int*)_cholmodSparse->i,
441 // (double*)_cholmodSparse->x, true);
442
443 _cholmodFactor = cholmod_analyze(_cholmodSparse, &_cholmodCommon);
444 cholmod_factorize(_cholmodSparse, _cholmodFactor, &_cholmodCommon);
445
446#if 0
447 int* p = (int*)_cholmodFactor->Perm;
448 for (int i = 0; i < (int)n; ++i)
449 if (i != p[i])
450 cerr << "wrong permutation" << i << " -> " << p[i] << endl;
451#endif
452
453 if (_cholmodCommon.status == CHOLMOD_NOT_POSDEF) {
454 // std::cerr << "Cholesky failure, writing debug.txt (Hessian loadable by
455 // Octave)" << std::endl; writeCCSMatrix("debug.txt", _cholmodSparse->nrow,
456 // _cholmodSparse->ncol, (int*)_cholmodSparse->p, (int*)_cholmodSparse->i,
457 // (double*)_cholmodSparse->x, true);
458 return false;
459 }
460
461 // change to the specific format we need to have a pretty normal L
462 int change_status = cholmod_change_factor(CHOLMOD_REAL, 1, 0, 1, 1,
464 if (!change_status) {
465 return false;
466 }
467
468 return true;
469}
int rows() const
rows of the matrix

References _cholmodCommon, _cholmodFactor, _cholmodSparse, _updateMat, g2o::SparseBlockMatrix< MatrixType >::cols(), g2o::cholmod::CholmodExt::columnsAllocated, g2o::SparseBlockMatrix< MatrixType >::fillCCS(), g2o::SparseBlockMatrix< MatrixType >::nonZeros(), and g2o::SparseBlockMatrix< MatrixType >::rows().

Referenced by updateInitialization().

◆ convertTripletUpdateToSparse()

void g2o::SparseOptimizerIncremental::convertTripletUpdateToSparse ( )
protected

Definition at line 530 of file graph_optimizer_sparse_incremental.cpp.

530 {
531 // re-allocate the memory
532 if (_tripletWorkspace.size() < (int)_permutedUpdate->ncol) {
533 _tripletWorkspace.resize(_permutedUpdate->ncol * 2);
534 }
535
536 // reallocate num-zeros
537 if (_permutedUpdateAsSparse->nzmax < _permutedUpdate->nzmax) {
539 delete[] static_cast<int*>(_permutedUpdateAsSparse->i);
540 delete[] static_cast<double*>(_permutedUpdateAsSparse->x);
541 _permutedUpdateAsSparse->x = new double[_permutedUpdateAsSparse->nzmax];
543 }
544
547 delete[] static_cast<int*>(_permutedUpdateAsSparse->p);
550 }
551
554
555 int* w = _tripletWorkspace.data();
556 memset(w, 0, sizeof(int) * _permutedUpdate->ncol);
557
558 int* Ti = static_cast<int*>(_permutedUpdate->i);
559 int* Tj = static_cast<int*>(_permutedUpdate->j);
560 double* Tx = static_cast<double*>(_permutedUpdate->x);
561
562 int* Cp = static_cast<int*>(_permutedUpdateAsSparse->p);
563 int* Ci = static_cast<int*>(_permutedUpdateAsSparse->i);
564 double* Cx = static_cast<double*>(_permutedUpdateAsSparse->x);
565
566 for (size_t k = 0; k < _permutedUpdate->nnz; ++k) /* column counts */
567 w[Tj[k]]++;
568
569 /* column pointers */
570 const int n = _permutedUpdate->ncol;
571 int nz = 0;
572 for (int i = 0; i < n; i++) {
573 Cp[i] = nz;
574 nz += w[i];
575 w[i] = Cp[i];
576 }
577 Cp[n] = nz;
578 assert((size_t)nz == _permutedUpdate->nnz);
579
580 for (size_t k = 0; k < _permutedUpdate->nnz; ++k) {
581 int p = w[Tj[k]]++;
582 Ci[p] = Ti[k]; /* A(i,j) is the pth entry in C */
583 Cx[p] = Tx[k];
584 }
585}

References _permutedUpdate, _permutedUpdateAsSparse, _tripletWorkspace, and g2o::cholmod::CholmodExt::columnsAllocated.

Referenced by updateInitialization().

◆ initSolver()

bool g2o::SparseOptimizerIncremental::initSolver ( int  dimension,
int  batchEveryN 
)
virtual

Reimplemented from g2o::SparseOptimizerOnline.

Definition at line 485 of file graph_optimizer_sparse_incremental.cpp.

485 {
486 // cerr << __PRETTY_FUNCTION__ << endl;
487 slamDimension = dimension;
488 if (dimension == 3) {
489 setAlgorithm(createSolver("fix3_2_cholmod"));
490 OptimizationAlgorithmGaussNewton* gaussNewton =
491 dynamic_cast<OptimizationAlgorithmGaussNewton*>(solver());
492 assert(gaussNewton);
493 BlockSolver<BlockSolverTraits<3, 2>>* bs =
494 dynamic_cast<BlockSolver<BlockSolverTraits<3, 2>>*>(
495 &gaussNewton->solver());
496 assert(bs && "Unable to get internal block solver");
497 LinearSolverCholmodOnline<Matrix3d>* s =
498 dynamic_cast<LinearSolverCholmodOnline<Matrix3d>*>(&bs->linearSolver());
499 bs->setAdditionalVectorSpace(300);
500 bs->setSchur(false);
503 } else {
504 setAlgorithm(createSolver("fix6_3_cholmod"));
505 OptimizationAlgorithmGaussNewton* gaussNewton =
506 dynamic_cast<OptimizationAlgorithmGaussNewton*>(solver());
507 assert(gaussNewton);
508 BlockSolver<BlockSolverTraits<6, 3>>* bs =
509 dynamic_cast<BlockSolver<BlockSolverTraits<6, 3>>*>(
510 &gaussNewton->solver());
511 assert(bs && "Unable to get internal block solver");
512 LinearSolverCholmodOnline<Matrix<double, 6, 6>>* s =
513 dynamic_cast<LinearSolverCholmodOnline<Matrix<double, 6, 6>>*>(
514 &bs->linearSolver());
515 bs->setAdditionalVectorSpace(600);
516 bs->setSchur(false);
519 }
521 _solverInterface->batchEveryN = batchEveryN;
522 if (!solver()) {
523 cerr << "Error allocating solver. Allocating CHOLMOD solver failed!"
524 << endl;
525 return false;
526 }
527 return true;
528}
void setAlgorithm(OptimizationAlgorithm *algorithm)
OptimizationAlgorithm * solver()
static OptimizationAlgorithm * createSolver(const std::string &solverName)

References _cmember, _solverInterface, g2o::SparseOptimizerOnline::_underlyingSolver, g2o::LinearSolverCholmodOnlineInterface::batchEveryN, g2o::LinearSolverCholmodOnlineInterface::cmember, g2o::createSolver(), g2o::BlockSolver< Traits >::linearSolver(), g2o::Solver::setAdditionalVectorSpace(), g2o::SparseOptimizer::setAlgorithm(), g2o::BlockSolver< Traits >::setSchur(), g2o::SparseOptimizerOnline::slamDimension, g2o::OptimizationAlgorithmWithHessian::solver(), and g2o::SparseOptimizer::solver().

◆ optimize()

int g2o::SparseOptimizerIncremental::optimize ( int  iterations,
bool  online = false 
)
virtual

starts one optimization run given the current configuration of the graph, and the current settings stored in the class instance. It can be called only after initializeOptimization

Reimplemented from g2o::SparseOptimizer.

Definition at line 89 of file graph_optimizer_sparse_incremental.cpp.

89 {
90 (void)iterations; // we only do one iteration anyhow
92 solver->init(online);
93
94 bool ok = true;
95
96 if (!online || batchStep) {
97 // cerr << "performing batch step" << endl;
98 if (!online) {
100 if (!ok) {
101 cerr << __PRETTY_FUNCTION__ << ": Failure while building CCS structure"
102 << endl;
103 return 0;
104 }
105 }
106
107 // copy over the updated estimate as new linearization point
108 if (slamDimension == 3) {
109 for (size_t i = 0; i < indexMapping().size(); ++i) {
110 OnlineVertexSE2* v = static_cast<OnlineVertexSE2*>(indexMapping()[i]);
111 v->setEstimate(v->updatedEstimate);
112 }
113 } else if (slamDimension == 6) {
114 for (size_t i = 0; i < indexMapping().size(); ++i) {
115 OnlineVertexSE3* v = static_cast<OnlineVertexSE3*>(indexMapping()[i]);
116 v->setEstimate(v->updatedEstimate);
117 }
118 }
119
121 // SparseOptimizer::linearizeSystem();
123
124 // mark vertices to be sorted as last
125 int numBlocksRequired = _ivMap.size();
126 if (_cmember.size() < numBlocksRequired) {
127 _cmember.resize(2 * numBlocksRequired);
128 }
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) {
132 const HyperGraph::EdgeSet& eset = _ivMap[i]->edges();
133 for (HyperGraph::EdgeSet::const_iterator it = eset.begin();
134 it != eset.end(); ++it) {
135 OptimizableGraph::Edge* e = static_cast<OptimizableGraph::Edge*>(*it);
136 OptimizableGraph::Vertex* v1 =
137 static_cast<OptimizableGraph::Vertex*>(e->vertices()[0]);
138 OptimizableGraph::Vertex* v2 =
139 static_cast<OptimizableGraph::Vertex*>(e->vertices()[1]);
140 if (v1->hessianIndex() >= 0) _cmember(v1->hessianIndex()) = 1;
141 if (v2->hessianIndex() >= 0) _cmember(v2->hessianIndex()) = 1;
142 }
143 }
144 // OptimizableGraph::Vertex* lastPose = _ivMap.back();
145 //_cmember(lastPose->hessianIndex()) = 2;
146 }
147
148 ok = _underlyingSolver->solve();
149
150 // get the current cholesky factor along with the permutation
151 _L = _solverInterface->L();
152 if (_perm.size() < (int)_L->n) _perm.resize(2 * _L->n);
153 int* p = static_cast<int*>(_L->Perm);
154 for (size_t i = 0; i < _L->n; ++i) _perm[p[i]] = i;
155
156 } else {
157 // update the b vector
158 for (HyperGraph::VertexSet::iterator it = _touchedVertices.begin();
159 it != _touchedVertices.end(); ++it) {
160 OptimizableGraph::Vertex* v = static_cast<OptimizableGraph::Vertex*>(*it);
161 int iBase = v->colInHessian();
162 v->copyB(_underlyingSolver->b() + iBase);
163 }
165 }
166
168
169 if (verbose()) {
171 cerr << "nodes = " << vertices().size()
172 << "\t edges= " << _activeEdges.size()
173 << "\t chi2= " << FIXED(activeChi2()) << endl;
174 }
175
177
178 if (!ok) return 0;
179 return 1;
180}
std::set< Edge * > EdgeSet
const VertexIDMap & vertices() const
virtual cholmod_factor * L() const =0
virtual bool solve(double *x, double *b)=0
virtual bool init(bool online=false)=0
double * b()
return b, the right hand side of the system
Definition solver.h:101
virtual bool buildStructure(bool zeroBlocks=false)=0
double * x()
return x, the solution vector
Definition solver.h:98
virtual bool solve()=0
virtual bool buildSystem()=0
EdgeContainer _activeEdges
sorted according to EdgeIDCompare
OptimizationAlgorithm * _algorithm
bool verbose() const
verbose information during optimization
const VertexContainer & indexMapping() const
the index mapping of the vertices
#define __PRETTY_FUNCTION__
Definition macros.h:90
class G2O_CORE_API OptimizationAlgorithm

References __PRETTY_FUNCTION__, g2o::SparseOptimizer::_activeEdges, g2o::SparseOptimizer::_algorithm, _cmember, g2o::SparseOptimizer::_ivMap, _L, _perm, _solverInterface, _touchedVertices, g2o::SparseOptimizerOnline::_underlyingSolver, g2o::SparseOptimizer::activeChi2(), g2o::Solver::b(), g2o::SparseOptimizerOnline::batchStep, g2o::Solver::buildStructure(), g2o::Solver::buildSystem(), g2o::OptimizableGraph::Vertex::colInHessian(), g2o::SparseOptimizer::computeActiveErrors(), g2o::OptimizableGraph::Vertex::copyB(), g2o::SparseOptimizerOnline::gnuplotVisualization(), g2o::OptimizableGraph::Vertex::hessianIndex(), g2o::SparseOptimizer::indexMapping(), g2o::OptimizationAlgorithm::init(), g2o::LinearSolverCholmodOnlineInterface::L(), g2o::BaseVertex< D, T >::setEstimate(), g2o::SparseOptimizerOnline::slamDimension, g2o::Solver::solve(), g2o::LinearSolverCholmodOnlineInterface::solve(), g2o::SparseOptimizer::solver(), g2o::SparseOptimizerOnline::update(), g2o::OnlineVertexSE2::updatedEstimate, g2o::OnlineVertexSE3::updatedEstimate, g2o::SparseOptimizer::verbose(), g2o::HyperGraph::Edge::vertices(), g2o::HyperGraph::vertices(), g2o::SparseOptimizerOnline::vizWithGnuplot, and g2o::Solver::x().

◆ updateInitialization()

bool g2o::SparseOptimizerIncremental::updateInitialization ( HyperGraph::VertexSet vset,
HyperGraph::EdgeSet eset 
)
virtual

HACK updating the internal structures for online processing

Reimplemented from g2o::SparseOptimizerOnline.

Definition at line 182 of file graph_optimizer_sparse_incremental.cpp.

183 {
184 if (batchStep) {
186 }
187
188 for (HyperGraph::VertexSet::iterator it = vset.begin(); it != vset.end();
189 ++it) {
190 OptimizableGraph::Vertex* v = static_cast<OptimizableGraph::Vertex*>(*it);
191 v->clearQuadraticForm(); // be sure that b is zero for this vertex
192 }
193
194 // get the touched vertices
195 _touchedVertices.clear();
196 for (HyperGraph::EdgeSet::iterator it = eset.begin(); it != eset.end();
197 ++it) {
198 OptimizableGraph::Edge* e = static_cast<OptimizableGraph::Edge*>(*it);
199 OptimizableGraph::Vertex* v1 =
200 static_cast<OptimizableGraph::Vertex*>(e->vertices()[0]);
201 OptimizableGraph::Vertex* v2 =
202 static_cast<OptimizableGraph::Vertex*>(e->vertices()[1]);
203 if (!v1->fixed()) _touchedVertices.insert(v1);
204 if (!v2->fixed()) _touchedVertices.insert(v2);
205 }
206 // cerr << PVAR(_touchedVertices.size()) << endl;
207
208 // updating the internal structures
209 std::vector<HyperGraph::Vertex*> newVertices;
210 newVertices.reserve(vset.size());
211 _activeVertices.reserve(_activeVertices.size() + vset.size());
212 _activeEdges.reserve(_activeEdges.size() + eset.size());
213 for (HyperGraph::EdgeSet::iterator it = eset.begin(); it != eset.end(); ++it)
214 _activeEdges.push_back(static_cast<OptimizableGraph::Edge*>(*it));
215 // cerr << "updating internal done." << endl;
216
217 // update the index mapping
218 size_t next = _ivMap.size();
219 for (HyperGraph::VertexSet::iterator it = vset.begin(); it != vset.end();
220 ++it) {
221 OptimizableGraph::Vertex* v = static_cast<OptimizableGraph::Vertex*>(*it);
222 if (!v->fixed()) {
223 if (!v->marginalized()) {
224 v->setHessianIndex(next);
225 _ivMap.push_back(v);
226 newVertices.push_back(v);
227 _activeVertices.push_back(v);
228 next++;
229 } else // not supported right now
230 abort();
231 } else {
232 v->setHessianIndex(-1);
233 }
234 }
235 // cerr << "updating index mapping done." << endl;
236
237 // backup the tempindex and prepare sorting structure
238#ifdef _MSC_VER
239 VertexBackup* backupIdx = new VertexBackup[_touchedVertices.size()];
240#else
241 VertexBackup backupIdx[_touchedVertices.size()];
242#endif
243 memset(backupIdx, 0, sizeof(VertexBackup) * _touchedVertices.size());
244 int idx = 0;
245 for (HyperGraph::VertexSet::iterator it = _touchedVertices.begin();
246 it != _touchedVertices.end(); ++it) {
247 OptimizableGraph::Vertex* v = static_cast<OptimizableGraph::Vertex*>(*it);
248 backupIdx[idx].hessianIndex = v->hessianIndex();
249 backupIdx[idx].vertex = v;
250 backupIdx[idx].hessianData = v->hessianData();
251 ++idx;
252 }
253 sort(backupIdx,
254 backupIdx +
256 .size()); // sort according to the hessianIndex which is the
257 // same order as used later by the optimizer
258 for (int i = 0; i < idx; ++i) {
259 backupIdx[i].vertex->setHessianIndex(i);
260 }
261 // cerr << "backup tempindex done." << endl;
262
263 // building the structure of the update
264 _updateMat.clear(true); // get rid of the old matrix structure
265 _updateMat.rowBlockIndices().clear();
266 _updateMat.colBlockIndices().clear();
267 _updateMat.blockCols().clear();
268
269 // placing the current stuff in _updateMat
270 MatrixXd* lastBlock = 0;
271 int sizePoses = 0;
272 for (int i = 0; i < idx; ++i) {
273 OptimizableGraph::Vertex* v = backupIdx[i].vertex;
274 int dim = v->dimension();
275 sizePoses += dim;
276 _updateMat.rowBlockIndices().push_back(sizePoses);
277 _updateMat.colBlockIndices().push_back(sizePoses);
278 _updateMat.blockCols().push_back(
280 int ind = v->hessianIndex();
281 // cerr << PVAR(ind) << endl;
282 if (ind >= 0) {
283 MatrixXd* m = _updateMat.block(ind, ind, true);
284 v->mapHessianMemory(m->data());
285 lastBlock = m;
286 }
287 }
288 if (lastBlock) {
289 lastBlock->diagonal().array() += 1e-6; // HACK to get Eigen value > 0
290 }
291
292 for (HyperGraph::EdgeSet::const_iterator it = eset.begin(); it != eset.end();
293 ++it) {
294 OptimizableGraph::Edge* e = static_cast<OptimizableGraph::Edge*>(*it);
295 OptimizableGraph::Vertex* v1 = (OptimizableGraph::Vertex*)e->vertices()[0];
296 OptimizableGraph::Vertex* v2 = (OptimizableGraph::Vertex*)e->vertices()[1];
297
298 int ind1 = v1->hessianIndex();
299 if (ind1 == -1) continue;
300 int ind2 = v2->hessianIndex();
301 if (ind2 == -1) continue;
302 bool transposedBlock = ind1 > ind2;
303 if (transposedBlock) // make sure, we allocate the upper triangular block
304 swap(ind1, ind2);
305
306 MatrixXd* m = _updateMat.block(ind1, ind2, true);
307 e->mapHessianMemory(m->data(), 0, 1, transposedBlock);
308 }
309
310 // build the system into _updateMat
311 for (HyperGraph::EdgeSet::iterator it = eset.begin(); it != eset.end();
312 ++it) {
313 OptimizableGraph::Edge* e = static_cast<OptimizableGraph::Edge*>(*it);
314 e->computeError();
315 }
316 for (HyperGraph::EdgeSet::iterator it = eset.begin(); it != eset.end();
317 ++it) {
318 OptimizableGraph::Edge* e = static_cast<OptimizableGraph::Edge*>(*it);
319 e->linearizeOplus(jacobianWorkspace());
320 e->constructQuadraticForm();
321 }
322
323 // restore the original data for the vertex
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);
328 }
329
330 // update the structure of the real block matrix
331 bool solverStatus = _algorithm->updateStructure(newVertices, eset);
332
333 bool updateStatus = computeCholeskyUpdate();
334 if (!updateStatus) {
335 cerr << "Error while computing update" << endl;
336 }
337
338 cholmod_sparse* updateAsSparseFactor =
339 cholmod_factor_to_sparse(_cholmodFactor, &_cholmodCommon);
340
341 // convert CCS update by permuting back to the permutation of L
342 if (updateAsSparseFactor->nzmax > _permutedUpdate->nzmax) {
343 // cerr << "realloc _permutedUpdate" << endl;
344 cholmod_reallocate_triplet(updateAsSparseFactor->nzmax, _permutedUpdate,
346 }
347 _permutedUpdate->nnz = 0;
348 _permutedUpdate->nrow = _permutedUpdate->ncol = _L->n;
349 {
350 int* Ap = static_cast<int*>(updateAsSparseFactor->p);
351 int* Ai = static_cast<int*>(updateAsSparseFactor->i);
352 double* Ax = static_cast<double*>(updateAsSparseFactor->x);
353 int* Bj = static_cast<int*>(_permutedUpdate->j);
354 int* Bi = static_cast<int*>(_permutedUpdate->i);
355 double* Bx = static_cast<double*>(_permutedUpdate->x);
356 for (size_t c = 0; c < updateAsSparseFactor->ncol; ++c) {
357 const int& rbeg = Ap[c];
358 const int& rend = Ap[c + 1];
359 int cc = c / slamDimension;
360 int coff = c % slamDimension;
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];
366
367 int rr = r / slamDimension;
368 int roff = r % slamDimension;
369 const int& rbase = backupIdx[rr].vertex->colInHessian();
370
371 int row = _perm(rbase + roff);
372 int col = ccol;
373 if (col > row) // lower triangular entry
374 swap(col, row);
375 Bi[_permutedUpdate->nnz] = row;
376 Bj[_permutedUpdate->nnz] = col;
377 Bx[_permutedUpdate->nnz] = val;
378 ++_permutedUpdate->nnz;
379 }
380 }
381 }
382 cholmod_free_sparse(&updateAsSparseFactor, &_cholmodCommon);
383#ifdef _MSC_VER
384 delete[] backupIdx;
385#endif
386
387#if 0
388 cholmod_sparse* updatePermuted = cholmod_triplet_to_sparse(_permutedUpdate, _permutedUpdate->nnz, &_cholmodCommon);
389 //writeCCSMatrix("update-permuted.txt", updatePermuted->nrow, updatePermuted->ncol, (int*)updatePermuted->p, (int*)updatePermuted->i, (double*)updatePermuted->x, false);
390 _solverInterface->choleskyUpdate(updatePermuted);
391 cholmod_free_sparse(&updatePermuted, &_cholmodCommon);
392#else
395#endif
396
397 return solverStatus;
398}
virtual int choleskyUpdate(cholmod_sparse *update)=0
virtual bool updateStructure(const std::vector< HyperGraph::Vertex * > &vset, const HyperGraph::EdgeSet &edges)=0
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
SparseMatrixBlock * block(int r, int c, bool alloc=false)
const std::vector< int > & rowBlockIndices() const
indices of the row blocks
virtual bool updateInitialization(HyperGraph::VertexSet &vset, HyperGraph::EdgeSet &eset)
VertexContainer _activeVertices
sorted according to VertexIDCompare
JacobianWorkspace & jacobianWorkspace()
the workspace for storing the Jacobians of the graph

References g2o::SparseOptimizer::_activeEdges, g2o::SparseOptimizer::_activeVertices, g2o::SparseOptimizer::_algorithm, _cholmodCommon, _cholmodFactor, g2o::SparseOptimizer::_ivMap, _L, _perm, _permutedUpdate, _permutedUpdateAsSparse, _solverInterface, _touchedVertices, _updateMat, g2o::SparseOptimizerOnline::batchStep, g2o::SparseBlockMatrix< MatrixType >::block(), g2o::SparseBlockMatrix< MatrixType >::blockCols(), g2o::LinearSolverCholmodOnlineInterface::choleskyUpdate(), g2o::SparseBlockMatrix< MatrixType >::clear(), g2o::OptimizableGraph::Vertex::clearQuadraticForm(), g2o::SparseBlockMatrix< MatrixType >::colBlockIndices(), computeCholeskyUpdate(), g2o::OptimizableGraph::Edge::computeError(), g2o::OptimizableGraph::Edge::constructQuadraticForm(), convertTripletUpdateToSparse(), g2o::OptimizableGraph::Vertex::dimension(), g2o::OptimizableGraph::Vertex::fixed(), g2o::OptimizableGraph::Vertex::hessianData(), g2o::OptimizableGraph::Vertex::hessianIndex(), g2o::OptimizableGraph::jacobianWorkspace(), g2o::OptimizableGraph::Edge::linearizeOplus(), g2o::OptimizableGraph::Vertex::mapHessianMemory(), g2o::OptimizableGraph::Edge::mapHessianMemory(), g2o::OptimizableGraph::Vertex::marginalized(), g2o::SparseBlockMatrix< MatrixType >::rowBlockIndices(), g2o::OptimizableGraph::Vertex::setHessianIndex(), g2o::SparseOptimizerOnline::slamDimension, g2o::SparseOptimizerOnline::updateInitialization(), g2o::OptimizationAlgorithm::updateStructure(), and g2o::HyperGraph::Edge::vertices().

Member Data Documentation

◆ _cholmodCommon

cholmod_common g2o::SparseOptimizerIncremental::_cholmodCommon
protected

◆ _cholmodFactor

cholmod_factor* g2o::SparseOptimizerIncremental::_cholmodFactor
protected

◆ _cholmodSparse

cholmod::CholmodExt* g2o::SparseOptimizerIncremental::_cholmodSparse
protected

◆ _cmember

Eigen::VectorXi g2o::SparseOptimizerIncremental::_cmember
protected

Definition at line 55 of file graph_optimizer_sparse_incremental.h.

Referenced by initSolver(), and optimize().

◆ _L

cholmod_factor* g2o::SparseOptimizerIncremental::_L
protected

◆ _perm

Eigen::VectorXi g2o::SparseOptimizerIncremental::_perm
protected

Definition at line 54 of file graph_optimizer_sparse_incremental.h.

Referenced by optimize(), and updateInitialization().

◆ _permutedUpdate

cholmod_triplet* g2o::SparseOptimizerIncremental::_permutedUpdate
protected

◆ _permutedUpdateAsSparse

cholmod::CholmodExt* g2o::SparseOptimizerIncremental::_permutedUpdateAsSparse
protected

◆ _solverInterface

LinearSolverCholmodOnlineInterface* g2o::SparseOptimizerIncremental::_solverInterface
protected

◆ _touchedVertices

HyperGraph::VertexSet g2o::SparseOptimizerIncremental::_touchedVertices
protected

Definition at line 53 of file graph_optimizer_sparse_incremental.h.

Referenced by optimize(), and updateInitialization().

◆ _tripletWorkspace

Eigen::VectorXi g2o::SparseOptimizerIncremental::_tripletWorkspace
protected

Definition at line 57 of file graph_optimizer_sparse_incremental.h.

Referenced by convertTripletUpdateToSparse().

◆ _updateMat

SparseBlockMatrix<Eigen::MatrixXd> g2o::SparseOptimizerIncremental::_updateMat
protected

The documentation for this class was generated from the following files: