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 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&amp; 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&amp; 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&amp; 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&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 405 * @brief Extract parameter attributes from XML element
355 406 *
356 407 * @param[in] xml XML element
... ...