dqk51 Subroutine

public subroutine dqk51(f, a, b, Result, Abserr, Resabs, Resasc)

estimate 1D integral on finite interval using a 51 point gauss-kronrod rule and give error estimate, non-automatic

to compute i = integral of f over (a,b) with error estimate j = integral of abs(f) over (a,b)

History

  • QUADPACK: date written 800101, revision date 830518 (yymmdd).

Arguments

Type IntentOptional Attributes Name
procedure(func) :: f

function subroutine defining the integrand function f(x).

real(kind=wp), intent(in) :: a

lower limit of integration

real(kind=wp), intent(in) :: b

upper limit of integration

real(kind=wp), intent(out) :: Result

approximation to the integral i. result is computed by applying the 51-point kronrod rule (resk) obtained by optimal addition of abscissae to the 25-point gauss rule (resg).

real(kind=wp), intent(out) :: Abserr

estimate of the modulus of the absolute error, which should not exceed abs(i-result)

real(kind=wp), intent(out) :: Resabs

approximation to the integral j

real(kind=wp), intent(out) :: Resasc

approximation to the integral of abs(f-i/(b-a)) over (a,b)


Called by

proc~~dqk51~~CalledByGraph proc~dqk51 quadpack_generic::dqk51 proc~dqage quadpack_generic::dqage proc~dqage->proc~dqk51 proc~dqag quadpack_generic::dqag proc~dqag->proc~dqage

