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 | 183 | /***********************************************************************//** |
| 184 | 184 | * @brief Set mean energy |
| 185 | 185 | * |
| 186 | - * @param[in] Mean energy. | |
| 186 | + * @param[in] mean Mean energy. | |
| 187 | 187 | ***************************************************************************/ |
| 188 | 188 | inline |
| 189 | 189 | void GModelSpectralGauss::mean(const GEnergy& mean) |
| ... | ... | @@ -209,7 +209,7 @@ GEnergy GModelSpectralGauss::sigma(void) const |
| 209 | 209 | /***********************************************************************//** |
| 210 | 210 | * @brief Set energy width |
| 211 | 211 | * |
| 212 | - * @param[in] Energy width | |
| 212 | + * @param[in] sigma Energy width | |
| 213 | 213 | ***************************************************************************/ |
| 214 | 214 | inline |
| 215 | 215 | void GModelSpectralGauss::sigma(const GEnergy& sigma) | ... | ... |
src/model/GModelSpectralGauss.cpp
| ... | ... | @@ -270,12 +270,59 @@ double GModelSpectralGauss::eval(const GEnergy& srcEng, |
| 270 | 270 | * |
| 271 | 271 | * This method simply calls the eval() method as no analytical gradients will |
| 272 | 272 | * be computed. See the eval() method for details. |
| 273 | + * | |
| 274 | + * TODO: Implement this | |
| 273 | 275 | ***************************************************************************/ |
| 274 | 276 | double GModelSpectralGauss::eval_gradients(const GEnergy& srcEng, |
| 275 | 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 | 773 | // Return value |
| 727 | 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 | + | ... | ... |