qagpe.f

Go to the documentation of this file.
00001       subroutine qagpe(f,a,b,npts2,points,epsabs,epsrel,limit,result,
00002      *   abserr,neval,ier,alist,blist,rlist,elist,pts,iord,level,ndin,
00003      *   last)
00004 c***begin prologue  qagpe
00005 c***date written   800101   (yymmdd)
00006 c***revision date  830518   (yymmdd)
00007 c***category no.  h2a2a1
00008 c***keywords  automatic integrator, general-purpose,
00009 c             singularities at user specified points,
00010 c             extrapolation, globally adaptive.
00011 c***author  piessens,robert ,appl. math. & progr. div. - k.u.leuven
00012 c           de doncker,elise,appl. math. & progr. div. - k.u.leuven
00013 c***purpose  the routine calculates an approximation result to a given
00014 c            definite integral i = integral of f over (a,b),hopefully
00015 c            satisfying following claim for accuracy abs(i-result).le.
00016 c            max(epsabs,epsrel*abs(i)). break points of the integration
00017 c            interval, where local difficulties of the integrand may
00018 c            occur(e.g. singularities,discontinuities),provided by user.
00019 c***description
00020 c
00021 c        computation of a definite integral
00022 c        standard fortran subroutine
00023 c        real version
00024 c
00025 c        parameters
00026 c         on entry
00027 c            f      - subroutine f(x,ierr,result) defining the integrand
00028 c                     function f(x). the actual name for f needs to be
00029 c                     declared e x t e r n a l in the driver program.
00030 c
00031 c            a      - real
00032 c                     lower limit of integration
00033 c
00034 c            b      - real
00035 c                     upper limit of integration
00036 c
00037 c            npts2  - integer
00038 c                     number equal to two more than the number of
00039 c                     user-supplied break points within the integration
00040 c                     range, npts2.ge.2.
00041 c                     if npts2.lt.2, the routine will end with ier = 6.
00042 c
00043 c            points - real
00044 c                     vector of dimension npts2, the first (npts2-2)
00045 c                     elements of which are the user provided break
00046 c                     points. if these points do not constitute an
00047 c                     ascending sequence there will be an automatic
00048 c                     sorting.
00049 c
00050 c            epsabs - real
00051 c                     absolute accuracy requested
00052 c            epsrel - real
00053 c                     relative accuracy requested
00054 c                     if  epsabs.le.0
00055 c                     and epsrel.lt.max(50*rel.mach.acc.,0.5d-28),
00056 c                     the routine will end with ier = 6.
00057 c
00058 c            limit  - integer
00059 c                     gives an upper bound on the number of subintervals
00060 c                     in the partition of (a,b), limit.ge.npts2
00061 c                     if limit.lt.npts2, the routine will end with
00062 c                     ier = 6.
00063 c
00064 c         on return
00065 c            result - real
00066 c                     approximation to the integral
00067 c
00068 c            abserr - real
00069 c                     estimate of the modulus of the absolute error,
00070 c                     which should equal or exceed abs(i-result)
00071 c
00072 c            neval  - integer
00073 c                     number of integrand evaluations
00074 c
00075 c            ier    - integer
00076 c                     ier = 0 normal and reliable termination of the
00077 c                             routine. it is assumed that the requested
00078 c                             accuracy has been achieved.
00079 c                     ier.gt.0 abnormal termination of the routine.
00080 c                             the estimates for integral and error are
00081 c                             less reliable. it is assumed that the
00082 c                             requested accuracy has not been achieved.
00083 c            error messages
00084 c                     ier = 1 maximum number of subdivisions allowed
00085 c                             has been achieved. one can allow more
00086 c                             subdivisions by increasing the value of
00087 c                             limit (and taking the according dimension
00088 c                             adjustments into account). however, if
00089 c                             this yields no improvement it is advised
00090 c                             to analyze the integrand in order to
00091 c                             determine the integration difficulties. if
00092 c                             the position of a local difficulty can be
00093 c                             determined (i.e. singularity,
00094 c                             discontinuity within the interval), it
00095 c                             should be supplied to the routine as an
00096 c                             element of the vector points. if necessary
00097 c                             an appropriate special-purpose integrator
00098 c                             must be used, which is designed for
00099 c                             handling the type of difficulty involved.
00100 c                         = 2 the occurrence of roundoff error is
00101 c                             detected, which prevents the requested
00102 c                             tolerance from being achieved.
00103 c                             the error may be under-estimated.
00104 c                         = 3 extremely bad integrand behaviour occurs
00105 c                             at some points of the integration
00106 c                             interval.
00107 c                         = 4 the algorithm does not converge.
00108 c                             roundoff error is detected in the
00109 c                             extrapolation table. it is presumed that
00110 c                             the requested tolerance cannot be
00111 c                             achieved, and that the returned result is
00112 c                             the best which can be obtained.
00113 c                         = 5 the integral is probably divergent, or
00114 c                             slowly convergent. it must be noted that
00115 c                             divergence can occur with any other value
00116 c                             of ier.gt.0.
00117 c                         = 6 the input is invalid because
00118 c                             npts2.lt.2 or
00119 c                             break points are specified outside
00120 c                             the integration range or
00121 c                             (epsabs.le.0 and
00122 c                              epsrel.lt.max(50*rel.mach.acc.,0.5d-28))
00123 c                             or limit.lt.npts2.
00124 c                             result, abserr, neval, last, rlist(1),
00125 c                             and elist(1) are set to zero. alist(1) and
00126 c                             blist(1) are set to a and b respectively.
00127 c
00128 c            alist  - real
00129 c                     vector of dimension at least limit, the first
00130 c                      last  elements of which are the left end points
00131 c                     of the subintervals in the partition of the given
00132 c                     integration range (a,b)
00133 c
00134 c            blist  - real
00135 c                     vector of dimension at least limit, the first
00136 c                      last  elements of which are the right end points
00137 c                     of the subintervals in the partition of the given
00138 c                     integration range (a,b)
00139 c
00140 c            rlist  - real
00141 c                     vector of dimension at least limit, the first
00142 c                      last  elements of which are the integral
00143 c                     approximations on the subintervals
00144 c
00145 c            elist  - real
00146 c                     vector of dimension at least limit, the first
00147 c                      last  elements of which are the moduli of the
00148 c                     absolute error estimates on the subintervals
00149 c
00150 c            pts    - real
00151 c                     vector of dimension at least npts2, containing the
00152 c                     integration limits and the break points of the
00153 c                     interval in ascending sequence.
00154 c
00155 c            level  - integer
00156 c                     vector of dimension at least limit, containing the
00157 c                     subdivision levels of the subinterval, i.e. if
00158 c                     (aa,bb) is a subinterval of (p1,p2) where p1 as
00159 c                     well as p2 is a user-provided break point or
00160 c                     integration limit, then (aa,bb) has level l if
00161 c                     abs(bb-aa) = abs(p2-p1)*2**(-l).
00162 c
00163 c            ndin   - integer
00164 c                     vector of dimension at least npts2, after first
00165 c                     integration over the intervals (pts(i)),pts(i+1),
00166 c                     i = 0,1, ..., npts2-2, the error estimates over
00167 c                     some of the intervals may have been increased
00168 c                     artificially, in order to put their subdivision
00169 c                     forward. if this happens for the subinterval
00170 c                     numbered k, ndin(k) is put to 1, otherwise
00171 c                     ndin(k) = 0.
00172 c
00173 c            iord   - integer
00174 c                     vector of dimension at least limit, the first k
00175 c                     elements of which are pointers to the
00176 c                     error estimates over the subintervals,
00177 c                     such that elist(iord(1)), ..., elist(iord(k))
00178 c                     form a decreasing sequence, with k = last
00179 c                     if last.le.(limit/2+2), and k = limit+1-last
00180 c                     otherwise
00181 c
00182 c            last   - integer
00183 c                     number of subintervals actually produced in the
00184 c                     subdivisions process
00185 c
00186 c***references  (none)
00187 c***routines called  qelg,qk21,qpsrt,r1mach
00188 c***end prologue  qagpe
00189       real a,abseps,abserr,alist,area,area1,area12,area2,a1,
00190      *  a2,b,blist,b1,b2,correc,defabs,defab1,defab2,
00191      *  dres,r1mach,elist,epmach,epsabs,epsrel,erlarg,erlast,errbnd,
00192      *  errmax,error1,erro12,error2,errsum,ertest,oflow,points,pts,
00193      *  resa,resabs,reseps,result,res3la,rlist,rlist2,sign,temp,
00194      *  uflow
00195       integer i,id,ier,ierro,ind1,ind2,iord,ip1,iroff1,iroff2,
00196      *  iroff3,j,jlow,jupbnd,k,ksgn,ktmin,last,levcur,level,levmax,
00197      *  limit,maxerr,ndin,neval,nint,nintp1,npts,npts2,nres,
00198      *  nrmax,numrl2
00199       logical extrap,noext
00200 c
00201 c
00202       dimension alist(limit),blist(limit),elist(limit),iord(limit),
00203      *  level(limit),ndin(npts2),points(npts2),pts(npts2),res3la(3),
00204      *  rlist(limit),rlist2(52)
00205 c
00206       external f
00207 c
00208 c            the dimension of rlist2 is determined by the value of
00209 c            limexp in subroutine epsalg (rlist2 should be of dimension
00210 c            (limexp+2) at least).
00211 c
00212 c
00213 c            list of major variables
00214 c            -----------------------
00215 c
00216 c           alist     - list of left end points of all subintervals
00217 c                       considered up to now
00218 c           blist     - list of right end points of all subintervals
00219 c                       considered up to now
00220 c           rlist(i)  - approximation to the integral over
00221 c                       (alist(i),blist(i))
00222 c           rlist2    - array of dimension at least limexp+2
00223 c                       containing the part of the epsilon table which
00224 c                       is still needed for further computations
00225 c           elist(i)  - error estimate applying to rlist(i)
00226 c           maxerr    - pointer to the interval with largest error
00227 c                       estimate
00228 c           errmax    - elist(maxerr)
00229 c           erlast    - error on the interval currently subdivided
00230 c                       (before that subdivision has taken place)
00231 c           area      - sum of the integrals over the subintervals
00232 c           errsum    - sum of the errors over the subintervals
00233 c           errbnd    - requested accuracy max(epsabs,epsrel*
00234 c                       abs(result))
00235 c           *****1    - variable for the left subinterval
00236 c           *****2    - variable for the right subinterval
00237 c           last      - index for subdivision
00238 c           nres      - number of calls to the extrapolation routine
00239 c           numrl2    - number of elements in rlist2. if an
00240 c                       appropriate approximation to the compounded
00241 c                       integral has been obtained, it is put in
00242 c                       rlist2(numrl2) after numrl2 has been increased
00243 c                       by one.
00244 c           erlarg    - sum of the errors over the intervals larger
00245 c                       than the smallest interval considered up to now
00246 c           extrap    - logical variable denoting that the routine
00247 c                       is attempting to perform extrapolation. i.e.
00248 c                       before subdividing the smallest interval we
00249 c                       try to decrease the value of erlarg.
00250 c           noext     - logical variable denoting that extrapolation is
00251 c                       no longer allowed (true-value)
00252 c
00253 c            machine dependent constants
00254 c            ---------------------------
00255 c
00256 c           epmach is the largest relative spacing.
00257 c           uflow is the smallest positive magnitude.
00258 c           oflow is the largest positive magnitude.
00259 c
00260 c***first executable statement  qagpe
00261       epmach = r1mach(4)
00262 c
00263 c            test on validity of parameters
00264 c            -----------------------------
00265 c
00266       ier = 0
00267       neval = 0
00268       last = 0
00269       result = 0.0e+00
00270       abserr = 0.0e+00
00271       alist(1) = a
00272       blist(1) = b
00273       rlist(1) = 0.0e+00
00274       elist(1) = 0.0e+00
00275       iord(1) = 0
00276       level(1) = 0
00277       npts = npts2-2
00278       if(npts2.lt.2.or.limit.le.npts.or.(epsabs.le.0.0e+00.and.
00279      *  epsrel.lt.amax1(0.5e+02*epmach,0.5e-14))) ier = 6
00280       if(ier.eq.6) go to 210
00281 c
00282 c            if any break points are provided, sort them into an
00283 c            ascending sequence.
00284 c
00285       sign = 1.0e+00
00286       if(a.gt.b) sign = -1.0e+00
00287       pts(1) = amin1(a,b)
00288       if(npts.eq.0) go to 15
00289       do 10 i = 1,npts
00290         pts(i+1) = points(i)
00291    10 continue
00292    15 pts(npts+2) = amax1(a,b)
00293       nint = npts+1
00294       a1 = pts(1)
00295       if(npts.eq.0) go to 40
00296       nintp1 = nint+1
00297       do 20 i = 1,nint
00298         ip1 = i+1
00299         do 20 j = ip1,nintp1
00300           if(pts(i).le.pts(j)) go to 20
00301           temp = pts(i)
00302           pts(i) = pts(j)
00303           pts(j) = temp
00304    20 continue
00305       if(pts(1).ne.amin1(a,b).or.pts(nintp1).ne.
00306      *  amax1(a,b)) ier = 6
00307       if(ier.eq.6) go to 999
00308 c
00309 c            compute first integral and error approximations.
00310 c            ------------------------------------------------
00311 c
00312    40 resabs = 0.0e+00
00313       do 50 i = 1,nint
00314         b1 = pts(i+1)
00315         call qk21(f,a1,b1,area1,error1,defabs,resa,ier)
00316         if (ier.lt.0) return
00317         abserr = abserr+error1
00318         result = result+area1
00319         ndin(i) = 0
00320         if(error1.eq.resa.and.error1.ne.0.0e+00) ndin(i) = 1
00321         resabs = resabs+defabs
00322         level(i) = 0
00323         elist(i) = error1
00324         alist(i) = a1
00325         blist(i) = b1
00326         rlist(i) = area1
00327         iord(i) = i
00328         a1 = b1
00329    50 continue
00330       errsum = 0.0e+00
00331       do 55 i = 1,nint
00332         if(ndin(i).eq.1) elist(i) = abserr
00333         errsum = errsum+elist(i)
00334    55 continue
00335 c
00336 c           test on accuracy.
00337 c
00338       last = nint
00339       neval = 21*nint
00340       dres = abs(result)
00341       errbnd = amax1(epsabs,epsrel*dres)
00342       if(abserr.le.0.1e+03*epmach*resabs.and.abserr.gt.
00343      *  errbnd) ier = 2
00344       if(nint.eq.1) go to 80
00345       do 70 i = 1,npts
00346         jlow = i+1
00347         ind1 = iord(i)
00348         do 60 j = jlow,nint
00349           ind2 = iord(j)
00350           if(elist(ind1).gt.elist(ind2)) go to 60
00351           ind1 = ind2
00352           k = j
00353    60   continue
00354         if(ind1.eq.iord(i)) go to 70
00355         iord(k) = iord(i)
00356         iord(i) = ind1
00357    70 continue
00358       if(limit.lt.npts2) ier = 1
00359    80 if(ier.ne.0.or.abserr.le.errbnd) go to 999
00360 c
00361 c           initialization
00362 c           --------------
00363 c
00364       rlist2(1) = result
00365       maxerr = iord(1)
00366       errmax = elist(maxerr)
00367       area = result
00368       nrmax = 1
00369       nres = 0
00370       numrl2 = 1
00371       ktmin = 0
00372       extrap = .false.
00373       noext = .false.
00374       erlarg = errsum
00375       ertest = errbnd
00376       levmax = 1
00377       iroff1 = 0
00378       iroff2 = 0
00379       iroff3 = 0
00380       ierro = 0
00381       uflow = r1mach(1)
00382       oflow = r1mach(2)
00383       abserr = oflow
00384       ksgn = -1
00385       if(dres.ge.(0.1e+01-0.5e+02*epmach)*resabs) ksgn = 1
00386 c
00387 c           main do-loop
00388 c           ------------
00389 c
00390       do 160 last = npts2,limit
00391 c
00392 c           bisect the subinterval with the nrmax-th largest
00393 c           error estimate.
00394 c
00395         levcur = level(maxerr)+1
00396         a1 = alist(maxerr)
00397         b1 = 0.5e+00*(alist(maxerr)+blist(maxerr))
00398         a2 = b1
00399         b2 = blist(maxerr)
00400         erlast = errmax
00401         call qk21(f,a1,b1,area1,error1,resa,defab1,ier)
00402         if (ier.lt.0) return
00403         call qk21(f,a2,b2,area2,error2,resa,defab2,ier)
00404         if (ier.lt.0) return
00405 c
00406 c           improve previous approximations to integral
00407 c           and error and test for accuracy.
00408 c
00409         neval = neval+42
00410         area12 = area1+area2
00411         erro12 = error1+error2
00412         errsum = errsum+erro12-errmax
00413         area = area+area12-rlist(maxerr)
00414         if(defab1.eq.error1.or.defab2.eq.error2) go to 95
00415         if(abs(rlist(maxerr)-area12).gt.0.1e-04*abs(area12)
00416      *  .or.erro12.lt.0.99e+00*errmax) go to 90
00417         if(extrap) iroff2 = iroff2+1
00418         if(.not.extrap) iroff1 = iroff1+1
00419    90   if(last.gt.10.and.erro12.gt.errmax) iroff3 = iroff3+1
00420    95   level(maxerr) = levcur
00421         level(last) = levcur
00422         rlist(maxerr) = area1
00423         rlist(last) = area2
00424         errbnd = amax1(epsabs,epsrel*abs(area))
00425 c
00426 c           test for roundoff error and eventually
00427 c           set error flag.
00428 c
00429         if(iroff1+iroff2.ge.10.or.iroff3.ge.20) ier = 2
00430         if(iroff2.ge.5) ierro = 3
00431 c
00432 c           set error flag in the case that the number of
00433 c           subintervals equals limit.
00434 c
00435         if(last.eq.limit) ier = 1
00436 c
00437 c           set error flag in the case of bad integrand behaviour
00438 c           at a point of the integration range
00439 c
00440         if(amax1(abs(a1),abs(b2)).le.(0.1e+01+0.1e+03*epmach)*
00441      *  (abs(a2)+0.1e+04*uflow)) ier = 4
00442 c
00443 c           append the newly-created intervals to the list.
00444 c
00445         if(error2.gt.error1) go to 100
00446         alist(last) = a2
00447         blist(maxerr) = b1
00448         blist(last) = b2
00449         elist(maxerr) = error1
00450         elist(last) = error2
00451         go to 110
00452   100   alist(maxerr) = a2
00453         alist(last) = a1
00454         blist(last) = b1
00455         rlist(maxerr) = area2
00456         rlist(last) = area1
00457         elist(maxerr) = error2
00458         elist(last) = error1
00459 c
00460 c           call subroutine qpsrt to maintain the descending ordering
00461 c           in the list of error estimates and select the
00462 c           subinterval with nrmax-th largest error estimate (to be
00463 c           bisected next).
00464 c
00465   110   call qpsrt(limit,last,maxerr,errmax,elist,iord,nrmax)
00466 c ***jump out of do-loop
00467         if(errsum.le.errbnd) go to 190
00468 c ***jump out of do-loop
00469         if(ier.ne.0) go to 170
00470         if(noext) go to 160
00471         erlarg = erlarg-erlast
00472         if(levcur+1.le.levmax) erlarg = erlarg+erro12
00473         if(extrap) go to 120
00474 c
00475 c           test whether the interval to be bisected next is the
00476 c           smallest interval.
00477 c
00478         if(level(maxerr)+1.le.levmax) go to 160
00479         extrap = .true.
00480         nrmax = 2
00481   120   if(ierro.eq.3.or.erlarg.le.ertest) go to 140
00482 c
00483 c           the smallest interval has the largest error.
00484 c           before bisecting decrease the sum of the errors
00485 c           over the larger intervals (erlarg) and perform
00486 c           extrapolation.
00487 c
00488         id = nrmax
00489         jupbnd = last
00490         if(last.gt.(2+limit/2)) jupbnd = limit+3-last
00491         do 130 k = id,jupbnd
00492           maxerr = iord(nrmax)
00493           errmax = elist(maxerr)
00494 c ***jump out of do-loop
00495           if(level(maxerr)+1.le.levmax) go to 160
00496           nrmax = nrmax+1
00497   130   continue
00498 c
00499 c           perform extrapolation.
00500 c
00501   140   numrl2 = numrl2+1
00502         rlist2(numrl2) = area
00503         if(numrl2.le.2) go to 155
00504         call qelg(numrl2,rlist2,reseps,abseps,res3la,nres)
00505         ktmin = ktmin+1
00506         if(ktmin.gt.5.and.abserr.lt.0.1e-02*errsum) ier = 5
00507         if(abseps.ge.abserr) go to 150
00508         ktmin = 0
00509         abserr = abseps
00510         result = reseps
00511         correc = erlarg
00512         ertest = amax1(epsabs,epsrel*abs(reseps))
00513 c ***jump out of do-loop
00514         if(abserr.lt.ertest) go to 170
00515 c
00516 c           prepare bisection of the smallest interval.
00517 c
00518   150   if(numrl2.eq.1) noext = .true.
00519         if(ier.ge.5) go to 170
00520   155   maxerr = iord(1)
00521         errmax = elist(maxerr)
00522         nrmax = 1
00523         extrap = .false.
00524         levmax = levmax+1
00525         erlarg = errsum
00526   160 continue
00527 c
00528 c           set the final result.
00529 c           ---------------------
00530 c
00531 c
00532   170 if(abserr.eq.oflow) go to 190
00533       if((ier+ierro).eq.0) go to 180
00534       if(ierro.eq.3) abserr = abserr+correc
00535       if(ier.eq.0) ier = 3
00536       if(result.ne.0.0e+00.and.area.ne.0.0e+00)go to 175
00537       if(abserr.gt.errsum)go to 190
00538       if(area.eq.0.0e+00) go to 210
00539       go to 180
00540   175 if(abserr/abs(result).gt.errsum/abs(area))go to 190
00541 c
00542 c           test on divergence.
00543 c
00544   180 if(ksgn.eq.(-1).and.amax1(abs(result),abs(area)).le.
00545      *  resabs*0.1e-01) go to 210
00546       if(0.1e-01.gt.(result/area).or.(result/area).gt.0.1e+03.or.
00547      *  errsum.gt.abs(area)) ier = 6
00548       go to 210
00549 c
00550 c           compute global integral sum.
00551 c
00552   190 result = 0.0e+00
00553       do 200 k = 1,last
00554         result = result+rlist(k)
00555   200 continue
00556       abserr = errsum
00557   210 if(ier.gt.2) ier = ier - 1
00558       result = result*sign
00559  999  return
00560       end
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines