Commit a1f774ed96e5945fc1b1a29c84344cb52fd009bc

Authored by Jürgen Knödlseder
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.
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&amp; value) @@ -282,8 +290,9 @@ void GModelPar::value(const double&amp; 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&amp; min) @@ -307,8 +316,9 @@ void GModelPar::min(const double&amp; 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&amp; max) @@ -334,8 +344,9 @@ void GModelPar::max(const double&amp; 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&amp; min, const double&amp; max) @@ -351,6 +362,46 @@ void GModelPar::range(const double&amp; min, const double&amp; 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