/***************************************************************************
* GOptimizerLM.hpp - Levenberg Marquardt optimizer *
* ----------------------------------------------------------------------- *
* copyright (C) 2009-2017 by Juergen Knoedlseder *
* ----------------------------------------------------------------------- *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see . *
* *
***************************************************************************/
/**
* @file GOptimizerLM.hpp
* @brief Levenberg Marquardt optimizer class interface definition
* @author Juergen Knoedlseder
*/
#ifndef GOPTIMIZERLM_HPP
#define GOPTIMIZERLM_HPP
/* __ Includes ___________________________________________________________ */
#include
#include "GOptimizer.hpp"
#include "GOptimizerFunction.hpp"
#include "GLog.hpp"
/* __ Definitions ________________________________________________________ */
#define G_LM_CONVERGED 0
#define G_LM_STALLED 1
#define G_LM_SINGULAR 2
#define G_LM_NOT_POSTIVE_DEFINITE 3
#define G_LM_BAD_ERRORS 4
/***********************************************************************//**
* @class GOptimizerLM
*
* @brief Levenberg Marquardt optimizer class
*
* This method implements an Levenberg Marquardt optimizer.
***************************************************************************/
class GOptimizerLM : public GOptimizer {
public:
// Constructors and destructors
GOptimizerLM(void);
explicit GOptimizerLM(GLog* log);
GOptimizerLM(const GOptimizerLM& opt);
virtual ~GOptimizerLM(void);
// Operators
GOptimizerLM& operator=(const GOptimizerLM& opt);
// Implemented pure virtual base class methods
virtual void clear(void);
virtual GOptimizerLM* clone(void) const;
virtual std::string classname(void) const;
virtual void optimize(GOptimizerFunction& fct, GOptimizerPars& pars);
virtual void errors(GOptimizerFunction& fct, GOptimizerPars& pars);
virtual double value(void) const;
virtual int status(void) const;
virtual int iter(void) const;
virtual std::string print(const GChatter& chatter = NORMAL) const;
// Methods
void logger(GLog* log);
void max_iter(const int& max_iter);
void max_stalls(const int& max_stalls);
void max_boundary_hits(const int& max_hit);
void lambda_start(const double& value);
void lambda_inc(const double& value);
void lambda_dec(const double& value);
void eps(const double& eps);
void accept_dec(const double& value);
int max_iter(void) const;
int max_stalls(void) const;
int max_boundary_hits(void) const;
const double& lambda_start(void) const;
const double& lambda_inc(void) const;
const double& lambda_dec(void) const;
const double& lambda(void) const;
const double& eps(void) const;
const double& accept_dec(void) const;
protected:
// Protected methods
void init_members(void);
void copy_members(const GOptimizerLM& opt);
void free_members(void);
double iteration(GOptimizerFunction& fct, GOptimizerPars& pars);
double step_size(const GVector& grad, const GOptimizerPars& pars);
// Protected members
int m_npars; //!< Number of parameters
int m_nfree; //!< Number of free parameters
double m_lambda_start; //!< Initial start value
double m_lambda_inc; //!< Lambda increase
double m_lambda_dec; //!< Lambda decrease
double m_eps; //!< Absolute precision
double m_accept_dec; //!< Acceptable function decrease
int m_max_iter; //!< Maximum number of iterations
int m_max_stall; //!< Maximum number of stalls
int m_max_hit; //!< Maximum number of successive hits
int m_max_dec; //!< Maximum number of function decrease
bool m_step_adjust; //!< Adjust step size to boundaries
std::vector m_hit_boundary; //!< Bookkeeping array for boundary hits
std::vector m_hit_minimum; //!< Bookkeeping of successive minimum hits
std::vector m_hit_maximum; //!< Bookkeeping of successive maximum hits
std::vector m_par_freeze; //!< Bookkeeping of parameter freeze
std::vector m_par_remove; //!< Bookkeeping of parameter removal
double m_lambda; //!< Actual lambda
double m_value; //!< Actual function value
double m_delta; //!< Function improvement
int m_status; //!< Fit status
int m_iter; //!< Iteration
int m_num_dec; //!< Number of function decreases
GLog* m_logger; //!< Pointer to optional logger
};
/***********************************************************************//**
* @brief Return class name
*
* @return String containing the class name ("GOptimizerLM").
***************************************************************************/
inline
std::string GOptimizerLM::classname(void) const
{
return ("GOptimizerLM");
}
/***********************************************************************//**
* @brief Return function value
*
* @return Function value.
***************************************************************************/
inline
double GOptimizerLM::value(void) const
{
return (m_value);
}
/***********************************************************************//**
* @brief Return optimizer status
*
* @return Optimizer status.
***************************************************************************/
inline
int GOptimizerLM::status(void) const
{
return (m_status);
}
/***********************************************************************//**
* @brief Return number of iterations
*
* @return Number of iterations.
***************************************************************************/
inline
int GOptimizerLM::iter(void) const
{
return (m_iter);
}
/***********************************************************************//**
* @brief Set logger
*
* @param[in] log Logger to use in optimizer.
*
* Set the logger into which the optimizer will dump any output.
***************************************************************************/
inline
void GOptimizerLM::logger(GLog* log)
{
m_logger = log;
return;
}
/***********************************************************************//**
* @brief Set maximum number of iterations
*
* @param[in] max_iter Maximum number of iterations.
***************************************************************************/
inline
void GOptimizerLM::max_iter(const int& max_iter)
{
m_max_iter = max_iter;
return;
}
/***********************************************************************//**
* @brief Set maximum number of allowed subsequent stalls
*
* @param[in] max_stalls Maximum number of allowed subsequent stalls.
***************************************************************************/
inline
void GOptimizerLM::max_stalls(const int& max_stalls)
{
m_max_stall = max_stalls;
return;
}
/***********************************************************************//**
* @brief Set maximum number of parameter boundary hits
*
* @param[in] max_hit Maximum number of parameter boundary hits.
***************************************************************************/
inline
void GOptimizerLM::max_boundary_hits(const int& max_hit)
{
m_max_hit = max_hit;
return;
}
/***********************************************************************//**
* @brief Set lambda starting value
*
* @param[in] value Lambda starting value.
***************************************************************************/
inline
void GOptimizerLM::lambda_start(const double& value)
{
m_lambda_start = value;
return;
}
/***********************************************************************//**
* @brief Set lambda increment value
*
* @param[in] value Lambda increment value.
***************************************************************************/
inline
void GOptimizerLM::lambda_inc(const double& value)
{
m_lambda_inc = value;
return;
}
/***********************************************************************//**
* @brief Set lambda decrement value
*
* @param[in] value Lambda decrement value.
***************************************************************************/
inline
void GOptimizerLM::lambda_dec(const double& value)
{
m_lambda_dec = value;
return;
}
/***********************************************************************//**
* @brief Set requested absolute convergence precision
*
* @param[in] eps Requested absolute convergence precision.
***************************************************************************/
inline
void GOptimizerLM::eps(const double& eps)
{
m_eps = eps;
return;
}
/***********************************************************************//**
* @brief Set acceptable function decrease
*
* @param[in] value Acceptable function decrease.
*
* Sets the acceptable function decrease value for which the new solution
* will be kept and the iterations continue. This strategy provides better
* convergence in case that a function decrease is encountered.
***************************************************************************/
inline
void GOptimizerLM::accept_dec(const double& value)
{
m_accept_dec = value;
return;
}
/***********************************************************************//**
* @brief Return maximum number of iterations
*
* @return Maximum number of iterations.
***************************************************************************/
inline
int GOptimizerLM::max_iter(void) const
{
return (m_max_iter);
}
/***********************************************************************//**
* @brief Return maximum number of allowed subsequent stalls
*
* @return Maximum number of allowed subsequent stalls.
***************************************************************************/
inline
int GOptimizerLM::max_stalls(void) const
{
return (m_max_stall);
}
/***********************************************************************//**
* @brief Return maximum number of parameter boundary hits
*
* @return Maximum number of parameter boundary hits.
***************************************************************************/
inline
int GOptimizerLM::max_boundary_hits(void) const
{
return (m_max_hit);
}
/***********************************************************************//**
* @brief Return lambda starting value
*
* @return Lambda starting value.
***************************************************************************/
inline
const double& GOptimizerLM::lambda_start(void) const
{
return (m_lambda_start);
}
/***********************************************************************//**
* @brief Return lambda increment value
*
* @return Lambda increment value.
***************************************************************************/
inline
const double& GOptimizerLM::lambda_inc(void) const
{
return (m_lambda_inc);
}
/***********************************************************************//**
* @brief Return lambda decrement value
*
* @return Lambda decrement value.
***************************************************************************/
inline
const double& GOptimizerLM::lambda_dec(void) const
{
return (m_lambda_dec);
}
/***********************************************************************//**
* @brief Return lambda value
*
* @return Lambda value.
***************************************************************************/
inline
const double& GOptimizerLM::lambda(void) const
{
return (m_lambda);
}
/***********************************************************************//**
* @brief Return requested absolute convergence precision
*
* @return Requested absolute convergence precision.
***************************************************************************/
inline
const double& GOptimizerLM::eps(void) const
{
return (m_eps);
}
/***********************************************************************//**
* @brief Return acceptable function decrease
*
* @return Acceptable function decrease.
***************************************************************************/
inline
const double& GOptimizerLM::accept_dec(void) const
{
return (m_accept_dec);
}
#endif /* GOPTIMIZERLM_HPP */