Real GaussKronrodAdaptive::integrateRecursively(
    const boost::function<Real (Real)>& f,
    Real a,
    Real b,
    Real tolerance) const {

    Real halflength = (b - a) / 2;
    Real center = (a + b) / 2;

    Real g7; // will be result of G7 integral
    Real k15; // will be result of K15 integral

    Real t, fsum; // t (abscissa) and f(t)
    Real fc = f(center);
    g7 = fc * g7w[0];
    k15 = fc * k15w[0];

    // calculate g7 and half of k15
    Integer j, j2;
    for (j = 1, j2 = 2; j < 4; j++, j2 += 2) {
        t = halflength * k15t[j2];
        fsum = f(center - t) + f(center + t);
        g7  += fsum * g7w[j];
        k15 += fsum * k15w[j2];
    }

    // calculate other half of k15
    for (j2 = 1; j2 < 8; j2 += 2) {
        t = halflength * k15t[j2];
        fsum = f(center - t) + f(center + t);
        k15 += fsum * k15w[j2];
    }

    // multiply by (a - b) / 2
    g7 = halflength * g7;
    k15 = halflength * k15;

    // 15 more function evaluations have been used
    increaseNumberOfEvaluations(15);

    // error is <= k15 - g7
    // if error is larger than tolerance then split the interval
    // in two and integrate recursively
    if (std::fabs(k15 - g7) < tolerance) {
        return k15;
    } else {
        QL_REQUIRE(numberOfEvaluations()+30 <=
                   maxEvaluations(),
                   "maximum number of function evaluations "
                   "exceeded");
        return integrateRecursively(f, a, center, tolerance/2)
               + integrateRecursively(f, center, b, tolerance/2);
    }
}
 Real GaussLobattoIntegral::adaptivGaussLobattoStep(
                                  const boost::function<Real (Real)>& f,
                                  Real a, Real b, Real fa, Real fb,
                                  Real acc) const {
     QL_REQUIRE(numberOfEvaluations() < maxEvaluations(),
                "max number of iterations reached");
     
     const Real h=(b-a)/2; 
     const Real m=(a+b)/2;
     
     const Real mll=m-alpha_*h; 
     const Real ml =m-beta_*h; 
     const Real mr =m+beta_*h; 
     const Real mrr=m+alpha_*h;
     
     const Real fmll= f(mll);
     const Real fml = f(ml);
     const Real fm  = f(m);
     const Real fmr = f(mr);
     const Real fmrr= f(mrr);
     increaseNumberOfEvaluations(5);
     
     const Real integral2=(h/6)*(fa+fb+5*(fml+fmr));
     const Real integral1=(h/1470)*(77*(fa+fb)
                                    +432*(fmll+fmrr)+625*(fml+fmr)+672*fm);
     
     // avoid 80 bit logic on x86 cpu
     volatile Real dist = acc + (integral1-integral2);
     if(dist==acc || mll<=a || b<=mrr) {
         QL_REQUIRE(m>a && b>m,"Interval contains no more machine number");
         return integral1;
     }
     else {
         return  adaptivGaussLobattoStep(f,a,mll,fa,fmll,acc)  
               + adaptivGaussLobattoStep(f,mll,ml,fmll,fml,acc)
               + adaptivGaussLobattoStep(f,ml,m,fml,fm,acc)
               + adaptivGaussLobattoStep(f,m,mr,fm,fmr,acc)
               + adaptivGaussLobattoStep(f,mr,mrr,fmr,fmrr,acc)
               + adaptivGaussLobattoStep(f,mrr,b,fmrr,fb,acc);
     }
 }