Commit 1e57632c95e62281c732dfc057d6957ccbb1baa5
Merge branch 'upper-limit' into integration
Showing
1 changed file
with
31 additions
and
3 deletions
src/ctulimit/ctulimit.cpp
| 1 | 1 | /*************************************************************************** |
| 2 | 2 | * ctulimit - Upper limit calculation tool * |
| 3 | 3 | * ----------------------------------------------------------------------- * |
| 4 | - * copyright (C) 2015-2020 by Michael Mayer * | |
| 4 | + * copyright (C) 2015-2021 by Michael Mayer * | |
| 5 | 5 | * ----------------------------------------------------------------------- * |
| 6 | 6 | * * |
| 7 | 7 | * This program is free software: you can redistribute it and/or modify * |
| ... | ... | @@ -268,7 +268,8 @@ void ctulimit::run(void) |
| 268 | 268 | |
| 269 | 269 | } // endif: likelihood was zero |
| 270 | 270 | |
| 271 | - // Get parameter brackets | |
| 271 | + // Get parameter brackets. Note that this method recomputes m_best_logL | |
| 272 | + // to make sure that the value is coherent for the upper limit search. | |
| 272 | 273 | double parmin; |
| 273 | 274 | double parmax; |
| 274 | 275 | get_parameter_brackets(parmin, parmax); |
| ... | ... | @@ -280,6 +281,7 @@ void ctulimit::run(void) |
| 280 | 281 | log_value(NORMAL, "Model name", m_skymodel->name()); |
| 281 | 282 | log_value(NORMAL, "Parameter name", m_model_par->name()); |
| 282 | 283 | log_value(NORMAL, "Confidence level", gammalib::str(m_confidence*100.0)+"%"); |
| 284 | + log_value(NORMAL, "Best log-likelihood value", m_best_logL); | |
| 283 | 285 | log_value(NORMAL, "Log-likelihood difference", m_dlogL); |
| 284 | 286 | log_value(NORMAL, "Initial parameter range", |
| 285 | 287 | "["+gammalib::str(parmin)+", "+gammalib::str(parmax)+"]"); |
| ... | ... | @@ -604,6 +606,13 @@ void ctulimit::get_parameter_brackets(double& parmin, double& parmax) |
| 604 | 606 | double value = m_model_par->factor_value(); |
| 605 | 607 | double error = m_model_par->factor_error(); |
| 606 | 608 | |
| 609 | + // Re-compute best log-likelihood for value fixed at optimum | |
| 610 | + m_best_logL = evaluate(*m_model_par, value); | |
| 611 | + | |
| 612 | + // Write best log-likelihood | |
| 613 | + log_value(NORMAL, "Best log-likelihood", | |
| 614 | + "logL("+gammalib::str(value)+")="+gammalib::str(m_best_logL)); | |
| 615 | + | |
| 607 | 616 | // If parameter error is zero then take parameter value as error |
| 608 | 617 | if (error == 0.0) { |
| 609 | 618 | error = value; |
| ... | ... | @@ -671,7 +680,12 @@ void ctulimit::get_parameter_brackets(double& parmin, double& parmax) |
| 671 | 680 | * Exceeded maximum number of iterations in the upper limit |
| 672 | 681 | * search. |
| 673 | 682 | * |
| 674 | - * Calculates the upper limit using a bisection method. | |
| 683 | + * Calculates the upper limit using a bisection method. The bisection is | |
| 684 | + * stopped if the log-likelihood value is within the tolerance of the target | |
| 685 | + * value. The bisection is also stopped putting a warning in the log file if | |
| 686 | + * the parameter interval becomes smaller than a tolerance of 1.0e-6. The | |
| 687 | + * method stops with an exception if the maximum number of iterations is | |
| 688 | + * exhausted. | |
| 675 | 689 | ***************************************************************************/ |
| 676 | 690 | void ctulimit::ulimit_bisection(const double& parmin, const double& parmax) |
| 677 | 691 | { |
| ... | ... | @@ -710,6 +724,20 @@ void ctulimit::ulimit_bisection(const double& parmin, const double& parmax) |
| 710 | 724 | break; |
| 711 | 725 | } |
| 712 | 726 | |
| 727 | + // Check for vanishing parameter range | |
| 728 | + if (std::abs(wrk_min-wrk_max) < 1.0e-6) { | |
| 729 | + std::string msg = "*** WARNING: Parameter range " | |
| 730 | + "["+gammalib::str(wrk_min)+", "+ | |
| 731 | + gammalib::str(wrk_max)+"] has reduced to a " | |
| 732 | + "narrow interval without reaching convergence!\n" | |
| 733 | + " The best log-likelihood value is " | |
| 734 | + "probably not an absolute but only a local " | |
| 735 | + "minimum.\n" | |
| 736 | + " Stop iterations."; | |
| 737 | + log_string(TERSE, msg); | |
| 738 | + break; | |
| 739 | + } | |
| 740 | + | |
| 713 | 741 | // Change boundaries for further iteration |
| 714 | 742 | if (eval_mid > 0.0) { |
| 715 | 743 | wrk_max = mid; // logL too large, new range = [wrk_min, mid] | ... | ... |