GammaLib  1.7.0.dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
GOptimizerPars.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * GOptimizerPars.cpp - Optimizer parameter container class *
3  * ----------------------------------------------------------------------- *
4  * copyright (C) 2009-2018 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 GOptimizerPars.cpp
23  * @brief Optimizer parameter container 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 "GOptimizerPars.hpp"
33 #include "GTools.hpp"
34 
35 /* __ Method name definitions ____________________________________________ */
36 #define G_ACCESS "GOptimizerPars::operator[](std::string&)"
37 #define G_AT1 "GOptimizerPars::at(int&)"
38 #define G_AT2 "GOptimizerPars::at(std::string&)"
39 #define G_SET1 "GOptimizerPars::set(int&, GOptimizerPar&)"
40 #define G_SET2 "GOptimizerPars::set(std::string&, GOptimizerPar&)"
41 #define G_ATTACH1 "GOptimizerPars::attach(int&, GOptimizerPar*)"
42 #define G_ATTACH2 "GOptimizerPars::attach(std::string&, GOptimizerPar*)"
43 #define G_INSERT1 "GOptimizerPars::insert(int&, GOptimizerPar&)"
44 #define G_INSERT2 "GOptimizerPars::insert(std::string&, GOptimizerPar&)"
45 #define G_REMOVE1 "GOptimizerPars::remove(int&)"
46 #define G_REMOVE2 "GOptimizerPars::remove(std::string&)"
47 
48 
49 /* __ Macros _____________________________________________________________ */
50 
51 /* __ Coding definitions _________________________________________________ */
52 
53 /* __ Debug definitions __________________________________________________ */
54 
55 
56 /*==========================================================================
57  = =
58  = Constructors/destructors =
59  = =
60  ==========================================================================*/
61 
62 /***********************************************************************//**
63  * @brief Void constructor
64  ***************************************************************************/
66 {
67  // Initialise members
68  init_members();
69 
70  // Return
71  return;
72 }
73 
74 
75 /***********************************************************************//**
76  * @brief Parameter constructor
77  *
78  * @param[in] number Number of parameters to allocate.
79  *
80  * Allocates @p number parameters in the parameter container.
81  ***************************************************************************/
83 {
84  // Initialise members
85  init_members();
86 
87  // Allocate parameters
88  for (int i = 0; i < number; ++i) {
89  m_alloc.push_back(true);
90  m_pars.push_back(new GOptimizerPar);
91  }
92 
93  // Return
94  return;
95 }
96 
97 
98 /***********************************************************************//**
99  * @brief Copy constructor
100  *
101  * @param[in] pars Optimizer parameters.
102  ***************************************************************************/
104 {
105  // Initialise members
106  init_members();
107 
108  // Copy members
109  copy_members(pars);
110 
111  // Return
112  return;
113 }
114 
115 
116 /***********************************************************************//**
117  * @brief Destructor
118  ***************************************************************************/
120 {
121  // Free members
122  free_members();
123 
124  // Return
125  return;
126 }
127 
128 
129 /*==========================================================================
130  = =
131  = Operators =
132  = =
133  ==========================================================================*/
134 
135 /***********************************************************************//**
136  * @brief Assignment operator
137  *
138  * @param[in] pars Optimizer parameters.
139  * @return Optimizer parameters.
140  ***************************************************************************/
142 {
143  // Execute only if object is not identical
144  if (this != &pars) {
145 
146  // Free members
147  free_members();
148 
149  // Initialise members
150  init_members();
151 
152  // Copy members
153  copy_members(pars);
154 
155  } // endif: object was not identical
156 
157  // Return
158  return *this;
159 }
160 
161 
162 /***********************************************************************//**
163  * @brief Return pointer to parameter
164  *
165  * @param[in] name Parameter name.
166  *
167  * @exception GException::invalid_argument
168  * Parameter with specified @p name not found in container.
169  *
170  * Returns a pointer to the parameter with the specified @p name.
171  ***************************************************************************/
172 GOptimizerPar* GOptimizerPars::operator[](const std::string& name)
173 {
174  // Get parameter index
175  int index = get_index(name);
176 
177  // Throw exception if model name was not found
178  if (index == -1) {
179  std::string msg = "Parameter \""+name+"\" not found in parameter"
180  " container.\nPlease specify a valid parameter"
181  " name.";
183  }
184 
185  // Return pointer
186  return m_pars[index];
187 }
188 
189 
190 /***********************************************************************//**
191  * @brief Return pointer to parameter (const version)
192  *
193  * @param[in] name Parameter name.
194  *
195  * @exception GException::invalid_argument
196  * Parameter with specified @p name not found in container.
197  *
198  * Returns a pointer to the parameter with the specified @p name.
199  ***************************************************************************/
200 const GOptimizerPar* GOptimizerPars::operator[](const std::string& name) const
201 {
202  // Get parameter index
203  int index = get_index(name);
204 
205  // Throw exception if model name was not found
206  if (index == -1) {
207  std::string msg = "Parameter \""+name+"\" not found in parameter"
208  " container.\nPlease specify a valid parameter"
209  " name.";
211  }
212 
213  // Return pointer
214  return m_pars[index];
215 }
216 
217 
218 /*==========================================================================
219  = =
220  = Public methods =
221  = =
222  ==========================================================================*/
223 
224 /***********************************************************************//**
225  * @brief Clear parameter container
226  *
227  * Removes all parameters from the container.
228  ***************************************************************************/
230 {
231  // Free class members
232  free_members();
233 
234  // Initialise members
235  init_members();
236 
237  // Return
238  return;
239 }
240 
241 
242 /***********************************************************************//**
243  * @brief Clone parameter container
244  *
245  * @return Pointer to deep copy of parameter container
246  ***************************************************************************/
248 {
249  return new GOptimizerPars(*this);
250 }
251 
252 
253 /***********************************************************************//**
254  * @brief Return pointer to parameter
255  *
256  * @param[in] index Parameter index [0,...,size()-1].
257  * @return Pointer to parameter.
258  *
259  * @exception GException::out_of_range
260  * Extension number is out of range.
261  *
262  * Returns a pointer to the parameter with the specified @p index.
263  ***************************************************************************/
265 {
266  // Compile option: raise an exception if index is out of range
267  #if defined(G_RANGE_CHECK)
268  if (index < 0 || index >= size()) {
269  throw GException::out_of_range(G_AT1, "Parameter index", index, size());
270  }
271  #endif
272 
273  // Return pointer
274  return (m_pars[index]);
275 }
276 
277 
278 /***********************************************************************//**
279  * @brief Return pointer to parameter (const version)
280  *
281  * @param[in] index Parameter index [0,...,size()-1].
282  * @return Pointer to parameter.
283  *
284  * @exception GException::out_of_range
285  * Extension number is out of range.
286  *
287  * Returns a pointer to the parameter with the specified @p index.
288  ***************************************************************************/
289 const GOptimizerPar* GOptimizerPars::at(const int& index) const
290 {
291  // Compile option: raise an exception if index is out of range
292  #if defined(G_RANGE_CHECK)
293  if (index < 0 || index >= size()) {
294  throw GException::out_of_range(G_AT1, "Parameter index", index, size());
295  }
296  #endif
297 
298  // Return pointer
299  return (m_pars[index]);
300 }
301 
302 
303 /***********************************************************************//**
304  * @brief Return number of free parameters
305  *
306  * @return Number of free parameters.
307  *
308  * Determines the number of free parameters by collecting statistics from all
309  * model parameters.
310  ***************************************************************************/
311 int GOptimizerPars::nfree(void) const
312 {
313  // Initialise number of free parameters
314  int nfree = 0;
315 
316  // Collect all free parameters
317  for (int i = 0; i < size(); ++i) {
318  if (m_pars[i]->is_free()) {
319  nfree++;
320  }
321  }
322 
323  // Return
324  return nfree;
325 }
326 
327 
328 /***********************************************************************//**
329  * @brief Set parameter in container
330  *
331  * @param[in] index Parameter index [0,...,size()-1].
332  * @param[in] par Parameter.
333  * @return Pointer to deep copy of parameter.
334  *
335  * @exception GException::out_of_range
336  * Parameter index is out of range.
337  *
338  * Set parameter in the container. A deep copy of the parameter will be made.
339  ***************************************************************************/
340 GOptimizerPar* GOptimizerPars::set(const int& index, const GOptimizerPar& par)
341 {
342  // Compile option: raise an exception if index is out of range
343  #if defined(G_RANGE_CHECK)
344  if (index < 0 || index >= size()) {
345  throw GException::out_of_range(G_SET1, "Parameter index", index, size());
346  }
347  #endif
348 
349  // Free existing parameter only if it differs from current parameter.
350  // This prevents unintential deallocation of the argument
351  if ((m_alloc[index]) && (m_pars[index] != &par)) {
352  delete m_pars[index];
353  }
354 
355  // Clone parameter
356  GOptimizerPar* ptr = par.clone();
357 
358  // Set parameter
359  m_alloc[index] = true;
360  m_pars[index] = ptr;
361 
362  // Return parameter pointer
363  return ptr;
364 }
365 
366 
367 /***********************************************************************//**
368  * @brief Set parameter in container
369  *
370  * @param[in] name Parameter name.
371  * @param[in] par Parameter.
372  * @return Pointer to deep copy of parameter.
373  *
374  * @exception GException::invalid_argument
375  * Specified parameter @p name not found in container.
376  ***************************************************************************/
377 GOptimizerPar* GOptimizerPars::set(const std::string& name, const GOptimizerPar& par)
378 {
379  // Get parameter index
380  int index = get_index(name);
381 
382  // Throw exception if model name was not found
383  if (index == -1) {
384  std::string msg = "Parameter \""+name+"\" not found in parameter"
385  " container.\nPlease specify a valid parameter"
386  " name.";
388  }
389 
390  // Set parameter
391  return set(index, par);
392 }
393 
394 
395 /***********************************************************************//**
396  * @brief Append parameter to container
397  *
398  * @param[in] par Parameter reference.
399  * @return Pointer to appended parameter.
400  *
401  * Appends a parameter to the container. The method stores a copy of the
402  * parameter in the container, hence the client may delete the parameter
403  * after the method is called.
404  ***************************************************************************/
406 {
407  // Clone parameter
408  GOptimizerPar* ptr = par.clone();
409 
410  // Inserts deep copy of parameter
411  m_alloc.push_back(true);
412  m_pars.push_back(ptr);
413 
414  // Return parameter pointer
415  return ptr;
416 }
417 
418 
419 /***********************************************************************//**
420  * @brief Attach parameter to container
421  *
422  * @param[in] par Parameter pointer.
423  ***************************************************************************/
425 {
426  // Push pointer in vector if it is valid
427  if (par != NULL) {
428  m_alloc.push_back(false);
429  m_pars.push_back(par);
430  }
431 
432  // Return
433  return;
434 }
435 
436 
437 /***********************************************************************//**
438  * @brief Attach parameter to container at the specified index
439  *
440  * @param[in] index Parameter index [0,...,size()-1].
441  * @param[in] par Parameter pointer.
442  *
443  * @exception GException::out_of_range
444  * Parameter @p index is not valid.
445  *
446  * Attaches parameter pointer at the specified @p index.
447  ***************************************************************************/
448 void GOptimizerPars::attach(const int& index, GOptimizerPar* par)
449 {
450  // Compile option: raise an exception if index is out of range
451  #if defined(G_RANGE_CHECK)
452  if (index < 0 || index >= size()) {
453  throw GException::out_of_range(G_ATTACH1, "Parameter index", index, size());
454  }
455  #endif
456 
457  // Delete parameter if it has been allocated
458  if (m_alloc[index]) {
459  delete m_pars[index];
460  }
461 
462  // Set parameter
463  m_alloc[index] = false;
464  m_pars[index] = par;
465 
466  // Return
467  return;
468 }
469 
470 
471 /***********************************************************************//**
472  * @brief Attach parameter to container at the specified index
473  *
474  * @param[in] name Parameter name.
475  * @param[in] par Parameter pointer.
476  *
477  * @exception GException::out_of_range
478  * Parameter @p index is not valid.
479  *
480  * Attaches parameter pointer at the specified @p index.
481  ***************************************************************************/
482 void GOptimizerPars::attach(const std::string& name, GOptimizerPar* par)
483 {
484  // Get parameter index
485  int index = get_index(name);
486 
487  // Throw exception if model name was not found
488  if (index == -1) {
489  std::string msg = "Parameter \""+name+"\" not found in parameter"
490  " container.\nPlease specify a valid parameter"
491  " name.";
493  }
494 
495  // Remove parameter
496  attach(index, par);
497 
498  // Return
499  return;
500 }
501 
502 
503 /***********************************************************************//**
504  * @brief Insert parameter into container
505  *
506  * @param[in] index Parameter index [0,...,size()-1].
507  * @param[in] par Parameter.
508  * @return Pointer to deep copy of parameter.
509  *
510  * @exception GException::out_of_range
511  * Parameter index is out of range.
512  *
513  * Set parameter in the container. A deep copy of the parameter will be made.
514  ***************************************************************************/
515 GOptimizerPar* GOptimizerPars::insert(const int& index, const GOptimizerPar& par)
516 {
517  // Compile option: raise an exception if index is out of range
518  #if defined(G_RANGE_CHECK)
519  if (index < 0 || index >= size()) {
520  throw GException::out_of_range(G_INSERT1, "Parameter index", index, size());
521  }
522  #endif
523 
524  // Clone parameter
525  GOptimizerPar* ptr = par.clone();
526 
527  // Inserts deep copy of parameter
528  m_alloc.insert(m_alloc.begin()+index, true);
529  m_pars.insert(m_pars.begin()+index, ptr);
530 
531  // Return parameter pointer
532  return ptr;
533 }
534 
535 
536 /***********************************************************************//**
537  * @brief Insert parameter into container
538  *
539  * @param[in] name Parameter name.
540  * @param[in] par Parameter.
541  * @return Pointer to deep copy of parameter.
542  *
543  * @exception GException::invalid_argument
544  * Specified parameter @p name not found in container.
545  ***************************************************************************/
546 GOptimizerPar* GOptimizerPars::insert(const std::string& name,
547  const GOptimizerPar& par)
548 {
549  // Get parameter index
550  int index = get_index(name);
551 
552  // Throw exception if model name was not found
553  if (index == -1) {
554  std::string msg = "Parameter \""+name+"\" not found in parameter"
555  " container.\nPlease specify a valid parameter"
556  " name.";
558  }
559 
560  // Insert parameter
561  return insert(index, par);
562 }
563 
564 
565 /***********************************************************************//**
566  * @brief Remove parameter from container
567  *
568  * @param[in] index Parameter index [0,...,size()-1].
569  *
570  * @exception GException::out_of_range
571  * Parameter index is out of range.
572  *
573  * Remove parameter of specified @p index from container.
574  ***************************************************************************/
575 void GOptimizerPars::remove(const int& index)
576 {
577  // Compile option: raise exception if index is out of range
578  #if defined(G_RANGE_CHECK)
579  if (index < 0 || index >= size()) {
580  throw GException::out_of_range(G_REMOVE1, "Parameter index",
581  index, size());
582  }
583  #endif
584 
585  // Delete parameter if it has been allocated
586  if (m_alloc[index]) {
587  delete m_pars[index];
588  }
589 
590  // Erase parameter from container
591  m_alloc.erase(m_alloc.begin() + index);
592  m_pars.erase(m_pars.begin() + index);
593 
594  // Return
595  return;
596 }
597 
598 
599 /***********************************************************************//**
600  * @brief Remove parameter from container
601  *
602  * @param[in] name Parameter name.
603  *
604  * @exception GException::invalid_argument
605  * Specified parameter @p name not found in container.
606  ***************************************************************************/
607 void GOptimizerPars::remove(const std::string& name)
608 {
609  // Get parameter index
610  int index = get_index(name);
611 
612  // Throw exception if model name was not found
613  if (index == -1) {
614  std::string msg = "Parameter \""+name+"\" not found in parameter"
615  " container.\nPlease specify a valid parameter"
616  " name.";
618  }
619 
620  // Remove parameter
621  remove(index);
622 
623  // Return
624  return;
625 }
626 
627 
628 /***********************************************************************//**
629  * @brief Append parameter container
630  *
631  * @param[in] pars Parameter container.
632  *
633  * Append parameter container to the container. All parameters that were
634  * allocated within @p pars will be clones, for the other parameters, the
635  * pointers will be copied.
636  ***************************************************************************/
638 {
639  // Do nothing if parameter container is empty
640  if (!pars.is_empty()) {
641 
642  // Get size. Note that we extract the size first to avoid an
643  // endless loop that arises when a container is appended to
644  // itself.
645  int num = pars.size();
646 
647  // Reserve enough space
648  reserve(size() + num);
649 
650  // Loop over all parameters
651  for (int i = 0; i < num; ++i) {
652  GOptimizerPar* par = (pars.m_alloc[i]) ? pars.m_pars[i]->clone()
653  : pars.m_pars[i];
654  m_pars.push_back(par);
655  }
656 
657  } // endif: parameter container was not empty
658 
659  // Return
660  return;
661 }
662 
663 
664 /***********************************************************************//**
665  * @brief Signals if parameter name exists
666  *
667  * @param[in] name Parameter name.
668  * @return True if parameter with specified @p name exists.
669  *
670  * Searches all parameter names for a match with the specified @p name. If
671  * the specified name has been found, true is returned.
672  ***************************************************************************/
673 bool GOptimizerPars::contains(const std::string& name) const
674 {
675  // Get model index
676  int index = get_index(name);
677 
678  // Return
679  return (index != -1);
680 }
681 
682 
683 /***********************************************************************//**
684  * @brief Print parameters
685  *
686  * @param[in] chatter Chattiness.
687  * @return String containing parameter container information.
688  *
689  * Prints all parameters into a string.
690  ***************************************************************************/
691 std::string GOptimizerPars::print(const GChatter& chatter) const
692 {
693  // Initialise result string
694  std::string result;
695 
696  // Continue only if chatter is not silent
697  if (chatter != SILENT) {
698 
699  // Append header
700  result.append("=== GOptimizerPars ===");
701 
702  // Append information
703  result.append("\n"+gammalib::parformat("Number of parameters"));
704  result.append(gammalib::str(size()));
705 
706  // Append parameters
707  for (int i = 0; i < size(); ++i) {
708  result.append("\n"+m_pars[i]->print(chatter));
709  }
710 
711  } // endif: chatter was not silent
712 
713  // Return result
714  return result;
715 }
716 
717 
718 
719 /*==========================================================================
720  = =
721  = Private methods =
722  = =
723  ==========================================================================*/
724 
725 /***********************************************************************//**
726  * @brief Initialise class members
727  ***************************************************************************/
729 {
730  // Initialise members
731  m_alloc.clear();
732  m_pars.clear();
733 
734  // Return
735  return;
736 }
737 
738 
739 /***********************************************************************//**
740  * @brief Copy class members
741  *
742  * @param[in] pars Optimizer parameters.
743  ***************************************************************************/
745 {
746  // Copy members
747  m_alloc = pars.m_alloc;
748 
749  // Clone or copy parameter pointers, depending on whether they have
750  // been allocated or not in the instance from which we copy
751  for (int i = 0; i < pars.size(); ++i) {
752  GOptimizerPar* par = (pars.m_alloc[i]) ? pars.m_pars[i]->clone()
753  : pars.m_pars[i];
754  m_pars.push_back(par);
755  }
756 
757  // Return
758  return;
759 }
760 
761 
762 /***********************************************************************//**
763  * @brief Delete class members
764  ***************************************************************************/
766 {
767  // Free all allocated parameters
768  for (int i = 0; i < size(); ++i) {
769  if (m_alloc[i] && m_pars[i] != NULL) {
770  delete m_pars[i];
771  m_pars[i] = NULL;
772  }
773  }
774 
775  // Return
776  return;
777 }
778 
779 
780 /***********************************************************************//**
781  * @brief Return parameter index by name
782  *
783  * @param[in] name Parameter name.
784  * @return Parameter index (-1 if parameter name has not been found)
785  *
786  * Returns parameter index based on the specified @p name. If no parameter
787  * with the specified @p name is found the method returns -1.
788  ***************************************************************************/
789 int GOptimizerPars::get_index(const std::string& name) const
790 {
791  // Initialise index
792  int index = -1;
793 
794  // Search parameter with specified name
795  for (int i = 0; i < size(); ++i) {
796  if (m_pars[i]->name() == name) {
797  index = i;
798  break;
799  }
800  }
801 
802  // Return index
803  return index;
804 }
void remove(const int &index)
Remove parameter from container.
GOptimizerPar * clone(void) const
Clone parameter.
std::string number(const std::string &noun, const int &number)
Convert singular noun into number noun.
Definition: GTools.cpp:1046
#define G_ATTACH2
GOptimizerPar * set(const int &index, const GOptimizerPar &par)
Set parameter in container.
std::vector< GOptimizerPar * > m_pars
List of parameters.
GOptimizerPar * insert(const int &index, const GOptimizerPar &par)
Insert parameter into container.
GOptimizerPars(void)
Void constructor.
GOptimizerPar * at(const int &index)
Return pointer to parameter.
Optimizer parameter container class.
void reserve(const int &num)
Reserves space for parameters in container.
bool is_empty(void) const
Signals if there are no parameters in container.
Gammalib tools definition.
#define G_REMOVE1
#define G_AT1
void clear(void)
Clear parameter container.
GOptimizerPar * operator[](const int &index)
Return pointer to parameter.
void init_members(void)
Initialise class members.
#define G_SET1
GOptimizerPars & operator=(const GOptimizerPars &pars)
Assignment operator.
GOptimizerPars * clone(void) const
Clone parameter container.
#define G_SET2
GChatter
Definition: GTypemaps.hpp:33
std::vector< bool > m_alloc
Flags allocation.
Optimizer parameters base class definition.
void attach(GOptimizerPar *par)
Attach parameter to container.
virtual ~GOptimizerPars(void)
Destructor.
#define G_INSERT1
bool contains(const std::string &name) const
Signals if parameter name exists.
void extend(const GOptimizerPars &pars)
Append parameter container.
#define G_ATTACH1
GOptimizerPar * append(const GOptimizerPar &par)
Append parameter to container.
int get_index(const std::string &name) const
Return parameter index by name.
#define G_REMOVE2
int nfree(void) const
Return number of free parameters.
#define G_ACCESS
Exception handler interface definition.
#define G_INSERT2
int size(void) const
Return number of parameters in container.
void free_members(void)
Delete class members.
std::string parformat(const std::string &s, const int &indent=0)
Convert string in parameter format.
Definition: GTools.cpp:1022
void copy_members(const GOptimizerPars &pars)
Copy class members.
std::string print(const GChatter &chatter=NORMAL) const
Print parameters.
std::string str(const unsigned short int &value)
Convert unsigned short integer value into string.
Definition: GTools.cpp:413
Optimizer parameter class.