From 32044eaac879ad482d457b858983a415a63ebee6 Mon Sep 17 00:00:00 2001 From: Frank Dellaert Date: Tue, 16 Jun 2015 22:24:39 -0700 Subject: [PATCH] Added a named constructor to mimick Ceres defaults --- .../nonlinear/LevenbergMarquardtOptimizer.cpp | 12 +++--- gtsam/nonlinear/LevenbergMarquardtOptimizer.h | 42 +++++++++++++++---- timing/timeSFMBAL.cpp | 5 +-- 3 files changed, 42 insertions(+), 17 deletions(-) diff --git a/gtsam/nonlinear/LevenbergMarquardtOptimizer.cpp b/gtsam/nonlinear/LevenbergMarquardtOptimizer.cpp index 5fb51a243..398ccda75 100644 --- a/gtsam/nonlinear/LevenbergMarquardtOptimizer.cpp +++ b/gtsam/nonlinear/LevenbergMarquardtOptimizer.cpp @@ -105,8 +105,8 @@ void LevenbergMarquardtParams::print(const std::string& str) const { std::cout << " lambdaLowerBound: " << lambdaLowerBound << "\n"; std::cout << " minModelFidelity: " << minModelFidelity << "\n"; std::cout << " diagonalDamping: " << diagonalDamping << "\n"; - std::cout << " min_diagonal: " << min_diagonal_ << "\n"; - std::cout << " max_diagonal: " << max_diagonal_ << "\n"; + std::cout << " min_diagonal: " << min_diagonal << "\n"; + std::cout << " max_diagonal: " << max_diagonal << "\n"; std::cout << " verbosityLM: " << verbosityLMTranslator(verbosityLM) << "\n"; std::cout.flush(); @@ -119,7 +119,7 @@ GaussianFactorGraph::shared_ptr LevenbergMarquardtOptimizer::linearize() const { /* ************************************************************************* */ void LevenbergMarquardtOptimizer::increaseLambda() { - if (params_.useFixedLambdaFactor_) { + if (params_.useFixedLambdaFactor) { state_.lambda *= params_.lambdaFactor; } else { state_.lambda *= params_.lambdaFactor; @@ -131,7 +131,7 @@ void LevenbergMarquardtOptimizer::increaseLambda() { /* ************************************************************************* */ void LevenbergMarquardtOptimizer::decreaseLambda(double stepQuality) { - if (params_.useFixedLambdaFactor_) { + if (params_.useFixedLambdaFactor) { state_.lambda /= params_.lambdaFactor; } else { // CHECK_GT(step_quality, 0.0); @@ -156,8 +156,8 @@ GaussianFactorGraph::shared_ptr LevenbergMarquardtOptimizer::buildDampedSystem( state_.hessianDiagonal = linear.hessianDiagonal(); BOOST_FOREACH(Vector& v, state_.hessianDiagonal | map_values) { for (int aa = 0; aa < v.size(); aa++) { - v(aa) = std::min(std::max(v(aa), params_.min_diagonal_), - params_.max_diagonal_); + v(aa) = std::min(std::max(v(aa), params_.min_diagonal), + params_.max_diagonal); v(aa) = sqrt(v(aa)); } } diff --git a/gtsam/nonlinear/LevenbergMarquardtOptimizer.h b/gtsam/nonlinear/LevenbergMarquardtOptimizer.h index e5561af48..632a7ac0c 100644 --- a/gtsam/nonlinear/LevenbergMarquardtOptimizer.h +++ b/gtsam/nonlinear/LevenbergMarquardtOptimizer.h @@ -55,9 +55,9 @@ public: std::string logFile; ///< an optional CSV log file, with [iteration, time, error, labda] bool diagonalDamping; ///< if true, use diagonal of Hessian bool reuse_diagonal_; ///< an additional option in Ceres for diagonalDamping (TODO: should be in state?) - bool useFixedLambdaFactor_; ///< if true applies constant increase (or decrease) to lambda according to lambdaFactor - double min_diagonal_; ///< when using diagonal damping saturates the minimum diagonal entries (default: 1e-6) - double max_diagonal_; ///< when using diagonal damping saturates the maximum diagonal entries (default: 1e32) + bool useFixedLambdaFactor; ///< if true applies constant increase (or decrease) to lambda according to lambdaFactor + double min_diagonal; ///< when using diagonal damping saturates the minimum diagonal entries (default: 1e-6) + double max_diagonal; ///< when using diagonal damping saturates the maximum diagonal entries (default: 1e32) LevenbergMarquardtParams() : lambdaInitial(1e-5), @@ -68,9 +68,37 @@ public: minModelFidelity(1e-3), diagonalDamping(false), reuse_diagonal_(false), - useFixedLambdaFactor_(true), - min_diagonal_(1e-6), - max_diagonal_(1e32) {} + useFixedLambdaFactor(true), + min_diagonal(1e-6), + max_diagonal(1e32) {} + + static LevenbergMarquardtParams CeresDefaults() { + LevenbergMarquardtParams p; + + // Termination condition, same as options.max_num_iterations + p.maxIterations = 50; + + // Termination condition, turn off because no corresponding option in CERES + p.absoluteErrorTol = 0; // Frank thinks this is not tolerance (was 1e-6) + + // Termination condition, turn off because no corresponding option in CERES + p.errorTol = 0; // 1e-6; + + // Termination condition, same as options.function_tolerance + p.relativeErrorTol = 1e-6; // This is function_tolerance (was 1e-03) + + // Change lambda parameters to be the same as Ceres + p.lambdaUpperBound = 1e32; + p.lambdaLowerBound = 1e-16; + p.lambdaInitial = 1e-04; + p.lambdaFactor = 2.0; + p.useFixedLambdaFactor = false; // Luca says this is important + + p.diagonalDamping = true; + p.minModelFidelity = 1e-3; // options.min_relative_decrease in CERES + + return p; + } virtual ~LevenbergMarquardtParams() {} virtual void print(const std::string& str = "") const; @@ -94,7 +122,7 @@ public: inline void setLogFile(const std::string& s) { logFile = s; } inline void setDiagonalDamping(bool flag) { diagonalDamping = flag; } inline void setUseFixedLambdaFactor(bool flag) { - useFixedLambdaFactor_ = flag; + useFixedLambdaFactor = flag; } }; diff --git a/timing/timeSFMBAL.cpp b/timing/timeSFMBAL.cpp index 154a72dc9..45a1cae81 100644 --- a/timing/timeSFMBAL.cpp +++ b/timing/timeSFMBAL.cpp @@ -72,13 +72,10 @@ int main(int argc, char* argv[]) { // Optimize // Set parameters to be similar to ceres - LevenbergMarquardtParams params; + LevenbergMarquardtParams params = LevenbergMarquardtParams::CeresDefaults(); params.setOrdering(ordering); params.setVerbosity("ERROR"); params.setVerbosityLM("TRYLAMBDA"); - params.setDiagonalDamping(true); - params.setlambdaInitial(1e-4); - params.setlambdaFactor(2.0); LevenbergMarquardtOptimizer lm(graph, initial, params); Values actual = lm.optimize();