Commit f0bddd131b8f5960cb82e7d855dff14bb84d291e

Authored by Jürgen Knödlseder
1 parent dc59816a

Assure numerical accuracy in gammalib::plaw_integral() method

src/numerics/GMath.cpp
... ... @@ -546,14 +546,17 @@ double gammalib::plaw_integral(const double& x1,
546 546 const double& f2)
547 547 {
548 548 // Compute power law slope
549   - double fratio = std::log(f2/f1);
550   - double xratio = std::log(x2/x1);
551   - double slope = fratio / xratio;
552   -
553   - // Compute integral
  549 + double x2x1 = x2/x1;
  550 + double fratio = std::log(f2/f1);
  551 + double xratio = std::log(x2x1);
  552 + double slope = fratio / xratio;
  553 + double slopep1 = slope + 1.0;
  554 +
  555 + // Compute integral. Computations dependend on the slope. We add here a
  556 + // kluge to assure numerical accuracy.
554 557 double integral;
555   - if (slope != -1.0) {
556   - integral = f1 / (slope + 1.0) * (x2 * std::pow(x2/x1, slope) - x1);
  558 + if (std::abs(slopep1) > 1.0e-11) {
  559 + integral = f1 / slopep1 * (x2 * std::pow(x2x1, slope) - x1);
557 560 }
558 561 else {
559 562 integral = f1 * x1 * xratio;
... ...
test/test_GNumerics.cpp
... ... @@ -90,6 +90,7 @@ void TestGNumerics::test_math(void)
90 90 // Test power law integration
91 91 test_value(gammalib::plaw_integral(2.0, 3.0, 9.0, 5.0), 29.112577);
92 92 test_value(gammalib::plaw_integral(2.0, 9.0, 9.0, 2.0), 27.073393);
  93 + test_value(gammalib::plaw_integral(2.0, 9.0, 5.0, 2.0), 12.471065);
93 94  
94 95 // Exit test
95 96 return;
... ...