00001 /*************************************************************************** 00002 * GOptimizerPar.hpp - Optimizer parameter class * 00003 * ----------------------------------------------------------------------- * 00004 * copyright (C) 2013-2016 by Juergen Knoedlseder * 00005 * ----------------------------------------------------------------------- * 00006 * * 00007 * This program is free software: you can redistribute it and/or modify * 00008 * it under the terms of the GNU General Public License as published by * 00009 * the Free Software Foundation, either version 3 of the License, or * 00010 * (at your option) any later version. * 00011 * * 00012 * This program is distributed in the hope that it will be useful, * 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00015 * GNU General Public License for more details. * 00016 * * 00017 * You should have received a copy of the GNU General Public License * 00018 * along with this program. If not, see <http://www.gnu.org/licenses/>. * 00019 * * 00020 ***************************************************************************/ 00021 /** 00022 * @file GOptimizerPar.hpp 00023 * @brief Optimizer parameter class interface definition 00024 * @author Juergen Knoedlseder 00025 */ 00026 00027 #ifndef GOPTIMIZERPAR_HPP 00028 #define GOPTIMIZERPAR_HPP 00029 00030 /* __ Includes ___________________________________________________________ */ 00031 #include <string> 00032 #include <cmath> 00033 #include "GBase.hpp" 00034 #include "GXmlElement.hpp" 00035 00036 00037 /***********************************************************************//** 00038 * @class GOptimizerPar 00039 * 00040 * @brief Optimizer parameter class 00041 * 00042 * This class implements a function parameter for the optimizer. A function 00043 * parameter is a numerical value that is used to describe a function. 00044 * 00045 * A function parameter has the following attributes: 00046 * - @p value gives the numerical value of the parameter 00047 * - @p error gives the statistical uncertainty in the parameter value 00048 * - @p gradient gives the gradient of a function with respect to the 00049 * parameter 00050 * - @p min gives the minimum value that the parameter value can take 00051 * - @p max gives the maximum value that the parameter value can take 00052 * 00053 * The parameter attributes are set and retrieved using the value(), 00054 * error(), gradient(), min() and max() methods, respectively. Furthermore, 00055 * the range() method is used to simultaneously set the minimum and maximum 00056 * value of a parameter. 00057 * 00058 * The minimum and maximum values are optional, and existence of these 00059 * attributes is tested using the has_min() and has_max() methods, 00060 * respectively. The minimum value, maximum value are removed using the 00061 * remove_min() and remove_max() methods. Simultaneous removal of minimum 00062 * and maximum values is done using the remove_range() method. 00063 * 00064 * Each parameter has furthermore the following properties: 00065 * - @p free specifies whether the parameter should be fitted 00066 * - @p grad specifies whether the parameter gradient is computed 00067 * analytically (true) or numerically (false) 00068 * 00069 * The parameter property @p free is set using the free() and fix() 00070 * methods and it is retrieved using the is_free() and is_fixed() methods. 00071 * The attribute @p grad is set and retrieved using the has has_grad() 00072 * methods. 00073 * 00074 * Each function parameter is factorized into a @p factor and a @p scale 00075 * term. The GOptimizerPar class stores the factors and the scale factor has 00076 * data members, and the true values are computed using the following 00077 * relations: 00078 * 00079 * value = m_factor_value * m_scale 00080 * error = m_factor_error * m_scale 00081 * gradient = m_factor_gradient * m_scale 00082 * min = m_factor_min * m_scale 00083 * max = m_factor_max * m_scale 00084 * 00085 * The @p factor and @p scale terms can be set and retrieved using the 00086 * factor_value(), factor_error(), factor_gradient(), factor_min(), 00087 * factor_max() and scale() methods. 00088 ***************************************************************************/ 00089 class GOptimizerPar : public GBase { 00090 00091 public: 00092 // Constructors and destructors 00093 GOptimizerPar(void); 00094 GOptimizerPar(const std::string& name, const double& value); 00095 GOptimizerPar(const std::string& name, const double& factor, 00096 const double& scale); 00097 GOptimizerPar(const GOptimizerPar& par); 00098 virtual ~GOptimizerPar(void); 00099 00100 // Operators 00101 GOptimizerPar& operator=(const GOptimizerPar& par); 00102 00103 // Attribute methods 00104 double value(void) const; 00105 double error(void) const; 00106 double gradient(void) const; 00107 double min(void) const; 00108 double max(void) const; 00109 void value(const double& value); 00110 void error(const double& error); 00111 void gradient(const double& gradient); 00112 void min(const double& min); 00113 void max(const double& max); 00114 void range(const double& min, const double& max); 00115 00116 // Factorization methods 00117 const double& factor_value(void) const; 00118 const double& factor_error(void) const; 00119 const double& factor_gradient(void) const; 00120 const double& factor_min(void) const; 00121 const double& factor_max(void) const; 00122 const double& scale(void) const; 00123 void factor_value(const double& value); 00124 void factor_error(const double& error); 00125 void factor_gradient(const double& gradient) const; 00126 void factor_min(const double& min); 00127 void factor_max(const double& max); 00128 void factor_range(const double& min, const double& max); 00129 void scale(const double& scale); 00130 00131 // Boundary methods 00132 bool has_min(void) const; 00133 bool has_max(void) const; 00134 bool has_range(void) const; 00135 void remove_min(void); 00136 void remove_max(void); 00137 void remove_range(void); 00138 00139 // Property methods 00140 bool is_free(void) const; 00141 bool is_fixed(void) const; 00142 bool has_grad(void) const; 00143 void free(void); 00144 void fix(void); 00145 void has_grad(const bool& grad); 00146 00147 // Other methods 00148 void clear(void); 00149 GOptimizerPar* clone(void) const; 00150 std::string classname(void) const; 00151 const std::string& name(void) const; 00152 const std::string& unit(void) const; 00153 void name(const std::string& name); 00154 void unit(const std::string& unit); 00155 void autoscale(void); 00156 std::string print(const GChatter& chatter = NORMAL) const; 00157 00158 protected: 00159 // Protected methods 00160 void init_members(void); 00161 void copy_members(const GOptimizerPar& par); 00162 void free_members(void); 00163 00164 // Proteced data members 00165 std::string m_name; //!< Parameter name 00166 std::string m_unit; //!< Parameter unit 00167 double m_factor_value; //!< Parameter value factor 00168 double m_factor_error; //!< Uncertainty in parameter value factor 00169 double m_factor_min; //!< Parameter minimum factor 00170 double m_factor_max; //!< Parameter maximum factor 00171 mutable double m_factor_gradient; //!< Function gradient factor 00172 double m_scale; //!< Parameter scaling (true = factor * scale) 00173 bool m_free; //!< Parameter is free 00174 bool m_has_min; //!< Parameter has minimum boundary 00175 bool m_has_max; //!< Parameter has maximum boundary 00176 bool m_has_grad; //!< Parameter has analytic gradient 00177 }; 00178 00179 00180 /***********************************************************************//** 00181 * @brief Return class name 00182 * 00183 * @return String containing the class name ("GOptimizerPar"). 00184 ***************************************************************************/ 00185 inline 00186 std::string GOptimizerPar::classname(void) const 00187 { 00188 return ("GOptimizerPar"); 00189 } 00190 00191 00192 /***********************************************************************//** 00193 * @brief Return parameter value 00194 * 00195 * @return Parameter value. 00196 * 00197 * Returns the parameter value. The parameter value is computed by 00198 * multiplying the value factor by the scale factor. 00199 ***************************************************************************/ 00200 inline 00201 double GOptimizerPar::value(void) const 00202 { 00203 return (m_factor_value * m_scale); 00204 } 00205 00206 00207 /***********************************************************************//** 00208 * @brief Return parameter error 00209 * 00210 * @return Parameter error. 00211 * 00212 * Returns the parameter error. The parameter error is computed by 00213 * multiplying the error factor by the scale factor. By definition, the error 00214 * is a positive number, hence the method returns the absolute value of the 00215 * internally computed error. 00216 ***************************************************************************/ 00217 inline 00218 double GOptimizerPar::error(void) const 00219 { 00220 return std::abs(m_factor_error * m_scale); 00221 } 00222 00223 00224 /***********************************************************************//** 00225 * @brief Return parameter gradient 00226 * 00227 * @return Parameter gradient. 00228 * 00229 * Returns the parameter gradient. The parameter gradient is computed by 00230 * dividing the gradient factor by the scale factor. The method returns 00231 * zero in case that the scale factor is zero. 00232 ***************************************************************************/ 00233 inline 00234 double GOptimizerPar::gradient(void) const 00235 { 00236 // The GOptimizerPar class makes sure that m_scale is never 0, so no test 00237 // is needed here 00238 return (m_factor_gradient / m_scale); 00239 } 00240 00241 00242 /***********************************************************************//** 00243 * @brief Return parameter minimum boundary 00244 * 00245 * @return Parameter minimum boundary. 00246 * 00247 * Returns the parameter minimum boundary. The parameter minimum boundary is 00248 * computed by multiplying the minimum boundary factor by the scale factor. 00249 ***************************************************************************/ 00250 inline 00251 double GOptimizerPar::min(void) const 00252 { 00253 return (m_factor_min * m_scale); 00254 } 00255 00256 00257 /***********************************************************************//** 00258 * @brief Return parameter maximum boundary 00259 * 00260 * @return Parameter maximum boundary. 00261 * 00262 * Returns the parameter maximum boundary. The parameter maximum boundary is 00263 * computed by multiplying the maximum boundary factor by the scale factor. 00264 ***************************************************************************/ 00265 inline 00266 double GOptimizerPar::max(void) const 00267 { 00268 return (m_factor_max * m_scale); 00269 } 00270 00271 00272 /***********************************************************************//** 00273 * @brief Return parameter value factor 00274 * 00275 * @return Parameter value factor. 00276 * 00277 * Returns the parameter value factor. 00278 ***************************************************************************/ 00279 inline 00280 const double& GOptimizerPar::factor_value(void) const 00281 { 00282 return (m_factor_value); 00283 } 00284 00285 00286 /***********************************************************************//** 00287 * @brief Return parameter error factor 00288 * 00289 * @return Parameter error factor. 00290 * 00291 * Returns the parameter error factor. 00292 ***************************************************************************/ 00293 inline 00294 const double& GOptimizerPar::factor_error(void) const 00295 { 00296 return (m_factor_error); 00297 } 00298 00299 00300 /***********************************************************************//** 00301 * @brief Return parameter gradient factor 00302 * 00303 * @return Parameter gradient factor. 00304 * 00305 * Returns the parameter gradient factor. 00306 ***************************************************************************/ 00307 inline 00308 const double& GOptimizerPar::factor_gradient(void) const 00309 { 00310 return (m_factor_gradient); 00311 } 00312 00313 00314 /***********************************************************************//** 00315 * @brief Return parameter minimum boundary factor 00316 * 00317 * @return Parameter minimum boundary factor. 00318 * 00319 * Returns the parameter minimum boundary factor. 00320 ***************************************************************************/ 00321 inline 00322 const double& GOptimizerPar::factor_min(void) const 00323 { 00324 return (m_factor_min); 00325 } 00326 00327 00328 /***********************************************************************//** 00329 * @brief Return parameter maximum boundary factor 00330 * 00331 * @return Parameter maximum boundary factor. 00332 * 00333 * Returns the parameter maximum boundary factor. 00334 ***************************************************************************/ 00335 inline 00336 const double& GOptimizerPar::factor_max(void) const 00337 { 00338 return (m_factor_max); 00339 } 00340 00341 00342 /***********************************************************************//** 00343 * @brief Return parameter scale 00344 * 00345 * @return Parameter scale factor. 00346 * 00347 * Returns the parameter scale factor. 00348 ***************************************************************************/ 00349 inline 00350 const double& GOptimizerPar::scale(void) const 00351 { 00352 return (m_scale); 00353 } 00354 00355 00356 /***********************************************************************//** 00357 * @brief Set parameter error factor 00358 * 00359 * @param[in] error Parameter error factor. 00360 * 00361 * Sets the parameter error factor. 00362 ***************************************************************************/ 00363 inline 00364 void GOptimizerPar::factor_error(const double& error) 00365 { 00366 m_factor_error = error; 00367 return; 00368 } 00369 00370 00371 /***********************************************************************//** 00372 * @brief Set parameter gradient factor 00373 * 00374 * @param[in] gradient Parameter gradient factor. 00375 * 00376 * Sets the parameter gradient factor. 00377 ***************************************************************************/ 00378 inline 00379 void GOptimizerPar::factor_gradient(const double& gradient) const 00380 { 00381 m_factor_gradient = gradient; 00382 return; 00383 } 00384 00385 00386 /***********************************************************************//** 00387 * @brief Signal if parameter has minimum boundary 00388 * 00389 * @return True if parameter has minimum boundary, false otherwise. 00390 * 00391 * Signals if the parameter has a minimum boundary. 00392 ***************************************************************************/ 00393 inline 00394 bool GOptimizerPar::has_min(void) const 00395 { 00396 return m_has_min; 00397 } 00398 00399 00400 /***********************************************************************//** 00401 * @brief Signal if parameter has maximum boundary 00402 * 00403 * @return True if parameter has maximum boundary, false otherwise. 00404 * 00405 * Signals if the parameter has a maximum boundary. 00406 ***************************************************************************/ 00407 inline 00408 bool GOptimizerPar::has_max(void) const 00409 { 00410 return m_has_max; 00411 } 00412 00413 00414 /***********************************************************************//** 00415 * @brief Signal if parameter has minimum and maximum boundaries 00416 * 00417 * @return True if parameter has minimum and maximum boundaries, false 00418 * otherwise. 00419 * 00420 * Signals if the parameter has a minimum and a maximum boundary. 00421 ***************************************************************************/ 00422 inline 00423 bool GOptimizerPar::has_range(void) const 00424 { 00425 return (m_has_min && m_has_max); 00426 } 00427 00428 00429 /***********************************************************************//** 00430 * @brief Removes minimum boundary 00431 * 00432 * Removes minimum boundary from the parameter. 00433 ***************************************************************************/ 00434 inline 00435 void GOptimizerPar::remove_min(void) 00436 { 00437 m_has_min = false; 00438 return; 00439 } 00440 00441 00442 /***********************************************************************//** 00443 * @brief Removes maximum boundary 00444 * 00445 * Removes maximum boundary from the parameter. 00446 ***************************************************************************/ 00447 inline 00448 void GOptimizerPar::remove_max(void) 00449 { 00450 m_has_max = false; 00451 return; 00452 } 00453 00454 00455 /***********************************************************************//** 00456 * @brief Removes minimum and maximum boundary 00457 * 00458 * Removes minimum and maximum boundary from the parameter. 00459 ***************************************************************************/ 00460 inline 00461 void GOptimizerPar::remove_range(void) 00462 { 00463 m_has_min = false; 00464 m_has_max = false; 00465 return; 00466 } 00467 00468 00469 /***********************************************************************//** 00470 * @brief Signal if parameter is free 00471 * 00472 * @return True if parameter is free, false otherwise. 00473 * 00474 * Signals if the parameter is free, i.e. that it shall be fitted in a 00475 * parameter optimization process. 00476 ***************************************************************************/ 00477 inline 00478 bool GOptimizerPar::is_free(void) const 00479 { 00480 return m_free; 00481 } 00482 00483 00484 /***********************************************************************//** 00485 * @brief Signal if parameter is fixed 00486 * 00487 * @return True if parameter is fixed, false otherwise. 00488 * 00489 * Signals if the parameter is fixed, i.e. that it shall NOT be fitted in a 00490 * parameter optimization process. 00491 ***************************************************************************/ 00492 inline 00493 bool GOptimizerPar::is_fixed(void) const 00494 { 00495 return (!m_free); 00496 } 00497 00498 00499 /***********************************************************************//** 00500 * @brief Signal if parameter gradient is computed analytically 00501 * 00502 * @return True if parameter is gradient is computed analytically, false 00503 * otherwise. 00504 * 00505 * Signals if the parameter gradient is computed analytically. This property 00506 * is used in the function optimization process to identify parameters for 00507 * which gradients need to be computed numerically. 00508 ***************************************************************************/ 00509 inline 00510 bool GOptimizerPar::has_grad(void) const 00511 { 00512 return m_has_grad; 00513 } 00514 00515 00516 /***********************************************************************//** 00517 * @brief Free a parameter 00518 * 00519 * Frees a parameter for optimization. The parameter shall be fitted in a 00520 * parameter optimization process. 00521 ***************************************************************************/ 00522 inline 00523 void GOptimizerPar::free(void) 00524 { 00525 m_free = true; 00526 return; 00527 } 00528 00529 00530 /***********************************************************************//** 00531 * @brief Fix a parameter 00532 * 00533 * Fixes a parameter for optimization. The parameter shall NOT be altered 00534 * in a parameter optimization process. 00535 ***************************************************************************/ 00536 inline 00537 void GOptimizerPar::fix(void) 00538 { 00539 m_free = false; 00540 return; 00541 } 00542 00543 00544 /***********************************************************************//** 00545 * @brief Set gradient property 00546 * 00547 * @param[in] grad Gradient flag 00548 * 00549 * Sets the gradient property of the parameter. If @p grad is set to 00550 * true, the parameter gradient will be computed analytically by the method 00551 * that evaluates the function. If false, the gradients needs to be computed 00552 * numerically. 00553 ***************************************************************************/ 00554 inline 00555 void GOptimizerPar::has_grad(const bool& grad) 00556 { 00557 m_has_grad = grad; 00558 return; 00559 } 00560 00561 00562 /***********************************************************************//** 00563 * @brief Return parameter name 00564 * 00565 * @return Parameter name. 00566 * 00567 * Returns the parameter name. 00568 ***************************************************************************/ 00569 inline 00570 const std::string& GOptimizerPar::name(void) const 00571 { 00572 return m_name; 00573 } 00574 00575 00576 /***********************************************************************//** 00577 * @brief Return parameter unit 00578 * 00579 * @return Parameter unit. 00580 * 00581 * Returns the parameter unit. 00582 ***************************************************************************/ 00583 inline 00584 const std::string& GOptimizerPar::unit(void) const 00585 { 00586 return m_unit; 00587 } 00588 00589 00590 /***********************************************************************//** 00591 * @brief Set parameter name 00592 * 00593 * @param[in] name Parameter name. 00594 * 00595 * Sets the parameter name. 00596 ***************************************************************************/ 00597 inline 00598 void GOptimizerPar::name(const std::string& name) 00599 { 00600 m_name = name; 00601 return; 00602 } 00603 00604 00605 /***********************************************************************//** 00606 * @brief Set parameter unit 00607 * 00608 * @param[in] unit Parameter unit. 00609 * 00610 * Sets the parameter unit. 00611 ***************************************************************************/ 00612 inline 00613 void GOptimizerPar::unit(const std::string& unit) 00614 { 00615 m_unit = unit; 00616 return; 00617 } 00618 00619 #endif /* GOPTIMIZERPAR_HPP */