g2o
Public Member Functions | Protected Member Functions | Protected Attributes | List of all members
g2o::OptimizationAlgorithmLevenberg Class Reference

Implementation of the Levenberg Algorithm. More...

#include <optimization_algorithm_levenberg.h>

Inheritance diagram for g2o::OptimizationAlgorithmLevenberg:
Inheritance graph
[legend]
Collaboration diagram for g2o::OptimizationAlgorithmLevenberg:
Collaboration graph
[legend]

Public Member Functions

 OptimizationAlgorithmLevenberg (Solver *solver)
 
virtual ~OptimizationAlgorithmLevenberg ()
 
virtual SolverResult solve (int iteration, bool online=false)
 
virtual void printVerbose (std::ostream &os) const
 
double currentLambda () const
 return the currently used damping factor More...
 
void setMaxTrialsAfterFailure (int max_trials)
 the number of internal iteration if an update step increases chi^2 within Levenberg-Marquardt More...
 
int maxTrialsAfterFailure () const
 get the number of inner iterations for Levenberg-Marquardt More...
 
double userLambdaInit ()
 return the lambda set by the user, if < 0 the SparseOptimizer will compute the initial lambda More...
 
void setUserLambdaInit (double lambda)
 specify the initial lambda used for the first iteraion, if not given the SparseOptimizer tries to compute a suitable value More...
 
int levenbergIteration ()
 return the number of levenberg iterations performed in the last round More...
 
- Public Member Functions inherited from g2o::OptimizationAlgorithmWithHessian
 OptimizationAlgorithmWithHessian (Solver *solver)
 
virtual ~OptimizationAlgorithmWithHessian ()
 
virtual bool init (bool online=false)
 
virtual bool computeMarginals (SparseBlockMatrix< MatrixXD > &spinv, const std::vector< std::pair< int, int > > &blockIndices)
 
virtual bool buildLinearStructure ()
 
virtual void updateLinearSystem ()
 
virtual bool updateStructure (const std::vector< HyperGraph::Vertex * > &vset, const HyperGraph::EdgeSet &edges)
 
Solversolver ()
 return the underlying solver used to solve the linear system More...
 
virtual void setWriteDebug (bool writeDebug)
 
virtual bool writeDebug () const
 
- Public Member Functions inherited from g2o::OptimizationAlgorithm
 OptimizationAlgorithm ()
 
virtual ~OptimizationAlgorithm ()
 
const SparseOptimizeroptimizer () const
 return the optimizer operating on More...
 
SparseOptimizeroptimizer ()
 
void setOptimizer (SparseOptimizer *optimizer)
 
const PropertyMapproperties () const
 return the properties of the solver More...
 
bool updatePropertiesFromString (const std::string &propString)
 
void printProperties (std::ostream &os) const
 

Protected Member Functions

double computeLambdaInit () const
 
double computeScale () const
 

Protected Attributes

Property< int > * _maxTrialsAfterFailure
 
Property< double > * _userLambdaInit
 
double _currentLambda
 
double _tau
 
double _goodStepLowerScale
 lower bound for lambda decrease if a good LM step More...
 
double _goodStepUpperScale
 upper bound for lambda decrease if a good LM step More...
 
double _ni
 
int _levenbergIterations
 the numer of levenberg iterations performed to accept the last step More...
 
- Protected Attributes inherited from g2o::OptimizationAlgorithmWithHessian
Solver_solver
 
Property< bool > * _writeDebug
 
- Protected Attributes inherited from g2o::OptimizationAlgorithm
SparseOptimizer_optimizer
 the optimizer the solver is working on More...
 
PropertyMap _properties
 the properties of your solver, use this to store the parameters of your solver More...
 

Detailed Description

Implementation of the Levenberg Algorithm.

Definition at line 38 of file optimization_algorithm_levenberg.h.

Constructor & Destructor Documentation

g2o::OptimizationAlgorithmLevenberg::OptimizationAlgorithmLevenberg ( Solver solver)
explicit

construct the Levenberg algorithm, which will use the given Solver for solving the linearized system.

Definition at line 40 of file optimization_algorithm_levenberg.cpp.

References _currentLambda, _goodStepLowerScale, _goodStepUpperScale, _levenbergIterations, _maxTrialsAfterFailure, _ni, g2o::OptimizationAlgorithm::_properties, _tau, _userLambdaInit, and g2o::PropertyMap::makeProperty().

