41 #include "../stuff/timeutil.h" 42 #include "../stuff/macros.h" 43 #include "../stuff/misc.h" 44 #include "../../config.h" 51 _forceStopFlag(0), _verbose(false), _algorithm(0), _computeBatchStatistics(false)
65 if (actions.size() > 0) {
66 for (HyperGraphActionSet::iterator it = actions.begin(); it != actions.end(); ++it)
71 # pragma omp parallel for default (shared) if (_activeEdges.size() > 50) 73 for (
int k = 0; k < static_cast<int>(
_activeEdges.size()); ++k) {
79 for (
int k = 0; k < static_cast<int>(
_activeEdges.size()); ++k) {
83 cerr <<
"computeActiveErrors(): found NaN in error for edge " << e << endl;
121 for (HyperGraph::VertexIDMap::iterator it=
vertices().begin(); it!=
vertices().end(); ++it){
127 for (HyperGraph::VertexIDMap::iterator it=
vertices().begin(); it!=
vertices().end(); ++it){
143 for (HyperGraph::VertexIDMap::iterator it=
vertices().begin(); it!=
vertices().end(); ++it){
145 maxDim = std::max(maxDim,v->
dimension());
148 for (HyperGraph::VertexIDMap::iterator it=
vertices().begin(); it!=
vertices().end(); ++it){
156 for (HyperGraph::EdgeSet::const_iterator eit = v->
edges().begin(); eit != v->
edges().end(); ++eit) {
172 _ivMap.resize(vlist.size());
174 for (
int k=0; k<2; k++)
175 for (VertexContainer::iterator it=vlist.begin(); it!=vlist.end(); ++it){
193 for (
size_t i=0; i<
_ivMap.size(); ++i){
194 _ivMap[i]->setHessianIndex(-1);
201 for (VertexIDMap::iterator it=
vertices().begin(); it!=
vertices().end(); ++it)
202 vset.insert(it->second);
207 if (
edges().size() == 0) {
212 assert(workspaceAllocated &&
"Error while allocating memory for the Jacobians");
217 set<Edge*> auxEdgeSet;
218 for (HyperGraph::VertexSet::iterator it=vset.begin(); it!=vset.end(); ++it){
223 for (OptimizableGraph::EdgeSet::const_iterator it=vEdges.begin(); it!=vEdges.end(); ++it){
225 if (level < 0 || e->level() == level) {
227 bool allVerticesOK =
true;
228 for (vector<HyperGraph::Vertex*>::const_iterator vit = e->
vertices().begin(); vit != e->
vertices().end(); ++vit) {
229 if (vset.find(*vit) == vset.end()) {
230 allVerticesOK =
false;
235 auxEdgeSet.insert(e);
247 if (estimateDim > 0) {
248 Eigen::VectorXd estimateData(estimateDim);
251 bool hasNan =
arrayHasNaN(estimateData.data(), estimateDim, &k);
253 cerr <<
__PRETTY_FUNCTION__ <<
": Vertex " << v->
id() <<
" contains a nan entry at index " << k << endl;
262 for (set<Edge*>::iterator it = auxEdgeSet.begin(); it != auxEdgeSet.end(); ++it)
271 assert(workspaceAllocated &&
"Error while allocating memory for the Jacobians");
276 set<Vertex*> auxVertexSet;
277 for (HyperGraph::EdgeSet::iterator it=eset.begin(); it!=eset.end(); ++it){
279 for (vector<HyperGraph::Vertex*>::const_iterator vit = e->
vertices().begin(); vit != e->
vertices().end(); ++vit) {
280 auxVertexSet.insert(static_cast<OptimizableGraph::Vertex*>(*vit));
282 _activeEdges.push_back(reinterpret_cast<OptimizableGraph::Edge*>(*it));
286 for (set<Vertex*>::iterator it = auxVertexSet.begin(); it != auxVertexSet.end(); ++it)
294 for (VertexIDMap::iterator it=
vertices().begin(); it!=
vertices().end(); ++it) {
309 std::set<Vertex*> backupVertices;
313 for (
size_t i = 0; i < e->
vertices().size(); ++i) {
316 fixedVertices.insert(v);
318 for (EdgeSet::const_iterator vedgeIt = v->
edges().begin(); vedgeIt != v->
edges().end(); ++vedgeIt) {
323 fixedVertices.insert(v);
328 std::set<Vertex*>::const_iterator foundIt = backupVertices.find(v);
329 if (foundIt == backupVertices.end()) {
331 backupVertices.insert(v);
338 estimatePropagator.
propagate(fixedVertices, costFunction);
341 for (std::set<Vertex*>::iterator it = backupVertices.begin(); it != backupVertices.end(); ++it) {
347 cerr <<
"iteration= -1\t chi2= " <<
activeChi2()
350 <<
"\t (using initial guess from " << costFunction.
name() <<
")" << endl;
357 cerr <<
__PRETTY_FUNCTION__ <<
": 0 vertices to optimize, maybe forgot to call initializeOptimization()" << endl;
376 for (
int i=0; i<iterations && !
terminate() && ok; i++){
391 bool errorComputed =
false;
394 errorComputed =
true;
404 cerr <<
"iteration= " << i
406 <<
"\t time= " << dts
407 <<
"\t cumTime= " << cumTime
422 void SparseOptimizer::update(
const double*
update)
425 for (
size_t i=0; i <
_ivMap.size(); ++i) {
448 std::vector<HyperGraph::Vertex*> newVertices;
449 newVertices.reserve(vset.size());
452 for (HyperGraph::EdgeSet::iterator it = eset.begin(); it != eset.end(); ++it) {
458 size_t next =
_ivMap.size();
459 for (HyperGraph::VertexSet::iterator it = vset.begin(); it != vset.end(); ++it) {
465 newVertices.push_back(v);
518 for (VertexContainer::iterator it = vlist.begin(); it != vlist.end(); ++it)
524 for (VertexContainer::iterator it = vlist.begin(); it != vlist.end(); ++it)
530 for (HyperGraph::VertexSet::iterator it = vlist.begin(); it != vlist.end(); ++it) {
535 cerr << __FUNCTION__ <<
": FATAL PUSH SET" << endl;
541 for (HyperGraph::VertexSet::iterator it = vlist.begin(); it != vlist.end(); ++it){
546 cerr << __FUNCTION__ <<
": FATAL POP SET" << endl;
552 for (VertexContainer::iterator it = vlist.begin(); it != vlist.end(); ++it)
592 return insertResult.second;
virtual void printVerbose(std::ostream &os) const
virtual bool updateInitialization(HyperGraph::VertexSet &vset, HyperGraph::EdgeSet &eset)
virtual void computeInitialGuess()
virtual SolverResult solve(int iteration, bool online=false)=0
int id() const
returns the id
statistics about the optimization
const Vertex * vertex(size_t i) const
bool terminate()
if external stop flag is given, return its state. False otherwise
#define __PRETTY_FUNCTION__
void setHessianIndex(int ti)
set the temporary index of the vertex in the parameter blocks
int numVertices
how many vertices are involved
virtual bool getEstimateData(double *estimate) const
VertexContainer _activeVertices
sorted according to VertexIDCompare
virtual const double * errorData() const =0
returns the error vector cached after calling the computeError;
int dimension() const
returns the dimensions of the error function
virtual ~SparseOptimizer()
std::vector< Vertex * > VertexContainer
void setComputeBatchStatistics(bool computeBatchStatistics)
virtual bool updateStructure(const std::vector< HyperGraph::Vertex * > &vset, const HyperGraph::EdgeSet &edges)=0
bool removeComputeErrorAction(HyperGraphAction *action)
remove an action that should no longer be execured before computing the error vectors ...
virtual bool allVerticesFixed() const =0
std::set< Vertex * > VertexSet
virtual double chi2() const =0
computes the chi2 based on the cached error value, only valid after computeError has been called...
propagation of an initial guess
int optimize(int iterations, bool online=false)
virtual bool init(bool online=false)=0
virtual double initialEstimatePossible(const OptimizableGraph::VertexSet &from, OptimizableGraph::Vertex *to)
int hessianIndex() const
temporary index of this node in the parameter vector obtained from linearization
int iteration
which iteration
void computeActiveErrors()
virtual void setToOrigin()
virtual void postIteration(int)
called at the end of an iteration (argument is the number of the iteration)
const VertexIDMap & vertices() const
bool arrayHasNaN(const double *array, int size, int *nanIndex=0)
void update(const std::string &key, const XmlRpc::XmlRpcValue &v)
void oplus(const double *v)
std::set< Edge * > EdgeSet
virtual Vertex * findGauge()
finds a gauge in the graph to remove the undefined dof.
int dimension() const
dimension of the estimated state belonging to this node
virtual bool removeVertex(HyperGraph::Vertex *v)
virtual bool removeVertex(Vertex *v)
removes a vertex from the graph. Returns true on success (vertex was present)
const VertexContainer & vertices() const
virtual void robustify(double squaredError, Eigen::Vector3d &rho) const =0
const EdgeSet & edges() const
returns the set of hyper-edges that are leaving/entering in this vertex
void setVerbose(bool verbose)
virtual int estimateDimension() const
bool computeMarginals(SparseBlockMatrix< MatrixXd > &spinv, const std::vector< std::pair< int, int > > &blockIndices)
RobustKernel * robustKernel() const
if NOT NULL, error of this edge will be robustifed with the kernel
virtual void initialEstimate(const OptimizableGraph::VertexSet &from, OptimizableGraph::Vertex *to)=0
const EdgeSet & edges() const
virtual bool computeMarginals(SparseBlockMatrix< MatrixXd > &spinv, const std::vector< std::pair< int, int > > &blockIndices)=0
VertexContainer::const_iterator findActiveVertex(const OptimizableGraph::Vertex *v) const
void setForceStopFlag(bool *flag)
virtual void computeError()=0
void setAlgorithm(OptimizationAlgorithm *algorithm)
int numEdges
how many edges
BatchStatisticsContainer _batchStatistics
global statistics of the optimizer, e.g., timing, num-non-zeros
void push()
push all the active vertices onto a stack
void setOptimizer(SparseOptimizer *optimizer)
virtual void push()=0
backup the position of the vertex to a stack
EdgeContainer _activeEdges
sorted according to EdgeIDCompare
virtual const char * name() const
void propagate(OptimizableGraph::Vertex *v, const EstimatePropagator::PropagateCost &cost, const EstimatePropagator::PropagateAction &action=PropagateAction(), double maxDistance=std::numeric_limits< double >::max(), double maxEdgeCost=std::numeric_limits< double >::max())
cost for traversing along active edges in the optimizer
double get_monotonic_time()
virtual void clear()
clears the graph and empties all structures.
virtual void pop()=0
restore the position of the vertex by retrieving the position from the stack
order vertices based on their ID
bool buildIndexMapping(SparseOptimizer::VertexContainer &vlist)
void pop()
pop (restore) the estimate of the active vertices from the stack
void sortVectorContainers()
bool _computeBatchStatistics
bool marginalized() const
true => this node is marginalized out during the optimization
order edges based on the internal ID, which is assigned to the edge in addEdge()
A general case Vertex for optimization.
bool addComputeErrorAction(HyperGraphAction *action)
add an action to be executed before the error vectors are computed
abstract Vertex, your types must derive from that one
void setToOrigin()
sets the node to the origin (used in the multilevel stuff)
bool computeBatchStatistics() const
EdgeContainer::const_iterator findActiveEdge(const OptimizableGraph::Edge *e) const
JacobianWorkspace _jacobianWorkspace
double activeRobustChi2() const
virtual void preIteration(int)
called at the beginning of an iteration (argument is the number of the iteration) ...
bool fixed() const
true => this node is fixed during the optimization
void discardTop()
same as above, but for the active vertices
std::set< HyperGraphAction * > HyperGraphActionSet
virtual bool initializeOptimization(HyperGraph::EdgeSet &eset)
Generic interface for a non-linear solver operating on a graph.
std::vector< HyperGraphActionSet > _graphActions
bool verbose() const
verbose information during optimization
const OptimizationAlgorithm * algorithm() const
the solver used by the optimizer
Sparse matrix which uses blocks.
static void setGlobalStats(G2OBatchStatistics *b)
OptimizationAlgorithm * _algorithm
Abstract action that operates on an entire graph.
double activeChi2() const