Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-06-02 08:48:22

0001 #ifndef DEXP_INTEGRATOR_1D_H
0002 #define DEXP_INTEGRATOR_1D_H
0003 
0004 /**
0005  * @file DExpIntegrator1D.h
0006  * @author Bryan BERTHOU (SPhN / CEA Saclay)
0007  * @author Daniele Binosi (ECT*)
0008  * @date December 15, 2015
0009  * @version 1.0
0010  *
0011  */
0012 
0013 #include <vector>
0014 
0015 #include "Integrator1D.h"
0016 
0017 class FunctionType1D;
0018 
0019 namespace NumA {
0020 
0021 /**
0022  * @class DExpIntegrator1D
0023  * @brief This is an implementation of the double exponential rule.
0024  *
0025  * The functions being integrated are required to be smooth (no discontinuities in the function or any of its
0026  * derivatives), with no infinities in the middle of the integration interval
0027  * (but it does allow functions that become infinite at the ends of the integration interval).
0028  *
0029  * The method is based on the observation that the trapezoid rule converges extremely fast for functions
0030  * that go to zero like exp(-exp(t)). In practice, it implements a change of variables to implement this property
0031  * in the function to be integrated.
0032  *
0033  * The change of variable is x = tanh( pi sinh(t) /2) which transforms an integral over [-1, 1]
0034  * into an integral with integrand suited to the double exponential rule. The transformed integral is infinite,
0035  * but one can truncate the domain of integration to [-3, 3].
0036  *
0037  * The limit '3' is chosen for two reasons:
0038  *
0039  * 1. The transformed x values are equal to 1 for 12 or more significant figures;
0040  * 2. The smallest weights are 12 orders of magnitude smaller than the largest weights (setting
0041  * the cutoff larger than 3 would not have a significant impact on the integral value
0042  * unless there is a strong singularity at one of the end points).
0043  *
0044  * The change of variables x(t) is an odd function, whereas its derivative w(t) is even;
0045  * thus in the cpp file we will store only positive values of nodes and weights.
0046  *
0047  * The integration first applies the trapezoid rule to [-3, 3] in steps of size 1, subsequently cutting the step size
0048  * in half each time, and comparing the results. The routine stops when subsequent iterations are close
0049  * enough together or the maximum integration points have been used. Notice that by cutting h in half,
0050  * the previous integral can be reused; we only need evaluate the integrand at the newly added points.
0051  *
0052  * As we assume that values at the ends of the interval hardly matter due to the rapid decay of the integrand
0053  * we don't treat the end points differently.
0054  *
0055  * See Integrator1D documentation for an example.
0056  */
0057 class DExpIntegrator1D: public Integrator1D {
0058 public:
0059     /**
0060      * Default constructor.
0061      */
0062     DExpIntegrator1D();
0063 
0064     /**
0065      * Default destructor.
0066      */
0067     virtual ~DExpIntegrator1D();
0068 
0069     DExpIntegrator1D* clone() const;
0070 
0071     virtual double integrate(FunctionType1D* pFunction, double a, double b,
0072             std::vector<double> &parameters);
0073 
0074 protected:
0075     /**
0076      * Copy constructor.
0077      * Called by clone().
0078      * @param other DExpIntegrator1D object to copy.
0079      */
0080     DExpIntegrator1D(const DExpIntegrator1D &other);
0081 
0082 private:
0083 
0084     ////////////////////////////////////////////////////////////
0085     // Member data
0086     ////////////////////////////////////////////////////////////
0087     double m_errorEstimate; ///< Absolute error estimate.
0088     int m_numFunctionEvaluations; ///< Number of evaluations.
0089     std::vector<double> m_nodes; ///< Nodes of the quadrature.
0090     std::vector<double> m_weights; ///< Weights of the quadrature.
0091     std::vector<int> m_offsets;
0092 };
0093 
0094 } // namespace NumA
0095 
0096 #endif /* DEXP_INTEGRATOR_1D_H */