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; }
void BaseMultiEdge<D, E>::linearizeOplus(JacobianWorkspace& jacobianWorkspace) { for (size_t i = 0; i < _vertices.size(); ++i) { OptimizableGraph::Vertex* v = static_cast<OptimizableGraph::Vertex*>(_vertices[i]); assert(v->dimension() >= 0); new (&_jacobianOplus[i]) JacobianType(jacobianWorkspace.workspaceForVertex(i), D, v->dimension()); } linearizeOplus(); }
void BaseBinaryEdge<D, E, VertexXiType, VertexXjType>::linearizeOplus(JacobianWorkspace& jacobianWorkspace) { new (&_jacobianOplusXi) JacobianXiOplusType(jacobianWorkspace.workspaceForVertex(0), D, Di); new (&_jacobianOplusXj) JacobianXjOplusType(jacobianWorkspace.workspaceForVertex(1), D, Dj); linearizeOplus(); }