Commit a1f774ed96e5945fc1b1a29c84344cb52fd009bc
1 parent
79c3437b
Add autoscale() method.
The autoscale() method sets the scale factor so that the value becomes unity. This is only possible for parameters with non-zero values.
Showing
3 changed files
with
69 additions
and
16 deletions
include/GModelPar.hpp
| 1 | /*************************************************************************** | 1 | /*************************************************************************** |
| 2 | - * GModelPar.hpp - Model parameter class * | 2 | + * GModelPar.hpp - Model parameter class * |
| 3 | * ----------------------------------------------------------------------- * | 3 | * ----------------------------------------------------------------------- * |
| 4 | * copyright (C) 2009-2013 by Juergen Knoedlseder * | 4 | * copyright (C) 2009-2013 by Juergen Knoedlseder * |
| 5 | * ----------------------------------------------------------------------- * | 5 | * ----------------------------------------------------------------------- * |
| @@ -102,6 +102,7 @@ public: | @@ -102,6 +102,7 @@ public: | ||
| 102 | void free(void) { m_free=true; } | 102 | void free(void) { m_free=true; } |
| 103 | void fix(void) { m_free=false; } | 103 | void fix(void) { m_free=false; } |
| 104 | void hasgrad(const bool& grad) { m_hasgrad=grad; } | 104 | void hasgrad(const bool& grad) { m_hasgrad=grad; } |
| 105 | + void autoscale(void); | ||
| 105 | void read(const GXmlElement& xml); | 106 | void read(const GXmlElement& xml); |
| 106 | void write(GXmlElement& xml) const; | 107 | void write(GXmlElement& xml) const; |
| 107 | std::string print(void) const; | 108 | std::string print(void) const; |
pyext/GModelPar.i
| 1 | /*************************************************************************** | 1 | /*************************************************************************** |
| 2 | - * GModelPar.i - Model parameter class Python interface * | 2 | + * GModelPar.i - Model parameter class * |
| 3 | * ----------------------------------------------------------------------- * | 3 | * ----------------------------------------------------------------------- * |
| 4 | * copyright (C) 2009-2013 by Juergen Knoedlseder * | 4 | * copyright (C) 2009-2013 by Juergen Knoedlseder * |
| 5 | * ----------------------------------------------------------------------- * | 5 | * ----------------------------------------------------------------------- * |
| @@ -82,6 +82,7 @@ public: | @@ -82,6 +82,7 @@ public: | ||
| 82 | void free(void); | 82 | void free(void); |
| 83 | void fix(void); | 83 | void fix(void); |
| 84 | void hasgrad(const bool& grad); | 84 | void hasgrad(const bool& grad); |
| 85 | + void autoscale(void); | ||
| 85 | void read(const GXmlElement& xml); | 86 | void read(const GXmlElement& xml); |
| 86 | void write(GXmlElement& xml) const; | 87 | void write(GXmlElement& xml) const; |
| 87 | }; | 88 | }; |
src/model/GModelPar.cpp
| 1 | /*************************************************************************** | 1 | /*************************************************************************** |
| 2 | - * GModelPar.cpp - Model parameter class * | 2 | + * GModelPar.cpp - Model parameter class * |
| 3 | * ----------------------------------------------------------------------- * | 3 | * ----------------------------------------------------------------------- * |
| 4 | * copyright (C) 2009-2013 by Juergen Knoedlseder * | 4 | * copyright (C) 2009-2013 by Juergen Knoedlseder * |
| 5 | * ----------------------------------------------------------------------- * | 5 | * ----------------------------------------------------------------------- * |
| @@ -49,7 +49,7 @@ | @@ -49,7 +49,7 @@ | ||
| 49 | 49 | ||
| 50 | /*========================================================================== | 50 | /*========================================================================== |
| 51 | = = | 51 | = = |
| 52 | - = GModelPar constructors/destructors = | 52 | + = Constructors/destructors = |
| 53 | = = | 53 | = = |
| 54 | ==========================================================================*/ | 54 | ==========================================================================*/ |
| 55 | 55 | ||
| @@ -71,7 +71,7 @@ GModelPar::GModelPar(void) | @@ -71,7 +71,7 @@ GModelPar::GModelPar(void) | ||
| 71 | * | 71 | * |
| 72 | * @param[in] name Parameter name. | 72 | * @param[in] name Parameter name. |
| 73 | * @param[in] value Parameter value. | 73 | * @param[in] value Parameter value. |
| 74 | - * @param[in] scale Parameter scaling (default: 1.0). | 74 | + * @param[in] scale Parameter scaling (default = 1.0). |
| 75 | * | 75 | * |
| 76 | * Constructs a model parameter from parameter name, value and scaling. The | 76 | * Constructs a model parameter from parameter name, value and scaling. The |
| 77 | * real value of the parameter is the specified value times the scaling. | 77 | * real value of the parameter is the specified value times the scaling. |
| @@ -134,6 +134,7 @@ GModelPar::~GModelPar(void) | @@ -134,6 +134,7 @@ GModelPar::~GModelPar(void) | ||
| 134 | * @brief Assignment operator | 134 | * @brief Assignment operator |
| 135 | * | 135 | * |
| 136 | * @param[in] par Model parameter. | 136 | * @param[in] par Model parameter. |
| 137 | + * @return Model parameter. | ||
| 137 | ***************************************************************************/ | 138 | ***************************************************************************/ |
| 138 | GModelPar& GModelPar::operator=(const GModelPar& par) | 139 | GModelPar& GModelPar::operator=(const GModelPar& par) |
| 139 | { | 140 | { |
| @@ -163,8 +164,8 @@ GModelPar& GModelPar::operator=(const GModelPar& par) | @@ -163,8 +164,8 @@ GModelPar& GModelPar::operator=(const GModelPar& par) | ||
| 163 | ==========================================================================*/ | 164 | ==========================================================================*/ |
| 164 | 165 | ||
| 165 | /***********************************************************************//** | 166 | /***********************************************************************//** |
| 166 | - * @brief Clear instance | ||
| 167 | -***************************************************************************/ | 167 | + * @brief Clear model parameter |
| 168 | + ***************************************************************************/ | ||
| 168 | void GModelPar::clear(void) | 169 | void GModelPar::clear(void) |
| 169 | { | 170 | { |
| 170 | // Free class members | 171 | // Free class members |
| @@ -179,10 +180,13 @@ void GModelPar::clear(void) | @@ -179,10 +180,13 @@ void GModelPar::clear(void) | ||
| 179 | 180 | ||
| 180 | 181 | ||
| 181 | /***********************************************************************//** | 182 | /***********************************************************************//** |
| 182 | - * @brief Clone instance | ||
| 183 | -***************************************************************************/ | 183 | + * @brief Clone model parameter |
| 184 | + * | ||
| 185 | + * @return Pointer to deep copy of model parameter. | ||
| 186 | + ***************************************************************************/ | ||
| 184 | GModelPar* GModelPar::clone(void) const | 187 | GModelPar* GModelPar::clone(void) const |
| 185 | { | 188 | { |
| 189 | + // Clone model parameter | ||
| 186 | return new GModelPar(*this); | 190 | return new GModelPar(*this); |
| 187 | } | 191 | } |
| 188 | 192 | ||
| @@ -200,9 +204,10 @@ GModelPar* GModelPar::clone(void) const | @@ -200,9 +204,10 @@ GModelPar* GModelPar::clone(void) const | ||
| 200 | void GModelPar::real_value(const double& value) | 204 | void GModelPar::real_value(const double& value) |
| 201 | { | 205 | { |
| 202 | // Throw error if scale is 0 | 206 | // Throw error if scale is 0 |
| 203 | - if (m_scale == 0.0) | 207 | + if (m_scale == 0.0) { |
| 204 | throw GException::model_invalid_parscale(G_REAL_VALUE, m_scale, | 208 | throw GException::model_invalid_parscale(G_REAL_VALUE, m_scale, |
| 205 | "Zero scale not allowed for model parameter."); | 209 | "Zero scale not allowed for model parameter."); |
| 210 | + } | ||
| 206 | 211 | ||
| 207 | // Compute value | 212 | // Compute value |
| 208 | double val = value / m_scale; | 213 | double val = value / m_scale; |
| @@ -228,9 +233,10 @@ void GModelPar::real_value(const double& value) | @@ -228,9 +233,10 @@ void GModelPar::real_value(const double& value) | ||
| 228 | void GModelPar::real_error(const double& error) | 233 | void GModelPar::real_error(const double& error) |
| 229 | { | 234 | { |
| 230 | // Throw error if scale is 0 | 235 | // Throw error if scale is 0 |
| 231 | - if (m_scale == 0.0) | 236 | + if (m_scale == 0.0) { |
| 232 | throw GException::model_invalid_parscale(G_REAL_ERROR, m_scale, | 237 | throw GException::model_invalid_parscale(G_REAL_ERROR, m_scale, |
| 233 | "Zero scale not allowed for model parameter."); | 238 | "Zero scale not allowed for model parameter."); |
| 239 | + } | ||
| 234 | 240 | ||
| 235 | // Compute error | 241 | // Compute error |
| 236 | double err = error / m_scale; | 242 | double err = error / m_scale; |
| @@ -255,13 +261,15 @@ void GModelPar::value(const double& value) | @@ -255,13 +261,15 @@ void GModelPar::value(const double& value) | ||
| 255 | { | 261 | { |
| 256 | // If there is a minimum boundary and if value is below this boundary | 262 | // If there is a minimum boundary and if value is below this boundary |
| 257 | // then throw an error | 263 | // then throw an error |
| 258 | - if (m_hasmin && value < m_min) | 264 | + if (m_hasmin && value < m_min) { |
| 259 | throw GException::out_of_range(G_VALUE, value, m_min, m_max); | 265 | throw GException::out_of_range(G_VALUE, value, m_min, m_max); |
| 266 | + } | ||
| 260 | 267 | ||
| 261 | // If there is a maximum boundary and if value is above this boundary | 268 | // If there is a maximum boundary and if value is above this boundary |
| 262 | // then throw an error | 269 | // then throw an error |
| 263 | - if (m_hasmax && value > m_max) | 270 | + if (m_hasmax && value > m_max) { |
| 264 | throw GException::out_of_range(G_VALUE, value, m_min, m_max); | 271 | throw GException::out_of_range(G_VALUE, value, m_min, m_max); |
| 272 | + } | ||
| 265 | 273 | ||
| 266 | // Assign value | 274 | // Assign value |
| 267 | m_value = value; | 275 | m_value = value; |
| @@ -282,8 +290,9 @@ void GModelPar::value(const double& value) | @@ -282,8 +290,9 @@ void GModelPar::value(const double& value) | ||
| 282 | void GModelPar::min(const double& min) | 290 | void GModelPar::min(const double& min) |
| 283 | { | 291 | { |
| 284 | // If minimum is above actual value then throw error | 292 | // If minimum is above actual value then throw error |
| 285 | - if (m_value < min) | 293 | + if (m_value < min) { |
| 286 | throw GException::out_of_range(G_MIN, m_value, min, m_max); | 294 | throw GException::out_of_range(G_MIN, m_value, min, m_max); |
| 295 | + } | ||
| 287 | 296 | ||
| 288 | // Assign minimum | 297 | // Assign minimum |
| 289 | m_min = min; | 298 | m_min = min; |
| @@ -307,8 +316,9 @@ void GModelPar::min(const double& min) | @@ -307,8 +316,9 @@ void GModelPar::min(const double& min) | ||
| 307 | void GModelPar::max(const double& max) | 316 | void GModelPar::max(const double& max) |
| 308 | { | 317 | { |
| 309 | // If maximum is below value then throw error | 318 | // If maximum is below value then throw error |
| 310 | - if (m_value > max) | 319 | + if (m_value > max) { |
| 311 | throw GException::out_of_range(G_MAX, m_value, m_min, max); | 320 | throw GException::out_of_range(G_MAX, m_value, m_min, max); |
| 321 | + } | ||
| 312 | 322 | ||
| 313 | // Assign maximum | 323 | // Assign maximum |
| 314 | m_max = max; | 324 | m_max = max; |
| @@ -334,8 +344,9 @@ void GModelPar::max(const double& max) | @@ -334,8 +344,9 @@ void GModelPar::max(const double& max) | ||
| 334 | void GModelPar::range(const double& min, const double& max) | 344 | void GModelPar::range(const double& min, const double& max) |
| 335 | { | 345 | { |
| 336 | // If maximum is below value then throw error | 346 | // If maximum is below value then throw error |
| 337 | - if (m_value < min || m_value > max || min > max) | 347 | + if (m_value < min || m_value > max || min > max) { |
| 338 | throw GException::out_of_range(G_RANGE, m_value, min, max); | 348 | throw GException::out_of_range(G_RANGE, m_value, min, max); |
| 349 | + } | ||
| 339 | 350 | ||
| 340 | // Assign range | 351 | // Assign range |
| 341 | m_min = min; | 352 | m_min = min; |
| @@ -351,6 +362,46 @@ void GModelPar::range(const double& min, const double& max) | @@ -351,6 +362,46 @@ void GModelPar::range(const double& min, const double& max) | ||
| 351 | 362 | ||
| 352 | 363 | ||
| 353 | /***********************************************************************//** | 364 | /***********************************************************************//** |
| 365 | + * @brief Autoscale parameter | ||
| 366 | + * | ||
| 367 | + * Sets the value to unity and the scale factor to the real value of the | ||
| 368 | + * parameter. The method will also adjust the error and the gradient | ||
| 369 | + * accodringly. If parameter boundaries exist they will also be adjusted | ||
| 370 | + * accordingly. | ||
| 371 | + * | ||
| 372 | + * The method does nothing if the actual value is zero. | ||
| 373 | + ***************************************************************************/ | ||
| 374 | +void GModelPar::autoscale(void) | ||
| 375 | +{ | ||
| 376 | + // Continue only if the value is non-zero | ||
| 377 | + if (m_value != 0.0) { | ||
| 378 | + | ||
| 379 | + // Set the scale factor | ||
| 380 | + m_scale *= m_value; | ||
| 381 | + | ||
| 382 | + // Get inverse scaling factor | ||
| 383 | + double invscale = 1.0 / m_value; | ||
| 384 | + | ||
| 385 | + // Set values, error, gradient, min and max | ||
| 386 | + m_value *= invscale; | ||
| 387 | + m_error *= invscale; | ||
| 388 | + m_gradient *= invscale; | ||
| 389 | + if (m_hasmin) { | ||
| 390 | + m_min *= invscale; | ||
| 391 | + } | ||
| 392 | + if (m_hasmax) { | ||
| 393 | + m_max *= invscale; | ||
| 394 | + } | ||
| 395 | + | ||
| 396 | + | ||
| 397 | + } // endif: value was non-zero | ||
| 398 | + | ||
| 399 | + // Return | ||
| 400 | + return; | ||
| 401 | +} | ||
| 402 | + | ||
| 403 | + | ||
| 404 | +/***********************************************************************//** | ||
| 354 | * @brief Extract parameter attributes from XML element | 405 | * @brief Extract parameter attributes from XML element |
| 355 | * | 406 | * |
| 356 | * @param[in] xml XML element | 407 | * @param[in] xml XML element |