40  :
42  {
43  _currentLambda = -1.;
44  _tau = 1e-5;
45  _goodStepUpperScale = 2./3.;
46  _goodStepLowerScale = 1./3.;
47  _userLambdaInit = _properties.makeProperty<Property<double> >("initialLambda", 0.);
48  _maxTrialsAfterFailure = _properties.makeProperty<Property<int> >("maxTrialsAfterFailure", 10);
49  _ni=2.;
51  }
double _goodStepLowerScale
lower bound for lambda decrease if a good LM step
double _goodStepUpperScale
upper bound for lambda decrease if a good LM step
int _levenbergIterations
the numer of levenberg iterations performed to accept the last step
Solver * solver()
return the underlying solver used to solve the linear system
PropertyMap _properties
the properties of your solver, use this to store the parameters of your solver
P * makeProperty(const std::string &name_, const typename P::ValueType &v)
Definition: property.h:119
g2o::OptimizationAlgorithmLevenberg::~OptimizationAlgorithmLevenberg ( )
virtual

Definition at line 53 of file optimization_algorithm_levenberg.cpp.

54  {
55  }

Member Function Documentation

double g2o::OptimizationAlgorithmLevenberg::computeLambdaInit ( ) const
protected

helper for Levenberg, this function computes the initial damping factor, if the user did not specify an own value, see setUserLambdaInit()

Definition at line 149 of file optimization_algorithm_levenberg.cpp.

References g2o::OptimizationAlgorithm::_optimizer, _tau, _userLambdaInit, g2o::OptimizableGraph::Vertex::dimension(), g2o::OptimizableGraph::Vertex::hessian(), g2o::SparseOptimizer::indexMapping(), and g2o::Property< T >::value().

Referenced by solve().

150  {
151  if (_userLambdaInit->value() > 0)
152  return _userLambdaInit->value();
153  double maxDiagonal=0.;
154  for (size_t k = 0; k < _optimizer->indexMapping().size(); k++) {
156  assert(v);
157  int dim = v->dimension();
158  for (int j = 0; j < dim; ++j){
159  maxDiagonal = std::max(fabs(v->hessian(j,j)),maxDiagonal);
160  }
161  }
162  return _tau*maxDiagonal;
163  }
class G2O_CORE_API Vertex
SparseOptimizer * _optimizer
the optimizer the solver is working on
const VertexContainer & indexMapping() const
the index mapping of the vertices
const T & value() const
Definition: property.h:57
double g2o::OptimizationAlgorithmLevenberg::computeScale ( ) const
protected

Definition at line 165 of file optimization_algorithm_levenberg.cpp.

References _currentLambda, g2o::OptimizationAlgorithmWithHessian::_solver, g2o::Solver::b(), g2o::Solver::vectorSize(), and g2o::Solver::x().

Referenced by solve().

166  {
167  double scale = 0.;
168  for (size_t j=0; j < _solver->vectorSize(); j++){
169  scale += _solver->x()[j] * (_currentLambda * _solver->x()[j] + _solver->b()[j]);
170  }
171  return scale;
172  }
double * x()
return x, the solution vector
Definition: solver.h:96
double * b()
return b, the right hand side of the system
Definition: solver.h:99
size_t vectorSize() const
return the size of the solution vector (x) and b
Definition: solver.h:103
double g2o::OptimizationAlgorithmLevenberg::currentLambda ( ) const
inline

return the currently used damping factor

Definition at line 53 of file optimization_algorithm_levenberg.h.

int g2o::OptimizationAlgorithmLevenberg::levenbergIteration ( )
inline

return the number of levenberg iterations performed in the last round

Definition at line 67 of file optimization_algorithm_levenberg.h.

67 { return _levenbergIterations;}
int _levenbergIterations
the numer of levenberg iterations performed to accept the last step
int g2o::OptimizationAlgorithmLevenberg::maxTrialsAfterFailure ( ) const
inline

get the number of inner iterations for Levenberg-Marquardt

Definition at line 59 of file optimization_algorithm_levenberg.h.

59 { return _maxTrialsAfterFailure->value();}
const T & value() const
Definition: property.h:57
void g2o::OptimizationAlgorithmLevenberg::printVerbose ( std::ostream &  os) const
virtual

called by the optimizer if verbose. re-implement, if you want to print something

Reimplemented from g2o::OptimizationAlgorithm.

Definition at line 184 of file optimization_algorithm_levenberg.cpp.

References _currentLambda, _levenbergIterations, g2o::OptimizationAlgorithmWithHessian::_solver, and g2o::Solver::schur().

