Commit 86c503ee0b50aed42c16ceecb873af2a347909f4
1 parent
f730c08e
Adapt convergence threshold to optimization step size
Showing
2 changed files
with
17 additions
and
11 deletions
include/GOptimizerLM.hpp
| 1 | 1 | /*************************************************************************** |
| 2 | 2 | * GOptimizerLM.hpp - Levenberg Marquardt optimizer * |
| 3 | 3 | * ----------------------------------------------------------------------- * |
| 4 | - * copyright (C) 2009-2015 by Juergen Knoedlseder * | |
| 4 | + * copyright (C) 2009-2017 by Juergen Knoedlseder * | |
| 5 | 5 | * ----------------------------------------------------------------------- * |
| 6 | 6 | * * |
| 7 | 7 | * This program is free software: you can redistribute it and/or modify * |
| ... | ... | @@ -97,7 +97,7 @@ protected: |
| 97 | 97 | void init_members(void); |
| 98 | 98 | void copy_members(const GOptimizerLM& opt); |
| 99 | 99 | void free_members(void); |
| 100 | - void iteration(GOptimizerFunction& fct, GOptimizerPars& pars); | |
| 100 | + double iteration(GOptimizerFunction& fct, GOptimizerPars& pars); | |
| 101 | 101 | double step_size(const GVector& grad, const GOptimizerPars& pars); |
| 102 | 102 | |
| 103 | 103 | // Protected members | ... | ... |
src/opt/GOptimizerLM.cpp
| 1 | 1 | /*************************************************************************** |
| 2 | 2 | * GOptimizerLM.cpp - Levenberg Marquardt optimizer * |
| 3 | 3 | * ----------------------------------------------------------------------- * |
| 4 | - * copyright (C) 2009-2015 by Juergen Knoedlseder * | |
| 4 | + * copyright (C) 2009-2017 by Juergen Knoedlseder * | |
| 5 | 5 | * ----------------------------------------------------------------------- * |
| 6 | 6 | * * |
| 7 | 7 | * This program is free software: you can redistribute it and/or modify * |
| ... | ... | @@ -276,7 +276,7 @@ void GOptimizerLM::optimize(GOptimizerFunction& fct, GOptimizerPars& pars) |
| 276 | 276 | for (m_iter = 1; m_iter <= m_max_iter; ++m_iter) { |
| 277 | 277 | |
| 278 | 278 | // Perform one iteration |
| 279 | - iteration(fct, pars); | |
| 279 | + double step = iteration(fct, pars); | |
| 280 | 280 | |
| 281 | 281 | // Determine maximum (scaled) gradient |
| 282 | 282 | double grad_max = 0.0; |
| ... | ... | @@ -315,9 +315,9 @@ void GOptimizerLM::optimize(GOptimizerFunction& fct, GOptimizerPars& pars) |
| 315 | 315 | gammalib::str(grad_imax) + "]"; |
| 316 | 316 | } |
| 317 | 317 | (*m_logger)("%sIteration %3d: -logL=%.3f, Lambda=%.1e," |
| 318 | - " delta=%.3f, max(|grad|)=%f%s%s", | |
| 318 | + " delta=%.3f, step=%.1e, max(|grad|)=%f%s%s", | |
| 319 | 319 | status.c_str(), m_iter, m_value, lambda_old, |
| 320 | - m_delta, grad_max, | |
| 320 | + m_delta, step, grad_max, | |
| 321 | 321 | parname.c_str(), stalled.c_str()); |
| 322 | 322 | } |
| 323 | 323 | #if defined(G_DEBUG_OPT) |
| ... | ... | @@ -342,7 +342,9 @@ void GOptimizerLM::optimize(GOptimizerFunction& fct, GOptimizerPars& pars) |
| 342 | 342 | // free them now and continue. We do this only once, i.e. |
| 343 | 343 | // the next time a parameter is frozen and convergence is |
| 344 | 344 | // reached we really stop. |
| 345 | - if ((m_lambda <= lambda_old) && (m_delta >= 0.0) && (m_delta < m_eps)) { | |
| 345 | + if ((m_lambda <= lambda_old) && | |
| 346 | + (m_delta >= 0.0) && | |
| 347 | + (m_delta < step*m_eps)) { | |
| 346 | 348 | |
| 347 | 349 | // Check for frozen parameters, and if some exist, free |
| 348 | 350 | // them and start over |
| ... | ... | @@ -707,6 +709,7 @@ void GOptimizerLM::free_members(void) |
| 707 | 709 | * |
| 708 | 710 | * @param[in] fct Optimizer function. |
| 709 | 711 | * @param[in] pars Function parameters. |
| 712 | + * @return Step size for iteration. | |
| 710 | 713 | * |
| 711 | 714 | * This method performs one LM iteration. Note that the method only acts on |
| 712 | 715 | * the parameter value, i.e. it does not worry about the true scale of the |
| ... | ... | @@ -714,13 +717,16 @@ void GOptimizerLM::free_members(void) |
| 714 | 717 | * is assumed to return the gradient and curvature matrix with respect to the |
| 715 | 718 | * parameter values (and not the scaled true values). |
| 716 | 719 | ***************************************************************************/ |
| 717 | -void GOptimizerLM::iteration(GOptimizerFunction& fct, GOptimizerPars& pars) | |
| 720 | +double GOptimizerLM::iteration(GOptimizerFunction& fct, GOptimizerPars& pars) | |
| 718 | 721 | { |
| 719 | 722 | // Debug option: dump header |
| 720 | 723 | #if defined(G_DEBUG_ITER) |
| 721 | 724 | std::cout << "GOptimizerLM::iteration: enter" << std::endl; |
| 722 | 725 | #endif |
| 723 | 726 | |
| 727 | + // Initialise step size | |
| 728 | + double step = 0.0; | |
| 729 | + | |
| 724 | 730 | // Single loop for common exit point |
| 725 | 731 | do { |
| 726 | 732 | |
| ... | ... | @@ -788,7 +794,7 @@ void GOptimizerLM::iteration(GOptimizerFunction& fct, GOptimizerPars& pars) |
| 788 | 794 | } |
| 789 | 795 | |
| 790 | 796 | // Get LM step size |
| 791 | - double step = step_size(*grad, pars); | |
| 797 | + step = step_size(*grad, pars); | |
| 792 | 798 | |
| 793 | 799 | // Debug option: dump step size |
| 794 | 800 | #if defined(G_DEBUG_ITER) |
| ... | ... | @@ -976,8 +982,8 @@ void GOptimizerLM::iteration(GOptimizerFunction& fct, GOptimizerPars& pars) |
| 976 | 982 | std::cout << "GOptimizerLM::iteration: exit" << std::endl; |
| 977 | 983 | #endif |
| 978 | 984 | |
| 979 | - // Return | |
| 980 | - return; | |
| 985 | + // Return step size | |
| 986 | + return step; | |
| 981 | 987 | |
| 982 | 988 | } |
| 983 | 989 | ... | ... |