void SparseOptimizer::update(double* update) { // update the graph by calling oplus on the vertices for (size_t i=0; i < _ivMap.size(); ++i) { OptimizableGraph::Vertex* v = _ivMap[i]; v->oplus(update); update += v->dimension(); } }
void BaseMultiEdge<D, E>::linearizeOplus() { #ifdef G2O_OPENMP for (size_t i = 0; i < _vertices.size(); ++i) { OptimizableGraph::Vertex* v = static_cast<OptimizableGraph::Vertex*>(_vertices[i]); v->lockQuadraticForm(); } #endif const double delta = 1e-9; const double scalar = 1.0 / (2*delta); ErrorVector errorBak; ErrorVector errorBeforeNumeric = _error; for (size_t i = 0; i < _vertices.size(); ++i) { //Xi - estimate the jacobian numerically OptimizableGraph::Vertex* vi = static_cast<OptimizableGraph::Vertex*>(_vertices[i]); if (vi->fixed()) continue; const int vi_dim = vi->dimension(); #ifdef _MSC_VER double* add_vi = new double[vi_dim]; #else double add_vi[vi_dim]; #endif std::fill(add_vi, add_vi + vi_dim, 0.0); if (_jacobianOplus[i].rows() != _dimension || _jacobianOplus[i].cols() != vi_dim) _jacobianOplus[i].resize(_dimension, vi_dim); // add small step along the unit vector in each dimension for (int d = 0; d < vi_dim; ++d) { vi->push(); add_vi[d] = delta; vi->oplus(add_vi); computeError(); errorBak = _error; vi->pop(); vi->push(); add_vi[d] = -delta; vi->oplus(add_vi); computeError(); errorBak -= _error; vi->pop(); add_vi[d] = 0.0; _jacobianOplus[i].col(d) = scalar * errorBak; } // end dimension #ifdef _MSC_VER delete[] add_vi; #endif } _error = errorBeforeNumeric; #ifdef G2O_OPENMP for (int i = (int)(_vertices.size()) - 1; i >= 0; --i) { OptimizableGraph::Vertex* v = static_cast<OptimizableGraph::Vertex*>(_vertices[i]); v->unlockQuadraticForm(); } #endif }