185  {
186  os
187  << "\t schur= " << _solver->schur()
188  << "\t lambda= " << FIXED(_currentLambda)
189  << "\t levenbergIter= " << _levenbergIterations;
190  }
virtual bool schur()=0
should the solver perform the schur complement or not
int _levenbergIterations
the numer of levenberg iterations performed to accept the last step
void g2o::OptimizationAlgorithmLevenberg::setMaxTrialsAfterFailure ( int  max_trials)

the number of internal iteration if an update step increases chi^2 within Levenberg-Marquardt

Definition at line 174 of file optimization_algorithm_levenberg.cpp.

References _maxTrialsAfterFailure, and g2o::Property< T >::setValue().

175  {
176  _maxTrialsAfterFailure->setValue(max_trials);
177  }
void setValue(const T &v)
Definition: property.h:56
void g2o::OptimizationAlgorithmLevenberg::setUserLambdaInit ( double  lambda)

specify the initial lambda used for the first iteraion, if not given the SparseOptimizer tries to compute a suitable value

Definition at line 179 of file optimization_algorithm_levenberg.cpp.

References _userLambdaInit, and g2o::Property< T >::setValue().

180  {
181  _userLambdaInit->setValue(lambda);
182  }
void setValue(const T &v)
Definition: property.h:56
OptimizationAlgorithm::SolverResult g2o::OptimizationAlgorithmLevenberg::solve ( int  iteration,
bool  online = false 
)
virtual

Solve one iteration. The SparseOptimizer running on-top will call this for the given number of iterations.

Parameters
iterationindicates the current iteration

Implements g2o::OptimizationAlgorithm.

Definition at line 57 of file optimization_algorithm_levenberg.cpp.

References __PRETTY_FUNCTION__, _currentLambda, _goodStepLowerScale, _goodStepUpperScale, _levenbergIterations, _maxTrialsAfterFailure, _ni, g2o::OptimizationAlgorithm::_optimizer, g2o::OptimizationAlgorithmWithHessian::_solver, g2o::SparseOptimizer::activeRobustChi2(), g2o::Solver::buildStructure(), g2o::Solver::buildSystem(), g2o::SparseOptimizer::computeActiveErrors(), computeLambdaInit(), computeScale(), g2o::SparseOptimizer::discardTop(), g2o_isfinite, g2o::get_monotonic_time(), g2o::G2OBatchStatistics::globalStats(), g2o::G2OBatchStatistics::levenbergIterations, OK, g2o::Solver::optimizer(), g2o::SparseOptimizer::pop(), g2o::SparseOptimizer::push(), g2o::Solver::restoreDiagonal(), g2o::Solver::setLambda(), g2o::Solver::solve(), Terminate, g2o::SparseOptimizer::terminate(), g2o::G2OBatchStatistics::timeLinearSolution, g2o::G2OBatchStatistics::timeQuadraticForm, g2o::G2OBatchStatistics::timeResiduals, g2o::G2OBatchStatistics::timeUpdate, g2o::Property< T >::value(), and g2o::Solver::x().

