Commit efa5ea566f0bf64aca32f7e22a66761cbccf2f80
1 parent
6b0f4241
Begins to implement gradients in GModelSpectralGauss::eval_gradients
Showing
2 changed files
with
96 additions
and
4 deletions
include/GModelSpectralGauss.hpp
| @@ -183,7 +183,7 @@ GEnergy GModelSpectralGauss::mean(void) const | @@ -183,7 +183,7 @@ GEnergy GModelSpectralGauss::mean(void) const | ||
| 183 | /***********************************************************************//** | 183 | /***********************************************************************//** |
| 184 | * @brief Set mean energy | 184 | * @brief Set mean energy |
| 185 | * | 185 | * |
| 186 | - * @param[in] Mean energy. | 186 | + * @param[in] mean Mean energy. |
| 187 | ***************************************************************************/ | 187 | ***************************************************************************/ |
| 188 | inline | 188 | inline |
| 189 | void GModelSpectralGauss::mean(const GEnergy& mean) | 189 | void GModelSpectralGauss::mean(const GEnergy& mean) |
| @@ -209,7 +209,7 @@ GEnergy GModelSpectralGauss::sigma(void) const | @@ -209,7 +209,7 @@ GEnergy GModelSpectralGauss::sigma(void) const | ||
| 209 | /***********************************************************************//** | 209 | /***********************************************************************//** |
| 210 | * @brief Set energy width | 210 | * @brief Set energy width |
| 211 | * | 211 | * |
| 212 | - * @param[in] Energy width | 212 | + * @param[in] sigma Energy width |
| 213 | ***************************************************************************/ | 213 | ***************************************************************************/ |
| 214 | inline | 214 | inline |
| 215 | void GModelSpectralGauss::sigma(const GEnergy& sigma) | 215 | void GModelSpectralGauss::sigma(const GEnergy& sigma) |
src/model/GModelSpectralGauss.cpp
| @@ -270,12 +270,59 @@ double GModelSpectralGauss::eval(const GEnergy& srcEng, | @@ -270,12 +270,59 @@ double GModelSpectralGauss::eval(const GEnergy& srcEng, | ||
| 270 | * | 270 | * |
| 271 | * This method simply calls the eval() method as no analytical gradients will | 271 | * This method simply calls the eval() method as no analytical gradients will |
| 272 | * be computed. See the eval() method for details. | 272 | * be computed. See the eval() method for details. |
| 273 | + * | ||
| 274 | + * TODO: Implement this | ||
| 273 | ***************************************************************************/ | 275 | ***************************************************************************/ |
| 274 | double GModelSpectralGauss::eval_gradients(const GEnergy& srcEng, | 276 | double GModelSpectralGauss::eval_gradients(const GEnergy& srcEng, |
| 275 | const GTime& srcTime) | 277 | const GTime& srcTime) |
| 276 | { | 278 | { |
| 277 | - // Return | ||
| 278 | - return eval(srcEng, srcTime); | 279 | + double energy = srcEng.MeV(); |
| 280 | + double norm = m_norm.value(); | ||
| 281 | + double mean = m_mean.value(); | ||
| 282 | + double sigma = m_sigma.value(); | ||
| 283 | + | ||
| 284 | + // Update the evaluation cache | ||
| 285 | + update_eval_cache(srcEng); | ||
| 286 | + | ||
| 287 | + // Compute function value | ||
| 288 | + double term1 = (norm / sigma) * gammalib::inv_sqrt2pi; | ||
| 289 | + double term2 = (energy - mean) * (energy - mean) / (2 * sigma * sigma); | ||
| 290 | + double value = term1 * std::exp(- term2); | ||
| 291 | + | ||
| 292 | + // Compute partial derivatives with respect to the parameter factor | ||
| 293 | + // values. The partial derivatives with respect to the parameter | ||
| 294 | + // values are obtained by division by the scale factor. | ||
| 295 | + double g_norm = (m_norm.is_free()) | ||
| 296 | + ? m_norm.scale() * m_last_power : 0.0; | ||
| 297 | + double g_mean = (m_index.is_free()) | ||
| 298 | + ? value * m_index.scale() * std::log(m_last_e_norm) : 0.0; | ||
| 299 | + double g_sigma = (m_ecut.is_free()) | ||
| 300 | + ? value * m_last_e_cut / m_ecut.factor_value() : 0.0; | ||
| 301 | + | ||
| 302 | + // Set gradients | ||
| 303 | + m_norm.factor_gradient(g_norm); | ||
| 304 | + m_mean.factor_gradient(g_mean); | ||
| 305 | + m_sigma.factor_gradient(g_sigma); | ||
| 306 | + | ||
| 307 | + // Compile option: Check for NaN/Inf | ||
| 308 | + #if defined(G_NAN_CHECK) | ||
| 309 | + if (gammalib::is_notanumber(value) || gammalib::is_infinite(value)) { | ||
| 310 | + std::cout << "*** ERROR: GModelSpectralExpPlaw::eval_gradients"; | ||
| 311 | + std::cout << "(srcEng=" << srcEng; | ||
| 312 | + std::cout << ", srcTime=" << srcTime << "):"; | ||
| 313 | + std::cout << " NaN/Inf encountered"; | ||
| 314 | + std::cout << " (value=" << value; | ||
| 315 | + std::cout << ", e_norm=" << m_last_e_norm; | ||
| 316 | + std::cout << ", e_cut=" << m_last_e_cut; | ||
| 317 | + std::cout << ", power=" << m_last_power; | ||
| 318 | + std::cout << ")" << std::endl; | ||
| 319 | + } | ||
| 320 | + #endif | ||
| 321 | + | ||
| 322 | + // Return | ||
| 323 | + return value; | ||
| 324 | + } | ||
| 325 | + | ||
| 279 | } | 326 | } |
| 280 | 327 | ||
| 281 | 328 | ||
| @@ -726,3 +773,48 @@ double GModelSpectralGauss::eflux_kernel::eval(const double& energy) | @@ -726,3 +773,48 @@ double GModelSpectralGauss::eflux_kernel::eval(const double& energy) | ||
| 726 | // Return value | 773 | // Return value |
| 727 | return value; | 774 | return value; |
| 728 | } | 775 | } |
| 776 | + | ||
| 777 | +/***********************************************************************//** | ||
| 778 | + * @brief Update eval precomputation cache | ||
| 779 | + * | ||
| 780 | + * @param[in] energy Energy. | ||
| 781 | + * | ||
| 782 | + * Updates the precomputation cache for eval() and eval_gradients() methods. | ||
| 783 | + * | ||
| 784 | + * TODO integrate this to correct form | ||
| 785 | + ***************************************************************************/ | ||
| 786 | +void GModelSpectralGauss::update_eval_cache(const GEnergy& energy) const | ||
| 787 | +{ | ||
| 788 | + // Get parameter values (takes 3 multiplications which are difficult | ||
| 789 | + // to avoid) | ||
| 790 | + double index = m_index.value(); | ||
| 791 | + double ecut = m_ecut.value(); | ||
| 792 | + double pivot = m_pivot.value(); | ||
| 793 | + | ||
| 794 | + // If the energy or one of the parameters index, cut-off or pivot | ||
| 795 | + // energy has changed then recompute the cache | ||
| 796 | + if ((m_last_energy != energy) || | ||
| 797 | + (m_last_index != index) || | ||
| 798 | + (m_last_ecut != ecut) || | ||
| 799 | + (m_last_pivot != pivot)) { | ||
| 800 | + | ||
| 801 | + // Store actual energy and parameter values | ||
| 802 | + m_last_energy = energy; | ||
| 803 | + m_last_index = index; | ||
| 804 | + m_last_ecut = ecut; | ||
| 805 | + m_last_pivot = pivot; | ||
| 806 | + | ||
| 807 | + // Compute and store value | ||
| 808 | + double eng = energy.MeV(); | ||
| 809 | + m_last_e_norm = eng / m_last_pivot; | ||
| 810 | + m_last_e_cut = eng / m_last_ecut; | ||
| 811 | + m_last_power = std::pow(m_last_e_norm, m_last_index) * | ||
| 812 | + std::exp(-m_last_e_cut); | ||
| 813 | + | ||
| 814 | + } // endif: recomputation was required | ||
| 815 | + | ||
| 816 | + // Return | ||
| 817 | + return; | ||
| 818 | +} | ||
| 819 | + | ||
| 820 | + |