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,14 +546,17 @@ double gammalib::plaw_integral(const double& x1,
546 const double& f2) 546 const double& f2)
547 { 547 {
548 // Compute power law slope 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 double integral; 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 else { 561 else {
559 integral = f1 * x1 * xratio; 562 integral = f1 * x1 * xratio;
test/test_GNumerics.cpp
@@ -90,6 +90,7 @@ void TestGNumerics::test_math(void) @@ -90,6 +90,7 @@ void TestGNumerics::test_math(void)
90 // Test power law integration 90 // Test power law integration
91 test_value(gammalib::plaw_integral(2.0, 3.0, 9.0, 5.0), 29.112577); 91 test_value(gammalib::plaw_integral(2.0, 3.0, 9.0, 5.0), 29.112577);
92 test_value(gammalib::plaw_integral(2.0, 9.0, 9.0, 2.0), 27.073393); 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 // Exit test 95 // Exit test
95 return; 96 return;