58  {
59  assert(_optimizer && "_optimizer not set");
60  assert(_solver->optimizer() == _optimizer && "underlying linear solver operates on different graph");
61 
62  if (iteration == 0 && !online) { // built up the CCS structure, here due to easy time measure
63  bool ok = _solver->buildStructure();
64  if (! ok) {
65  cerr << __PRETTY_FUNCTION__ << ": Failure while building CCS structure" << endl;
66  return OptimizationAlgorithm::Fail;
67  }
68  }
69 
70  double t=get_monotonic_time();
72  G2OBatchStatistics* globalStats = G2OBatchStatistics::globalStats();
73  if (globalStats) {
74  globalStats->timeResiduals = get_monotonic_time()-t;
76  }
77 
78  double currentChi = _optimizer->activeRobustChi2();
79  double tempChi=currentChi;
80 
82  if (globalStats) {
83  globalStats->timeQuadraticForm = get_monotonic_time()-t;
84  }
85 
86  // core part of the Levenbarg algorithm
87  if (iteration == 0) {
89  _ni = 2;
90  }
91 
92  double rho=0;
93  int& qmax = _levenbergIterations;
94  qmax = 0;
95  do {
96  _optimizer->push();
97  if (globalStats) {
98  globalStats->levenbergIterations++;
100  }
101  // update the diagonal of the system matrix
103  bool ok2 = _solver->solve();
104  if (globalStats) {
105  globalStats->timeLinearSolution+=get_monotonic_time()-t;
106  t=get_monotonic_time();
107  }
108  _optimizer->update(_solver->x());
109  if (globalStats) {
110  globalStats->timeUpdate = get_monotonic_time()-t;
111  }
112 
113  // restore the diagonal
115 
117  tempChi = _optimizer->activeRobustChi2();
118 
119  if (! ok2)
120  tempChi=std::numeric_limits<double>::max();
121 
122  rho = (currentChi-tempChi);
123  double scale = computeScale();
124  scale += 1e-3; // make sure it's non-zero :)
125  rho /= scale;
126 
127  if (rho>0 && g2o_isfinite(tempChi)){ // last step was good
128  double alpha = 1.-pow((2*rho-1),3);
129  // crop lambda between minimum and maximum factors
130  alpha = (std::min)(alpha, _goodStepUpperScale);
131  double scaleFactor = (std::max)(_goodStepLowerScale, alpha);
132  _currentLambda *= scaleFactor;
133  _ni = 2;
134  currentChi=tempChi;
136  } else {
138  _ni*=2;
139  _optimizer->pop(); // restore the last state before trying to optimize
140  }
141  qmax++;
142  } while (rho<0 && qmax < _maxTrialsAfterFailure->value() && ! _optimizer->terminate());
143 
144  if (qmax == _maxTrialsAfterFailure->value() || rho==0)
145  return Terminate;
146  return OK;
147  }
double get_monotonic_time()
Definition: timeutil.cpp:113
virtual void restoreDiagonal()=0
bool terminate()
if external stop flag is given, return its state. False otherwise
#define __PRETTY_FUNCTION__
Definition: macros.h:89
double _goodStepLowerScale
lower bound for lambda decrease if a good LM step
double _goodStepUpperScale
upper bound for lambda decrease if a good LM step
int _levenbergIterations
the numer of levenberg iterations performed to accept the last step
void pop(SparseOptimizer::VertexContainer &vlist)
pop (restore) the estimate a subset of the variables from the stack
virtual bool setLambda(double lambda, bool backup=false)=0
void discardTop(SparseOptimizer::VertexContainer &vlist)
ignore the latest stored element on the stack, remove it from the stack but do not restore the estima...
SparseOptimizer * _optimizer
the optimizer the solver is working on
static G2OBatchStatistics * globalStats()
Definition: batch_stats.h:73
SparseOptimizer * optimizer() const
the optimizer (graph) on which the solver works
Definition: solver.h:106
virtual bool solve()=0
double * x()
return x, the solution vector
Definition: solver.h:96
#define g2o_isfinite(x)
Definition: macros.h:101
virtual bool buildSystem()=0
double activeRobustChi2() const
const T & value() const
Definition: property.h:57
void push(SparseOptimizer::VertexContainer &vlist)
push the estimate of a subset of the variables onto a stack
virtual bool buildStructure(bool zeroBlocks=false)=0
double g2o::OptimizationAlgorithmLevenberg::userLambdaInit ( )
inline

return the lambda set by the user, if < 0 the SparseOptimizer will compute the initial lambda

Definition at line 62 of file optimization_algorithm_levenberg.h.

62 {return _userLambdaInit->value();}
const T & value() const
Definition: property.h:57

Member Data Documentation

double g2o::OptimizationAlgorithmLevenberg::_currentLambda
protected
double g2o::OptimizationAlgorithmLevenberg::_goodStepLowerScale
protected

lower bound for lambda decrease if a good LM step

Definition at line 75 of file optimization_algorithm_levenberg.h.

Referenced by OptimizationAlgorithmLevenberg(), and solve().

double g2o::OptimizationAlgorithmLevenberg::_goodStepUpperScale
protected

upper bound for lambda decrease if a good LM step

Definition at line 76 of file optimization_algorithm_levenberg.h.

Referenced by OptimizationAlgorithmLevenberg(), and solve().

int g2o::OptimizationAlgorithmLevenberg::_levenbergIterations
protected

the numer of levenberg iterations performed to accept the last step

Definition at line 78 of file optimization_algorithm_levenberg.h.

Referenced by OptimizationAlgorithmLevenberg(), printVerbose(), and solve().

Property<int>* g2o::OptimizationAlgorithmLevenberg::_maxTrialsAfterFailure
protected
double g2o::OptimizationAlgorithmLevenberg::_ni
protected

Definition at line 77 of file optimization_algorithm_levenberg.h.

Referenced by OptimizationAlgorithmLevenberg(), and solve().

double g2o::OptimizationAlgorithmLevenberg::_tau
protected
Property<double>* g2o::OptimizationAlgorithmLevenberg::_userLambdaInit
protected

The documentation for this class was generated from the following files: