217 for (
int i = 0; i <
m_npars; ++i) {
236 for (
int ipar = 0; ipar <
m_npars; ++ipar) {
237 if (pars[ipar]->is_free()) {
238 if ((*fct.
curvature())(ipar,ipar) == 0.0) {
240 *
m_logger <<
" Parameter \"" << pars[ipar]->name();
241 *
m_logger <<
"\" has zero curvature.";
242 *
m_logger <<
" Fix parameter." << std::endl;
259 (*m_logger)(
">Iteration %3d: -logL=%.3f, Lambda=%.1e",
262 #if defined(G_DEBUG_OPT)
263 std::cout <<
"Initial iteration: func=" <<
m_value <<
", Lambda="
266 #if defined(G_DEBUG_SHOW_GRAD_COVAR)
274 bool check_for_freeze =
true;
283 double grad_max = 0.0;
285 for (
int ipar = 0; ipar <
m_npars; ++ipar) {
286 if (pars[ipar]->is_free()) {
287 double grad = pars[ipar]->factor_gradient();
295 *
m_logger <<
" (" << pars[ipar]->name() <<
")";
296 *
m_logger <<
" has a zero gradient." << std::endl;
304 std::string stalled =
"";
308 stalled =
" (stalled)";
313 std::string parname =
"";
314 if (grad_imax != -1) {
315 parname =
" [" + pars[grad_imax]->name() +
":" +
318 (*m_logger)(
"%sIteration %3d: -logL=%.3f, Lambda=%.1e,"
319 " delta=%.3f, step=%.1e, max(|grad|)=%f%s%s",
322 parname.c_str(), stalled.c_str());
324 #if defined(G_DEBUG_OPT)
325 std::cout <<
"Iteration " <<
m_iter <<
": func="
326 <<
m_value <<
", Lambda=" << lambda_old
327 <<
", delta=" <<
m_delta << std::endl;
329 #if defined(G_DEBUG_SHOW_GRAD_COVAR)
352 if (check_for_freeze) {
356 check_for_freeze =
false;
361 for (
int ipar = 0; ipar <
m_npars; ++ipar) {
367 << pars[ipar]->name()
368 <<
"\" after convergence was"
369 " reached with frozen"
370 " parameter." << std::endl;
393 lambda_inc = (
m_lambda > lambda_old) ? lambda_inc + 1 : 0;
408 for (
int ipar = 0; ipar <
m_npars; ++ipar) {
413 << pars[ipar]->name()
414 <<
"\" after convergence was"
415 " reached with frozen"
416 " parameter." << std::endl;
434 (*m_logger)(
">Iteration %3d: -logL=%.3f, Lambda=%.1e (no free parameters)",
474 bool diag_loaded =
false;
477 for (
int i = 0; i < 2; ++i) {
483 for (
int ipar = 0; ipar <
npars; ++ipar) {
486 if (x[ipar] >= 0.0) {
487 pars[ipar]->factor_error(
sqrt(x[ipar]));
490 pars[ipar]->factor_error(0.0);
504 *
m_logger <<
"Non-Positive definite curvature matrix encountered."
506 *
m_logger <<
"Load diagonal elements with 1e-10."
507 <<
" Fit errors may be inaccurate."
512 *curvature = save_curvature;
513 for (
int ipar = 0; ipar <
npars; ++ipar) {
514 if ((*curvature)(ipar,ipar) != 0.0) {
515 (*curvature)(ipar,ipar) += 1.0e-10;
531 *
m_logger <<
"Non-Positive definite curvature matrix encountered,"
532 <<
" even after diagonal loading." << std::endl;
537 catch (std::exception &e) {
564 status =
"converged";
570 status =
"singular curvature matrix encountered";
573 status =
"curvature matrix not positive definite";
576 status =
"errors are inaccurate";
603 result.append(
"=== GOptimizerLM ===");
745 #if defined(G_DEBUG_ITER)
746 std::cout <<
"GOptimizerLM::iteration: enter" << std::endl;
766 for (
int ipar = 0; ipar <
m_npars; ++ipar) {
767 save_pars[ipar] = pars[ipar]->factor_value();
771 for (
int ipar = 0; ipar <
m_npars; ++ipar) {
772 (*curvature)(ipar,ipar) *= (1.0 +
m_lambda);
773 (*grad)[ipar] = -(*grad)[ipar];
777 #if defined(G_DEBUG_ITER)
778 std::cout <<
"Gradient : ";
779 for (
int ipar = 0; ipar <
m_npars; ++ipar) {
780 std::cout << (*grad)[ipar] <<
" ";
782 std::cout << std::endl;
783 std::cout <<
"Curvature: ";
784 for (
int ipar = 0; ipar <
m_npars; ++ipar) {
785 for (
int jpar = 0; jpar <
m_npars; ++jpar) {
786 std::cout << (*curvature)(ipar,jpar) <<
" ";
789 std::cout << std::endl;
794 *grad = curvature->
solve(*grad);
799 *
m_logger <<
"GOptimizerLM::iteration: "
800 <<
"Curvature matrix not positive definite."
805 catch (std::exception &e) {
813 #if defined(G_DEBUG_ITER)
814 std::cout <<
"Step size = " << step << std::endl;
818 for (
int ipar = 0; ipar <
m_npars; ++ipar) {
821 if (pars[ipar]->is_free()) {
824 double p = pars[ipar]->factor_value();
825 double p_min = pars[ipar]->factor_min();
826 double p_max = pars[ipar]->factor_max();
829 p += (*grad)[ipar] * step;
832 #if defined(G_DEBUG_ITER)
833 std::cout <<
"Trial factor value of ";
834 std::cout << pars[ipar]->name() <<
" = ";
835 std::cout << p << std::endl;
839 if (pars[ipar]->has_min() && p < p_min) {
842 *
m_logger <<
" Parameter \"" << pars[ipar]->name();
843 *
m_logger <<
"\" hits minimum " << p_min <<
" more than ";
845 *
m_logger <<
" Fix parameter at minimum for now." << std::endl;
852 *
m_logger <<
" Parameter \"" << pars[ipar]->name();
861 else if (pars[ipar]->has_max() && p > p_max) {
864 *
m_logger <<
" Parameter \"" << pars[ipar]->name();
865 *
m_logger <<
"\" hits maximum " << p_max <<
" more than ";
867 *
m_logger <<
" Fix parameter at maximum for now." << std::endl;
874 *
m_logger <<
" Parameter \"" << pars[ipar]->name();
889 pars[ipar]->factor_value(p);
892 #if defined(G_DEBUG_ITER)
893 std::cout <<
"New value of ";
894 std::cout << pars[ipar]->name() <<
" = ";
895 std::cout << pars[ipar]->value() << std::endl;
913 for (
int ipar = 0; ipar <
m_npars; ++ipar) {
914 if (pars[ipar]->is_free()) {
915 if ((*fct.
curvature())(ipar,ipar) == 0.0) {
917 *
m_logger <<
" Parameter \"" << pars[ipar]->name();
918 *
m_logger <<
"\" has zero curvature.";
919 *
m_logger <<
" Fix parameter." << std::endl;
935 #if defined(G_DEBUG_ITER)
936 std::cout <<
"Function value " <<
m_value;
937 std::cout <<
" (was " << save_value <<
")" << std::endl;
942 for (
int ipar = 0; ipar <
m_npars; ++ipar) {
943 if (pars[ipar]->factor_value() != save_pars[ipar]) {
983 m_value = save_value;
985 *curvature = save_curvature;
986 for (
int ipar = 0; ipar <
m_npars; ++ipar) {
987 pars[ipar]->factor_value(save_pars[ipar]);
994 #if defined(G_DEBUG_ITER)
995 std::cout <<
"GOptimizerLM::iteration: exit" << std::endl;
1027 for (
int ipar = 0; ipar < pars.
size(); ++ipar) {
1030 double p = pars[ipar]->factor_value();
1031 double p_min = pars[ipar]->factor_min();
1032 double p_max = pars[ipar]->factor_max();
1033 double delta = grad[ipar];
1036 if (pars[ipar]->has_min()) {
1037 double step_min = (delta < 0.0) ? (p_min - p)/delta : 1.0;
1038 if (step_min > 0.0) {
1039 if (step_min < step) {
1050 *
m_logger <<
"\" does not drive optimization step anymore.";
1058 if (pars[ipar]->has_max()) {
1059 double step_max = (delta > 0.0) ? (p_max - p)/delta : 1.0;
1060 if (step_max > 0.0) {
1061 if (step_max < step) {
1072 *
m_logger <<
"\" does not drive optimization step anymore.";
1082 if (ipar_bnd != -1) {
1086 *
m_logger << pars[ipar_bnd]->name();
1087 *
m_logger <<
"\" drives optimization step (step=";
1088 *
m_logger << step <<
")" << std::endl;
GOptimizerLM & operator=(const GOptimizerLM &opt)
Assignment operator.
const double & lambda_inc(void) const
Return lambda increment value.
double step_size(const GVector &grad, const GOptimizerPars &pars)
Return LM step size.
Optimizer function abstract base class.
void init_members(void)
Initialise class members.
Sparse matrix class interface definition.
GVector abs(const GVector &vector)
Computes absolute of vector elements.
virtual GMatrixSparse * curvature(void)=0
Optimizer parameter container class.
virtual void optimize(GOptimizerFunction &fct, GOptimizerPars &pars)
Optimize function parameters.
double m_lambda_start
Initial start value.
double m_lambda
Actual lambda.
void copy_members(const GOptimizerLM &opt)
Copy class members.
double m_eps
Absolute precision.
std::vector< bool > m_hit_boundary
Bookkeeping array for boundary hits.
virtual void eval(const GOptimizerPars &pars)=0
int m_npars
Number of parameters.
GOptimizerLM(void)
Void constructor.
virtual GOptimizer & operator=(const GOptimizer &opt)
Assignment operator.
std::vector< bool > m_par_remove
Bookkeeping of parameter removal.
int m_max_dec
Maximum number of function decrease.
double m_value
Actual function value.
GLog * m_logger
Pointer to optional logger.
Information logger interface definition.
virtual GOptimizerLM * clone(void) const
Clone object.
int m_nfree
Number of free parameters.
GVector sqrt(const GVector &vector)
Computes square root of vector elements.
GVector solve(const GVector &vector) const
Solves linear matrix equation.
bool m_step_adjust
Adjust step size to boundaries.
virtual void clear(void)
Clear object.
double m_delta
Function improvement.
double m_accept_dec
Acceptable function decrease.
GVector log(const GVector &vector)
Computes natural logarithm of vector elements.
#define G_LM_NOT_POSTIVE_DEFINITE
virtual ~GOptimizerLM(void)
Destructor.
double m_lambda_dec
Lambda decrease.
Abstract optimizer abstract base class.
std::vector< bool > m_par_freeze
Bookkeeping of parameter freeze.
double m_lambda_inc
Lambda increase.
Levenberg Marquardt optimizer class interface definition.
int m_num_dec
Number of function decreases.
void free_members(void)
Delete class members.
const int & npars(void) const
Return number of model parameters.
int m_max_iter
Maximum number of iterations.
int m_max_hit
Maximum number of successive hits.
std::vector< int > m_hit_maximum
Bookkeeping of successive maximum hits.
void init_members(void)
Initialise class members.
virtual GVector * gradient(void)=0
GVector cholesky_solver(const GVector &vector, const bool &compress=true) const
Cholesky solver.
int nfree(void) const
Return number of free parameters.
virtual double value(void) const =0
virtual void errors(GOptimizerFunction &fct, GOptimizerPars &pars)
Compute parameter uncertainties.
virtual std::string print(const GChatter &chatter=NORMAL) const
Print optimizer information.
Exception handler interface definition.
int size(void) const
Return number of parameters in container.
std::string parformat(const std::string &s, const int &indent=0)
Convert string in parameter format.
std::vector< int > m_hit_minimum
Bookkeeping of successive minimum hits.
GMatrixSparse cholesky_decompose(const bool &compress=true) const
Return Cholesky decomposition.
void free_members(void)
Delete class members.
Levenberg Marquardt optimizer class.
int m_max_stall
Maximum number of stalls.
virtual int status(void) const
Return optimizer status.
std::string status_string(void) const
Set fit status string.
double iteration(GOptimizerFunction &fct, GOptimizerPars &pars)
Perform one LM iteration.
std::string str(const unsigned short int &value)
Convert unsigned short integer value into string.