78    template<
class Function,
 
   79             typename std::enable_if_t<std::is_invocable_r_v<Scalar, Function, Scalar>>...>
 
   83                            const Scalar targetAbsoluteError,
 
   84                            int& numFunctionEvaluations,
 
   85                            Scalar& errorEstimate)
 
   91        const Scalar c = 0.5*(b - a);
 
   92        const Scalar d = 0.5*(a + b);
 
   93        return integrateCore_(f, c, d, targetAbsoluteError, numFunctionEvaluations, errorEstimate,
 
 
  107    template<
class Function,
 
  108             typename std::enable_if_t<std::is_invocable_r_v<Scalar, Function, Scalar>>...>
 
  112                            const Scalar targetAbsoluteError)
 
  114        int numFunctionEvaluations;
 
  115        Scalar errorEstimate;
 
  116        return integrate(f, a, b, targetAbsoluteError, numFunctionEvaluations, errorEstimate);
 
 
  121    template<
class Function>
 
  122    static Scalar integrateCore_(
const Function& f,
 
  125                                 Scalar targetAbsoluteError,
 
  126                                 int& numFunctionEvaluations,
 
  127                                 Scalar& errorEstimate,
 
  128                                 const double* abcissas,
 
  129                                 const double* weights)
 
  131        targetAbsoluteError /= c;
 
  135        static const int offsets[] = {1, 4, 7, 13, 25, 49, 97, 193};
 
  136        static const int numLevels = 
sizeof(offsets)/
sizeof(
int) - 1;
 
  138        Scalar newContribution = 0.0;
 
  139        Scalar integral = 0.0;
 
  141        errorEstimate = std::numeric_limits<Scalar>::max();
 
  142        Scalar previousDelta, currentDelta = std::numeric_limits<Scalar>::max();
 
  144        integral = f(c*abcissas[0] + d) * weights[0];
 
  146        for (i = offsets[0]; i != offsets[1]; ++i)
 
  147            integral += weights[i]*(f(c*abcissas[i] + d) + f(-c*abcissas[i] + d));
 
  149        for (
int level = 1; level != numLevels; ++level)
 
  152            newContribution = 0.0;
 
  153            for (i = offsets[level]; i != offsets[level+1]; ++i)
 
  154                newContribution += weights[i]*(f(c*abcissas[i] + d) + f(-c*abcissas[i] + d));
 
  155            newContribution *= h;
 
  158            previousDelta = currentDelta;
 
  160            currentDelta = abs(0.5*integral - newContribution);
 
  161            integral = 0.5*integral + newContribution;
 
  173            if (currentDelta == 0.0)
 
  177            const Scalar rate = log( currentDelta )/log( previousDelta );  
 
  179            if (rate > 1.9 && rate < 2.1)
 
  184                errorEstimate = currentDelta*currentDelta;
 
  189                errorEstimate = currentDelta;
 
  192            if (errorEstimate < 0.1*targetAbsoluteError)
 
  196        numFunctionEvaluations = 2*i - 1;
 
 
static Scalar integrate(const Function &f, const Scalar a, const Scalar b, const Scalar targetAbsoluteError, int &numFunctionEvaluations, Scalar &errorEstimate)
Integrate an analytic function over a finite interval.
Definition doubleexpintegrator.hh:80
static Scalar integrate(const Function &f, const Scalar a, const Scalar b, const Scalar targetAbsoluteError)
Integrate an analytic function over a finite interval.
Definition doubleexpintegrator.hh:109