32 #include "../stuff/timeutil.h" 33 #include "../stuff/macros.h" 34 #include "../stuff/misc.h" 39 using namespace Eigen;
41 template <
typename Traits>
44 _linearSolver(linearSolver)
64 template <
typename Traits>
66 int* blockLandmarkIndices,
int numLandmarkBlocks,
75 assert(
_sizePoses > 0 &&
"allocating with wrong size");
89 _coefficientsMutex.resize(numPoseBlocks);
94 template <
typename Traits>
135 template <
typename Traits>
142 template <
typename Traits>
147 size_t sparseDim = 0;
172 delete[] blockLandmarkIndices;
173 delete[] blockPoseIndices;
209 for (
size_t viIdx = 0; viIdx < e->
vertices().size(); ++viIdx) {
214 int indexV1Bak = ind1;
215 for (
size_t vjIdx = viIdx + 1; vjIdx < e->
vertices().size(); ++vjIdx) {
221 bool transposedBlock = ind1 > ind2;
222 if (transposedBlock){
231 schurMatrixLookup->
addBlock(ind1, ind2);
266 for (HyperGraph::EdgeSet::const_iterator it1=vedges.begin(); it1!=vedges.end(); ++it1){
267 for (
size_t i=0; i<(*it1)->vertices().size(); ++i)
272 for (HyperGraph::EdgeSet::const_iterator it2=vedges.begin(); it2!=vedges.end(); ++it2){
273 for (
size_t j=0; j<(*it2)->vertices().size(); ++j)
281 schurMatrixLookup->
addBlock(i1, i2);
291 delete schurMatrixLookup;
297 template <
typename Traits>
300 for (std::vector<HyperGraph::Vertex*>::const_iterator vit = vset.begin(); vit != vset.end(); ++vit) {
314 std::cerr <<
"updateStructure(): Schur not supported" << std::endl;
320 for (HyperGraph::EdgeSet::const_iterator it = edges.begin(); it != edges.end(); ++it) {
323 for (
size_t viIdx = 0; viIdx < e->
vertices().size(); ++viIdx) {
326 int indexV1Bak = ind1;
329 for (
size_t vjIdx = viIdx + 1; vjIdx < e->
vertices().size(); ++vjIdx) {
335 bool transposedBlock = ind1 > ind2;
353 template <
typename Traits>
379 # pragma omp parallel for default (shared) schedule(dynamic, 10) 381 for (
int landmarkIndex = 0; landmarkIndex < static_cast<int>(
_Hll->
blockCols().size()); ++landmarkIndex) {
383 assert(marginalizeColumn.size() == 1 &&
"more than one block in _Hll column");
387 assert (D && D->rows()==D->cols() &&
"Error in landmark matrix");
392 for (
int j=0; j<D->rows(); ++j) {
397 assert((
size_t)landmarkIndex < _HplCCS->blockCols().size() &&
"Index out of bounds");
401 it_outer != landmarkColumn.end(); ++it_outer) {
402 int i1 = it_outer->row;
413 Bb.noalias() += (*Bi)*db;
420 for (; it_inner != landmarkColumn.end(); ++it_inner) {
421 int i2 = it_inner->row;
424 while (targetColumnIt->row < i2 )
426 assert(targetColumnIt !=
_HschurTransposedCCS->
blockCols()[i1].end() && targetColumnIt->row == i2 &&
"invalid iterator, something wrong with the matrix structure");
429 (*Hi1i2).noalias() -= BDinv*Bj->transpose();
489 template <
typename Traits>
501 template <
typename Traits>
506 # pragma omp parallel for default (shared) if (_optimizer->indexMapping().size() > 1000) 527 # pragma omp parallel for default (shared) firstprivate(jacobianWorkspace) if (_optimizer->activeEdges().size() > 100) 534 for (
size_t i = 0; i < e->
vertices().size(); ++i) {
539 cerr <<
"buildSystem(): NaN within Jacobian for edge " << e <<
" for vertex " << i << endl;
549 # pragma omp parallel for default (shared) if (_optimizer->indexMapping().size() > 1000) 563 template <
typename Traits>
571 # pragma omp parallel for default (shared) if (_numPoses > 100) 577 b->diagonal().array() += lambda;
580 # pragma omp parallel for default (shared) if (_numLandmarks > 100) 586 b->diagonal().array() += lambda;
591 template <
typename Traits>
606 template <
typename Traits>
622 template <
typename Traits>
628 template <
typename Traits>
SparseBlockMatrix< PoseMatrixType > * _Hschur
Traits::PoseHessianType PoseHessianType
std::vector< LandmarkVectorType, Eigen::aligned_allocator< LandmarkVectorType > > _diagonalBackupLandmark
statistics about the optimization
Traits::LandmarkMatrixType LandmarkMatrixType
void setColInHessian(int c)
set the row of this vertex in the Hessian
virtual bool solve(const SparseBlockMatrix< MatrixType > &A, double *x, double *b)=0
SparseOptimizer * optimizer() const
the optimizer (graph) on which the solver works
#define __PRETTY_FUNCTION__
int cols() const
columns of the matrix
int dimension() const
returns the dimensions of the error function
const Vertex * vertex(size_t i) const
bool fixed() const
true => this node is fixed during the optimization
virtual void setWriteDebug(bool writeDebug)
SparseBlockMatrix< PoseMatrixType > * _Hpp
Traits::LandmarkHessianType LandmarkHessianType
virtual int copyB(double *b_) const =0
int fillSparseBlockMatrixCCSTransposed(SparseBlockMatrixCCS< MatrixType > &blockCCS) const
const EdgeContainer & activeEdges() const
the edges active in the current optimization
void multiply(double *&dest, const double *src) const
double * workspaceForVertex(int vertexIndex)
bool add(SparseBlockMatrix< MatrixType > *&dest) const
adds the current matrix to the destination
SparseOptimizer * _optimizer
void rightMultiply(double *&dest, const double *src) const
int hessianIndex() const
temporary index of this node in the parameter vector obtained from linearization
SparseBlockMatrixDiagonal< LandmarkMatrixType > * _DInvSchur
SparseMatrixBlock * block(int r, int c, bool alloc=false)
returns the block at location r,c. if alloc=true he block is created if it does not exist ...
virtual bool init(SparseOptimizer *optmizer, bool online=false)
bool writeOctave(const char *filename, bool upperTriangle=true) const
void resize(int *blockPoseIndices, int numPoseBlocks, int *blockLandmarkIndices, int numLandmarkBlocks, int totalDim)
lock a mutex within a scope
SparseBlockMatrixCCS< PoseLandmarkMatrixType > * _HplCCS
SparseBlockMatrix< LandmarkMatrixType > * _Hll
void clear(bool dealloc=false)
this zeroes all the blocks. If dealloc=true the blocks are removed from memory
virtual void linearizeOplus(JacobianWorkspace &jacobianWorkspace)=0
Traits::PoseMatrixType PoseMatrixType
geometry_msgs::TransformStamped t
virtual bool saveHessian(const std::string &fileName) const
write the hessian to disk using the specified file name
const std::vector< SparseColumn > & blockCols() const
the block matrices per block-column
bool arrayHasNaN(const double *array, int size, int *nanIndex=0)
int dimension() const
dimension of the estimated state belonging to this node
int rowBaseOfBlock(int r) const
where does the row at block-row r start?
size_t hessianPoseDimension
dimension of the pose matrix in Schur
JacobianWorkspace & jacobianWorkspace()
the workspace for storing the Jacobians of the graph
virtual bool computeMarginals(SparseBlockMatrix< MatrixXd > &spinv, const std::vector< std::pair< int, int > > &blockIndices)
Traits::LinearSolverType LinearSolverType
const VertexContainer & vertices() const
std::set< Edge * > EdgeSet
virtual void setWriteDebug(bool)
virtual bool buildStructure(bool zeroBlocks=false)
void takePatternFromHash(SparseBlockMatrixHashMap< MatrixType > &hashMatrix)
MatrixType * addBlock(int r, int c, bool zeroBlock=false)
virtual bool setLambda(double lambda, bool backup=false)
SparseBlockMatrixCCS< PoseMatrixType > * _HschurTransposedCCS
Traits::PoseLandmarkHessianType PoseLandmarkHessianType
virtual void constructQuadraticForm()=0
std::vector< PoseVectorType, Eigen::aligned_allocator< PoseVectorType > > _diagonalBackupPose
const std::vector< SparseColumn > & blockCols() const
the block matrices per block-column
size_t hessianLandmarkDimension
dimension of the landmark matrix in Schur
Traits::PoseLandmarkMatrixType PoseLandmarkMatrixType
Traits::LandmarkVectorType LandmarkVectorType
static G2OBatchStatistics * globalStats()
virtual bool writeDebug() const
double get_monotonic_time()
void resizeVector(size_t sx)
virtual bool solvePattern(SparseBlockMatrix< MatrixXd > &spinv, const std::vector< std::pair< int, int > > &blockIndices, const SparseBlockMatrix< MatrixType > &A)
virtual bool buildSystem()
int colInHessian() const
get the row of this vertex in the Hessian
virtual void mapHessianMemory(double *d)=0
bool marginalized() const
true => this node is marginalized out during the optimization
const std::vector< int > & colBlockIndices() const
indices of the column blocks
virtual void clearQuadraticForm()=0
const EdgeSet & edges() const
returns the set of hyper-edges that are leaving/entering in this vertex
A general case Vertex for optimization.
const std::vector< IntBlockMap > & blockCols() const
the block matrices per block-column
virtual bool updateStructure(const std::vector< HyperGraph::Vertex *> &vset, const HyperGraph::EdgeSet &edges)
SparseBlockMatrix< PoseLandmarkMatrixType > * _Hpl
size_t hessianDimension
rows / cols of the Hessian
double * b()
return b, the right hand side of the system
LinearSolver< PoseMatrixType > * _linearSolver
double timeSchurComplement
compute schur complement (0 if not done)
int fillSparseBlockMatrixCCS(SparseBlockMatrixCCS< MatrixType > &blockCCS) const
provide memory workspace for computing the Jacobians
Sparse matrix which uses blocks based on hash structures.
virtual void mapHessianMemory(double *d, int i, int j, bool rowMajor)=0
const std::vector< int > & rowBlockIndices() const
indices of the row blocks
const VertexContainer & indexMapping() const
the index mapping of the vertices
int rowBaseOfBlock(int r) const
where does the row at block-row r starts?
void swap(scoped_ptr< T > &, scoped_ptr< T > &)
BlockSolver(LinearSolverType *linearSolver)
base for the block solvers with some basic function interfaces
Sparse matrix which uses blocks.
double timeLinearSolver
time for solving, excluding Schur setup
double timeMarginals
computing the inverse elements (solve blocks) and thus the marginal covariances
const DiagonalVector & diagonal() const
the block matrices per block-column
virtual void restoreDiagonal()