ctools  2.1.0.dev
 All Classes Namespaces Files Functions Variables Macros Pages
ctlikelihood.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * ctlikelihood - Base class for likelihood tools *
3  * ----------------------------------------------------------------------- *
4  * copyright (C) 2016-2021 by Juergen Knoedlseder *
5  * ----------------------------------------------------------------------- *
6  * *
7  * This program is free software: you can redistribute it and/or modify *
8  * it under the terms of the GNU General Public License as published by *
9  * the Free Software Foundation, either version 3 of the License, or *
10  * (at your option) any later version. *
11  * *
12  * This program is distributed in the hope that it will be useful, *
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15  * GNU General Public License for more details. *
16  * *
17  * You should have received a copy of the GNU General Public License *
18  * along with this program. If not, see <http://www.gnu.org/licenses/>. *
19  * *
20  ***************************************************************************/
21 /**
22  * @file ctlikelihood.cpp
23  * @brief Likelihood tool base class implementation
24  * @author Juergen Knoedlseder
25  */
26 
27 /* __ Includes ___________________________________________________________ */
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31 #include <string>
32 #include <typeinfo>
33 #include "ctlikelihood.hpp"
34 
35 /* __ Method name definitions ____________________________________________ */
36 #define G_OPT "ctlikelihood::opt(GOptimizer*)"
37 #define G_EVALUATE "ctlikelihood::evaluate(GModelPar&, double&)"
38 
39 /* __ Debug definitions __________________________________________________ */
40 
41 /* __ Coding definitions _________________________________________________ */
42 
43 
44 /*==========================================================================
45  = =
46  = Constructors/destructors =
47  = =
48  ==========================================================================*/
49 
50 /***********************************************************************//**
51  * @brief Name constructor
52  *
53  * @param[in] name Likelihood tool name.
54  * @param[in] version Likelihood tool version.
55  *
56  * Constructs a likelihood tool from the @p name and @p version. See the
57  * equivalent ctool constructor for details.
58  ***************************************************************************/
59 ctlikelihood::ctlikelihood(const std::string& name,
60  const std::string& version) :
61  ctobservation(name, version)
62 {
63  // Initialise members
64  init_members();
65 
66  // Return
67  return;
68 }
69 
70 
71 /***********************************************************************//**
72  * @brief Application parameters constructor
73  *
74  * @param[in] name Observation tool name.
75  * @param[in] version Observation tool version.
76  * @param[in] pars Application parameters.
77  *
78  * Constructs a likelihood tool from the @p name, @p version and the
79  * application parameters @p pars. See the equivalent ctool constructor
80  * for details.
81  ***************************************************************************/
82 ctlikelihood::ctlikelihood(const std::string& name,
83  const std::string& version,
84  const GApplicationPars& pars) :
85  ctobservation(name, version, pars)
86 {
87  // Initialise members
88  init_members();
89 
90  // Return
91  return;
92 }
93 
94 
95 /***********************************************************************//**
96  * @brief Command line constructor
97  *
98  * @param[in] name Likelihood tool name.
99  * @param[in] version Likelihood tool version.
100  * @param[in] argc Number of arguments in command line.
101  * @param[in] argv Array of command line arguments.
102  *
103  * Constructs a likelihood tool from the @p name, @p version and command
104  * line arguments. See the equivalent ctool constructor for details.
105  ***************************************************************************/
106 ctlikelihood::ctlikelihood(const std::string& name,
107  const std::string& version,
108  int argc,
109  char *argv[]) :
110  ctobservation(name, version, argc, argv)
111 {
112  // Initialise members
113  init_members();
114 
115  // Return
116  return;
117 }
118 
119 
120 /***********************************************************************//**
121  * @brief Observations constructor
122  *
123  * @param[in] name Likelihood tool name.
124  * @param[in] version Likelihood tool version.
125  * @param[in] obs Observation container.
126  *
127  * Constructs a likelihood tool from the @p name, @p version and an
128  * observation container.
129  ***************************************************************************/
130 ctlikelihood::ctlikelihood(const std::string& name,
131  const std::string& version,
132  const GObservations& obs) :
133  ctobservation(name, version, obs)
134 {
135  // Initialise members
136  init_members();
137 
138  // Return
139  return;
140 }
141 
142 
143 /***********************************************************************//**
144  * @brief Copy constructor
145  *
146  * @param[in] app Likelihood tool.
147  *
148  * Constructs an instance of a likelihood tool by copying information from
149  * another likelihood tool.
150  ***************************************************************************/
152 {
153  // Initialise members
154  init_members();
155 
156  // Copy members
157  copy_members(app);
158 
159  // Return
160  return;
161 }
162 
163 
164 /***********************************************************************//**
165  * @brief Destructor
166  *
167  * Destructs the likelihood tool.
168  ***************************************************************************/
170 {
171  // Free members
172  free_members();
173 
174  // Return
175  return;
176 }
177 
178 
179 /*==========================================================================
180  = =
181  = Operators =
182  = =
183  ==========================================================================*/
184 
185 /***********************************************************************//**
186  * @brief Assignment operator
187  *
188  * @param[in] app Likelihood tool.
189  * @return Likelihood tool.
190  *
191  * Assigns a likelihood tool.
192  ***************************************************************************/
194 {
195  // Execute only if object is not identical
196  if (this != &app) {
197 
198  // Copy base class members
199  this->ctobservation::operator=(app);
200 
201  // Free members
202  free_members();
203 
204  // Initialise members
205  init_members();
206 
207  // Copy members
208  copy_members(app);
209 
210  } // endif: object was not identical
211 
212  // Return this object
213  return *this;
214 }
215 
216 
217 /*==========================================================================
218  = =
219  = Public methods =
220  = =
221  ==========================================================================*/
222 
223 /***********************************************************************//**
224  * @brief Set optimizer
225  *
226  * @param[in] opt Pointer to optimizer.
227  *
228  * @exception GException::invalid_argument
229  * Specified optimizer is not of type GOptimizerLM.
230  *
231  * Sets the optimizer. So far only optimizers of type GOptimizerLM are
232  * supported. If a different optimizer is specified the method throws an
233  * exception.
234  ***************************************************************************/
235 void ctlikelihood::opt(const GOptimizer* opt)
236 {
237  // Throw an exception if the optimizer is not a LM optimizer
238  const GOptimizerLM* lm = dynamic_cast<const GOptimizerLM*>(opt);
239  if (lm == NULL) {
240  std::string cls = std::string(typeid(opt).name());
241  std::string msg = "Method requires \"GOptimizerLM\" optimizer yet the "
242  "provided optimizer is of type \""+cls+"\". Please "
243  "specify an instance of \"GOptimizerLM\" as "
244  "argument.";
245  throw GException::invalid_argument(G_OPT, msg);
246  }
247 
248  // Set optimizer
249  m_opt = *lm;
250 
251  // Return
252  return;
253 }
254 
255 
256 /*==========================================================================
257  = =
258  = Protected methods exposed in Python =
259  = =
260  ==========================================================================*/
261 
262 /***********************************************************************//**
263  * @brief Evaluates the log-likelihood function
264  *
265  * @param[in] par Model parameter
266  * @param[in] value Model parameter factor value
267  * @return Log-likelihood function
268  *
269  * Evaluates the log-likelihood function at a given @p value.
270  ***************************************************************************/
271 double ctlikelihood::evaluate(GModelPar& par, const double& value)
272 {
273  // Initialise log-likelihood value
274  double logL = 0.0;
275 
276  // Throw an exception if the parameter is below the minimum boundary
277  if (par.has_min() && value < par.factor_min()) {
278  std::string msg = "Parameter \""+par.name()+"\" value"+
279  gammalib::str(value)+" is below its minimum boundary "+
280  gammalib::str(par.factor_min())+". To omit this "
281  "error please lower the minimum parameter boundary.";
282  throw GException::invalid_value(G_EVALUATE, msg);
283  }
284 
285  // Throw an exception if the parameter is above the maximum boundary
286  if (par.has_max() && value > par.factor_max()) {
287  std::string msg = "Parameter \""+par.name()+"\" value"+
288  gammalib::str(value)+" is above its maximum boundary "+
289  gammalib::str(par.factor_max())+". To omit this "
290  "error please raise the maximum parameter boundary.";
291  throw GException::invalid_value(G_EVALUATE, msg);
292  }
293 
294  // Change parameter factor
295  par.factor_value(value);
296 
297  // Fix parameter
298  par.fix();
299 
300  // Re-optimize log-likelihood
301  m_obs.optimize(m_opt);
302 
303  // Free parameter
304  par.free();
305 
306  // Retrieve log-likelihood
307  logL = m_obs.logL();
308 
309  // Return log-likelihood
310  return logL;
311 }
312 
313 
314 /*==========================================================================
315  = =
316  = Protected methods =
317  = =
318  ==========================================================================*/
319 
320 /***********************************************************************//**
321  * @brief Initialise class members
322  ***************************************************************************/
324 {
325  // Initialise members
326  m_opt.clear();
327 
328  // Initialise optimizer characteristics
329  m_opt.max_iter(50); // Maximum number of iterations
330  m_opt.max_stalls(10); // Maximum number of stalls
331  m_opt.eps(0.005); // Accuracy of maximum likelihood value
332 
333  // Set optimizer characteristics from optional user parameters
334  if (has_par("like_accuracy")) {
335  m_opt.eps((*this)["like_accuracy"].real());
336  }
337  if (has_par("max_iter")) {
338  m_opt.max_iter((*this)["max_iter"].integer());
339  }
340 
341  // Return
342  return;
343 }
344 
345 
346 /***********************************************************************//**
347  * @brief Copy class members
348  *
349  * @param[in] app Likelihood tool.
350  ***************************************************************************/
352 {
353  // Copy members
354  m_opt = app.m_opt;
355 
356  // Return
357  return;
358 }
359 
360 
361 /***********************************************************************//**
362  * @brief Delete class members
363  ***************************************************************************/
365 {
366  // Return
367  return;
368 }
void copy_members(const ctlikelihood &app)
Copy class members.
#define G_EVALUATE
ctlikelihood & operator=(const ctlikelihood &app)
Assignment operator.
double evaluate(GModelPar &par, const double &value)
Evaluates the log-likelihood function.
virtual ~ctlikelihood(void)
Destructor.
const GOptimizer * opt(void) const
Return optimizer.
Likelihood tool base class interface definition.
Base class for observation tools.
void free_members(void)
Delete class members.
#define G_OPT
ctobservation & operator=(const ctobservation &app)
Assignment operator.
void init_members(void)
Initialise class members.
GObservations m_obs
Observation container.
ctlikelihood(const std::string &name, const std::string &version)
Name constructor.
Base class for likelihood tools.
GOptimizerLM m_opt
Optimizer.