bool SparseOptimizer::gaugeFreedom() { if (vertices().empty()) return false; int maxDim=0; for (HyperGraph::VertexIDMap::iterator it=vertices().begin(); it!=vertices().end(); ++it){ OptimizableGraph::Vertex* v=static_cast<OptimizableGraph::Vertex*>(it->second); maxDim = std::max(maxDim,v->dimension()); } for (HyperGraph::VertexIDMap::iterator it=vertices().begin(); it!=vertices().end(); ++it){ OptimizableGraph::Vertex* v=static_cast<OptimizableGraph::Vertex*>(it->second); if (v->dimension() == maxDim) { // test for fixed vertex if (v->fixed()) { return false; } // test for full dimension prior for (HyperGraph::EdgeSet::const_iterator eit = v->edges().begin(); eit != v->edges().end(); ++eit) { OptimizableGraph::Edge* e = static_cast<OptimizableGraph::Edge*>(*eit); if (e->vertices().size() == 1 && e->dimension() == maxDim) return false; } } } return true; }
void SparseOptimizer::computeActiveErrors() { // call the callbacks in case there is something registered HyperGraphActionSet& actions = _graphActions[AT_COMPUTEACTIVERROR]; if (actions.size() > 0) { for (HyperGraphActionSet::iterator it = actions.begin(); it != actions.end(); ++it) (*(*it))(this); } # ifdef G2O_OPENMP # pragma omp parallel for default (shared) if (_activeEdges.size() > 50) # endif for (int k = 0; k < static_cast<int>(_activeEdges.size()); ++k) { OptimizableGraph::Edge* e = _activeEdges[k]; e->computeError(); } # ifndef NDEBUG for (int k = 0; k < static_cast<int>(_activeEdges.size()); ++k) { OptimizableGraph::Edge* e = _activeEdges[k]; bool hasNan = arrayHasNaN(e->errorData(), e->dimension()); if (hasNan) { cerr << "computeActiveErrors(): found NaN in error for edge " << e << endl; } } # endif }
bool BlockSolver<Traits>::buildSystem() { // clear b vector # ifdef G2O_OPENMP # pragma omp parallel for default (shared) if (_optimizer->indexMapping().size() > 1000) # endif for (int i = 0; i < static_cast<int>(_optimizer->indexMapping().size()); ++i) { OptimizableGraph::Vertex* v=_optimizer->indexMapping()[i]; assert(v); v->clearQuadraticForm(); } _Hpp->clear(); if (_doSchur) { _Hll->clear(); _Hpl->clear(); } // resetting the terms for the pairwise constraints // built up the current system by storing the Hessian blocks in the edges and vertices # ifndef G2O_OPENMP // no threading, we do not need to copy the workspace JacobianWorkspace& jacobianWorkspace = _optimizer->jacobianWorkspace(); # else // if running with threads need to produce copies of the workspace for each thread JacobianWorkspace jacobianWorkspace = _optimizer->jacobianWorkspace(); # pragma omp parallel for default (shared) firstprivate(jacobianWorkspace) if (_optimizer->activeEdges().size() > 100) # endif for (int k = 0; k < static_cast<int>(_optimizer->activeEdges().size()); ++k) { OptimizableGraph::Edge* e = _optimizer->activeEdges()[k]; e->linearizeOplus(jacobianWorkspace); // jacobian of the nodes' oplus (manifold) e->constructQuadraticForm(); # ifndef NDEBUG for (size_t i = 0; i < e->vertices().size(); ++i) { const OptimizableGraph::Vertex* v = static_cast<const OptimizableGraph::Vertex*>(e->vertex(i)); if (! v->fixed()) { bool hasANan = arrayHasNaN(jacobianWorkspace.workspaceForVertex(i), e->dimension() * v->dimension()); if (hasANan) { std::cerr << "buildSystem(): NaN within Jacobian for edge " << e << " for vertex " << i << std::endl; break; } } } # endif } // flush the current system in a sparse block matrix # ifdef G2O_OPENMP # pragma omp parallel for default (shared) if (_optimizer->indexMapping().size() > 1000) # endif for (int i = 0; i < static_cast<int>(_optimizer->indexMapping().size()); ++i) { OptimizableGraph::Vertex* v=_optimizer->indexMapping()[i]; int iBase = v->colInHessian(); if (v->marginalized()) iBase+=_sizePoses; v->copyB(_b+iBase); } return 0; }