GammaLib 2.1.0.dev
Loading...
Searching...
No Matches
GOptimizerPar.cpp
Go to the documentation of this file.
1/***************************************************************************
2 * GOptimizerPar.cpp - Optimizer parameter class *
3 * ----------------------------------------------------------------------- *
4 * copyright (C) 2013-2020 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 GOptimizerPar.cpp
23 * @brief Optimizer parameter class implementation
24 * @author Juergen Knoedlseder
25 */
26
27/* __ Includes ___________________________________________________________ */
28#ifdef HAVE_CONFIG_H
29#include <config.h>
30#endif
31#include "GException.hpp"
32#include "GOptimizerPar.hpp"
33#include "GTools.hpp"
34
35/* __ Method name definitions ____________________________________________ */
36#define G_CONSTRUCT "GOptimizerPar::GOptimizerPar(std::string&, double&,"\
37 " double&)"
38#define G_MIN "GOptimizerPar::min(double&)"
39#define G_MAX "GOptimizerPar::max(double&)"
40#define G_FACTOR_VALUE "GOptimizerPar::factor_value(double&)"
41#define G_FACTOR_MIN "GOptimizerPar::factor_min(double&)"
42#define G_FACTOR_MAX "GOptimizerPar::factor_max(double&)"
43#define G_SCALE "GOptimizerPar::scale(double&)"
44
45/* __ Macros _____________________________________________________________ */
46
47/* __ Coding definitions _________________________________________________ */
48
49/* __ Debug definitions __________________________________________________ */
50
51
52/*==========================================================================
53 = =
54 = Constructors/destructors =
55 = =
56 ==========================================================================*/
57
58/***********************************************************************//**
59 * @brief Void constructor
60 ***************************************************************************/
62{
63 // Initialise members
65
66 // Return
67 return;
68}
69
70
71/***********************************************************************//**
72 * @brief Parameter constructor
73 *
74 * @param[in] name Parameter name.
75 * @param[in] value Parameter value.
76 *
77 * Constructs a parameter from a parameter @p name and a parameter @p value.
78 *
79 * The parameter is auto-scaled, which for a @p value that differs from zero
80 * sets the scale factor to @p value and the @p factor_value to unity. For a
81 * @p value of zero, the scale factor will be set to unity and the
82 * @p factor_value will be set to @p value.
83 ***************************************************************************/
84GOptimizerPar::GOptimizerPar(const std::string& name, const double& value)
85{
86 // Initialise members
88
89 // Set name attribute
90 m_name = name;
91
92 // Set auto-scaled factor and scale attributes
93 if (value != 0.0) {
94 m_factor_value = 1.0;
95 m_scale = value;
96 }
97 else {
99 m_scale = 1.0;
100 }
101
102 // Return
103 return;
104}
105
106
107/***********************************************************************//**
108 * @brief Parameter constructor
109 *
110 * @param[in] name Parameter name.
111 * @param[in] factor Parameter value factor.
112 * @param[in] scale Parameter scaling (non-zero value).
113 *
114 * @exception GException::invalid_argument
115 * Sacle factor of 0 specified.
116 *
117 * Constructs a parameter from a parameter @p name, value @p factor
118 * and @p scale factor. The @p scale factor needs to be a non-zero value.
119 * If the @p scale factor is zero, an exception is thrown.
120 ***************************************************************************/
121GOptimizerPar::GOptimizerPar(const std::string& name,
122 const double& factor,
123 const double& scale)
124{
125 // Make sure that scale is not zero
126 if (scale == 0.0) {
127 std::string msg = "Specified a parameter scale factor of 0.\n"
128 "Parameters need a non-zero scale factor.";
130 }
131
132 // Initialise members
133 init_members();
134
135 // Set attributes
136 m_name = name;
137 m_factor_value = factor;
138 m_scale = scale;
139
140 // Return
141 return;
142}
143
144
145/***********************************************************************//**
146 * @brief Copy constructor
147 *
148 * @param[in] par Function parameter.
149 ***************************************************************************/
151{
152 // Initialise members
153 init_members();
154
155 // Copy members
156 copy_members(par);
157
158 // Return
159 return;
160}
161
162
163/***********************************************************************//**
164 * @brief Destructor
165 ***************************************************************************/
167{
168 // Free members
169 free_members();
170
171 // Return
172 return;
173}
174
175
176/*==========================================================================
177 = =
178 = Operators =
179 = =
180 ==========================================================================*/
181
182/***********************************************************************//**
183 * @brief Assignment operator
184 *
185 * @param[in] par Function parameter.
186 * @return Function parameter.
187 ***************************************************************************/
189{
190 // Execute only if object is not identical
191 if (this != &par) {
192
193 // Free members
194 free_members();
195
196 // Initialise members
197 init_members();
198
199 // Copy members
200 copy_members(par);
201
202 } // endif: object was not identical
203
204 // Return
205 return *this;
206}
207
208
209/*==========================================================================
210 = =
211 = Public methods =
212 = =
213 ==========================================================================*/
214
215/***********************************************************************//**
216 * @brief Clear parameter
217 *
218 * Resets parameter to a clean initial state.
219 ***************************************************************************/
221{
222 // Free class members
223 free_members();
224
225 // Initialise members
226 init_members();
227
228 // Return
229 return;
230}
231
232
233/***********************************************************************//**
234 * @brief Clone parameter
235 *
236 * @return Pointer to deep copy of parameter.
237 ***************************************************************************/
239{
240 // Clone parameter
241 return new GOptimizerPar(*this);
242}
243
244
245/***********************************************************************//**
246 * @brief Set parameter value
247 *
248 * @param[in] value Parameter value.
249 *
250 * Sets the parameter value. The method stores the value factor which is
251 * obtained by dividing the @p value by the scale factor.
252 *
253 * The method calls factor_value() for assigning the value factor, and this
254 * method will verify that the value lies within the specified boundaries.
255 ***************************************************************************/
256void GOptimizerPar::value(const double& value)
257{
258 // Set value factor. The GOptimizerPar class makes sure that m_scale is
259 // never 0, so no test is needed here
261
262 // Return
263 return;
264}
265
266
267/***********************************************************************//**
268 * @brief Set parameter error
269 *
270 * @param[in] error Parameter error.
271 *
272 * Sets the parameter error. The method stores the error factor which is
273 * obtained by dividing the @p error by the scale factor.
274 ***************************************************************************/
275void GOptimizerPar::error(const double& error)
276{
277 // Set error factor. The GOptimizerPar class makes sure that m_scale is
278 // never 0, so no test is needed here
280
281 // Return
282 return;
283}
284
285
286/***********************************************************************//**
287 * @brief Set parameter gradient
288 *
289 * @param[in] gradient Parameter gradient.
290 *
291 * Sets the parameter gradient. The method stores the gradient factor which
292 * is obtained by multiplying @p gradient by the scale factor.
293 ***************************************************************************/
294void GOptimizerPar::gradient(const double& gradient)
295{
296 // Set gradient factor.
298
299 // Return
300 return;
301}
302
303
304/***********************************************************************//**
305 * @brief Set minimum parameter boundary
306 *
307 * @param[in] min Minimum parameter boundary.
308 *
309 * @exception GException::invalid_argument
310 * Minimum parameter boundary is larger than the parameter value
311 *
312 * Sets the minimum parameter boundary.
313 ***************************************************************************/
314void GOptimizerPar::min(const double& min)
315{
316 // Check if minimum is larger than value
317 if (min > value()) {
318 std::string msg = "Specified minimum parameter value "+
319 gammalib::str(min)+" is larger than the parameter "
320 "value "+gammalib::str(value())+".";
322 }
323
324 // If scale is negative then set maximum factor boundary
325 if (m_scale < 0) {
327 m_has_factor_max = true;
328 }
329
330 // ... otherwise set minimum factor boundary
331 else {
333 m_has_factor_min = true;
334 }
335
336 // Return
337 return;
338}
339
340
341/***********************************************************************//**
342 * @brief Set maximum parameter boundary
343 *
344 * @param[in] max Maximum parameter boundary.
345 *
346 * @exception GException::invalid_argument
347 * Maximum parameter boundary is smaller than the parameter value
348 *
349 * Sets the maximum parameter boundary.
350 ***************************************************************************/
351void GOptimizerPar::max(const double& max)
352{
353 // Check if maximum is smaller than value
354 if (max < value()) {
355 std::string msg = "Specified maximum parameter value "+
356 gammalib::str(max)+" is smaller than the parameter "
357 "value "+gammalib::str(value())+".";
359 }
360
361 // If scale is negative then set minimum factor boundary
362 if (m_scale < 0) {
364 m_has_factor_min = true;
365 }
366
367 // ... otherwise set maximum factor boundary
368 else {
370 m_has_factor_max = true;
371 }
372
373 // Return
374 return;
375}
376
377
378/***********************************************************************//**
379 * @brief Set parameter value factor
380 *
381 * @param[in] value Value factor.
382 *
383 * @exception GException::invalid_argument
384 * Parameter @p value outside [min,max] boundaries.
385 *
386 * Sets the value factor of the parameter. The method makes sure that
387 * none of the boundaries is violated. Otherwise, exceptions are thrown.
388 ***************************************************************************/
389void GOptimizerPar::factor_value(const double& value)
390{
391 // If there is a minimum boundary and if value is below this boundary
392 // then throw an exception
393 if (has_factor_min() && (value < factor_min())) {
394 std::string msg = "Specified value factor "+gammalib::str(value)+
395 " is smaller than the minimum boundary "+
398 }
399
400 // If there is a maximum boundary and if value is above this boundary
401 // then throw an exception
402 if (has_factor_max() && (value > factor_max())) {
403 std::string msg = "Specified value factor "+gammalib::str(value)+
404 " is larger than the maximum boundary "+
407 }
408
409 // Assign value
411
412 // Return
413 return;
414}
415
416
417/***********************************************************************//**
418 * @brief Set minimum parameter boundary factor
419 *
420 * @param[in] min Minimum parameter boundary factor.
421 *
422 * @exception GException::invalid_argument
423 * Minimum parameter boundary factor larger than value factor.
424 *
425 * Sets the minimum boundary factor of the parameter. The method makes
426 * sure that the minimum is not larger than the actual value factor.
427 * Otherwise, an exception is thrown.
428 ***************************************************************************/
430{
431 // Check if minimum is larger than value
432 if (min > m_factor_value) {
433 std::string msg = "Specified minimum factor "+gammalib::str(min)+
434 " is larger than the value factor "+
437 }
438
439 // Set value and flag
441 m_has_factor_min = true;
442
443 // Return
444 return;
445}
446
447
448/***********************************************************************//**
449 * @brief Set maximum parameter boundary factor
450 *
451 * @param[in] max Maximum parameter boundary factor.
452 *
453 * @exception GException::invalid_argument
454 * Maximum parameter boundary factor smaller than value factor.
455 *
456 * Sets the maximum boundary factor of the parameter. The method makes
457 * sure that the maximum is not smaller than the actual value factor.
458 * Otherwise, an exception is thrown.
459 ***************************************************************************/
461{
462 // Check if maximum is smaller than value
463 if (max < m_factor_value) {
464 std::string msg = "Specified maximum factor "+gammalib::str(max)+
465 " is smaller than the value factor "+
468 }
469
470 // Set value and flag
472 m_has_factor_max = true;
473
474 // Return
475 return;
476}
477
478
479/***********************************************************************//**
480 * @brief Set minimum and maximum parameter boundary factors
481 *
482 * @param[in] min Minimum parameter boundary factor.
483 * @param[in] max Maximum parameter boundary factor.
484 *
485 * Sets the minimum and maximum parameter boundary factors. The method calls
486 * the factor_min() and factor_max() methods which perform validity checking
487 * of the arguments.
488 ***************************************************************************/
489void GOptimizerPar::factor_range(const double& min, const double& max)
490{
491 // Set minimum and maximum
494
495 // Return
496 return;
497}
498
499
500/***********************************************************************//**
501 * @brief Set scale factor
502 *
503 * @param[in] scale Scale factor.
504 *
505 * @exception GException::invalid_argument
506 * Sacle factor of 0 specified.
507 *
508 * Sets the scale factor of the parameter. All parameter attributes are
509 * rescaled accordingly.
510 *
511 * An exception is thrown if a scale factor of 0 is specified.
512 ***************************************************************************/
513void GOptimizerPar::scale(const double& scale)
514{
515 // Make sure that scale is not zero
516 if (scale == 0.0) {
517 std::string msg = "Specified parameter scale factor of 0.\n"
518 "Parameters need a non-zero scale factor.";
520 }
521
522 // Set rescaling
523 double rescale = m_scale/scale;
524
525 // Set new scale factor
526 m_scale = scale;
527
528 // Set values, error, gradient, min and max
529 m_factor_value *= rescale;
530 m_factor_error *= rescale;
531 m_factor_gradient /= rescale;
532 m_factor_min *= rescale;
533 m_factor_max *= rescale;
534
535 // If re-scaling changes sign then swap minimum and maximum boundary
536 if (rescale < 0.0) {
537
538 // Store maximum in swap space
539 bool bswap = m_has_factor_max;
540 double dswap = m_factor_max;
541
542 // Set maximum
545
546 // Set minimum
547 m_has_factor_min = bswap;
548 m_factor_min = dswap;
549 }
550
551 // Return
552 return;
553}
554
555
556/***********************************************************************//**
557 * @brief Autoscale parameter
558 *
559 * Sets the value factor to unity and the scale factor to the real value
560 * of the parameter. The method will also adjust the error factor and
561 * gradient factor, as well as the minimum and maximum factors if they
562 * exist.
563 *
564 * The method does nothing if the actual value factor is zero.
565 ***************************************************************************/
567{
568 // Get value
569 double value = this->value();
570
571 // Continue only if the value is non-zero
572 if (value != 0.0) {
573
574 // Re-scale to value
575 this->scale(value);
576
577 } // endif: value was non-zero
578
579 // Return
580 return;
581}
582
583
584/***********************************************************************//**
585 * @brief Print parameter information
586 *
587 * @param[in] chatter Chattiness.
588 * @return String with parameter information.
589 ***************************************************************************/
590std::string GOptimizerPar::print(const GChatter& chatter) const
591{
592 // Initialise result string
593 std::string result;
594
595 // Continue only if chatter is not silent
596 if (chatter != SILENT) {
597
598 // Append parameter name
599 result.append(gammalib::parformat(" "+name()));
600
601 // Append value
602 result.append(gammalib::str(value()));
603
604 // For free parameters, append statistical uncertainty
605 if (m_free) {
606 result.append(" +/- "+gammalib::str(error()));
607 }
608
609 // Append parameter limites if they exist
610 if (has_min() && has_max()) {
611 result.append(" ["+gammalib::str(min()) + ","+gammalib::str(max())+"]");
612 }
613 else if (has_min()) {
614 result.append(" ["+gammalib::str(min()) + ",infty[");
615 }
616 else if (has_max()) {
617 result.append(" ]-infty,"+gammalib::str(max())+"]");
618 }
619
620 // Append parameter unit
621 result.append(" "+m_unit);
622
623 // Signal if parameter was free or fixed
624 if (m_free) {
625 result.append(" (free");
626 }
627 else {
628 result.append(" (fixed");
629 }
630
631 // Append parameter scale
632 result.append(",scale="+gammalib::str(m_scale));
633
634 // Signal if parameter has analytic gradient
635 if (m_has_grad) {
636 result.append(",gradient)");
637 }
638 else {
639 result.append(")");
640 }
641
642 } // endif: chatter was not silent
643
644 // Return result
645 return result;
646}
647
648
649/*==========================================================================
650 = =
651 = Private methods =
652 = =
653 ==========================================================================*/
654
655/***********************************************************************//**
656 * @brief Initialise class members
657 ***************************************************************************/
659{
660 // Initialise members
661 m_name.clear();
662 m_unit.clear();
663 m_factor_value = 0.0;
664 m_factor_error = 0.0;
665 m_factor_gradient = 0.0;
666 m_factor_min = 0.0;
667 m_factor_max = 0.0;
668 m_scale = 1.0;
669 m_free = true;
670 m_has_factor_min = false;
671 m_has_factor_max = false;
672 m_has_grad = false;
673
674 // Return
675 return;
676}
677
678
679/***********************************************************************//**
680 * @brief Copy class members
681 *
682 * @param[in] par Model parameter.
683 ***************************************************************************/
685{
686 // Copy members
687 m_name = par.m_name;
688 m_unit = par.m_unit;
694 m_scale = par.m_scale;
695 m_free = par.m_free;
699
700 // Return
701 return;
702}
703
704
705/***********************************************************************//**
706 * @brief Delete class members
707 ***************************************************************************/
709{
710 // Return
711 return;
712}
Exception handler interface definition.
#define G_MIN(a, b)
#define G_MAX(a, b)
#define G_CONSTRUCT
Definition GModelPar.cpp:36
#define G_FACTOR_VALUE
Definition GModelPar.cpp:37
#define G_SCALE
Definition GModel.cpp:38
Optimizer parameter class interface definition.
Gammalib tools definition.
GChatter
Definition GTypemaps.hpp:33
@ SILENT
Definition GTypemaps.hpp:34
double min(const GVector &vector)
Computes minimum vector element.
Definition GVector.cpp:954
double max(const GVector &vector)
Computes maximum vector element.
Definition GVector.cpp:983
Optimizer parameter class.
bool m_has_grad
Parameter has analytic gradient.
const double & factor_max(void) const
Return parameter maximum factor boundary.
double m_factor_error
Uncertainty in parameter factor value.
const double & factor_value(void) const
Return parameter factor value.
const double & factor_error(void) const
Return parameter factor error.
const double & scale(void) const
Return parameter scale.
void init_members(void)
Initialise class members.
virtual ~GOptimizerPar(void)
Destructor.
void copy_members(const GOptimizerPar &par)
Copy class members.
double m_factor_gradient
Function factor gradient.
void free_members(void)
Delete class members.
double m_factor_min
Parameter minimum factor value.
double error(void) const
Return parameter error.
bool has_min(void) const
Signal if parameter has minimum boundary.
std::string print(const GChatter &chatter=NORMAL) const
Print parameter information.
double m_scale
Parameter scaling (true = factor * scale)
double max(void) const
Return parameter maximum boundary.
bool m_has_factor_min
Parameter has minimum factor boundary.
double m_factor_value
Parameter factor value.
double m_factor_max
Parameter maximum factor value.
std::string m_name
Parameter name.
double min(void) const
Return parameter minimum boundary.
bool m_has_factor_max
Parameter has maximum factor boundary.
const double & factor_gradient(void) const
Return parameter factor gradient.
bool has_factor_min(void) const
Signal if parameter has minimum factor boundary.
void autoscale(void)
Autoscale parameter.
bool has_max(void) const
Signal if parameter has maximum boundary.
bool m_free
Parameter is free.
GOptimizerPar(void)
Void constructor.
void factor_range(const double &min, const double &max)
Set minimum and maximum parameter boundary factors.
const double & factor_min(void) const
Return parameter minimum factor boundary.
double gradient(void) const
Return parameter gradient.
bool has_factor_max(void) const
Signal if parameter has maximum factor boundary.
GOptimizerPar * clone(void) const
Clone parameter.
void clear(void)
Clear parameter.
std::string m_unit
Parameter unit.
double value(void) const
Return parameter value.
GOptimizerPar & operator=(const GOptimizerPar &par)
Assignment operator.
const std::string & name(void) const
Return parameter name.
std::string parformat(const std::string &s, const int &indent=0)
Convert string in parameter format.
Definition GTools.cpp:1162
std::string str(const unsigned short int &value)
Convert unsigned short integer value into string.
Definition GTools.cpp:508