Integration and derivatives¶
Scalar functions¶
The following code illustrates how integrations and derivatives are
computed within GammaLib for scalar functions (see examples/cpp/numerics/numerics.cpp
for
the source code):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | class function : public GFunction {
public:
function(const double& sigma) : m_a(1.0/(sigma*std::sqrt(gammalib::twopi))), m_sigma(sigma) {}
double eval(const double& x) { return m_a*std::exp(-0.5*x*x/(m_sigma*m_sigma)); }
protected:
double m_a;
double m_sigma;
};
int main(void) {
function fct(3.0);
GIntegral integral(&fct);
integral.eps(1.0e-8);
double result = integral.romb(-15.0, +15.0);
std::cout << "Integral: " << result << std::endl;
GDerivative derivative(&fct);
std::cout << "Derivative(0): " << derivative.value(0.0) << std::endl;
return 0;
}
|
The function that should be integrated or differentiated is defined in
lines 1-8 as a class that derives from the abstract GFunction base
class. The only method that needs to be implement in the derived class,
here named function
is the GFunction::eval() method that takes a const reference
to a double precision value as argument and that returns a double precision
value, which is the function value evaluated at the argument. Parameters
may be passed to the function upon construction, as illustrated by the
m_a
and m_sigma
members that are initialised by the constructor.
The function is allocated in line 10 with a sigma parameter of 3. Line 11
the prepares for the integration by allocating an integration object. The
GIntegral constructor takes a reference to the function as argument.
In line 12, the relative precision of the integration object is set to
\(10^{-8}\) (by default the precision is set to \(10^{-6}\)).
In line 13, the integration is done over the parameter interval
\([-15,15]\). As this covers basically the entire area of the
Gaussian function, the result will be very close to 1 (the result is
printed in line 14). Note that the Romberg method is used for integration
by invoking the romb
method. This is the only method that is so far
available in GammaLib.
Differentiating a function is similar. For this purpose, a GDerivative object is created in line 15 with takes a reference to the function as argument. Using the GDerivative::value() method, the derivative is computed in line 16 for a function argument of 0. As the Gaussian has a maximum there, the result will be 0.
Vector functions¶
GammaLib provides also support for vector functions, which are functions that return instead of a scalar a vector. These vector functions may be used for efficient response computation, where integrations are needed for vectors instead of scalars.
Vector functions are implemented by the abstract GFunctions base class for which the following pure virtual functions needed to be implemented
virtual int size(void) const = 0;
virtual GVector eval(const double& x) = 0;
Vector functions can be integrated using the GIntegrals class which is analoguous
to the GIntegral class for scalar functions. Specifically, the integration
methods romberg
and trapzd
return instances of GVector instead of scalars.