Commit ed1c51d0bdf9d2cfc1975d047740d02579c037fe
1 parent
15c02402
Preliminary implementation of new model parameter interface.
A new model parameter interface has been implemented that puts the internal workings of the class more in the background. For example, the real_xxx() methods have been replaced by Xxx() methods, and the xxx() methods became factor_xxx(). For example, real_value() becomes Value() and value() becomes factor_value(). For the moment, upper case letters are used so that no mix with the former xxx() methods occur. This is for validating the change, and will be modified in a future commit.
Showing
3 changed files
with
635 additions
and
268 deletions
include/GModelPar.hpp
| ... | ... | @@ -38,70 +38,116 @@ |
| 38 | 38 | * |
| 39 | 39 | * @brief Model parameter class |
| 40 | 40 | * |
| 41 | - * This method implements a model parameter. The model parameter is | |
| 42 | - * factorised into a "value" and a "scale" factor, the real parameter value | |
| 43 | - * being the product of both. Parameter optimization is only done on the | |
| 44 | - * "value" part of the parameter. This allows scaling of the parameter to | |
| 45 | - * have a "value" around unity (which makes the optimizer routines better | |
| 46 | - * behave). Methods that work on the real value (i.e. the product of | |
| 47 | - * "value" and "scale") are prefixed with "real_". | |
| 41 | + * This class implements a model parameter. A model parameter is a numerical | |
| 42 | + * value that is used to describe a model. A model parameter has the | |
| 43 | + * following attributes: | |
| 44 | + * - @p value gives the numerical value of the parameter | |
| 45 | + * - @p error gives the statistical uncertainty in the parameter value | |
| 46 | + * - @p gradient gives the gradient of a the model with respect to the | |
| 47 | + * parameter | |
| 48 | + * - @p min gives the minimum value that the parameter value can take | |
| 49 | + * - @p max gives the maximum value that the parameter value can take | |
| 48 | 50 | * |
| 49 | - * The parameter "value" can optionally by bounded by a minimum and/or | |
| 50 | - * maximum value. Note that the boundaries apply to "value". | |
| 51 | + * The parameter attributes are set and retrieved using the value(), | |
| 52 | + * error(), gradient(), min() and max() methods, respectively. Furthermore, | |
| 53 | + * the range() method is used to simultaneously set the minimum and maximum | |
| 54 | + * value of a parameter. | |
| 51 | 55 | * |
| 52 | - * Each parameter has a name, and holds optionally information about its | |
| 53 | - * gradient (if "hasgrad" is true). | |
| 56 | + * The minimum and maximum values are optional, and existence of these | |
| 57 | + * attributes is tested using the hasmin() and hasmax() methods, | |
| 58 | + * respectively. The minimum value, maximum value are removed using the | |
| 59 | + * remove_min() and remove_max() methods. Simultaneous removal of minimum | |
| 60 | + * and maximum values is done using the remove_range() method. | |
| 61 | + * | |
| 62 | + * Each parameter has furthermore the following properties: | |
| 63 | + * - @p free specifies whether the parameter should be fitted | |
| 64 | + * - @p grad specifies whether the parameter gradient is computed | |
| 65 | + * analytically (true) or numerically (false) | |
| 66 | + * | |
| 67 | + * The parameter property @p free is set using the free() and fix() | |
| 68 | + * methods and it is retrieved using the isfree() and isfixed() methods. | |
| 69 | + * The attribute @p grad is set and retrieved using the has hasgrad() | |
| 70 | + * methods. | |
| 71 | + * | |
| 72 | + * Each model parameter is factorized into a @p factor and a @p scale | |
| 73 | + * term. The GModelPar class stores the factors and the scale factor has | |
| 74 | + * data members, and the true values are computed using the following | |
| 75 | + * relations: | |
| 76 | + * | |
| 77 | + * value = m_factor_value * m_scale | |
| 78 | + * error = m_factor_error * m_scale | |
| 79 | + * gradient = m_factor_gradient * m_scale | |
| 80 | + * min = m_factor_min * m_scale | |
| 81 | + * max = m_factor_max * m_scale | |
| 82 | + * | |
| 83 | + * The @p factor and @p scale terms can be set and retrieved using the | |
| 84 | + * factor_value(), factor_error(), factor_gradient(), factor_min(), | |
| 85 | + * factor_max() and scale() methods. | |
| 54 | 86 | ***************************************************************************/ |
| 55 | 87 | class GModelPar : public GBase { |
| 56 | 88 | |
| 57 | 89 | public: |
| 58 | 90 | // Constructors and destructors |
| 59 | 91 | GModelPar(void); |
| 60 | - GModelPar(const std::string& name, const double& value, | |
| 61 | - const double& scale = 1.0); | |
| 92 | + explicit GModelPar(const std::string& name, const double& value, int i); | |
| 93 | + explicit GModelPar(const std::string& name, const double& factor, const double& scale); | |
| 62 | 94 | GModelPar(const GModelPar& par); |
| 63 | 95 | virtual ~GModelPar(void); |
| 64 | 96 | |
| 65 | 97 | // Operators |
| 66 | 98 | GModelPar& operator=(const GModelPar& par); |
| 67 | 99 | |
| 68 | - // Methods | |
| 69 | - void clear(void); | |
| 70 | - GModelPar* clone(void) const; | |
| 71 | - std::string name(void) const { return m_name; } | |
| 72 | - std::string unit(void) const { return m_unit; } | |
| 73 | - double real_value(void) const { return m_value*m_scale; } | |
| 74 | - double real_error(void) const { return m_error*m_scale; } | |
| 75 | - double real_gradient(void) const { return m_gradient*m_scale; } | |
| 76 | - double real_min(void) const { return m_min*m_scale; } | |
| 77 | - double real_max(void) const { return m_max*m_scale; } | |
| 78 | - double value(void) const { return m_value; } | |
| 79 | - double error(void) const { return m_error; } | |
| 80 | - double gradient(void) const { return m_gradient; } | |
| 81 | - double min(void) const { return m_min; } | |
| 82 | - double max(void) const { return m_max; } | |
| 83 | - double scale(void) const { return m_scale; } | |
| 84 | - bool isfree(void) const { return m_free; } | |
| 100 | + // Attribute methods | |
| 101 | + double Value(void) const; | |
| 102 | + double Error(void) const { return m_factor_error*m_scale; } | |
| 103 | + double Gradient(void) const { return m_factor_gradient*m_scale; } | |
| 104 | + double Min(void) const { return m_factor_min*m_scale; } | |
| 105 | + double Max(void) const { return m_factor_max*m_scale; } | |
| 106 | + void Value(const double& value); | |
| 107 | + void Error(const double& error); | |
| 108 | + void Gradient(const double& gradient); | |
| 109 | + void Min(const double& min); | |
| 110 | + void Max(const double& max); | |
| 111 | + void Range(const double& min, const double& max); | |
| 112 | + | |
| 113 | + // Factorization methods | |
| 114 | + const double& factor_value(void) const { return m_factor_value; } | |
| 115 | + const double& factor_error(void) const { return m_factor_error; } | |
| 116 | + const double& factor_gradient(void) const { return m_factor_gradient; } | |
| 117 | + const double& factor_min(void) const { return m_factor_min; } | |
| 118 | + const double& factor_max(void) const { return m_factor_max; } | |
| 119 | + const double& scale(void) const { return m_scale; } | |
| 120 | + void factor_value(const double& value); | |
| 121 | + void factor_error(const double& error) { m_factor_error=error; } | |
| 122 | + void factor_gradient(const double& gradient) { m_factor_gradient=gradient; } | |
| 123 | + void factor_min(const double& min); | |
| 124 | + void factor_max(const double& max); | |
| 125 | + void factor_range(const double& min, const double& max); | |
| 126 | + void Scale(const double& scale); | |
| 127 | + | |
| 128 | + // Boundary methods | |
| 85 | 129 | bool hasmin(void) const { return m_hasmin; } |
| 86 | 130 | bool hasmax(void) const { return m_hasmax; } |
| 87 | - bool hasgrad(void) const { return m_hasgrad; } | |
| 88 | - void name(const std::string& name) { m_name=name; } | |
| 89 | - void unit(const std::string& unit) { m_unit=unit; } | |
| 90 | - void real_value(const double& value); | |
| 91 | - void real_error(const double& error); | |
| 92 | - void value(const double& value); | |
| 93 | - void error(const double& error) { m_error=error; } | |
| 94 | - void gradient(const double& gradient) { m_gradient=gradient; } | |
| 95 | - void min(const double& min); | |
| 96 | - void max(const double& max); | |
| 97 | - void scale(const double& scale) { m_scale=scale; } | |
| 98 | - void range(const double& min, const double& max); | |
| 131 | + bool hasrange(void) const { return m_hasmin && m_hasmax; } | |
| 99 | 132 | void remove_min(void) { m_hasmin=false; } |
| 100 | 133 | void remove_max(void) { m_hasmax=false; } |
| 101 | 134 | void remove_range(void) { m_hasmin=false; m_hasmax=false; } |
| 135 | + | |
| 136 | + // Property methods | |
| 137 | + bool isfree(void) const { return m_free; } | |
| 138 | + bool isfixed(void) const { return !m_free; } | |
| 139 | + bool hasgrad(void) const { return m_hasgrad; } | |
| 102 | 140 | void free(void) { m_free=true; } |
| 103 | 141 | void fix(void) { m_free=false; } |
| 104 | 142 | void hasgrad(const bool& grad) { m_hasgrad=grad; } |
| 143 | + | |
| 144 | + // Other methods | |
| 145 | + void clear(void); | |
| 146 | + GModelPar* clone(void) const; | |
| 147 | + std::string name(void) const { return m_name; } | |
| 148 | + std::string unit(void) const { return m_unit; } | |
| 149 | + void name(const std::string& name) { m_name=name; } | |
| 150 | + void unit(const std::string& unit) { m_unit=unit; } | |
| 105 | 151 | void autoscale(void); |
| 106 | 152 | void read(const GXmlElement& xml); |
| 107 | 153 | void write(GXmlElement& xml) const; |
| ... | ... | @@ -114,18 +160,32 @@ protected: |
| 114 | 160 | void free_members(void); |
| 115 | 161 | |
| 116 | 162 | // Proteced data members |
| 117 | - std::string m_name; //!< Parameter name | |
| 118 | - std::string m_unit; //!< Parameter unit | |
| 119 | - double m_value; //!< Parameter value | |
| 120 | - double m_error; //!< Uncertainty in parameter value | |
| 121 | - double m_gradient; //!< Model gradient | |
| 122 | - double m_min; //!< Parameter minimum | |
| 123 | - double m_max; //!< Parameter maximum | |
| 124 | - double m_scale; //!< Parameter scale (real = m_value * m_scale) | |
| 125 | - bool m_free; //!< Parameter is free | |
| 126 | - bool m_hasmin; //!< Parameter has minimum boundary | |
| 127 | - bool m_hasmax; //!< Parameter has maximum boundary | |
| 128 | - bool m_hasgrad; //!< Parameter has analytic gradient | |
| 163 | + std::string m_name; //!< Parameter name | |
| 164 | + std::string m_unit; //!< Parameter unit | |
| 165 | + double m_factor_value; //!< Parameter value factor | |
| 166 | + double m_factor_error; //!< Uncertainty in parameter value factor | |
| 167 | + double m_factor_gradient; //!< Model gradient factor | |
| 168 | + double m_factor_min; //!< Parameter minimum factor | |
| 169 | + double m_factor_max; //!< Parameter maximum factor | |
| 170 | + double m_scale; //!< Parameter scaling (true = factor * scale) | |
| 171 | + bool m_free; //!< Parameter is free | |
| 172 | + bool m_hasmin; //!< Parameter has minimum boundary | |
| 173 | + bool m_hasmax; //!< Parameter has maximum boundary | |
| 174 | + bool m_hasgrad; //!< Parameter has analytic gradient | |
| 129 | 175 | }; |
| 130 | 176 | |
| 177 | + | |
| 178 | +/***********************************************************************//** | |
| 179 | + * @brief Return parameter value | |
| 180 | + * | |
| 181 | + * @return True parameter value. | |
| 182 | + * | |
| 183 | + * Returns the true parameter value | |
| 184 | + ***************************************************************************/ | |
| 185 | +inline | |
| 186 | +double GModelPar::Value(void) const | |
| 187 | +{ | |
| 188 | + return (m_factor_value*m_scale); | |
| 189 | +} | |
| 190 | + | |
| 131 | 191 | #endif /* GMODELPAR_HPP */ | ... | ... |
pyext/GModelPar.i
| ... | ... | @@ -40,48 +40,61 @@ class GModelPar : public GBase { |
| 40 | 40 | public: |
| 41 | 41 | // Constructors and destructors |
| 42 | 42 | GModelPar(void); |
| 43 | - GModelPar(const std::string& name, const double& value, | |
| 44 | - const double& scale = 1.0); | |
| 45 | - GModelPar(const GModelPar& par); | |
| 43 | + explicit GModelPar(const std::string& name, const double& value, int i); | |
| 44 | + explicit GModelPar(const std::string& name, const double& factor, const double& scale); | |
| 46 | 45 | virtual ~GModelPar(void); |
| 47 | 46 | |
| 48 | - // Methods | |
| 47 | + // Attribute methods | |
| 48 | + double Value(void) const; | |
| 49 | + double Error(void) const { return m_factor_error*m_scale; } | |
| 50 | + double Gradient(void) const { return m_factor_gradient*m_scale; } | |
| 51 | + double Min(void) const { return m_factor_min*m_scale; } | |
| 52 | + double Max(void) const { return m_factor_max*m_scale; } | |
| 53 | + void Value(const double& value); | |
| 54 | + void Error(const double& error); | |
| 55 | + void Gradient(const double& min); | |
| 56 | + void Min(const double& min); | |
| 57 | + void Max(const double& max); | |
| 58 | + void Range(const double& min, const double& max); | |
| 59 | + | |
| 60 | + // Factorization methods | |
| 61 | + const double& factor_value(void) const { return m_factor_value; } | |
| 62 | + const double& factor_error(void) const { return m_factor_error; } | |
| 63 | + const double& factor_gradient(void) const { return m_factor_gradient; } | |
| 64 | + const double& factor_min(void) const { return m_factor_min; } | |
| 65 | + const double& factor_max(void) const { return m_factor_max; } | |
| 66 | + const double& scale(void) const { return m_scale; } | |
| 67 | + void factor_value(const double& value); | |
| 68 | + void factor_error(const double& error) { m_factor_error=error; } | |
| 69 | + void factor_gradient(const double& gradient) { m_factor_gradient=gradient; } | |
| 70 | + void factor_min(const double& min); | |
| 71 | + void factor_max(const double& max); | |
| 72 | + void factor_range(const double& min, const double& max); | |
| 73 | + void Scale(const double& scale); | |
| 74 | + | |
| 75 | + // Boundary methods | |
| 76 | + bool hasmin(void) const { return m_hasmin; } | |
| 77 | + bool hasmax(void) const { return m_hasmax; } | |
| 78 | + bool hasrange(void) const { return m_hasmin && m_hasmax; } | |
| 79 | + void remove_min(void) { m_hasmin=false; } | |
| 80 | + void remove_max(void) { m_hasmax=false; } | |
| 81 | + void remove_range(void) { m_hasmin=false; m_hasmax=false; } | |
| 82 | + | |
| 83 | + // Property methods | |
| 84 | + bool isfree(void) const { return m_free; } | |
| 85 | + bool isfixed(void) const { return !m_free; } | |
| 86 | + bool hasgrad(void) const { return m_hasgrad; } | |
| 87 | + void free(void) { m_free=true; } | |
| 88 | + void fix(void) { m_free=false; } | |
| 89 | + void hasgrad(const bool& grad) { m_hasgrad=grad; } | |
| 90 | + | |
| 91 | + // Other methods | |
| 49 | 92 | void clear(void); |
| 50 | 93 | GModelPar* clone(void) const; |
| 51 | - std::string name(void) const; | |
| 52 | - std::string unit(void) const; | |
| 53 | - double real_value(void) const; | |
| 54 | - double real_error(void) const; | |
| 55 | - double real_gradient(void) const; | |
| 56 | - double real_min(void) const; | |
| 57 | - double real_max(void) const; | |
| 58 | - double value(void) const; | |
| 59 | - double error(void) const; | |
| 60 | - double gradient(void) const; | |
| 61 | - double min(void) const; | |
| 62 | - double max(void) const; | |
| 63 | - double scale(void) const; | |
| 64 | - bool isfree(void) const; | |
| 65 | - bool hasmin(void) const; | |
| 66 | - bool hasmax(void) const; | |
| 67 | - bool hasgrad(void) const; | |
| 68 | - void name(const std::string& name); | |
| 69 | - void unit(const std::string& unit); | |
| 70 | - void real_value(const double& value); | |
| 71 | - void real_error(const double& error); | |
| 72 | - void value(const double& value); | |
| 73 | - void error(const double& error); | |
| 74 | - void gradient(const double& gradient); | |
| 75 | - void min(const double& min); | |
| 76 | - void max(const double& max); | |
| 77 | - void scale(const double& scale); | |
| 78 | - void range(const double& min, const double& max); | |
| 79 | - void remove_min(void); | |
| 80 | - void remove_max(void); | |
| 81 | - void remove_range(void); | |
| 82 | - void free(void); | |
| 83 | - void fix(void); | |
| 84 | - void hasgrad(const bool& grad); | |
| 94 | + std::string name(void) const { return m_name; } | |
| 95 | + std::string unit(void) const { return m_unit; } | |
| 96 | + void name(const std::string& name) { m_name=name; } | |
| 97 | + void unit(const std::string& unit) { m_unit=unit; } | |
| 85 | 98 | void autoscale(void); |
| 86 | 99 | void read(const GXmlElement& xml); |
| 87 | 100 | void write(GXmlElement& xml) const; | ... | ... |
src/model/GModelPar.cpp
| ... | ... | @@ -33,12 +33,14 @@ |
| 33 | 33 | #include "GTools.hpp" |
| 34 | 34 | |
| 35 | 35 | /* __ Method name definitions ____________________________________________ */ |
| 36 | -#define G_REAL_VALUE "GModelPar::real_value(double&)" | |
| 37 | -#define G_REAL_ERROR "GModelPar::real_error(double&)" | |
| 38 | -#define G_VALUE "GModelPar::value(double&)" | |
| 39 | -#define G_MIN "GModelPar::min(double&)" | |
| 40 | -#define G_MAX "GModelPar::max(double&)" | |
| 41 | -#define G_RANGE "GModelPar::range(double&, double&)" | |
| 36 | +#define G_VALUE "GModelPar::Value(double&)" | |
| 37 | +#define G_ERROR "GModelPar::Error(double&)" | |
| 38 | +#define G_FACTOR_VALUE "GModelPar::factor_value(double&)" | |
| 39 | +#define G_FACTOR_MIN "GModelPar::factor_min(double&)" | |
| 40 | +#define G_FACTOR_MAX "GModelPar::factor_max(double&)" | |
| 41 | +#define G_FACTOR_RANGE "GModelPar::factor_range(double&, double&)" | |
| 42 | +#define G_SCALE "GModelPar::Scale(double&)" | |
| 43 | +#define G_READ "GModelPar::read(GXmlElement&)" | |
| 42 | 44 | |
| 43 | 45 | /* __ Macros _____________________________________________________________ */ |
| 44 | 46 | |
| ... | ... | @@ -71,22 +73,59 @@ GModelPar::GModelPar(void) |
| 71 | 73 | * |
| 72 | 74 | * @param[in] name Parameter name. |
| 73 | 75 | * @param[in] value Parameter value. |
| 74 | - * @param[in] scale Parameter scaling (default = 1.0). | |
| 75 | 76 | * |
| 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 | + * Constructs a model parameter from a parameter @p name and a parameter | |
| 78 | + * @p value. | |
| 79 | + * | |
| 80 | + * The parameter is auto-scaled, which for a @p value that differs from zero | |
| 81 | + * sets the scale factor to @p value and the @p factor_value to unity. For a | |
| 82 | + * @p value of zero, the scale factor will be set to unity and the | |
| 83 | + * @p factor_value will be set to @p value. | |
| 84 | + ***************************************************************************/ | |
| 85 | +GModelPar::GModelPar(const std::string& name, const double& value, int i) | |
| 86 | +{ | |
| 87 | + // Initialise members | |
| 88 | + init_members(); | |
| 89 | + | |
| 90 | + // Set name attribute | |
| 91 | + m_name = name; | |
| 92 | + | |
| 93 | + // Set auto-scaled factor and scale attributes | |
| 94 | + if (value != 0.0) { | |
| 95 | + m_factor_value = 1.0; | |
| 96 | + m_scale = value; | |
| 97 | + } | |
| 98 | + else { | |
| 99 | + m_factor_value = value; | |
| 100 | + m_scale = 1.0; | |
| 101 | + } | |
| 102 | + | |
| 103 | + // Return | |
| 104 | + return; | |
| 105 | +} | |
| 106 | + | |
| 107 | + | |
| 108 | +/***********************************************************************//** | |
| 109 | + * @brief Parameter constructor | |
| 110 | + * | |
| 111 | + * @param[in] name Parameter name. | |
| 112 | + * @param[in] factor Parameter factor. | |
| 113 | + * @param[in] scale Parameter scaling. | |
| 114 | + * | |
| 115 | + * Constructs a model parameter from a parameter @p name, @p factor and | |
| 116 | + * @p scale factor. | |
| 78 | 117 | ***************************************************************************/ |
| 79 | 118 | GModelPar::GModelPar(const std::string& name, |
| 80 | - const double& value, | |
| 119 | + const double& factor, | |
| 81 | 120 | const double& scale) |
| 82 | 121 | { |
| 83 | 122 | // Initialise members |
| 84 | 123 | init_members(); |
| 85 | 124 | |
| 86 | 125 | // Set attributes |
| 87 | - this->name(name); | |
| 88 | - this->value(value); | |
| 89 | - this->scale(scale); | |
| 126 | + m_name = name; | |
| 127 | + m_factor_value = factor; | |
| 128 | + m_scale = scale; | |
| 90 | 129 | |
| 91 | 130 | // Return |
| 92 | 131 | return; |
| ... | ... | @@ -192,28 +231,40 @@ GModelPar* GModelPar::clone(void) const |
| 192 | 231 | |
| 193 | 232 | |
| 194 | 233 | /***********************************************************************//** |
| 195 | - * @brief Set real parameter value | |
| 234 | + * @brief Set parameter value | |
| 196 | 235 | * |
| 197 | - * @param[in] value Real parameter value. | |
| 236 | + * @param[in] value Parameter value. | |
| 198 | 237 | * |
| 199 | - * @exception GException::model_invalid_parscale | |
| 200 | - * Parameter has a zero scale factor | |
| 238 | + * Sets the parameter value. The method stores the value factor which is | |
| 239 | + * obtained by dividing the @p value by the scale factor. | |
| 201 | 240 | * |
| 202 | - * Assigns the real parameter value by dividing by the parameter scale. | |
| 241 | + * The method calls factor_value() for assigning the value factor, and this | |
| 242 | + * method will verify that the value lies within the specified boundaries. | |
| 203 | 243 | ***************************************************************************/ |
| 204 | -void GModelPar::real_value(const double& value) | |
| 244 | +void GModelPar::Value(const double& value) | |
| 205 | 245 | { |
| 206 | - // Throw error if scale is 0 | |
| 207 | - if (m_scale == 0.0) { | |
| 208 | - throw GException::model_invalid_parscale(G_REAL_VALUE, m_scale, | |
| 209 | - "Zero scale not allowed for model parameter."); | |
| 210 | - } | |
| 211 | - | |
| 212 | - // Compute value | |
| 213 | - double val = value / m_scale; | |
| 246 | + // Set value factor. The GModelPar class makes sure that m_scale is | |
| 247 | + // never 0, so no test is needed here | |
| 248 | + factor_value(value / m_scale); | |
| 249 | + | |
| 250 | + // Return | |
| 251 | + return; | |
| 252 | +} | |
| 214 | 253 | |
| 215 | - // Assign value | |
| 216 | - this->value(val); | |
| 254 | + | |
| 255 | +/***********************************************************************//** | |
| 256 | + * @brief Set parameter error | |
| 257 | + * | |
| 258 | + * @param[in] error Parameter error. | |
| 259 | + * | |
| 260 | + * Sets the parameter error. The method stores the error factor which is | |
| 261 | + * obtained by dividing the @p error by the scale factor. | |
| 262 | + ***************************************************************************/ | |
| 263 | +void GModelPar::Error(const double& error) | |
| 264 | +{ | |
| 265 | + // Set error factor. The GModelPar class makes sure that m_scale is | |
| 266 | + // never 0, so no test is needed here | |
| 267 | + factor_error(error / m_scale); | |
| 217 | 268 | |
| 218 | 269 | // Return |
| 219 | 270 | return; |
| ... | ... | @@ -221,28 +272,56 @@ void GModelPar::real_value(const double& value) |
| 221 | 272 | |
| 222 | 273 | |
| 223 | 274 | /***********************************************************************//** |
| 224 | - * @brief Set real parameter error | |
| 275 | + * @brief Set parameter gradient | |
| 225 | 276 | * |
| 226 | - * @param[in] error Real parameter error. | |
| 277 | + * @param[in] gradient Parameter gradient. | |
| 278 | + * | |
| 279 | + * Sets the parameter gradient. The method stores the gradient factor which | |
| 280 | + * is obtained by dividing @p gradient by the scale factor. | |
| 281 | + ***************************************************************************/ | |
| 282 | +void GModelPar::Gradient(const double& gradient) | |
| 283 | +{ | |
| 284 | + // Set gradient factor. The GModelPar class makes sure that m_scale is | |
| 285 | + // never 0, so no test is needed here | |
| 286 | + factor_gradient(gradient / m_scale); | |
| 287 | + | |
| 288 | + // Return | |
| 289 | + return; | |
| 290 | +} | |
| 291 | + | |
| 292 | + | |
| 293 | +/***********************************************************************//** | |
| 294 | + * @brief Set minimum parameter boundary | |
| 227 | 295 | * |
| 228 | - * @exception GException::model_invalid_parscale | |
| 229 | - * Parameter has a zero scale factor | |
| 296 | + * @param[in] min Parameter minimum. | |
| 230 | 297 | * |
| 231 | - * Assigns the real parameter error by dividing by the parameter scale. | |
| 298 | + * Sets the minimum parameter boundary. The method stores the minimum | |
| 299 | + * boundary factor which is obtained by dividing @p min by the scale factor. | |
| 232 | 300 | ***************************************************************************/ |
| 233 | -void GModelPar::real_error(const double& error) | |
| 301 | +void GModelPar::Min(const double& min) | |
| 234 | 302 | { |
| 235 | - // Throw error if scale is 0 | |
| 236 | - if (m_scale == 0.0) { | |
| 237 | - throw GException::model_invalid_parscale(G_REAL_ERROR, m_scale, | |
| 238 | - "Zero scale not allowed for model parameter."); | |
| 239 | - } | |
| 240 | - | |
| 241 | - // Compute error | |
| 242 | - double err = error / m_scale; | |
| 303 | + // Set minimum boundary factor. The GModelPar class makes sure that | |
| 304 | + // m_scale is never 0, so no test is needed here | |
| 305 | + factor_min(min / m_scale); | |
| 306 | + | |
| 307 | + // Return | |
| 308 | + return; | |
| 309 | +} | |
| 243 | 310 | |
| 244 | - // Assign error | |
| 245 | - this->error(err); | |
| 311 | + | |
| 312 | +/***********************************************************************//** | |
| 313 | + * @brief Set maximum parameter boundary | |
| 314 | + * | |
| 315 | + * @param[in] max Parameter maximum. | |
| 316 | + * | |
| 317 | + * Sets the maximum parameter boundary. The method stores the maximum | |
| 318 | + * boundary factor which is obtained by dividing @p max by the scale factor. | |
| 319 | + ***************************************************************************/ | |
| 320 | +void GModelPar::Max(const double& max) | |
| 321 | +{ | |
| 322 | + // Set maximum boundary factor. The GModelPar class makes sure that | |
| 323 | + // m_scale is never 0, so no test is needed here | |
| 324 | + factor_max(max / m_scale); | |
| 246 | 325 | |
| 247 | 326 | // Return |
| 248 | 327 | return; |
| ... | ... | @@ -250,29 +329,58 @@ void GModelPar::real_error(const double& error) |
| 250 | 329 | |
| 251 | 330 | |
| 252 | 331 | /***********************************************************************//** |
| 253 | - * @brief Set parameter value | |
| 332 | + * @brief Set minimum and maximum parameter boundaries | |
| 254 | 333 | * |
| 255 | - * @param[in] value Parameter value. | |
| 334 | + * @param[in] min Parameter minimum. | |
| 335 | + * @param[in] max Parameter maximum. | |
| 256 | 336 | * |
| 257 | - * @exception GException::out_of_range | |
| 258 | - * Parameter value outside valid range | |
| 337 | + * Sets the minimum and maximum parameter boundaries. The method calls the | |
| 338 | + * min() and max() methods to set the boundaries. | |
| 259 | 339 | ***************************************************************************/ |
| 260 | -void GModelPar::value(const double& value) | |
| 340 | +void GModelPar::Range(const double& min, const double& max) | |
| 341 | +{ | |
| 342 | + // Set minimum and maximum | |
| 343 | + this->Min(min); | |
| 344 | + this->Max(max); | |
| 345 | + | |
| 346 | + // Return | |
| 347 | + return; | |
| 348 | +} | |
| 349 | + | |
| 350 | + | |
| 351 | +/***********************************************************************//** | |
| 352 | + * @brief Set parameter value factor | |
| 353 | + * | |
| 354 | + * @param[in] value Value factor. | |
| 355 | + * | |
| 356 | + * @exception GException::invalid_argument | |
| 357 | + * Parameter @p value outside [min,max] boundaries. | |
| 358 | + * | |
| 359 | + * Sets the value factor of the model parameter. The method makes sure that | |
| 360 | + * none of the boundaries is violated. Otherwise, exceptions are thrown. | |
| 361 | + ***************************************************************************/ | |
| 362 | +void GModelPar::factor_value(const double& value) | |
| 261 | 363 | { |
| 262 | 364 | // If there is a minimum boundary and if value is below this boundary |
| 263 | - // then throw an error | |
| 264 | - if (m_hasmin && value < m_min) { | |
| 265 | - throw GException::out_of_range(G_VALUE, value, m_min, m_max); | |
| 365 | + // then throw an exception | |
| 366 | + if (m_hasmin && value < m_factor_min) { | |
| 367 | + std::string msg = "Specified value factor "+str(value)+ | |
| 368 | + " is smaller than the minimum boundary "+ | |
| 369 | + str(m_factor_min)+"."; | |
| 370 | + throw GException::invalid_argument(G_FACTOR_VALUE, msg); | |
| 266 | 371 | } |
| 267 | 372 | |
| 268 | 373 | // If there is a maximum boundary and if value is above this boundary |
| 269 | - // then throw an error | |
| 270 | - if (m_hasmax && value > m_max) { | |
| 271 | - throw GException::out_of_range(G_VALUE, value, m_min, m_max); | |
| 374 | + // then throw an exception | |
| 375 | + if (m_hasmax && value > m_factor_max) { | |
| 376 | + std::string msg = "Specified value factor "+str(value)+ | |
| 377 | + " is larger than the maximum boundary "+ | |
| 378 | + str(m_factor_max)+"."; | |
| 379 | + throw GException::invalid_argument(G_FACTOR_VALUE, msg); | |
| 272 | 380 | } |
| 273 | 381 | |
| 274 | 382 | // Assign value |
| 275 | - m_value = value; | |
| 383 | + m_factor_value = value; | |
| 276 | 384 | |
| 277 | 385 | // Return |
| 278 | 386 | return; |
| ... | ... | @@ -280,22 +388,29 @@ void GModelPar::value(const double& value) |
| 280 | 388 | |
| 281 | 389 | |
| 282 | 390 | /***********************************************************************//** |
| 283 | - * @brief Set parameter minimum | |
| 391 | + * @brief Set parameter minimum factor | |
| 284 | 392 | * |
| 285 | - * @param[in] min Parameter minimum. | |
| 393 | + * @param[in] min Minimum factor. | |
| 394 | + * | |
| 395 | + * @exception GException::invalid_argument | |
| 396 | + * Parameter @p min larger than value factor. | |
| 286 | 397 | * |
| 287 | - * @exception GException::out_of_range | |
| 288 | - * Parameter minimum is larger than actual parameter value. | |
| 398 | + * Sets the minimum boundary factor of the model parameter. The method makes | |
| 399 | + * sure that the minimum is not larger than the actual value factor. | |
| 400 | + * Otherwise, an exception is thrown. | |
| 289 | 401 | ***************************************************************************/ |
| 290 | -void GModelPar::min(const double& min) | |
| 402 | +void GModelPar::factor_min(const double& min) | |
| 291 | 403 | { |
| 292 | - // If minimum is above actual value then throw error | |
| 293 | - if (m_value < min) { | |
| 294 | - throw GException::out_of_range(G_MIN, m_value, min, m_max); | |
| 404 | + // Check if minimum is larger than value | |
| 405 | + if (min > m_factor_value) { | |
| 406 | + std::string msg = "Specified minimum factor "+str(min)+ | |
| 407 | + " is larger than the value factor "+ | |
| 408 | + str(m_factor_value)+"."; | |
| 409 | + throw GException::invalid_argument(G_FACTOR_VALUE, msg); | |
| 295 | 410 | } |
| 296 | 411 | |
| 297 | - // Assign minimum | |
| 298 | - m_min = min; | |
| 412 | + // Assign minimum factor | |
| 413 | + m_factor_min = min; | |
| 299 | 414 | |
| 300 | 415 | // Flag that minimum was set |
| 301 | 416 | m_hasmin = true; |
| ... | ... | @@ -306,22 +421,29 @@ void GModelPar::min(const double& min) |
| 306 | 421 | |
| 307 | 422 | |
| 308 | 423 | /***********************************************************************//** |
| 309 | - * @brief Set parameter maximum | |
| 424 | + * @brief Set parameter maximum factor | |
| 310 | 425 | * |
| 311 | - * @param[in] max Parameter maximum. | |
| 426 | + * @param[in] max Maximum factor. | |
| 427 | + * | |
| 428 | + * @exception GException::invalid_argument | |
| 429 | + * Parameter @p max smaller than value factor. | |
| 312 | 430 | * |
| 313 | - * @exception GException::out_of_range | |
| 314 | - * Parameter maximum is smaller than actual parameter value. | |
| 431 | + * Sets the maximum boundary factor of the model parameter. The method makes | |
| 432 | + * sure that the maximum is not smaller than the actual value factor. | |
| 433 | + * Otherwise, an exception is thrown. | |
| 315 | 434 | ***************************************************************************/ |
| 316 | -void GModelPar::max(const double& max) | |
| 435 | +void GModelPar::factor_max(const double& max) | |
| 317 | 436 | { |
| 318 | - // If maximum is below value then throw error | |
| 319 | - if (m_value > max) { | |
| 320 | - throw GException::out_of_range(G_MAX, m_value, m_min, max); | |
| 437 | + // Check if maximum is smaller than value | |
| 438 | + if (max < m_factor_value) { | |
| 439 | + std::string msg = "Specified maximum factor "+str(max)+ | |
| 440 | + " is smaller than the value factor "+ | |
| 441 | + str(m_factor_value)+"."; | |
| 442 | + throw GException::invalid_argument(G_FACTOR_VALUE, msg); | |
| 321 | 443 | } |
| 322 | 444 | |
| 323 | 445 | // Assign maximum |
| 324 | - m_max = max; | |
| 446 | + m_factor_max = max; | |
| 325 | 447 | |
| 326 | 448 | // Flag that maximum was set |
| 327 | 449 | m_hasmax = true; |
| ... | ... | @@ -332,29 +454,91 @@ void GModelPar::max(const double& max) |
| 332 | 454 | |
| 333 | 455 | |
| 334 | 456 | /***********************************************************************//** |
| 335 | - * @brief Set parameter minimum and maximum | |
| 457 | + * @brief Set parameter minimum and maximum factors | |
| 336 | 458 | * |
| 337 | - * @param[in] min Parameter minimum. | |
| 338 | - * @param[in] max Parameter maximum. | |
| 459 | + * @param[in] min Minimum factor. | |
| 460 | + * @param[in] max Maximum factor. | |
| 339 | 461 | * |
| 340 | - * @exception GException::out_of_range | |
| 341 | - * Parameter boundaries are in conflict with actual parameter | |
| 342 | - * value. | |
| 462 | + * Sets the minimum and maximum boundary factors. The method calls the | |
| 463 | + * factor_min() and factor_max() methods which perform validity checking | |
| 464 | + * of the arguments. | |
| 343 | 465 | ***************************************************************************/ |
| 344 | -void GModelPar::range(const double& min, const double& max) | |
| 466 | +void GModelPar::factor_range(const double& min, const double& max) | |
| 345 | 467 | { |
| 346 | - // If maximum is below value then throw error | |
| 347 | - if (m_value < min || m_value > max || min > max) { | |
| 348 | - throw GException::out_of_range(G_RANGE, m_value, min, max); | |
| 468 | + // Set minimum and maximum | |
| 469 | + factor_min(min); | |
| 470 | + factor_max(max); | |
| 471 | + | |
| 472 | + // Return | |
| 473 | + return; | |
| 474 | +} | |
| 475 | + | |
| 476 | + | |
| 477 | +/***********************************************************************//** | |
| 478 | + * @brief Set scale factor | |
| 479 | + * | |
| 480 | + * @param[in] scale Scale factor. | |
| 481 | + * | |
| 482 | + * @exception GException::invalid_argument | |
| 483 | + * Sacle factor of 0 specified. | |
| 484 | + * | |
| 485 | + * Sets the scale factor of the model parameter. All parameter attributes are | |
| 486 | + * rescaled accordingly. | |
| 487 | + * | |
| 488 | + * Special care is taken for value boundaries, that need swaping if the scale | |
| 489 | + * factor changes its sign. In case of sign change the following logic applies: | |
| 490 | + * - if minimum and maximum boundaries are set they are swapped | |
| 491 | + * - if only a minimum boundary exists it will be replaced by a maximum boundary | |
| 492 | + * - if only a maximum boundary exists it will be replaced by a minimum boundary | |
| 493 | + * | |
| 494 | + * An exception is thrown if a scale factor of 0 is specified. | |
| 495 | + ***************************************************************************/ | |
| 496 | +void GModelPar::Scale(const double& scale) | |
| 497 | +{ | |
| 498 | + // Make sure that scale is not zero | |
| 499 | + if (scale == 0.0) { | |
| 500 | + std::string msg = "Specified scale factor of 0.\n" | |
| 501 | + "Model parameters need a non-zero scale factor."; | |
| 502 | + throw GException::invalid_argument(G_SCALE, msg); | |
| 349 | 503 | } |
| 350 | 504 | |
| 351 | - // Assign range | |
| 352 | - m_min = min; | |
| 353 | - m_max = max; | |
| 354 | - | |
| 355 | - // Flag that range was set | |
| 356 | - m_hasmin = true; | |
| 357 | - m_hasmax = true; | |
| 505 | + // Set rescaling | |
| 506 | + double rescale = m_scale/scale; | |
| 507 | + | |
| 508 | + // Set new scale factor | |
| 509 | + m_scale = scale; | |
| 510 | + | |
| 511 | + // Set values, error, gradient, min and max | |
| 512 | + m_factor_value *= rescale; | |
| 513 | + m_factor_error *= rescale; | |
| 514 | + m_factor_gradient *= rescale; | |
| 515 | + if (m_hasmin) { | |
| 516 | + m_factor_min *= rescale; | |
| 517 | + } | |
| 518 | + if (m_hasmax) { | |
| 519 | + m_factor_max *= rescale; | |
| 520 | + } | |
| 521 | + | |
| 522 | + // Takes care of boundaries in case of sign change | |
| 523 | + if (rescale < 0.0) { | |
| 524 | + if (m_hasmin && m_hasmax) { | |
| 525 | + double swap = m_factor_min; | |
| 526 | + m_factor_min = m_factor_max; | |
| 527 | + m_factor_max = swap; | |
| 528 | + } | |
| 529 | + else if (m_hasmin) { | |
| 530 | + m_factor_max = m_factor_min; | |
| 531 | + m_hasmax = true; | |
| 532 | + m_factor_min = 0.0; | |
| 533 | + m_hasmin = false; | |
| 534 | + } | |
| 535 | + else if (m_hasmax) { | |
| 536 | + m_factor_min = m_factor_max; | |
| 537 | + m_hasmin = true; | |
| 538 | + m_factor_max = 0.0; | |
| 539 | + m_hasmax = false; | |
| 540 | + } | |
| 541 | + } | |
| 358 | 542 | |
| 359 | 543 | // Return |
| 360 | 544 | return; |
| ... | ... | @@ -364,35 +548,61 @@ void GModelPar::range(const double& min, const double& max) |
| 364 | 548 | /***********************************************************************//** |
| 365 | 549 | * @brief Autoscale parameter |
| 366 | 550 | * |
| 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. | |
| 551 | + * Sets the value factor to unity and the scale factor to the real value | |
| 552 | + * of the parameter. The method will also adjust the error factor and | |
| 553 | + * gradient factor, as well as the minimum and maximum factors if they | |
| 554 | + * exist. | |
| 371 | 555 | * |
| 372 | - * The method does nothing if the actual value is zero. | |
| 556 | + * Special care is taken for value boundaries, that need swaping if the scale | |
| 557 | + * factor changes its sign. In case of sign change the following logic applies: | |
| 558 | + * - if minimum and maximum boundaries are set they are swapped | |
| 559 | + * - if only a minimum boundary exists it will be replaced by a maximum boundary | |
| 560 | + * - if only a maximum boundary exists it will be replaced by a minimum boundary | |
| 561 | + * | |
| 562 | + * The method does nothing if the actual value factor is zero. | |
| 373 | 563 | ***************************************************************************/ |
| 374 | 564 | void GModelPar::autoscale(void) |
| 375 | 565 | { |
| 376 | - // Continue only if the value is non-zero | |
| 377 | - if (m_value != 0.0) { | |
| 566 | + // Continue only if the value factor is non-zero | |
| 567 | + if (m_factor_value != 0.0) { | |
| 378 | 568 | |
| 379 | 569 | // Set the scale factor |
| 380 | - m_scale *= m_value; | |
| 570 | + m_scale *= m_factor_value; | |
| 381 | 571 | |
| 382 | 572 | // Get inverse scaling factor |
| 383 | - double invscale = 1.0 / m_value; | |
| 573 | + double invscale = 1.0 / m_factor_value; | |
| 384 | 574 | |
| 385 | 575 | // Set values, error, gradient, min and max |
| 386 | - m_value *= invscale; | |
| 387 | - m_error *= invscale; | |
| 388 | - m_gradient *= invscale; | |
| 576 | + m_factor_value *= invscale; | |
| 577 | + m_factor_error *= invscale; | |
| 578 | + m_factor_gradient *= invscale; | |
| 389 | 579 | if (m_hasmin) { |
| 390 | - m_min *= invscale; | |
| 580 | + m_factor_min *= invscale; | |
| 391 | 581 | } |
| 392 | 582 | if (m_hasmax) { |
| 393 | - m_max *= invscale; | |
| 583 | + m_factor_max *= invscale; | |
| 394 | 584 | } |
| 395 | 585 | |
| 586 | + // Takes care of boundaries in case of sign change | |
| 587 | + if (invscale < 0.0) { | |
| 588 | + if (m_hasmin && m_hasmax) { | |
| 589 | + double swap = m_factor_min; | |
| 590 | + m_factor_min = m_factor_max; | |
| 591 | + m_factor_max = swap; | |
| 592 | + } | |
| 593 | + else if (m_hasmin) { | |
| 594 | + m_factor_max = m_factor_min; | |
| 595 | + m_hasmax = true; | |
| 596 | + m_factor_min = 0.0; | |
| 597 | + m_hasmin = false; | |
| 598 | + } | |
| 599 | + else if (m_hasmax) { | |
| 600 | + m_factor_min = m_factor_max; | |
| 601 | + m_hasmin = true; | |
| 602 | + m_factor_max = 0.0; | |
| 603 | + m_hasmax = false; | |
| 604 | + } | |
| 605 | + } | |
| 396 | 606 | |
| 397 | 607 | } // endif: value was non-zero |
| 398 | 608 | |
| ... | ... | @@ -406,50 +616,112 @@ void GModelPar::autoscale(void) |
| 406 | 616 | * |
| 407 | 617 | * @param[in] xml XML element |
| 408 | 618 | * |
| 409 | - * The following parameter attributes may exist (they take the default | |
| 410 | - * values when they are not found in the XML element): | |
| 411 | - * "value" (default=0.0), "error" (default=0.0), "scale" (default=1.0), | |
| 412 | - * "min" (default=INDEF), "max" (default=INDEF), "free" (default=0). | |
| 619 | + * @exception GException::invalid_value | |
| 620 | + * Invalid combination of parameter attributes encountered. | |
| 621 | + * | |
| 622 | + * Extracts the parameter attributes from an XML element of the form | |
| 623 | + * | |
| 624 | + * <parameter name=".." value=".." error=".." scale=".." min=".." max="..' free=".."> | |
| 625 | + * | |
| 626 | + * Each of the attributes are optional, with the following scheme for | |
| 627 | + * assigning default values in case that the attribute was not found: | |
| 628 | + * - @p value sets @p m_factor_value (defaults to 0.0) | |
| 629 | + * - @p error sets @p m_factor_error (defaults to 0.0) | |
| 630 | + * - @p scale sets @p m_scale (defaults to 1.0) | |
| 631 | + * - @p min sets @p m_factor_min (will remove_min() if not found) | |
| 632 | + * - @p max sets @p m_factor_max (will remove_max() if not found) | |
| 633 | + * - @p free sets @p m_free (papameter will be fixed if not found) | |
| 413 | 634 | ***************************************************************************/ |
| 414 | 635 | void GModelPar::read(const GXmlElement& xml) |
| 415 | 636 | { |
| 416 | 637 | // Get value |
| 417 | 638 | std::string arg = xml.attribute("value"); |
| 418 | - if (arg != "") | |
| 419 | - m_value = todouble(arg); | |
| 420 | - else | |
| 421 | - m_value = 0.0; | |
| 639 | + if (arg != "") { | |
| 640 | + m_factor_value = todouble(arg); | |
| 641 | + } | |
| 642 | + else { | |
| 643 | + m_factor_value = 0.0; | |
| 644 | + } | |
| 422 | 645 | |
| 423 | 646 | // Get error |
| 424 | 647 | arg = xml.attribute("error"); |
| 425 | - if (arg != "") | |
| 426 | - m_error = todouble(arg); | |
| 427 | - else | |
| 428 | - m_error = 0.0; | |
| 648 | + if (arg != "") { | |
| 649 | + m_factor_error = todouble(arg); | |
| 650 | + } | |
| 651 | + else { | |
| 652 | + m_factor_error = 0.0; | |
| 653 | + } | |
| 429 | 654 | |
| 430 | 655 | // Get scale factor |
| 431 | 656 | arg = xml.attribute("scale"); |
| 432 | - if (arg != "") | |
| 657 | + if (arg != "") { | |
| 433 | 658 | m_scale = todouble(arg); |
| 434 | - else | |
| 659 | + } | |
| 660 | + else { | |
| 435 | 661 | m_scale = 1.0; |
| 662 | + } | |
| 436 | 663 | |
| 437 | 664 | // Get min |
| 438 | 665 | arg = xml.attribute("min"); |
| 439 | - if (arg != "") | |
| 440 | - min(todouble(arg)); | |
| 666 | + if (arg != "") { | |
| 667 | + m_factor_min = todouble(arg); | |
| 668 | + m_hasmin = true; | |
| 669 | + } | |
| 670 | + else { | |
| 671 | + remove_min(); | |
| 672 | + } | |
| 441 | 673 | |
| 442 | 674 | // Get max |
| 443 | 675 | arg = xml.attribute("max"); |
| 444 | - if (arg != "") | |
| 445 | - max(todouble(arg)); | |
| 676 | + if (arg != "") { | |
| 677 | + m_factor_max = todouble(arg); | |
| 678 | + m_hasmax = true; | |
| 679 | + } | |
| 680 | + else { | |
| 681 | + remove_max(); | |
| 682 | + } | |
| 446 | 683 | |
| 447 | 684 | // Get free |
| 448 | 685 | if (xml.attribute("free") == "1" || |
| 449 | - tolower(xml.attribute("free")) == "true") | |
| 686 | + tolower(xml.attribute("free")) == "true") { | |
| 450 | 687 | free(); |
| 451 | - else | |
| 688 | + } | |
| 689 | + else { | |
| 452 | 690 | fix(); |
| 691 | + } | |
| 692 | + | |
| 693 | + // If there is a minimum and maximum, make sure that the maximum is | |
| 694 | + // not smaller than the minimum | |
| 695 | + if (m_hasmin && m_hasmax) { | |
| 696 | + if (m_factor_min > m_factor_max) { | |
| 697 | + std::string msg = "The model parameter "+m_name+ | |
| 698 | + " in the XML document has a minimum boundary "+ | |
| 699 | + str(m_factor_min)+ | |
| 700 | + " that is larger than the maximum boundary "+ | |
| 701 | + str(m_factor_max)+".\n"+xml.print(); | |
| 702 | + throw GException::invalid_value(G_READ, msg); | |
| 703 | + } | |
| 704 | + } | |
| 705 | + | |
| 706 | + // If there is a minimum, make sure that the value is not below it | |
| 707 | + if (m_hasmin && m_factor_value < m_factor_min) { | |
| 708 | + std::string msg = "The model parameter "+m_name+ | |
| 709 | + " in the XML document has a value "+ | |
| 710 | + str(m_factor_value)+ | |
| 711 | + " that is smaller than the minimum boundary "+ | |
| 712 | + str(m_factor_min)+".\n"+xml.print(); | |
| 713 | + throw GException::invalid_value(G_READ, msg); | |
| 714 | + } | |
| 715 | + | |
| 716 | + // If there is a maximum, make sure that the value is not above it | |
| 717 | + if (m_hasmax && m_factor_value > m_factor_max) { | |
| 718 | + std::string msg = "The model parameter "+m_name+ | |
| 719 | + " in the XML document has a value "+ | |
| 720 | + str(m_factor_value)+ | |
| 721 | + " that is larger than the maximum boundary "+ | |
| 722 | + str(m_factor_max)+".\n"+xml.print(); | |
| 723 | + throw GException::invalid_value(G_READ, msg); | |
| 724 | + } | |
| 453 | 725 | |
| 454 | 726 | // Return |
| 455 | 727 | return; |
| ... | ... | @@ -461,36 +733,48 @@ void GModelPar::read(const GXmlElement& xml) |
| 461 | 733 | * |
| 462 | 734 | * @param[in] xml XML element. |
| 463 | 735 | * |
| 464 | - * The following parameter attributes may exist (they take the default | |
| 465 | - * values when they are not found in the XML element): | |
| 466 | - * "value" (default=0.0), "error" (default=0.0), "scale" (default=1.0), | |
| 467 | - * "min" (default=INDEF), "max" (default=INDEF), "free" (default=0). | |
| 736 | + * Sets or updates the parameter attributes in an XML element of the form | |
| 737 | + * | |
| 738 | + * <parameter name=".." value=".." error=".." scale=".." min=".." max="..' free=".."> | |
| 739 | + * | |
| 740 | + * The following attributes will be set: | |
| 741 | + * - @p value | |
| 742 | + * - @p error (only in case that the parameter is free) | |
| 743 | + * - @p scale | |
| 744 | + * - @p min (only in case that a minimum exists) | |
| 745 | + * - @p max (only in case that a maximum exists) | |
| 746 | + * - @p free | |
| 468 | 747 | ***************************************************************************/ |
| 469 | 748 | void GModelPar::write(GXmlElement& xml) const |
| 470 | 749 | { |
| 471 | 750 | // Set value |
| 472 | - xml.attribute("value", str(m_value)); | |
| 751 | + xml.attribute("value", str(m_factor_value)); | |
| 473 | 752 | |
| 474 | 753 | // Set error (only if parameter is free) |
| 475 | - if (isfree()) | |
| 476 | - xml.attribute("error", str(m_error)); | |
| 754 | + if (isfree()) { | |
| 755 | + xml.attribute("error", str(m_factor_error)); | |
| 756 | + } | |
| 477 | 757 | |
| 478 | 758 | // Set scale |
| 479 | 759 | xml.attribute("scale", str(m_scale)); |
| 480 | 760 | |
| 481 | 761 | // Set minimum |
| 482 | - if (hasmin()) | |
| 483 | - xml.attribute("min", str(m_min)); | |
| 762 | + if (hasmin()) { | |
| 763 | + xml.attribute("min", str(m_factor_min)); | |
| 764 | + } | |
| 484 | 765 | |
| 485 | 766 | // Set maximum |
| 486 | - if (hasmax()) | |
| 487 | - xml.attribute("max", str(m_max)); | |
| 767 | + if (hasmax()) { | |
| 768 | + xml.attribute("max", str(m_factor_max)); | |
| 769 | + } | |
| 488 | 770 | |
| 489 | 771 | // Set free/fix flag |
| 490 | - if (isfree()) | |
| 772 | + if (isfree()) { | |
| 491 | 773 | xml.attribute("free", "1"); |
| 492 | - else | |
| 774 | + } | |
| 775 | + else { | |
| 493 | 776 | xml.attribute("free", "0"); |
| 777 | + } | |
| 494 | 778 | |
| 495 | 779 | // Return |
| 496 | 780 | return; |
| ... | ... | @@ -499,6 +783,8 @@ void GModelPar::write(GXmlElement& xml) const |
| 499 | 783 | |
| 500 | 784 | /***********************************************************************//** |
| 501 | 785 | * @brief Print parameter information |
| 786 | + * | |
| 787 | + * @return String with model parameter information. | |
| 502 | 788 | ***************************************************************************/ |
| 503 | 789 | std::string GModelPar::print(void) const |
| 504 | 790 | { |
| ... | ... | @@ -508,38 +794,46 @@ std::string GModelPar::print(void) const |
| 508 | 794 | // Append parameter name |
| 509 | 795 | result.append(parformat(" "+name())); |
| 510 | 796 | |
| 511 | - // Append real value | |
| 512 | - result.append(str(real_value())); | |
| 797 | + // Append value | |
| 798 | + result.append(str(Value())); | |
| 513 | 799 | |
| 514 | 800 | // For free parameters, append statistical uncertainty |
| 515 | - if (m_free) | |
| 516 | - result.append(" +/- "+str(fabs(real_error()))); | |
| 801 | + if (m_free) { | |
| 802 | + result.append(" +/- "+str(std::abs(Error()))); | |
| 803 | + } | |
| 517 | 804 | |
| 518 | 805 | // Append parameter limites if they exist |
| 519 | - if (m_hasmin && m_hasmax) | |
| 520 | - result.append(" ["+str(real_min()) + ","+str(real_max())+"]"); | |
| 521 | - else if (m_hasmin) | |
| 522 | - result.append(" ["+str(real_min()) + ",infty["); | |
| 523 | - else if (m_hasmax) | |
| 524 | - result.append(" ]-infty,"+str(real_max())+"]"); | |
| 806 | + if (m_hasmin && m_hasmax) { | |
| 807 | + result.append(" ["+str(Min()) + ","+str(Max())+"]"); | |
| 808 | + } | |
| 809 | + else if (m_hasmin) { | |
| 810 | + result.append(" ["+str(Min()) + ",infty["); | |
| 811 | + } | |
| 812 | + else if (m_hasmax) { | |
| 813 | + result.append(" ]-infty,"+str(Max())+"]"); | |
| 814 | + } | |
| 525 | 815 | |
| 526 | 816 | // Append parameter unit |
| 527 | 817 | result.append(" "+m_unit); |
| 528 | 818 | |
| 529 | 819 | // Signal if parameter was free or fixed |
| 530 | - if (m_free) | |
| 820 | + if (m_free) { | |
| 531 | 821 | result.append(" (free"); |
| 532 | - else | |
| 822 | + } | |
| 823 | + else { | |
| 533 | 824 | result.append(" (fixed"); |
| 825 | + } | |
| 534 | 826 | |
| 535 | 827 | // Append parameter scale |
| 536 | 828 | result.append(",scale="+str(m_scale)); |
| 537 | 829 | |
| 538 | 830 | // Signal if parameter has analytic gradient |
| 539 | - if (m_hasgrad) | |
| 831 | + if (m_hasgrad) { | |
| 540 | 832 | result.append(",gradient)"); |
| 541 | - else | |
| 833 | + } | |
| 834 | + else { | |
| 542 | 835 | result.append(")"); |
| 836 | + } | |
| 543 | 837 | |
| 544 | 838 | // Return result |
| 545 | 839 | return result; |
| ... | ... | @@ -560,16 +854,16 @@ void GModelPar::init_members(void) |
| 560 | 854 | // Initialise members |
| 561 | 855 | m_name.clear(); |
| 562 | 856 | m_unit.clear(); |
| 563 | - m_value = 0.0; | |
| 564 | - m_error = 0.0; | |
| 565 | - m_gradient = 0.0; | |
| 566 | - m_min = 0.0; | |
| 567 | - m_max = 0.0; | |
| 568 | - m_scale = 1.0; | |
| 569 | - m_free = true; | |
| 570 | - m_hasmin = false; | |
| 571 | - m_hasmax = false; | |
| 572 | - m_hasgrad = false; | |
| 857 | + m_factor_value = 0.0; | |
| 858 | + m_factor_error = 0.0; | |
| 859 | + m_factor_gradient = 0.0; | |
| 860 | + m_factor_min = 0.0; | |
| 861 | + m_factor_max = 0.0; | |
| 862 | + m_scale = 1.0; | |
| 863 | + m_free = true; | |
| 864 | + m_hasmin = false; | |
| 865 | + m_hasmax = false; | |
| 866 | + m_hasgrad = false; | |
| 573 | 867 | |
| 574 | 868 | // Return |
| 575 | 869 | return; |
| ... | ... | @@ -584,18 +878,18 @@ void GModelPar::init_members(void) |
| 584 | 878 | void GModelPar::copy_members(const GModelPar& par) |
| 585 | 879 | { |
| 586 | 880 | // Copy members |
| 587 | - m_name = par.m_name; | |
| 588 | - m_unit = par.m_unit; | |
| 589 | - m_value = par.m_value; | |
| 590 | - m_error = par.m_error; | |
| 591 | - m_gradient = par.m_gradient; | |
| 592 | - m_min = par.m_min; | |
| 593 | - m_max = par.m_max; | |
| 594 | - m_scale = par.m_scale; | |
| 595 | - m_free = par.m_free; | |
| 596 | - m_hasmin = par.m_hasmin; | |
| 597 | - m_hasmax = par.m_hasmax; | |
| 598 | - m_hasgrad = par.m_hasgrad; | |
| 881 | + m_name = par.m_name; | |
| 882 | + m_unit = par.m_unit; | |
| 883 | + m_factor_value = par.m_factor_value; | |
| 884 | + m_factor_error = par.m_factor_error; | |
| 885 | + m_factor_gradient = par.m_factor_gradient; | |
| 886 | + m_factor_min = par.m_factor_min; | |
| 887 | + m_factor_max = par.m_factor_max; | |
| 888 | + m_scale = par.m_scale; | |
| 889 | + m_free = par.m_free; | |
| 890 | + m_hasmin = par.m_hasmin; | |
| 891 | + m_hasmax = par.m_hasmax; | |
| 892 | + m_hasgrad = par.m_hasgrad; | |
| 599 | 893 | |
| 600 | 894 | // Return |
| 601 | 895 | return; | ... | ... |