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 | 4 | * copyright (C) 2009-2013 by Juergen Knoedlseder * |
| 5 | 5 | * ----------------------------------------------------------------------- * |
| ... | ... | @@ -102,6 +102,7 @@ public: |
| 102 | 102 | void free(void) { m_free=true; } |
| 103 | 103 | void fix(void) { m_free=false; } |
| 104 | 104 | void hasgrad(const bool& grad) { m_hasgrad=grad; } |
| 105 | + void autoscale(void); | |
| 105 | 106 | void read(const GXmlElement& xml); |
| 106 | 107 | void write(GXmlElement& xml) const; |
| 107 | 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 | 4 | * copyright (C) 2009-2013 by Juergen Knoedlseder * |
| 5 | 5 | * ----------------------------------------------------------------------- * |
| ... | ... | @@ -82,6 +82,7 @@ public: |
| 82 | 82 | void free(void); |
| 83 | 83 | void fix(void); |
| 84 | 84 | void hasgrad(const bool& grad); |
| 85 | + void autoscale(void); | |
| 85 | 86 | void read(const GXmlElement& xml); |
| 86 | 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 | 4 | * copyright (C) 2009-2013 by Juergen Knoedlseder * |
| 5 | 5 | * ----------------------------------------------------------------------- * |
| ... | ... | @@ -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 | 71 | * |
| 72 | 72 | * @param[in] name Parameter name. |
| 73 | 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 | 76 | * Constructs a model parameter from parameter name, value and scaling. The |
| 77 | 77 | * real value of the parameter is the specified value times the scaling. |
| ... | ... | @@ -134,6 +134,7 @@ GModelPar::~GModelPar(void) |
| 134 | 134 | * @brief Assignment operator |
| 135 | 135 | * |
| 136 | 136 | * @param[in] par Model parameter. |
| 137 | + * @return Model parameter. | |
| 137 | 138 | ***************************************************************************/ |
| 138 | 139 | GModelPar& GModelPar::operator=(const GModelPar& par) |
| 139 | 140 | { |
| ... | ... | @@ -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 | 169 | void GModelPar::clear(void) |
| 169 | 170 | { |
| 170 | 171 | // Free class members |
| ... | ... | @@ -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 | 187 | GModelPar* GModelPar::clone(void) const |
| 185 | 188 | { |
| 189 | + // Clone model parameter | |
| 186 | 190 | return new GModelPar(*this); |
| 187 | 191 | } |
| 188 | 192 | |
| ... | ... | @@ -200,9 +204,10 @@ GModelPar* GModelPar::clone(void) const |
| 200 | 204 | void GModelPar::real_value(const double& value) |
| 201 | 205 | { |
| 202 | 206 | // Throw error if scale is 0 |
| 203 | - if (m_scale == 0.0) | |
| 207 | + if (m_scale == 0.0) { | |
| 204 | 208 | throw GException::model_invalid_parscale(G_REAL_VALUE, m_scale, |
| 205 | 209 | "Zero scale not allowed for model parameter."); |
| 210 | + } | |
| 206 | 211 | |
| 207 | 212 | // Compute value |
| 208 | 213 | double val = value / m_scale; |
| ... | ... | @@ -228,9 +233,10 @@ void GModelPar::real_value(const double& value) |
| 228 | 233 | void GModelPar::real_error(const double& error) |
| 229 | 234 | { |
| 230 | 235 | // Throw error if scale is 0 |
| 231 | - if (m_scale == 0.0) | |
| 236 | + if (m_scale == 0.0) { | |
| 232 | 237 | throw GException::model_invalid_parscale(G_REAL_ERROR, m_scale, |
| 233 | 238 | "Zero scale not allowed for model parameter."); |
| 239 | + } | |
| 234 | 240 | |
| 235 | 241 | // Compute error |
| 236 | 242 | double err = error / m_scale; |
| ... | ... | @@ -255,13 +261,15 @@ void GModelPar::value(const double& value) |
| 255 | 261 | { |
| 256 | 262 | // If there is a minimum boundary and if value is below this boundary |
| 257 | 263 | // then throw an error |
| 258 | - if (m_hasmin && value < m_min) | |
| 264 | + if (m_hasmin && value < m_min) { | |
| 259 | 265 | throw GException::out_of_range(G_VALUE, value, m_min, m_max); |
| 266 | + } | |
| 260 | 267 | |
| 261 | 268 | // If there is a maximum boundary and if value is above this boundary |
| 262 | 269 | // then throw an error |
| 263 | - if (m_hasmax && value > m_max) | |
| 270 | + if (m_hasmax && value > m_max) { | |
| 264 | 271 | throw GException::out_of_range(G_VALUE, value, m_min, m_max); |
| 272 | + } | |
| 265 | 273 | |
| 266 | 274 | // Assign value |
| 267 | 275 | m_value = value; |
| ... | ... | @@ -282,8 +290,9 @@ void GModelPar::value(const double& value) |
| 282 | 290 | void GModelPar::min(const double& min) |
| 283 | 291 | { |
| 284 | 292 | // If minimum is above actual value then throw error |
| 285 | - if (m_value < min) | |
| 293 | + if (m_value < min) { | |
| 286 | 294 | throw GException::out_of_range(G_MIN, m_value, min, m_max); |
| 295 | + } | |
| 287 | 296 | |
| 288 | 297 | // Assign minimum |
| 289 | 298 | m_min = min; |
| ... | ... | @@ -307,8 +316,9 @@ void GModelPar::min(const double& min) |
| 307 | 316 | void GModelPar::max(const double& max) |
| 308 | 317 | { |
| 309 | 318 | // If maximum is below value then throw error |
| 310 | - if (m_value > max) | |
| 319 | + if (m_value > max) { | |
| 311 | 320 | throw GException::out_of_range(G_MAX, m_value, m_min, max); |
| 321 | + } | |
| 312 | 322 | |
| 313 | 323 | // Assign maximum |
| 314 | 324 | m_max = max; |
| ... | ... | @@ -334,8 +344,9 @@ void GModelPar::max(const double& max) |
| 334 | 344 | void GModelPar::range(const double& min, const double& max) |
| 335 | 345 | { |
| 336 | 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 | 348 | throw GException::out_of_range(G_RANGE, m_value, min, max); |
| 349 | + } | |
| 339 | 350 | |
| 340 | 351 | // Assign range |
| 341 | 352 | m_min = min; |
| ... | ... | @@ -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 | 405 | * @brief Extract parameter attributes from XML element |
| 355 | 406 | * |
| 356 | 407 | * @param[in] xml XML element | ... | ... |