graph_optimizer_sparse.cpp
Go to the documentation of this file.
00001 // g2o - General Graph Optimization
00002 // Copyright (C) 2011 R. Kuemmerle, G. Grisetti, W. Burgard
00003 //
00004 // g2o is free software: you can redistribute it and/or modify
00005 // it under the terms of the GNU Lesser General Public License as published
00006 // by the Free Software Foundation, either version 3 of the License, or
00007 // (at your option) any later version.
00008 //
00009 // g2o is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 // GNU Lesser General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU Lesser General Public License
00015 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
00016 
00017 #include "graph_optimizer_sparse.h"
00018 
00019 #include <iostream>
00020 #include <iomanip>
00021 #include <algorithm>
00022 #include <iterator>
00023 #include <cassert>
00024 #include <algorithm>
00025 
00026 #include "estimate_propagator.h"
00027 #include "solver.h"
00028 #include "batch_stats.h"
00029 #include "g2o/stuff/timeutil.h"
00030 #include "g2o/stuff/macros.h"
00031 #include "g2o/config.h"
00032 
00033  #include <typeinfo>
00034 
00035 namespace g2o{
00036   using namespace std;
00037 
00038 
00039   SparseOptimizer::SparseOptimizer(){
00040     _method=GaussNewton;
00041     _currentLambda = -1.;
00042     _solver = 0;
00043     _forceStopFlag = 0;
00044     _tau = 1e-5;
00045     _goodStepUpperScale = 2./3.;
00046     _goodStepLowerScale = 1./3.;
00047     _userLambdaInit = 0;
00048     _statistics = 0;
00049     _maxTrialsAfterFailure = 10;
00050   }
00051 
00052 /******************************************************************************/
00053 
00054   SparseOptimizer::~SparseOptimizer(){
00055     delete _solver;
00056     delete[] _statistics;
00057   }
00058 
00059 /******************************************************************************/
00060 
00061   void SparseOptimizer::computeActiveErrors()
00062   {
00063     for (EdgeContainer::const_iterator
00064          it = _activeEdges.begin();
00065          it != _activeEdges.end();
00066          it++)
00067     {
00068       OptimizableGraph::Edge* e = *it;
00069       e->computeError();
00070       if (e->robustKernel())   e->robustifyError();
00071     }
00072   }
00073 
00074 /******************************************************************************/
00075 
00076   double SparseOptimizer::activeChi2( ) const
00077   {
00078     double chi = 0.0;
00079     for (EdgeContainer::const_iterator
00080          it = _activeEdges.begin();
00081          it != _activeEdges.end();
00082          it++)
00083     {
00084       const OptimizableGraph::Edge* e = *it;
00085       chi += e->chi2();
00086     }
00087     return chi;
00088   }
00089 
00090 /******************************************************************************/
00091 
00092   OptimizableGraph::Vertex* SparseOptimizer::findGauge(){
00093     if (vertices().empty())
00094       return 0;
00095 
00096     int maxDim=0;
00097     for (HyperGraph::VertexIDMap::iterator
00098          it  = vertices().begin();
00099          it != vertices().end();
00100          it++)
00101     {
00102       OptimizableGraph::Vertex* v =
00103          static_cast<OptimizableGraph::Vertex*>(it->second);
00104       maxDim = std::max(maxDim,v->dimension());
00105     }
00106 
00107     OptimizableGraph::Vertex* rut=0;
00108     for (HyperGraph::VertexIDMap::iterator
00109          it  = vertices().begin();
00110          it != vertices().end();
00111          it++)
00112     {
00113       OptimizableGraph::Vertex* v =
00114          static_cast<OptimizableGraph::Vertex*>(it->second);
00115       if (v->dimension()==maxDim)
00116       {
00117         rut=v;
00118         break;
00119       }
00120     }
00121     return rut;
00122   }
00123 
00124 /******************************************************************************/
00125 
00126   bool SparseOptimizer::gaugeFreedom()
00127   {
00128     if (vertices().empty())
00129       return false;
00130 
00131     int maxDim=0;
00132     for (HyperGraph::VertexIDMap::iterator
00133          it  = vertices().begin();
00134          it != vertices().end();
00135          it++)
00136     {
00137       OptimizableGraph::Vertex* v =
00138          static_cast<OptimizableGraph::Vertex*>(it->second);
00139       maxDim = std::max(maxDim,v->dimension());
00140     }
00141 
00142     for (HyperGraph::VertexIDMap::iterator
00143          it  = vertices().begin();
00144          it != vertices().end();
00145          it++)
00146     {
00147       OptimizableGraph::Vertex* v =
00148          static_cast<OptimizableGraph::Vertex*>(it->second);
00149       if (v->dimension() == maxDim)
00150       {
00151         // test for full dimension prior
00152         for (HyperGraph::EdgeSet::const_iterator
00153              eit  = v->edges().begin();
00154              eit != v->edges().end();
00155              ++eit)
00156         {
00157           OptimizableGraph::Edge* e =
00158              static_cast<OptimizableGraph::Edge*>(*eit);
00159           if (e->vertices().size() == 1 && e->dimension() == maxDim)
00160             return false;
00161         }
00162       }
00163     }
00164     return true;
00165   }
00166 
00167 /******************************************************************************/
00168 
00169   bool SparseOptimizer::buildIndexMapping
00170      (SparseOptimizer::VertexContainer& vlist)
00171   {
00172     if (! vlist.size())
00173     {
00174       _ivMap.clear();
00175       return false;
00176     }
00177 
00178     _ivMap.resize(vlist.size());
00179     size_t i = 0;
00180     // Recorre todos los vertices dandoles un indice.
00181     // Si el vertice es fijo, su indice sera -1
00182     // Para los vertices no fijos, les da un indice incremental.
00183     // Primero se les da a los vertices no marginalizables y luego a los que si.
00184     // Al final _ivMap contendra todos los vertices no fijos con los vertices
00185     // no marginalizables en las primeras posiciones de _ivMap
00186     for (int k=0; k<2; k++)
00187       for (VertexContainer::iterator it=vlist.begin(); it!=vlist.end(); it++)
00188       {
00189          OptimizableGraph::Vertex* v = *it;
00190          if (! v->fixed())
00191          {
00192             if (static_cast<int>(v->marginalized()) == k)
00193             {
00194                v->setTempIndex(i);
00195                _ivMap[i]=v;
00196                i++;
00197             }
00198          }else   v->setTempIndex(-1);
00199       }
00200 
00201     _ivMap.resize(i);
00202     return true;
00203   }
00204 
00205 /******************************************************************************/
00206 
00207   void SparseOptimizer::clearIndexMapping()
00208   {
00209     for (size_t i=0; i<_ivMap.size(); i++)
00210     {
00211       _ivMap[i]->setTempIndex(-1);
00212       _ivMap[i]=0;
00213     }
00214   }
00215 
00216 /******************************************************************************/
00217 
00218   double SparseOptimizer::computeLambdaInit()
00219   {
00220     if (_userLambdaInit>0)   return _userLambdaInit;
00221     double maxDiagonal=0.;
00222     for (size_t k = 0; k < _ivMap.size(); k++)
00223     {
00224       OptimizableGraph::Vertex* v=_ivMap[k];
00225       assert(v);
00226       int dim = v->dimension();
00227       for (int j = 0; j < dim; ++j)
00228          maxDiagonal = std::max(fabs(v->hessian(j,j)),maxDiagonal);
00229     }
00230     return _tau*maxDiagonal;
00231   }
00232 
00233 /******************************************************************************/
00234 
00235   double SparseOptimizer::computeScale(double currentLMLambda, Solver* solver)
00236   {
00237     double scale=0;
00238     for (size_t j=0; j < solver->vectorSize(); j++)
00239        scale += solver->x()[j]
00240               * (currentLMLambda * solver->x()[j] + solver->b()[j]);
00241 
00242     return scale;
00243   }
00244 
00245 /******************************************************************************/
00246 
00247   bool SparseOptimizer::initializeOptimization(int level)
00248   {
00249     HyperGraph::VertexSet vset;
00250 
00251     for (VertexIDMap::iterator
00252          it  = vertices().begin();
00253          it != vertices().end();
00254          it++)
00255        vset.insert(it->second);
00256 
00257     return initializeOptimization(vset,level);
00258   }
00259 
00260 /******************************************************************************/
00261 
00262   bool SparseOptimizer::initializeOptimization
00263      (HyperGraph::VertexSet& vset, int level)
00264   {
00265 
00266     // Recorre todos los vertices introducidos en el optimizador.
00267     // Para cada vertice 'V' obtiene los edges de los que forma parte.
00268     // Para cada uno de esos edges, se mira si todos sus vertices estan en el
00269     // optimizador. Si lo estan, el edge se aniade a _activeEdges.
00270     // Si el vertice 'V' tiene algun edge con todos los demas vertices en el
00271     // optimizador, se aniade 'V' a _activeVertices
00272 
00273     // Al final se asignan unos indices internos para los vertices:
00274     // -1: vertices fijos
00275     // 0..n: vertices no fijos y NO marginalizables
00276     // n+1..m: vertices no fijos y marginalizables
00277     clearIndexMapping();
00278     _activeVertices.clear();
00279     _activeVertices.reserve(vset.size());
00280     _activeEdges.clear();
00281 
00282     set<Edge*> auxEdgeSet; // temporary structure to avoid duplicates
00283 
00284     for (HyperGraph::VertexSet::iterator
00285          it  = vset.begin();
00286          it != vset.end();
00287          it++)
00288     {
00289       OptimizableGraph::Vertex* v= (OptimizableGraph::Vertex*) *it;
00290       const OptimizableGraph::EdgeSet& vEdges=v->edges();
00291       // count if there are edges in that level. If not remove from the pool
00292       int levelEdges=0;
00293       for (OptimizableGraph::EdgeSet::const_iterator
00294            it  = vEdges.begin();
00295            it != vEdges.end();
00296            it++)
00297       {
00298         OptimizableGraph::Edge* e =
00299            reinterpret_cast<OptimizableGraph::Edge*>(*it);
00300         if (level < 0 || e->level() == level)
00301         {
00302           bool allVerticesOK = true;
00303           for (vector<HyperGraph::Vertex*>::const_iterator
00304                vit  = e->vertices().begin();
00305                vit != e->vertices().end();
00306                ++vit)
00307           {
00308             if (vset.find(*vit) == vset.end())
00309             {
00310               allVerticesOK = false;
00311               break;
00312             }
00313           }
00314 
00315           if (allVerticesOK)
00316           {
00317             auxEdgeSet.insert(reinterpret_cast<OptimizableGraph::Edge*>(*it));
00318             levelEdges++;
00319           }
00320         }
00321       }
00322       if (levelEdges)   _activeVertices.push_back(v);
00323     }
00324 
00325     _activeEdges.reserve(auxEdgeSet.size());
00326     for (set<Edge*>::iterator
00327          it = auxEdgeSet.begin();
00328          it != auxEdgeSet.end();
00329          ++it)
00330        _activeEdges.push_back(*it);
00331 
00332     sortVectorContainers();
00333     return buildIndexMapping(_activeVertices);
00334   }
00335 
00336 /******************************************************************************/
00337 
00338   bool SparseOptimizer::initializeOptimization(HyperGraph::EdgeSet& eset)
00339   {
00340     clearIndexMapping();
00341     _activeVertices.clear();
00342     _activeEdges.clear();
00343     _activeEdges.reserve(eset.size());
00344     set<Vertex*> auxVertexSet; // temporary structure to avoid duplicates
00345     for (HyperGraph::EdgeSet::iterator
00346          it  = eset.begin();
00347          it != eset.end();
00348          it++)
00349     {
00350       OptimizableGraph::Edge* e=(OptimizableGraph::Edge*)(*it);
00351       for (vector<HyperGraph::Vertex*>::const_iterator
00352            vit  = e->vertices().begin();
00353            vit != e->vertices().end();
00354            ++vit)
00355          auxVertexSet.insert(static_cast<OptimizableGraph::Vertex*>(*vit));
00356 
00357       _activeEdges.push_back(reinterpret_cast<OptimizableGraph::Edge*>(*it));
00358     }
00359 
00360     _activeVertices.reserve(auxVertexSet.size());
00361     for (set<Vertex*>::iterator
00362          it  = auxVertexSet.begin();
00363          it != auxVertexSet.end();
00364          ++it)
00365        _activeVertices.push_back(*it);
00366 
00367     sortVectorContainers();
00368     return buildIndexMapping(_activeVertices);
00369   }
00370 
00371 /******************************************************************************/
00372 
00373   void SparseOptimizer::computeInitialGuess()
00374   {
00375     OptimizableGraph::VertexSet emptySet;
00376     std::set<Vertex*> backupVertices;
00377     // these are the root nodes where to start the initialization
00378     HyperGraph::VertexSet fixedVertices;
00379     for (EdgeContainer::iterator
00380          it  = _activeEdges.begin();
00381          it != _activeEdges.end();
00382          ++it)
00383     {
00384       OptimizableGraph::Edge* e = *it;
00385       for (size_t i = 0; i < e->vertices().size(); ++i)
00386       {
00387         OptimizableGraph::Vertex* v =
00388            static_cast<OptimizableGraph::Vertex*>(e->vertices()[i]);
00389 
00390         if (v->fixed())   fixedVertices.insert(v);
00391         else
00392         {
00393           // check for having a prior which is able to fully initialize a vertex
00394           for (EdgeSet::const_iterator
00395                vedgeIt  = v->edges().begin();
00396                vedgeIt != v->edges().end();
00397                ++vedgeIt)
00398           {
00399             OptimizableGraph::Edge* vedge =
00400                static_cast<OptimizableGraph::Edge*>(*vedgeIt);
00401             if ( vedge->vertices().size() == 1
00402               && vedge->initialEstimatePossible(emptySet, v) > 0.)
00403             {
00404               //cerr << "Initialize with prior for " << v->id() << endl;
00405               vedge->initialEstimate(emptySet, v);
00406               fixedVertices.insert(v);
00407             }
00408           }
00409         }
00410 
00411         if (v->tempIndex() == -1)
00412         {
00413           std::set<Vertex*>::const_iterator foundIt = backupVertices.find(v);
00414           if (foundIt == backupVertices.end()) {
00415             v->push();
00416             backupVertices.insert(v);
00417           }
00418         }
00419       }
00420     }
00421 
00422     EstimatePropagator estimatePropagator(this);
00423     EstimatePropagator::PropagateCost costFunction(this);
00424     estimatePropagator.propagate(fixedVertices, costFunction);
00425 
00426     // restoring the vertices that should not be initialized
00427     for (std::set<Vertex*>::iterator
00428          it  = backupVertices.begin();
00429          it != backupVertices.end();
00430          ++it)
00431     {
00432       Vertex* v = *it;
00433       v->pop();
00434     }
00435     if (verbose())
00436     {
00437       computeActiveErrors();
00438       cerr << "iteration= -1\t chi2= " << activeChi2()
00439           << "\t time= 0.0"
00440           << "\t cumTime= 0.0"
00441           << "\t (using initial guess from spanning tree)" << endl;
00442     }
00443   }
00444 
00445 /******************************************************************************/
00446 
00447   int SparseOptimizer::optimize(int iterations, bool online)
00448   {
00449     // Si existe algun vertice marginalizable => se puede usar Schur
00450     bool useSchur=false;
00451     for (VertexContainer::iterator
00452          it  = _activeVertices.begin();
00453          it != _activeVertices.end();
00454          it++)
00455     {
00456       OptimizableGraph::Vertex* v= *it;
00457       if (v->marginalized())
00458       {
00459         useSchur=true;
00460         break;
00461       }
00462     }
00463 
00464     // Si el resolvedor soporta Schur y se puede usar => se activa Schur
00465     double t;
00466     Solver* solver = _solver;
00467     if (useSchur){
00468       if  (_solver->supportsSchur())
00469         _solver->setSchur(true);
00470     } else {
00471       if  (_solver->supportsSchur())
00472         _solver->setSchur(false);
00473     }
00474 
00475 
00476     solver->init(online);
00477     solver->setLevenberg(_method == LevenbergMarquardt);
00478 
00479     int cjIterations=0;
00480     double cumTime=0;
00481     double currentChi=0;
00482     double tempChi=0;
00483     if (_method == LevenbergMarquardt)
00484     {
00485       // Calcula el error de cada edge seleccionado en initializaOptimization
00486       computeActiveErrors();
00487       // Calcula la chi2 con la chi2 cada edge seleccionado
00488       currentChi = activeChi2();
00489       tempChi = currentChi;
00490     }
00491     bool ok=true;
00492 
00493     double ni=2.;
00494     //double currentLMLambda=1.;
00495 
00496     // METODO ITERATIVO ::: OPTIMIZACION
00497     for (int i=0; i<iterations && ! terminate() && ok; i++)
00498     {
00499       preIteration(i);
00500 
00501       G2OBatchStatistics* cstat = _statistics ? &(_statistics[i]) : 0;
00502       globalStats = cstat;
00503       if (cstat)
00504       {
00505         cstat->iteration = i;
00506         cstat->numEdges =  _activeEdges.size();
00507         cstat->numVertices = _activeVertices.size();
00508       }
00509 
00510 
00511       // Construccion del sistema: Matrices Hessianas, de Schur, ...
00512       // Solo se hace para la primera iteracion
00513       double ts = get_time();
00514       if (i == 0 && !online)
00515       { // built up the CCS structure, here due to easy time measure
00516         ok = solver->buildStructure();
00517         if (! ok)
00518         {
00519           cerr << __PRETTY_FUNCTION__
00520                << ": Failure while building CCS structure\n";
00521           return 0;
00522         }
00523       }
00524 
00525 
00526       // Calculo de los errores de los edges seleccionados
00527       t = get_time();
00528       computeActiveErrors();
00529       if (cstat)   cstat->timeResiduals = get_time() - t;
00530 
00531       // Linearizacion del sistema: Calculo de los jacobianos para cada edge
00532       // e->linealizeOPlus()
00533       t = get_time();
00534       linearizeSystem();
00535       if (cstat)   cstat->timeLinearize = get_time()-t;
00536 
00537 
00538 
00539       // Construccion del sistema: Calculo de la Hessiana y de -b
00540       t = get_time();
00541       solver->buildSystem();
00542       if (cstat)   cstat->timeQuadraticForm = get_time()-t;
00543 
00544 
00545       // Resolucion del sistema:   H * x = -b
00546       if (_method == GaussNewton)
00547       {
00548         t = get_time();
00549         ok = solver->solve();
00550         if (cstat)   cstat->timeLinearSolution = get_time()-t;
00551 
00552         t = get_time();
00553         update(solver->x());
00554         if (cstat)   cstat->timeUpdate = get_time()-t;
00555 
00556       } else if (_method == LevenbergMarquardt)
00557       {
00558         if (i==0)   _currentLambda = computeLambdaInit();
00559 
00560         double rho = 0;
00561         int qmax = 0;
00562         do
00563         { // Metodo de LM
00564           push(_activeVertices);
00565           if (cstat)   cstat->levenbergIterations++;
00566 
00567 
00568           // H = H + lambda * I
00569           // update the diagonal of the system matrix
00570           t = get_time();
00571           solver->setLambda(_currentLambda);
00572 
00573 
00574           // Resolucion del sistema
00575           bool ok2 = solver->solve();
00576           if (cstat)   cstat->timeLinearSolution+=get_time()-t;
00577 
00578 
00579           // Actualizacion del estado de los vertices no fijos
00580           // v->oplus(update);
00581           // vertice = vertice + x, x = incremento
00582           t = get_time();
00583           update(solver->x());
00584           if (cstat)   cstat->timeUpdate = get_time()-t;
00585 
00586 
00587           // H = H - lambda * I
00588           // restore the diagonal
00589           solver->setLambda(- _currentLambda);
00590 
00591 
00592           // Calculo de los nuevo errores y obtencion de la nueva chi
00593           t = get_time();
00594           computeActiveErrors();
00595           tempChi = activeChi2();
00596 
00597 
00598 
00599           // Calculo del factor de dampering
00600           if (! ok2)   tempChi = std::numeric_limits<double>::max();
00601 
00602           rho = (currentChi-tempChi);
00603           double scale = computeScale(_currentLambda, solver);
00604           scale += 1e-3;
00605           rho /=  scale ;
00606 
00607           if (rho > 0)
00608           { // last step was good
00609             double alpha = 1.-pow((2*rho-1),3);
00610 
00611             // crop lambda between minimum and maximum factors
00612             alpha = std::min(alpha, _goodStepUpperScale);
00613             double scaleFactor = std::max(_goodStepLowerScale, alpha);
00614 
00615             _currentLambda *= scaleFactor;
00616 
00617             ni = 2;
00618             currentChi = tempChi;
00619             t = get_time();
00620             discardTop(_activeVertices);
00621           } else
00622           {
00623             _currentLambda *= ni;
00624             ni *= 2;
00625             t = get_time();
00626             // restore the last state before trying to optimize
00627             pop(_activeVertices);
00628           }
00629           qmax++;
00630         } while (rho < 0 && qmax < _maxTrialsAfterFailure && ! terminate());
00631 
00632         if (qmax == _maxTrialsAfterFailure || fabs(rho) < 1e-15 /*rho == 0*/)
00633            i = iterations;
00634       } // end LevenbergMarquardt
00635 
00636 
00637       bool errorComputed = false;
00638       if (cstat)
00639       {
00640         computeActiveErrors();
00641         errorComputed = true;
00642         cstat->chi2 = activeChi2();
00643         cstat->timeIteration = get_time()-ts;
00644       }
00645 
00646       double dts = get_time()-ts;
00647       cumTime += dts;
00648       if (verbose())
00649       {
00650         if (! errorComputed)   computeActiveErrors();
00651         cerr << "iteration= " << i
00652              << "\t chi2= " << FIXED(activeChi2())
00653              << "\t time= " << dts
00654              << "\t cumTime= " << cumTime
00655              << "\t lambda= " << FIXED(_currentLambda)
00656              << "\t edges= " << _activeEdges.size()
00657              << "\t schur= " << useSchur  << endl;
00658       }
00659       ++cjIterations;
00660       postIteration(i);
00661     } // Fin de la iteracion
00662 
00663     if (! ok)   return 0;
00664     return cjIterations;
00665   }
00666 
00667 /******************************************************************************/
00668 
00669   void SparseOptimizer::linearizeSystem()
00670   {
00671 #   ifdef G2O_OPENMP
00672 #   pragma omp parallel for default (shared) if (_activeEdges.size() > 50)
00673 #   endif
00674     for (size_t k = 0; k < _activeEdges.size(); ++k)
00675     {
00676       OptimizableGraph::Edge* e = _activeEdges[k];
00677       // jacobian of the nodes' oplus (manifold)
00678       e->linearizeOplus();
00679     }
00680   }
00681 
00682 /******************************************************************************/
00683 
00684   void SparseOptimizer::update(double* update)
00685   {
00686     // update the graph by calling oplus on the vertices
00687     for (size_t i=0; i < _ivMap.size(); ++i)
00688     {
00689       OptimizableGraph::Vertex* v = _ivMap[i];
00690       v->oplus(update);
00691       update += v->dimension();
00692     }
00693   }
00694 
00695 /******************************************************************************/
00696 
00697   bool SparseOptimizer::updateInitialization(HyperGraph::VertexSet& vset, HyperGraph::EdgeSet& eset)
00698   {
00699     std::vector<HyperGraph::Vertex*> newVertices;
00700     newVertices.reserve(vset.size());
00701     _activeVertices.reserve(_activeVertices.size() + vset.size());
00702     //for (HyperGraph::VertexSet::iterator it = vset.begin(); it != vset.end(); ++it)
00703       //_activeVertices.push_back(static_cast<OptimizableGraph::Vertex*>(*it));
00704     _activeEdges.reserve(_activeEdges.size() + eset.size());
00705     for (HyperGraph::EdgeSet::iterator it = eset.begin(); it != eset.end(); ++it)
00706       _activeEdges.push_back(static_cast<OptimizableGraph::Edge*>(*it));
00707 
00708     // update the index mapping
00709     size_t next = _ivMap.size();
00710     for (HyperGraph::VertexSet::iterator it = vset.begin(); it != vset.end(); ++it) {
00711       OptimizableGraph::Vertex* v=static_cast<OptimizableGraph::Vertex*>(*it);
00712       if (! v->fixed()){
00713         if (! v->marginalized()){
00714           v->setTempIndex(next);
00715           _ivMap.push_back(v);
00716           newVertices.push_back(v);
00717           _activeVertices.push_back(v);
00718           next++;
00719         }
00720         else // not supported right now
00721           abort();
00722       }
00723       else {
00724         v->setTempIndex(-1);
00725       }
00726     }
00727 
00728     //if (newVertices.size() != vset.size())
00729     //cerr << __PRETTY_FUNCTION__ << ": something went wrong " << PVAR(vset.size()) << " " << PVAR(newVertices.size()) << endl;
00730     return _solver->updateStructure(newVertices, eset);
00731   }
00732 
00733 /******************************************************************************/
00734 
00735   void SparseOptimizer::sortVectorContainers()
00736   {
00737     // sort vector structures to get deterministic ordering based on IDs
00738     sort(_activeVertices.begin(), _activeVertices.end(), VertexIDCompare());
00739     sort(_activeEdges.begin(), _activeEdges.end(), EdgeIDCompare());
00740   }
00741 
00742 /******************************************************************************/
00743 
00744   void SparseOptimizer::clear() {
00745     _ivMap.clear();
00746     _activeVertices.clear();
00747     _activeEdges.clear();
00748     HyperGraph::clear();
00749   }
00750 
00751 /******************************************************************************/
00752 
00753   SparseOptimizer::VertexContainer::const_iterator SparseOptimizer::findActiveVertex(OptimizableGraph::Vertex* v) const
00754   {
00755     VertexContainer::const_iterator lower = lower_bound(_activeVertices.begin(), _activeVertices.end(), v, VertexIDCompare());
00756     if (lower == _activeVertices.end())
00757       return _activeVertices.end();
00758     if ((*lower) == v)
00759       return lower;
00760     return _activeVertices.end();
00761   }
00762 
00763 /******************************************************************************/
00764 
00765   SparseOptimizer::EdgeContainer::const_iterator SparseOptimizer::findActiveEdge(OptimizableGraph::Edge* e) const
00766   {
00767     EdgeContainer::const_iterator lower = lower_bound(_activeEdges.begin(), _activeEdges.end(), e, EdgeIDCompare());
00768     if (lower == _activeEdges.end())
00769       return _activeEdges.end();
00770     if ((*lower) == e)
00771       return lower;
00772     return _activeEdges.end();
00773   }
00774 
00775 /******************************************************************************/
00776 
00777   void SparseOptimizer::push(SparseOptimizer::VertexContainer& vlist)
00778   {
00779     for (VertexContainer::iterator it = vlist.begin(); it != vlist.end(); ++it)
00780       (*it)->push();
00781   }
00782 
00783 /******************************************************************************/
00784 
00785   void SparseOptimizer::pop(SparseOptimizer::VertexContainer& vlist)
00786   {
00787     for (VertexContainer::iterator it = vlist.begin(); it != vlist.end(); ++it)
00788       (*it)->pop();
00789   }
00790 
00791 /******************************************************************************/
00792 
00793   void SparseOptimizer::push(HyperGraph::VertexSet& vlist)
00794   {
00795     for (HyperGraph::VertexSet::iterator
00796          it  = vlist.begin();
00797          it != vlist.end();
00798          ++it)
00799     {
00800       OptimizableGraph::Vertex* v = dynamic_cast<OptimizableGraph::Vertex*>(*it);
00801       if (v)   v->push();
00802       else       cerr << "FATAL PUSH SET" << endl;
00803     }
00804   }
00805 
00806 /******************************************************************************/
00807 
00808   void SparseOptimizer::pop(HyperGraph::VertexSet& vlist)
00809   {
00810     for (HyperGraph::VertexSet::iterator it = vlist.begin(); it != vlist.end(); ++it){
00811       OptimizableGraph::Vertex* v = dynamic_cast<OptimizableGraph::Vertex*> (*it);
00812       if (v)
00813         v->pop();
00814       else
00815         cerr << "FATAL POP SET" << endl;
00816     }
00817   }
00818 
00819 /******************************************************************************/
00820 
00821   void SparseOptimizer::discardTop(SparseOptimizer::VertexContainer& vlist)
00822   {
00823     for (VertexContainer::iterator it = vlist.begin(); it != vlist.end(); ++it)
00824       (*it)->discardTop();
00825   }
00826 
00827 /******************************************************************************/
00828   void SparseOptimizer::setVerbose(bool verbose)
00829   {
00830     _verbose = verbose;
00831   }
00832 
00833 /******************************************************************************/
00834 
00835   void SparseOptimizer::setMethod(SparseOptimizer::Method method)
00836   {
00837     _method = method;
00838   }
00839 
00840 /******************************************************************************/
00841 
00842   void SparseOptimizer::setSolver(Solver* solver)
00843   {
00844     _solver = solver;
00845   }
00846 
00847 /******************************************************************************/
00848 
00849   void SparseOptimizer::setUserLambdaInit(double lambda)
00850   {
00851     _userLambdaInit = lambda;
00852   }
00853 
00854 /******************************************************************************/
00855 
00856   bool SparseOptimizer::computeMarginals()
00857   {
00858     return _solver->computeMarginals();
00859   }
00860 
00861 /******************************************************************************/
00862 
00863   bool SparseOptimizer::computeMarginals(SparseBlockMatrix<MatrixXd>& spinv, const std::vector<std::pair<int, int> >& blockIndices){
00864     return _solver->computeMarginals(spinv, blockIndices);
00865   }
00866 
00867 /******************************************************************************/
00868 
00869   void SparseOptimizer::setMaxTrialsAfterFailure(int max_trials)
00870   {
00871     _maxTrialsAfterFailure = max_trials;
00872   }
00873 
00874 /******************************************************************************/
00875 
00876   void SparseOptimizer::setForceStopFlag(bool* flag)
00877   {
00878     _forceStopFlag=flag;
00879   }
00880 
00881 /******************************************************************************/
00882 
00883   bool SparseOptimizer::removeVertex(Vertex* v)
00884   {
00885     if (v->tempIndex() >= 0) {
00886       clearIndexMapping();
00887       _ivMap.clear();
00888     }
00889     return HyperGraph::removeVertex(v);
00890   }
00891 
00892 } // end namespace


re_vision
Author(s): Dorian Galvez-Lopez
autogenerated on Sun Jan 5 2014 11:31:16