Source Code

    subroutine dqk51(f, a, b, Result, Abserr, Resabs, Resasc)
        implicit none

        procedure(func) :: f !! function subroutine defining the integrand function `f(x)`.
        real(wp), intent(in) :: a !! lower limit of integration
        real(wp), intent(in) :: b !! upper limit of integration
        real(wp), intent(out) :: Result !! approximation to the integral i.
                                        !! `result` is computed by applying the 51-point
                                        !! kronrod rule (resk) obtained by optimal addition
                                        !! of abscissae to the 25-point gauss rule (resg).
        real(wp), intent(out) :: Abserr !! estimate of the modulus of the absolute error,
                                        !! which should not exceed `abs(i-result)`
        real(wp), intent(out) :: Resabs !! approximation to the integral j
        real(wp), intent(out) :: Resasc !! approximation to the integral of `abs(f-i/(b-a))`
                                        !! over `(a,b)`

        real(wp) :: centr !! mid point of the interval
        real(wp) :: hlgth !! half-length of the interval
        real(wp) :: absc !! abscissa
        real(wp) :: fval1 !! function value
        real(wp) :: fval2 !! function value
        real(wp) :: resg !! result of the 25-point gauss formula
        real(wp) :: resk !! result of the 51-point kronrod formula
        real(wp) :: reskh !! approximation to the mean value of `f` over `(a,b)`, i.e. to `i/(b-a)`

        real(wp) :: dhlgth, fc, fsum, fv1(25), fv2(25)
        integer :: j, jtw, jtwm1

        ! the abscissae and weights are given for the interval (-1,1).
        ! because of symmetry only the positive abscissae and their
        ! corresponding weights are given.

        real(wp), dimension(13), parameter :: wg = [ &
                                              1.13937985010262879479029641132347736033e-2_wp, &
                                              2.63549866150321372619018152952991449360e-2_wp, &
                                              4.09391567013063126556234877116459536608e-2_wp, &
                                              5.49046959758351919259368915404733241601e-2_wp, &
                                              6.80383338123569172071871856567079685547e-2_wp, &
                                              8.01407003350010180132349596691113022902e-2_wp, &
                                              9.10282619829636498114972207028916533810e-2_wp, &
                                              1.00535949067050644202206890392685826988e-1_wp, &
                                              1.08519624474263653116093957050116619340e-1_wp, &
                                              1.14858259145711648339325545869555808641e-1_wp, &
                                              1.19455763535784772228178126512901047390e-1_wp, &
                                              1.22242442990310041688959518945851505835e-1_wp, &
                                              1.23176053726715451203902873079050142438e-1_wp] !! weights of the 25-point gauss rule

        real(wp), dimension(26), parameter :: xgk = [ &
                                              9.99262104992609834193457486540340593705e-1_wp, &
                                              9.95556969790498097908784946893901617258e-1_wp, &
                                              9.88035794534077247637331014577406227072e-1_wp, &
                                              9.76663921459517511498315386479594067745e-1_wp, &
                                              9.61614986425842512418130033660167241692e-1_wp, &
                                              9.42974571228974339414011169658470531905e-1_wp, &
                                              9.20747115281701561746346084546330631575e-1_wp, &
                                              8.94991997878275368851042006782804954175e-1_wp, &
                                              8.65847065293275595448996969588340088203e-1_wp, &
                                              8.33442628760834001421021108693569569461e-1_wp, &
                                              7.97873797998500059410410904994306569409e-1_wp, &
                                              7.59259263037357630577282865204360976388e-1_wp, &
                                              7.17766406813084388186654079773297780598e-1_wp, &
                                              6.73566368473468364485120633247622175883e-1_wp, &
                                              6.26810099010317412788122681624517881020e-1_wp, &
                                              5.77662930241222967723689841612654067396e-1_wp, &
                                              5.26325284334719182599623778158010178037e-1_wp, &
                                              4.73002731445714960522182115009192041332e-1_wp, &
                                              4.17885382193037748851814394594572487093e-1_wp, &
                                              3.61172305809387837735821730127640667422e-1_wp, &
                                              3.03089538931107830167478909980339329200e-1_wp, &
                                              2.43866883720988432045190362797451586406e-1_wp, &
                                              1.83718939421048892015969888759528415785e-1_wp, &
                                              1.22864692610710396387359818808036805532e-1_wp, &
                                              6.15444830056850788865463923667966312817e-2_wp, &
                                              0.00000000000000000000000000000000000000e0_wp] !! abscissae of the 51-point kronrod rule
                                                                                             !!
                                                                                             !! * xgk(2), xgk(4), ...  abscissae of the 25-point
                                                                                             !!   gauss rule
                                                                                             !! * xgk(1), xgk(3), ...  abscissae which are optimally
                                                                                             !!   added to the 25-point gauss rule

        real(wp), dimension(26), parameter :: wgk = [ &
                                              1.98738389233031592650785188284340988943e-3_wp, &
                                              5.56193213535671375804023690106552207018e-3_wp, &
                                              9.47397338617415160720771052365532387165e-3_wp, &
                                              1.32362291955716748136564058469762380776e-2_wp, &
                                              1.68478177091282982315166675363363158404e-2_wp, &
                                              2.04353711458828354565682922359389736788e-2_wp, &
                                              2.40099456069532162200924891648810813929e-2_wp, &
                                              2.74753175878517378029484555178110786148e-2_wp, &
                                              3.07923001673874888911090202152285856009e-2_wp, &
                                              3.40021302743293378367487952295512032257e-2_wp, &
                                              3.71162714834155435603306253676198759960e-2_wp, &
                                              4.00838255040323820748392844670756464014e-2_wp, &
                                              4.28728450201700494768957924394951611020e-2_wp, &
                                              4.55029130499217889098705847526603930437e-2_wp, &
                                              4.79825371388367139063922557569147549836e-2_wp, &
                                              5.02776790807156719633252594334400844406e-2_wp, &
                                              5.23628858064074758643667121378727148874e-2_wp, &
                                              5.42511298885454901445433704598756068261e-2_wp, &
                                              5.59508112204123173082406863827473468203e-2_wp, &
                                              5.74371163615678328535826939395064719948e-2_wp, &
                                              5.86896800223942079619741758567877641398e-2_wp, &
                                              5.97203403241740599790992919325618538354e-2_wp, &
                                              6.05394553760458629453602675175654271623e-2_wp, &
                                              6.11285097170530483058590304162927119227e-2_wp, &
                                              6.14711898714253166615441319652641775865e-2_wp, &
                                              6.15808180678329350787598242400645531904e-2_wp] !! weights of the 51-point kronrod rule.

        centr = 0.5_wp*(a + b)
        hlgth = 0.5_wp*(b - a)
        dhlgth = abs(hlgth)

        ! compute the 51-point kronrod approximation to
        ! the integral, and estimate the absolute error.

        fc = f(centr)
        resg = wg(13)*fc
        resk = wgk(26)*fc
        Resabs = abs(resk)
        do j = 1, 12
            jtw = j*2
            absc = hlgth*xgk(jtw)
            fval1 = f(centr - absc)
            fval2 = f(centr + absc)
            fv1(jtw) = fval1
            fv2(jtw) = fval2
            fsum = fval1 + fval2
            resg = resg + wg(j)*fsum
            resk = resk + wgk(jtw)*fsum
            Resabs = Resabs + wgk(jtw)*(abs(fval1) + abs(fval2))
        end do
        do j = 1, 13
            jtwm1 = j*2 - 1
            absc = hlgth*xgk(jtwm1)
            fval1 = f(centr - absc)
            fval2 = f(centr + absc)
            fv1(jtwm1) = fval1
            fv2(jtwm1) = fval2
            fsum = fval1 + fval2
            resk = resk + wgk(jtwm1)*fsum
            Resabs = Resabs + wgk(jtwm1)*(abs(fval1) + abs(fval2))
        end do
        reskh = resk*0.5_wp
        Resasc = wgk(26)*abs(fc - reskh)
        do j = 1, 25
            Resasc = Resasc + wgk(j) &
                     *(abs(fv1(j) - reskh) + abs(fv2(j) - reskh))
        end do
        Result = resk*hlgth
        Resabs = Resabs*dhlgth
        Resasc = Resasc*dhlgth
        Abserr = abs((resk - resg)*hlgth)
        if (Resasc /= 0.0_wp .and. Abserr /= 0.0_wp) &
            Abserr = Resasc*min(1.0_wp, (200.0_wp*Abserr/Resasc)**1.5_wp)
        if (Resabs > uflow/(50.0_wp*epmach)) &
            Abserr = max((epmach*50.0_wp)*Resabs, Abserr)

    end subroutine dqk51