https://github.com/CosmicFish/CosmicFish
Tip revision: 786da254acb46a444dbb78e0a61933286a14d0be authored by Matteo Martinelli on 15 June 2017, 11:25:13 UTC
code works, results to be checked and validated
code works, results to be checked and validated
Tip revision: 786da25
001_quadpack_double.f90
!----------------------------------------------------------------------------------------
!
! This file is part of CosmicFish.
!
! Copyright (C) 2015-2017 by the CosmicFish authors
!
! The CosmicFish code is free software;
! You can use it, redistribute it, and/or modify it under the terms
! of the GNU General Public License as published by the Free Software Foundation;
! either version 3 of the License, or (at your option) any later version.
! The full text of the license can be found in the file LICENSE at
! the top level of the CosmicFish distribution.
!
!----------------------------------------------------------------------------------------
!> @file 001_quadpack_double.f90
!! This file contains the relevant code for the double precision QUADPACK integration library.
!! This code was developed by many authors that retain the copyright for the following code.
!! This source file was modified by Marco Raveri to use it with the CosmicFish code.
!----------------------------------------------------------------------------------------
!> This module contains the relevant code for the double precision QUADPACK integration library.
module quadpack
implicit none
contains
!----------------------------------------------------------------------------------------
!> DGTSL solves a general tridiagonal linear system.
!!
!! Licensing:
!!
!! This code is distributed under the GNU LGPL license.
!!
!! Modified:
!!
!! 17 May 2005
!!
!! Author:
!!
!! FORTRAN90 version by John Burkardt.
!!
!! Reference:
!!
!! Jack Dongarra, Jim Bunch, Cleve Moler, Pete Stewart,
!! LINPACK User's Guide,
!! SIAM, 1979,
!! ISBN13: 978-0-898711-72-1,
!! LC: QA214.L56.
!!
!! Parameters:
!!
!! Input, integer ( kind = 4 ) N, the order of the tridiagonal matrix.
!!
!! Input/output, real ( kind = 8 ) C(N), contains the subdiagonal of the
!! tridiagonal matrix in entries C(2:N). On output, C is destroyed.
!!
!! Input/output, real ( kind = 8 ) D(N). On input, the diagonal of the
!! matrix. On output, D is destroyed.
!!
!! Input/output, real ( kind = 8 ) E(N), contains the superdiagonal of the
!! tridiagonal matrix in entries E(1:N-1). On output E is destroyed.
!!
!! Input/output, real ( kind = 8 ) B(N). On input, the right hand side.
!! On output, the solution.
!!
!! Output, integer ( kind = 4 ) INFO, error flag.
!! 0, normal value.
!! K, the K-th element of the diagonal becomes exactly zero. The
!! routine returns if this error condition is detected.
!!
subroutine dgtsl ( n, c, d, e, b, info )
implicit none
integer ( kind = 4 ) n
real ( kind = 8 ) b(n)
real ( kind = 8 ) c(n)
real ( kind = 8 ) d(n)
real ( kind = 8 ) e(n)
integer ( kind = 4 ) info
integer ( kind = 4 ) k
real ( kind = 8 ) t
info = 0
c(1) = d(1)
if ( 2 <= n ) then
d(1) = e(1)
e(1) = 0.0D+00
e(n) = 0.0D+00
do k = 1, n - 1
!
! Find the larger of the two rows.
!
if ( abs ( c(k) ) <= abs ( c(k+1) ) ) then
!
! Interchange rows.
!
t = c(k+1)
c(k+1) = c(k)
c(k) = t
t = d(k+1)
d(k+1) = d(k)
d(k) = t
t = e(k+1)
e(k+1) = e(k)
e(k) = t
t = b(k+1)
b(k+1) = b(k)
b(k) = t
end if
!
! Zero elements.
!
if ( c(k) == 0.0D+00 ) then
info = k
return
end if
t = -c(k+1) / c(k)
c(k+1) = d(k+1) + t * d(k)
d(k+1) = e(k+1) + t * e(k)
e(k+1) = 0.0D+00
b(k+1) = b(k+1) + t * b(k)
end do
end if
if ( c(n) == 0.0D+00 ) then
info = n
return
end if
!
! Back solve.
!
b(n) = b(n) / c(n)
if ( 1 < n ) then
b(n-1) = ( b(n-1) - d(n-1) * b(n) ) / c(n-1)
do k = n-2, 1, -1
b(k) = ( b(k) - d(k) * b(k+1) - e(k) * b(k+2) ) / c(k)
end do
end if
return
end subroutine dgtsl
!----------------------------------------------------------------------------------------
!> DQAGE estimates a definite integral.
!!
!! Modified:
!!
!! 11 September 2015
!!
!! Author:
!!
!! Robert Piessens, Elise de Doncker
!!
!!***purpose the routine calculates an approximation result to a given
!! definite integral i = integral of f over (a,b),
!! hopefully satisfying following claim for accuracy
!! abs(i-reslt).le.max(epsabs,epsrel*abs(i)).
!!
!! Parameters:
!!
!! on entry
!! f - real ( kind = 8 )
!! function subprogram defining the integrand
!! function f(x). the actual name for f needs to be
!! declared e x t e r n a l in the driver program.
!!
!! a - real ( kind = 8 )
!! lower limit of integration
!!
!! b - real ( kind = 8 )
!! upper limit of integration
!!
!! epsabs - real ( kind = 8 )
!! absolute accuracy requested
!! epsrel - real ( kind = 8 )
!! relative accuracy requested
!! if epsabs.le.0
!! and epsrel.lt.max(50*rel.mach.acc.,0.5d-28),
!! the routine will end with ier = 6.
!!
!! key - integer ( kind = 4 )
!! key for choice of local integration rule
!! a gauss-kronrod pair is used with
!! 7 - 15 points if key.lt.2,
!! 10 - 21 points if key = 2,
!! 15 - 31 points if key = 3,
!! 20 - 41 points if key = 4,
!! 25 - 51 points if key = 5,
!! 30 - 61 points if key.gt.5.
!!
!! limit - integer ( kind = 4 )
!! gives an upperbound on the number of subintervals
!! in the partition of (a,b), limit.ge.1.
!!
!! on return
!! result - real ( kind = 8 )
!! approximation to the integral
!!
!! abserr - real ( kind = 8 )
!! estimate of the modulus of the absolute error,
!! which should equal or exceed abs(i-result)
!!
!! neval - integer ( kind = 4 )
!! number of integrand evaluations
!!
!! ier - integer ( kind = 4 )
!! ier = 0 normal and reliable termination of the
!! routine. it is assumed that the requested
!! accuracy has been achieved.
!! ier.gt.0 abnormal termination of the routine
!! the estimates for result and error are
!! less reliable. it is assumed that the
!! requested accuracy has not been achieved.
!! error messages
!! ier = 1 maximum number of subdivisions allowed
!! has been achieved. one can allow more
!! subdivisions by increasing the value
!! of limit.
!! however, if this yields no improvement it
!! is rather advised to analyze the integrand
!! in order to determine the integration
!! difficulties. if the position of a local
!! difficulty can be determined(e.g.
!! singularity, discontinuity within the
!! interval) one will probably gain from
!! splitting up the interval at this point
!! and calling the integrator on the
!! subranges. if possible, an appropriate
!! special-purpose integrator should be used
!! which is designed for handling the type of
!! difficulty involved.
!! = 2 the occurrence of roundoff error is
!! detected, which prevents the requested
!! tolerance from being achieved.
!! = 3 extremely bad integrand behaviour occurs
!! at some points of the integration
!! interval.
!! = 6 the input is invalid, because
!! (epsabs.le.0 and
!! epsrel.lt.max(50*rel.mach.acc.,0.5d-28),
!! result, abserr, neval, last, rlist(1) ,
!! elist(1) and iord(1) are set to zero.
!! alist(1) and blist(1) are set to a and b
!! respectively.
!!
!! alist - real ( kind = 8 )
!! vector of dimension at least limit, the first
!! last elements of which are the left
!! end points of the subintervals in the partition
!! of the given integration range (a,b)
!!
!! blist - real ( kind = 8 )
!! vector of dimension at least limit, the first
!! last elements of which are the right
!! end points of the subintervals in the partition
!! of the given integration range (a,b)
!!
!! rlist - real ( kind = 8 )
!! vector of dimension at least limit, the first
!! last elements of which are the
!! integral approximations on the subintervals
!!
!! elist - real ( kind = 8 )
!! vector of dimension at least limit, the first
!! last elements of which are the moduli of the
!! absolute error estimates on the subintervals
!!
!! iord - integer ( kind = 4 )
!! vector of dimension at least limit, the first k
!! elements of which are pointers to the
!! error estimates over the subintervals,
!! such that elist(iord(1)), ...,
!! elist(iord(k)) form a decreasing sequence,
!! with k = last if last.le.(limit/2+2), and
!! k = limit+1-last otherwise
!!
!! last - integer ( kind = 4 )
!! number of subintervals actually produced in the
!! subdivision process
!!
!! Local Parameters:
!!
!! alist - list of left end points of all subintervals
!! considered up to now
!! blist - list of right end points of all subintervals
!! considered up to now
!! rlist(i) - approximation to the integral over
!! (alist(i),blist(i))
!! elist(i) - error estimate applying to rlist(i)
!! maxerr - pointer to the interval with largest
!! error estimate
!! errmax - elist(maxerr)
!! area - sum of the integrals over the subintervals
!! errsum - sum of the errors over the subintervals
!! errbnd - requested accuracy max(epsabs,epsrel*
!! abs(result))
!! *****1 - variable for the left subinterval
!! *****2 - variable for the right subinterval
!! last - index for subdivision
!!
!!
!! machine dependent constants
!!
!! epmach is the largest relative spacing.
!! uflow is the smallest positive magnitude.
!!
subroutine dqage ( f, a, b, epsabs, epsrel, key, limit, result, abserr, &
neval, ier, alist, blist, rlist, elist, iord, last )
implicit none
real ( kind = 8 ) a,abserr,alist,area,area1,area12,area2,a1,a2,b, &
blist,b1,b2,defabs,defab1,defab2,elist,epmach, &
epsabs,epsrel,errbnd,errmax,error1,error2,erro12,errsum,f, &
resabs,result,rlist,uflow
integer ( kind = 4 ) ier,iord,iroff1,iroff2,k,key,keyf,last,limit, &
maxerr, nrmax, neval
dimension alist(limit),blist(limit),elist(limit),iord(limit), &
rlist(limit)
external f
epmach = epsilon ( epmach )
uflow = tiny ( uflow )
!
! test on validity of parameters
!
ier = 0
neval = 0
last = 0
result = 0.0D+00
abserr = 0.0D+00
alist(1) = a
blist(1) = b
rlist(1) = 0.0D+00
elist(1) = 0.0D+00
iord(1) = 0
if(epsabs.le.0.0D+00.and. &
epsrel.lt. max ( 0.5D+02*epmach,0.5d-28)) then
ier = 6
return
end if
!
! first approximation to the integral
!
keyf = key
if(key.le.0) keyf = 1
if(key.ge.7) keyf = 6
neval = 0
if(keyf.eq.1) call dqk15(f,a,b,result,abserr,defabs,resabs)
if(keyf.eq.2) call dqk21(f,a,b,result,abserr,defabs,resabs)
if(keyf.eq.3) call dqk31(f,a,b,result,abserr,defabs,resabs)
if(keyf.eq.4) call dqk41(f,a,b,result,abserr,defabs,resabs)
if(keyf.eq.5) call dqk51(f,a,b,result,abserr,defabs,resabs)
if(keyf.eq.6) call dqk61(f,a,b,result,abserr,defabs,resabs)
last = 1
rlist(1) = result
elist(1) = abserr
iord(1) = 1
!
! test on accuracy.
!
errbnd = max ( epsabs, epsrel* abs ( result ) )
if(abserr.le.0.5D+02* epmach * defabs .and. &
abserr.gt.errbnd) then
ier = 2
end if
if(limit.eq.1) then
ier = 1
end if
if ( ier .ne. 0 .or. &
(abserr .le. errbnd .and. abserr .ne. resabs ) .or. &
abserr .eq. 0.0D+00 ) then
if(keyf.ne.1) then
neval = (10*keyf+1)*(2*neval+1)
else
neval = 30*neval+15
end if
return
end if
!
! initialization
!
errmax = abserr
maxerr = 1
area = result
errsum = abserr
nrmax = 1
iroff1 = 0
iroff2 = 0
!
! main do-loop
!
do last = 2, limit
!
! bisect the subinterval with the largest error estimate.
!
a1 = alist(maxerr)
b1 = 0.5D+00*(alist(maxerr)+blist(maxerr))
a2 = b1
b2 = blist(maxerr)
if(keyf.eq.1) call dqk15(f,a1,b1,area1,error1,resabs,defab1)
if(keyf.eq.2) call dqk21(f,a1,b1,area1,error1,resabs,defab1)
if(keyf.eq.3) call dqk31(f,a1,b1,area1,error1,resabs,defab1)
if(keyf.eq.4) call dqk41(f,a1,b1,area1,error1,resabs,defab1)
if(keyf.eq.5) call dqk51(f,a1,b1,area1,error1,resabs,defab1)
if(keyf.eq.6) call dqk61(f,a1,b1,area1,error1,resabs,defab1)
if(keyf.eq.1) call dqk15(f,a2,b2,area2,error2,resabs,defab2)
if(keyf.eq.2) call dqk21(f,a2,b2,area2,error2,resabs,defab2)
if(keyf.eq.3) call dqk31(f,a2,b2,area2,error2,resabs,defab2)
if(keyf.eq.4) call dqk41(f,a2,b2,area2,error2,resabs,defab2)
if(keyf.eq.5) call dqk51(f,a2,b2,area2,error2,resabs,defab2)
if(keyf.eq.6) call dqk61(f,a2,b2,area2,error2,resabs,defab2)
!
! improve previous approximations to integral
! and error and test for accuracy.
!
neval = neval+1
area12 = area1+area2
erro12 = error1+error2
errsum = errsum+erro12-errmax
area = area+area12-rlist(maxerr)
if ( defab1 .ne. error1 .and. defab2 .ne. error2 ) then
if( abs ( rlist(maxerr)-area12).le.0.1D-04* abs ( area12) &
.and. erro12.ge.0.99D+00*errmax) then
iroff1 = iroff1+1
end if
if(last.gt.10.and.erro12.gt.errmax) then
iroff2 = iroff2+1
end if
end if
rlist(maxerr) = area1
rlist(last) = area2
errbnd = max ( epsabs,epsrel* abs ( area))
if ( errbnd .lt. errsum ) then
!
! test for roundoff error and eventually set error flag.
!
if(iroff1.ge.6.or.iroff2.ge.20) then
ier = 2
end if
!
! set error flag in the case that the number of subintervals
! equals limit.
!
if(last.eq.limit) then
ier = 1
end if
!
! set error flag in the case of bad integrand behaviour
! at a point of the integration range.
!
if( max ( abs ( a1), abs ( b2)).le.(0.1D+01+0.1D+03* &
epmach)*( abs ( a2)+0.1D+04*uflow)) then
ier = 3
end if
end if
!
! append the newly-created intervals to the list.
!
if(error2.le.error1) then
alist(last) = a2
blist(maxerr) = b1
blist(last) = b2
elist(maxerr) = error1
elist(last) = error2
else
alist(maxerr) = a2
alist(last) = a1
blist(last) = b1
rlist(maxerr) = area2
rlist(last) = area1
elist(maxerr) = error2
elist(last) = error1
end if
!
! call dqpsrt to maintain the descending ordering
! in the list of error estimates and select the subinterval
! with the largest error estimate (to be bisected next).
!
call dqpsrt(limit,last,maxerr,errmax,elist,iord,nrmax)
if(ier.ne.0.or.errsum.le.errbnd) then
exit
end if
end do
!
! compute final result.
!
result = 0.0D+00
do k=1,last
result = result+rlist(k)
end do
abserr = errsum
if(keyf.ne.1) then
neval = (10*keyf+1)*(2*neval+1)
else
neval = 30*neval+15
end if
return
end subroutine dqage
!----------------------------------------------------------------------------------------
!> DQAG approximates an integral over a finite interval.
!!
!! Modified:
!!
!! 11 September 2015
!!
!! Author:
!!
!! Robert Piessens, Elise de Doncker
!!
!!***purpose the routine calculates an approximation result to a given
!! definite integral i = integral of f over (a,b),
!! hopefully satisfying following claim for accuracy
!! abs(i-result)le.max(epsabs,epsrel*abs(i)).
!!
!! Parameters:
!!
!! f - real ( kind = 8 )
!! function subprogam defining the integrand
!! function f(x). the actual name for f needs to be
!! declared e x t e r n a l in the driver program.
!!
!! a - real ( kind = 8 )
!! lower limit of integration
!!
!! b - real ( kind = 8 )
!! upper limit of integration
!!
!! epsabs - real ( kind = 8 )
!! absolute accoracy requested
!! epsrel - real ( kind = 8 )
!! relative accuracy requested
!! if epsabs.le.0
!! and epsrel.lt.max(50*rel.mach.acc.,0.5d-28),
!! the routine will end with ier = 6.
!!
!! key - integer ( kind = 4 )
!! key for choice of local integration rule
!! a gauss-kronrod pair is used with
!! 7 - 15 points if key.lt.2,
!! 10 - 21 points if key = 2,
!! 15 - 31 points if key = 3,
!! 20 - 41 points if key = 4,
!! 25 - 51 points if key = 5,
!! 30 - 61 points if key.gt.5.
!!
!! on return
!! result - real ( kind = 8 )
!! approximation to the integral
!!
!! abserr - real ( kind = 8 )
!! estimate of the modulus of the absolute error,
!! which should equal or exceed abs(i-result)
!!
!! neval - integer ( kind = 4 )
!! number of integrand evaluations
!!
!! ier - integer ( kind = 4 )
!! ier = 0 normal and reliable termination of the
!! routine. it is assumed that the requested
!! accuracy has been achieved.
!! ier.gt.0 abnormal termination of the routine
!! the estimates for result and error are
!! less reliable. it is assumed that the
!! requested accuracy has not been achieved.
!! error messages
!! ier = 1 maximum number of subdivisions allowed
!! has been achieved. one can allow more
!! subdivisions by increasing the value of
!! limit (and taking the according dimension
!! adjustments into account). however, if
!! this yield no improvement it is advised
!! to analyze the integrand in order to
!! determine the integration difficulaties.
!! if the position of a local difficulty can
!! be determined (i.e.singularity,
!! discontinuity within the interval) one
!! will probably gain from splitting up the
!! interval at this point and calling the
!! integrator on the subranges. if possible,
!! an appropriate special-purpose integrator
!! should be used which is designed for
!! handling the type of difficulty involved.
!! = 2 the occurrence of roundoff error is
!! detected, which prevents the requested
!! tolerance from being achieved.
!! = 3 extremely bad integrand behaviour occurs
!! at some points of the integration
!! interval.
!! = 6 the input is invalid, because
!! (epsabs.le.0 and
!! epsrel.lt.max(50*rel.mach.acc.,0.5d-28))
!! or limit.lt.1 or lenw.lt.limit*4.
!! result, abserr, neval, last are set
!! to zero.
!! except when lenw is invalid, iwork(1),
!! work(limit*2+1) and work(limit*3+1) are
!! set to zero, work(1) is set to a and
!! work(limit+1) to b.
!!
!! dimensioning parameters
!! limit - integer ( kind = 4 )
!! dimensioning parameter for iwork
!! limit determines the maximum number of subintervals
!! in the partition of the given integration interval
!! (a,b), limit.ge.1.
!! if limit.lt.1, the routine will end with ier = 6.
!!
!! lenw - integer ( kind = 4 )
!! dimensioning parameter for work
!! lenw must be at least limit*4.
!! if lenw.lt.limit*4, the routine will end with
!! ier = 6.
!!
!! last - integer ( kind = 4 )
!! on return, last equals the number of subintervals
!! produced in the subdivision process, which
!! determines the number of significant elements
!! actually in the work arrays.
!!
!! work arrays
!! iwork - integer ( kind = 4 )
!! vector of dimension at least limit, the first k
!! elements of which contain pointers to the error
!! estimates over the subintervals, such that
!! work(limit*3+iwork(1)),... , work(limit*3+iwork(k))
!! form a decreasing sequence with k = last if
!! last.le.(limit/2+2), and k = limit+1-last otherwise
!!
!! work - real ( kind = 8 )
!! vector of dimension at least lenw
!! on return
!! work(1), ..., work(last) contain the left end
!! points of the subintervals in the partition of
!! (a,b),
!! work(limit+1), ..., work(limit+last) contain the
!! right end points,
!! work(limit*2+1), ..., work(limit*2+last) contain
!! the integral approximations over the subintervals,
!! work(limit*3+1), ..., work(limit*3+last) contain
!! the error estimates.
!!
subroutine dqag ( f, a, b, epsabs, epsrel, key, result, abserr, neval, ier, &
limit, lenw, last, iwork, work )
implicit none
integer ( kind = 4 ) lenw
integer ( kind = 4 ) limit
real ( kind = 8 ) a
real ( kind = 8 ) abserr
real ( kind = 8 ) b
real ( kind = 8 ) epsabs
real ( kind = 8 ) epsrel
real ( kind = 8 ), external :: f
integer ( kind = 4 ) ier
integer ( kind = 4 ) iwork(limit)
integer ( kind = 4 ) key
integer ( kind = 4 ) last
integer ( kind = 4 ) lvl
integer ( kind = 4 ) l1
integer ( kind = 4 ) l2
integer ( kind = 4 ) l3
integer ( kind = 4 ) neval
real ( kind = 8 ) result
real ( kind = 8 ) work(lenw)
!
! check validity of lenw.
!
ier = 6
neval = 0
last = 0
result = 0.0D+00
abserr = 0.0D+00
if(limit.lt.1.or.lenw.lt.limit*4) go to 10
!
! prepare call for dqage.
!
l1 = limit+1
l2 = limit+l1
l3 = limit+l2
call dqage(f,a,b,epsabs,epsrel,key,limit,result,abserr,neval, &
ier,work(1),work(l1),work(l2),work(l3),iwork,last)
!
! call error handler if necessary.
!
lvl = 0
10 continue
if(ier.eq.6) lvl = 1
if(ier.ne.0) call xerror('abnormal return from dqag ',26,ier,lvl)
return
end subroutine dqag
!----------------------------------------------------------------------------------------
!> DQAGIE estimates an integral over a semi-infinite or infinite interval.
!!
!! Modified:
!!
!! 11 September 2015
!!
!! Author:
!!
!! Robert Piessens, Elise de Doncker
!!
!!***purpose the routine calculates an approximation result to a given
!! integral i = integral of f over (bound,+infinity)
!! or i = integral of f over (-infinity,bound)
!! or i = integral of f over (-infinity,+infinity),
!! hopefully satisfying following claim for accuracy
!! abs(i-result).le.max(epsabs,epsrel*abs(i))
!!
!! Parameters:
!!
!! f - real ( kind = 8 )
!! function subprogram defining the integrand
!! function f(x). the actual name for f needs to be
!! declared e x t e r n a l in the driver program.
!!
!! bound - real ( kind = 8 )
!! finite bound of integration range
!! (has no meaning if interval is doubly-infinite)
!!
!! inf - real ( kind = 8 )
!! indicating the kind of integration range involved
!! inf = 1 corresponds to (bound,+infinity),
!! inf = -1 to (-infinity,bound),
!! inf = 2 to (-infinity,+infinity).
!!
!! epsabs - real ( kind = 8 )
!! absolute accuracy requested
!! epsrel - real ( kind = 8 )
!! relative accuracy requested
!! if epsabs.le.0
!! and epsrel.lt.max(50*rel.mach.acc.,0.5d-28),
!! the routine will end with ier = 6.
!!
!! limit - integer ( kind = 4 )
!! gives an upper bound on the number of subintervals
!! in the partition of (a,b), limit.ge.1
!!
!! on return
!! result - real ( kind = 8 )
!! approximation to the integral
!!
!! abserr - real ( kind = 8 )
!! estimate of the modulus of the absolute error,
!! which should equal or exceed abs(i-result)
!!
!! neval - integer ( kind = 4 )
!! number of integrand evaluations
!!
!! ier - integer ( kind = 4 )
!! ier = 0 normal and reliable termination of the
!! routine. it is assumed that the requested
!! accuracy has been achieved.
!! - ier.gt.0 abnormal termination of the routine. the
!! estimates for result and error are less
!! reliable. it is assumed that the requested
!! accuracy has not been achieved.
!! error messages
!! ier = 1 maximum number of subdivisions allowed
!! has been achieved. one can allow more
!! subdivisions by increasing the value of
!! limit (and taking the according dimension
!! adjustments into account). however,if
!! this yields no improvement it is advised
!! to analyze the integrand in order to
!! determine the integration difficulties.
!! if the position of a local difficulty can
!! be determined (e.g. singularity,
!! discontinuity within the interval) one
!! will probably gain from splitting up the
!! interval at this point and calling the
!! integrator on the subranges. if possible,
!! an appropriate special-purpose integrator
!! should be used, which is designed for
!! handling the type of difficulty involved.
!! = 2 the occurrence of roundoff error is
!! detected, which prevents the requested
!! tolerance from being achieved.
!! the error may be under-estimated.
!! = 3 extremely bad integrand behaviour occurs
!! at some points of the integration
!! interval.
!! = 4 the algorithm does not converge.
!! roundoff error is detected in the
!! extrapolation table.
!! it is assumed that the requested tolerance
!! cannot be achieved, and that the returned
!! result is the best which can be obtained.
!! = 5 the integral is probably divergent, or
!! slowly convergent. it must be noted that
!! divergence can occur with any other value
!! of ier.
!! = 6 the input is invalid, because
!! (epsabs.le.0 and
!! epsrel.lt.max(50*rel.mach.acc.,0.5d-28),
!! result, abserr, neval, last, rlist(1),
!! elist(1) and iord(1) are set to zero.
!! alist(1) and blist(1) are set to 0
!! and 1 respectively.
!!
!! alist - real ( kind = 8 )
!! vector of dimension at least limit, the first
!! last elements of which are the left
!! end points of the subintervals in the partition
!! of the transformed integration range (0,1).
!!
!! blist - real ( kind = 8 )
!! vector of dimension at least limit, the first
!! last elements of which are the right
!! end points of the subintervals in the partition
!! of the transformed integration range (0,1).
!!
!! rlist - real ( kind = 8 )
!! vector of dimension at least limit, the first
!! last elements of which are the integral
!! approximations on the subintervals
!!
!! elist - real ( kind = 8 )
!! vector of dimension at least limit, the first
!! last elements of which are the moduli of the
!! absolute error estimates on the subintervals
!!
!! iord - integer ( kind = 4 )
!! vector of dimension limit, the first k
!! elements of which are pointers to the
!! error estimates over the subintervals,
!! such that elist(iord(1)), ..., elist(iord(k))
!! form a decreasing sequence, with k = last
!! if last.le.(limit/2+2), and k = limit+1-last
!! otherwise
!!
!! last - integer ( kind = 4 )
!! number of subintervals actually produced
!! in the subdivision process
!!
!! Local Parameters:
!!
!! the dimension of rlist2 is determined by the value of
!! limexp in routine dqelg.
!!
!! alist - list of left end points of all subintervals
!! considered up to now
!! blist - list of right end points of all subintervals
!! considered up to now
!! rlist(i) - approximation to the integral over
!! (alist(i),blist(i))
!! rlist2 - array of dimension at least (limexp+2),
!! containing the part of the epsilon table
!! wich is still needed for further computations
!! elist(i) - error estimate applying to rlist(i)
!! maxerr - pointer to the interval with largest error
!! estimate
!! errmax - elist(maxerr)
!! erlast - error on the interval currently subdivided
!! (before that subdivision has taken place)
!! area - sum of the integrals over the subintervals
!! errsum - sum of the errors over the subintervals
!! errbnd - requested accuracy max(epsabs,epsrel*
!! abs(result))
!! *****1 - variable for the left subinterval
!! *****2 - variable for the right subinterval
!! last - index for subdivision
!! nres - number of calls to the extrapolation routine
!! numrl2 - number of elements currently in rlist2. if an
!! appropriate approximation to the compounded
!! integral has been obtained, it is put in
!! rlist2(numrl2) after numrl2 has been increased
!! by one.
!! small - length of the smallest interval considered up
!! to now, multiplied by 1.5
!! erlarg - sum of the errors over the intervals larger
!! than the smallest interval considered up to now
!! extrap - logical variable denoting that the routine
!! is attempting to perform extrapolation. i.e.
!! before subdividing the smallest interval we
!! try to decrease the value of erlarg.
!! noext - logical variable denoting that extrapolation
!! is no longer allowed (true-value)
!!
!! machine dependent constants
!!
!! epmach is the largest relative spacing.
!! uflow is the smallest positive magnitude.
!! oflow is the largest positive magnitude.
!!
subroutine dqagie ( f, bound, inf, epsabs, epsrel, limit, result, abserr, &
neval, ier, alist, blist, rlist, elist, iord, last )
implicit none
real ( kind = 8 ) abseps,abserr,alist,area,area1,area12,area2,a1, &
a2,blist,boun,bound,b1,b2,correc,defabs,defab1,defab2, &
dres,elist,epmach,epsabs,epsrel,erlarg,erlast, &
errbnd,errmax,error1,error2,erro12,errsum,ertest,f,oflow,resabs, &
reseps,result,res3la,rlist,rlist2,small,uflow
integer ( kind = 4 ) id,ier,ierro,inf,iord,iroff1,iroff2, &
iroff3,jupbnd,k,ksgn, &
ktmin,last,limit,maxerr,neval,nres,nrmax,numrl2
logical extrap,noext
dimension alist(limit),blist(limit),elist(limit),iord(limit), &
res3la(3),rlist(limit),rlist2(52)
external f
epmach = epsilon ( epmach )
!
! test on validity of parameters
!
ier = 0
neval = 0
last = 0
result = 0.0D+00
abserr = 0.0D+00
alist(1) = 0.0D+00
blist(1) = 0.1D+01
rlist(1) = 0.0D+00
elist(1) = 0.0D+00
iord(1) = 0
if(epsabs.le.0.0D+00.and.epsrel.lt. max ( 0.5D+02*epmach,0.5D-28)) then
ier = 6
end if
if(ier.eq.6) then
return
end if
!
! first approximation to the integral
!
! determine the interval to be mapped onto (0,1).
! if inf = 2 the integral is computed as i = i1+i2, where
! i1 = integral of f over (-infinity,0),
! i2 = integral of f over (0,+infinity).
!
boun = bound
if(inf.eq.2) boun = 0.0D+00
call dqk15i(f,boun,inf,0.0D+00,0.1D+01,result,abserr, &
defabs,resabs)
!
! test on accuracy
!
last = 1
rlist(1) = result
elist(1) = abserr
iord(1) = 1
dres = abs ( result)
errbnd = max ( epsabs,epsrel*dres)
if(abserr.le.1.0D+02*epmach*defabs.and.abserr.gt.errbnd) ier = 2
if(limit.eq.1) ier = 1
if(ier.ne.0.or.(abserr.le.errbnd.and.abserr.ne.resabs).or. &
abserr.eq.0.0D+00) go to 130
!
! initialization
!
uflow = tiny ( uflow )
oflow = huge ( oflow )
rlist2(1) = result
errmax = abserr
maxerr = 1
area = result
errsum = abserr
abserr = oflow
nrmax = 1
nres = 0
ktmin = 0
numrl2 = 2
extrap = .false.
noext = .false.
ierro = 0
iroff1 = 0
iroff2 = 0
iroff3 = 0
ksgn = -1
if(dres.ge.(0.1D+01-0.5D+02*epmach)*defabs) ksgn = 1
!
! main do-loop
!
do 90 last = 2,limit
!
! bisect the subinterval with nrmax-th largest error estimate.
!
a1 = alist(maxerr)
b1 = 0.5D+00*(alist(maxerr)+blist(maxerr))
a2 = b1
b2 = blist(maxerr)
erlast = errmax
call dqk15i(f,boun,inf,a1,b1,area1,error1,resabs,defab1)
call dqk15i(f,boun,inf,a2,b2,area2,error2,resabs,defab2)
!
! improve previous approximations to integral
! and error and test for accuracy.
!
area12 = area1+area2
erro12 = error1+error2
errsum = errsum+erro12-errmax
area = area+area12-rlist(maxerr)
if(defab1.eq.error1.or.defab2.eq.error2)go to 15
if( abs ( rlist(maxerr)-area12).gt.0.1D-04* abs ( area12) &
.or.erro12.lt.0.99D+00*errmax) go to 10
if(extrap) iroff2 = iroff2+1
if(.not.extrap) iroff1 = iroff1+1
10 if(last.gt.10.and.erro12.gt.errmax) iroff3 = iroff3+1
15 rlist(maxerr) = area1
rlist(last) = area2
errbnd = max ( epsabs,epsrel* abs ( area))
!
! test for roundoff error and eventually set error flag.
!
if(iroff1+iroff2.ge.10.or.iroff3.ge.20) ier = 2
if(iroff2.ge.5) ierro = 3
!
! set error flag in the case that the number of
! subintervals equals limit.
!
if(last.eq.limit) ier = 1
!
! set error flag in the case of bad integrand behaviour
! at some points of the integration range.
!
if( max ( abs ( a1), abs ( b2)).le.(0.1D+01+0.1D+03*epmach)* &
( abs ( a2)+0.1D+04*uflow)) then
ier = 4
end if
!
! append the newly-created intervals to the list.
!
if(error2.gt.error1) go to 20
alist(last) = a2
blist(maxerr) = b1
blist(last) = b2
elist(maxerr) = error1
elist(last) = error2
go to 30
20 continue
alist(maxerr) = a2
alist(last) = a1
blist(last) = b1
rlist(maxerr) = area2
rlist(last) = area1
elist(maxerr) = error2
elist(last) = error1
!
! call dqpsrt to maintain the descending ordering
! in the list of error estimates and select the subinterval
! with nrmax-th largest error estimate (to be bisected next).
!
30 call dqpsrt(limit,last,maxerr,errmax,elist,iord,nrmax)
if(errsum.le.errbnd) go to 115
if(ier.ne.0) go to 100
if(last.eq.2) go to 80
if(noext) go to 90
erlarg = erlarg-erlast
if( abs ( b1-a1).gt.small) erlarg = erlarg+erro12
if(extrap) go to 40
!
! test whether the interval to be bisected next is the
! smallest interval.
!
if( abs ( blist(maxerr)-alist(maxerr)).gt.small) go to 90
extrap = .true.
nrmax = 2
40 if(ierro.eq.3.or.erlarg.le.ertest) go to 60
!
! the smallest interval has the largest error.
! before bisecting decrease the sum of the errors over the
! larger intervals (erlarg) and perform extrapolation.
!
id = nrmax
jupbnd = last
if(last.gt.(2+limit/2)) jupbnd = limit+3-last
do k = id,jupbnd
maxerr = iord(nrmax)
errmax = elist(maxerr)
if( abs ( blist(maxerr)-alist(maxerr)).gt.small) go to 90
nrmax = nrmax+1
end do
!
! perform extrapolation.
!
60 numrl2 = numrl2+1
rlist2(numrl2) = area
call dqelg(numrl2,rlist2,reseps,abseps,res3la,nres)
ktmin = ktmin+1
if(ktmin.gt.5.and.abserr.lt.0.1D-02*errsum) ier = 5
if(abseps.ge.abserr) go to 70
ktmin = 0
abserr = abseps
result = reseps
correc = erlarg
ertest = max ( epsabs,epsrel* abs ( reseps))
if(abserr.le.ertest) go to 100
!
! prepare bisection of the smallest interval.
!
70 if(numrl2.eq.1) noext = .true.
if(ier.eq.5) go to 100
maxerr = iord(1)
errmax = elist(maxerr)
nrmax = 1
extrap = .false.
small = small*0.5D+00
erlarg = errsum
go to 90
80 small = 0.375D+00
erlarg = errsum
ertest = errbnd
rlist2(2) = area
90 continue
!
! set final result and error estimate.
!
100 if(abserr.eq.oflow) go to 115
if((ier+ierro).eq.0) go to 110
if(ierro.eq.3) abserr = abserr+correc
if(ier.eq.0) ier = 3
if(result.ne.0.0D+00.and.area.ne.0.0D+00)go to 105
if(abserr.gt.errsum)go to 115
if(area.eq.0.0D+00) go to 130
go to 110
105 if(abserr/ abs ( result).gt.errsum/ abs ( area))go to 115
!
! test on divergence
!
110 continue
if ( ksgn .eq. (-1) .and. &
max ( abs ( result), abs ( area)) .le. defabs*0.1D-01 ) then
go to 130
end if
if ( 0.1D-01 .gt. (result/area) .or. &
(result/area) .gt. 0.1D+03 .or. &
errsum .gt. abs ( area) ) then
ier = 6
end if
go to 130
!
! compute global integral sum.
!
115 result = 0.0D+00
do k = 1,last
result = result+rlist(k)
end do
abserr = errsum
130 continue
neval = 30*last-15
if(inf.eq.2) neval = 2*neval
if(ier.gt.2) ier=ier-1
return
end subroutine dqagie
!----------------------------------------------------------------------------------------
!> DQAGI estimates an integral over a semi-infinite or infinite interval.
!!
!! Modified:
!!
!! 11 September 2015
!!
!! Author:
!!
!! Robert Piessens, Elise de Doncker
!!
!!***purpose the routine calculates an approximation result to a given
!! integral i = integral of f over (bound,+infinity)
!! or i = integral of f over (-infinity,bound)
!! or i = integral of f over (-infinity,+infinity)
!! hopefully satisfying following claim for accuracy
!! abs(i-result).le.max(epsabs,epsrel*abs(i)).
!!
!! Parameters:
!!
!! on entry
!! f - real ( kind = 8 )
!! function subprogram defining the integrand
!! function f(x). the actual name for f needs to be
!! declared e x t e r n a l in the driver program.
!!
!! bound - real ( kind = 8 )
!! finite bound of integration range
!! (has no meaning if interval is doubly-infinite)
!!
!! inf - integer ( kind = 4 )
!! indicating the kind of integration range involved
!! inf = 1 corresponds to (bound,+infinity),
!! inf = -1 to (-infinity,bound),
!! inf = 2 to (-infinity,+infinity).
!!
!! epsabs - real ( kind = 8 )
!! absolute accuracy requested
!! epsrel - real ( kind = 8 )
!! relative accuracy requested
!! if epsabs.le.0
!! and epsrel.lt.max(50*rel.mach.acc.,0.5d-28),
!! the routine will end with ier = 6.
!!
!!
!! on return
!! result - real ( kind = 8 )
!! approximation to the integral
!!
!! abserr - real ( kind = 8 )
!! estimate of the modulus of the absolute error,
!! which should equal or exceed abs(i-result)
!!
!! neval - integer ( kind = 4 )
!! number of integrand evaluations
!!
!! ier - integer ( kind = 4 )
!! ier = 0 normal and reliable termination of the
!! routine. it is assumed that the requested
!! accuracy has been achieved.
!! - ier.gt.0 abnormal termination of the routine. the
!! estimates for result and error are less
!! reliable. it is assumed that the requested
!! accuracy has not been achieved.
!! error messages
!! ier = 1 maximum number of subdivisions allowed
!! has been achieved. one can allow more
!! subdivisions by increasing the value of
!! limit (and taking the according dimension
!! adjustments into account). however, if
!! this yields no improvement it is advised
!! to analyze the integrand in order to
!! determine the integration difficulties. if
!! the position of a local difficulty can be
!! determined (e.g. singularity,
!! discontinuity within the interval) one
!! will probably gain from splitting up the
!! interval at this point and calling the
!! integrator on the subranges. if possible,
!! an appropriate special-purpose integrator
!! should be used, which is designed for
!! handling the type of difficulty involved.
!! = 2 the occurrence of roundoff error is
!! detected, which prevents the requested
!! tolerance from being achieved.
!! the error may be under-estimated.
!! = 3 extremely bad integrand behaviour occurs
!! at some points of the integration
!! interval.
!! = 4 the algorithm does not converge.
!! roundoff error is detected in the
!! extrapolation table.
!! it is assumed that the requested tolerance
!! cannot be achieved, and that the returned
!! result is the best which can be obtained.
!! = 5 the integral is probably divergent, or
!! slowly convergent. it must be noted that
!! divergence can occur with any other value
!! of ier.
!! = 6 the input is invalid, because
!! (epsabs.le.0 and
!! epsrel.lt.max(50*rel.mach.acc.,0.5d-28))
!! or limit.lt.1 or leniw.lt.limit*4.
!! result, abserr, neval, last are set to
!! zero. exept when limit or leniw is
!! invalid, iwork(1), work(limit*2+1) and
!! work(limit*3+1) are set to zero, work(1)
!! is set to a and work(limit+1) to b.
!!
!! dimensioning parameters
!! limit - integer ( kind = 4 )
!! dimensioning parameter for iwork
!! limit determines the maximum number of subintervals
!! in the partition of the given integration interval
!! (a,b), limit.ge.1.
!! if limit.lt.1, the routine will end with ier = 6.
!!
!! lenw - integer ( kind = 4 )
!! dimensioning parameter for work
!! lenw must be at least limit*4.
!! if lenw.lt.limit*4, the routine will end
!! with ier = 6.
!!
!! last - integer ( kind = 4 )
!! on return, last equals the number of subintervals
!! produced in the subdivision process, which
!! determines the number of significant elements
!! actually in the work arrays.
!!
!! work arrays
!! iwork - integer ( kind = 4 )
!! vector of dimension at least limit, the first
!! k elements of which contain pointers
!! to the error estimates over the subintervals,
!! such that work(limit*3+iwork(1)),... ,
!! work(limit*3+iwork(k)) form a decreasing
!! sequence, with k = last if last.le.(limit/2+2), and
!! k = limit+1-last otherwise
!!
!! work - real ( kind = 8 )
!! vector of dimension at least lenw
!! on return
!! work(1), ..., work(last) contain the left
!! end points of the subintervals in the
!! partition of (a,b),
!! work(limit+1), ..., work(limit+last) contain
!! the right end points,
!! work(limit*2+1), ...,work(limit*2+last) contain the
!! integral approximations over the subintervals,
!! work(limit*3+1), ..., work(limit*3)
!! contain the error estimates.
!!
subroutine dqagi ( f, bound, inf, epsabs, epsrel, result, abserr, neval, &
ier,limit,lenw,last,iwork,work)
implicit none
real ( kind = 8 ) abserr,bound,epsabs,epsrel,f,result,work
integer ( kind = 4 ) ier,inf,iwork,last,lenw,limit,lvl,l1,l2,l3,neval
dimension iwork(limit),work(lenw)
external f
!
! check validity of limit and lenw.
!
ier = 6
neval = 0
last = 0
result = 0.0D+00
abserr = 0.0D+00
if(limit.lt.1.or.lenw.lt.limit*4) go to 10
!
! prepare call for dqagie.
!
l1 = limit+1
l2 = limit+l1
l3 = limit+l2
call dqagie(f,bound,inf,epsabs,epsrel,limit,result,abserr, &
neval,ier,work(1),work(l1),work(l2),work(l3),iwork,last)
!
! call error handler if necessary.
!
lvl = 0
10 if(ier.eq.6) lvl = 1
if(ier.ne.0) then
call xerror('abnormal return from dqagi',26,ier,lvl)
end if
return
end subroutine dqagi
!----------------------------------------------------------------------------------------
!> DQAGPE computes a definite integral.
!!
!! Modified:
!!
!! 11 September 2015
!!
!! Author:
!!
!! Robert Piessens, Elise de Doncker
!!
!!***purpose the routine calculates an approximation result to a given
!! definite integral i = integral of f over (a,b), hopefully
!! satisfying following claim for accuracy abs(i-result).le.
!! max(epsabs,epsrel*abs(i)). break points of the integration
!! interval, where local difficulties of the integrand may
!! occur(e.g. singularities,discontinuities),provided by user.
!!
!! Parameters:
!!
!! on entry
!! f - real ( kind = 8 )
!! function subprogram defining the integrand
!! function f(x). the actual name for f needs to be
!! declared e x t e r n a l in the driver program.
!!
!! a - real ( kind = 8 )
!! lower limit of integration
!!
!! b - real ( kind = 8 )
!! upper limit of integration
!!
!! npts2 - integer ( kind = 4 )
!! number equal to two more than the number of
!! user-supplied break points within the integration
!! range, npts2.ge.2.
!! if npts2.lt.2, the routine will end with ier = 6.
!!
!! points - real ( kind = 8 )
!! vector of dimension npts2, the first (npts2-2)
!! elements of which are the user provided break
!! points. if these points do not constitute an
!! ascending sequence there will be an automatic
!! sorting.
!!
!! epsabs - real ( kind = 8 )
!! absolute accuracy requested
!! epsrel - real ( kind = 8 )
!! relative accuracy requested
!! if epsabs.le.0
!! and epsrel.lt.max(50*rel.mach.acc.,0.5d-28),
!! the routine will end with ier = 6.
!!
!! limit - integer ( kind = 4 )
!! gives an upper bound on the number of subintervals
!! in the partition of (a,b), limit.ge.npts2
!! if limit.lt.npts2, the routine will end with
!! ier = 6.
!!
!! on return
!! result - real ( kind = 8 )
!! approximation to the integral
!!
!! abserr - real ( kind = 8 )
!! estimate of the modulus of the absolute error,
!! which should equal or exceed abs(i-result)
!!
!! neval - integer ( kind = 4 )
!! number of integrand evaluations
!!
!! ier - integer ( kind = 4 )
!! ier = 0 normal and reliable termination of the
!! routine. it is assumed that the requested
!! accuracy has been achieved.
!! ier.gt.0 abnormal termination of the routine.
!! the estimates for integral and error are
!! less reliable. it is assumed that the
!! requested accuracy has not been achieved.
!! error messages
!! ier = 1 maximum number of subdivisions allowed
!! has been achieved. one can allow more
!! subdivisions by increasing the value of
!! limit (and taking the according dimension
!! adjustments into account). however, if
!! this yields no improvement it is advised
!! to analyze the integrand in order to
!! determine the integration difficulties. if
!! the position of a local difficulty can be
!! determined (i.e. singularity,
!! discontinuity within the interval), it
!! should be supplied to the routine as an
!! element of the vector points. if necessary
!! an appropriate special-purpose integrator
!! must be used, which is designed for
!! handling the type of difficulty involved.
!! = 2 the occurrence of roundoff error is
!! detected, which prevents the requested
!! tolerance from being achieved.
!! the error may be under-estimated.
!! = 3 extremely bad integrand behaviour occurs
!! at some points of the integration
!! interval.
!! = 4 the algorithm does not converge.
!! roundoff error is detected in the
!! extrapolation table. it is presumed that
!! the requested tolerance cannot be
!! achieved, and that the returned result is
!! the best which can be obtained.
!! = 5 the integral is probably divergent, or
!! slowly convergent. it must be noted that
!! divergence can occur with any other value
!! of ier.gt.0.
!! = 6 the input is invalid because
!! npts2.lt.2 or
!! break points are specified outside
!! the integration range or
!! (epsabs.le.0 and
!! epsrel.lt.max(50*rel.mach.acc.,0.5d-28))
!! or limit.lt.npts2.
!! result, abserr, neval, last, rlist(1),
!! and elist(1) are set to zero. alist(1) and
!! blist(1) are set to a and b respectively.
!!
!! alist - real ( kind = 8 )
!! vector of dimension at least limit, the first
!! last elements of which are the left end points
!! of the subintervals in the partition of the given
!! integration range (a,b)
!!
!! blist - real ( kind = 8 )
!! vector of dimension at least limit, the first
!! last elements of which are the right end points
!! of the subintervals in the partition of the given
!! integration range (a,b)
!!
!! rlist - real ( kind = 8 )
!! vector of dimension at least limit, the first
!! last elements of which are the integral
!! approximations on the subintervals
!!
!! elist - real ( kind = 8 )
!! vector of dimension at least limit, the first
!! last elements of which are the moduli of the
!! absolute error estimates on the subintervals
!!
!! pts - real ( kind = 8 )
!! vector of dimension at least npts2, containing the
!! integration limits and the break points of the
!! interval in ascending sequence.
!!
!! level - integer ( kind = 4 )
!! vector of dimension at least limit, containing the
!! subdivision levels of the subinterval, i.e. if
!! (aa,bb) is a subinterval of (p1,p2) where p1 as
!! well as p2 is a user-provided break point or
!! integration limit, then (aa,bb) has level l if
!! abs(bb-aa) = abs(p2-p1)*2**(-l).
!!
!! ndin - integer ( kind = 4 )
!! vector of dimension at least npts2, after first
!! integration over the intervals (pts(i)),pts(i+1),
!! i = 0,1, ..., npts2-2, the error estimates over
!! some of the intervals may have been increased
!! artificially, in order to put their subdivision
!! forward. if this happens for the subinterval
!! numbered k, ndin(k) is put to 1, otherwise
!! ndin(k) = 0.
!!
!! iord - integer ( kind = 4 )
!! vector of dimension at least limit, the first k
!! elements of which are pointers to the
!! error estimates over the subintervals,
!! such that elist(iord(1)), ..., elist(iord(k))
!! form a decreasing sequence, with k = last
!! if last.le.(limit/2+2), and k = limit+1-last
!! otherwise
!!
!! last - integer ( kind = 4 )
!! number of subintervals actually produced in the
!! subdivisions process
!!
!! Local Parameters:
!!
!! the dimension of rlist2 is determined by the value of
!! limexp in routine epsalg (rlist2 should be of dimension
!! (limexp+2) at least).
!!
!! alist - list of left end points of all subintervals
!! considered up to now
!! blist - list of right end points of all subintervals
!! considered up to now
!! rlist(i) - approximation to the integral over
!! (alist(i),blist(i))
!! rlist2 - array of dimension at least limexp+2
!! containing the part of the epsilon table which
!! is still needed for further computations
!! elist(i) - error estimate applying to rlist(i)
!! maxerr - pointer to the interval with largest error
!! estimate
!! errmax - elist(maxerr)
!! erlast - error on the interval currently subdivided
!! (before that subdivision has taken place)
!! area - sum of the integrals over the subintervals
!! errsum - sum of the errors over the subintervals
!! errbnd - requested accuracy max(epsabs,epsrel*
!! abs(result))
!! *****1 - variable for the left subinterval
!! *****2 - variable for the right subinterval
!! last - index for subdivision
!! nres - number of calls to the extrapolation routine
!! numrl2 - number of elements in rlist2. if an appropriate
!! approximation to the compounded integral has
!! been obtained, it is put in rlist2(numrl2) after
!! numrl2 has been increased by one.
!! erlarg - sum of the errors over the intervals larger
!! than the smallest interval considered up to now
!! extrap - logical variable denoting that the routine
!! is attempting to perform extrapolation. i.e.
!! before subdividing the smallest interval we
!! try to decrease the value of erlarg.
!! noext - logical variable denoting that extrapolation is
!! no longer allowed (true-value)
!!
!! machine dependent constants
!!
!! epmach is the largest relative spacing.
!! uflow is the smallest positive magnitude.
!! oflow is the largest positive magnitude.
!!
subroutine dqagpe(f,a,b,npts2,points,epsabs,epsrel,limit,result, &
abserr,neval,ier,alist,blist,rlist,elist,pts,iord,level,ndin, &
last)
implicit none
real ( kind = 8 ) a,abseps,abserr,alist,area,area1,area12,area2,a1, &
a2,b,blist,b1,b2,correc,defabs,defab1,defab2, &
dres,elist,epmach,epsabs,epsrel,erlarg,erlast,errbnd, &
errmax,error1,erro12,error2,errsum,ertest,f,oflow,points,pts, &
resa,resabs,reseps,result,res3la,rlist,rlist2,sgn,temp,uflow
integer ( kind = 4 ) i,id,ier,ierro,ind1,ind2,iord,ip1, &
iroff1,iroff2,iroff3,j, &
jlow,jupbnd,k,ksgn,ktmin,last,levcur,level,levmax,limit,maxerr, &
ndin,neval,nint,nintp1,npts,npts2,nres,nrmax,numrl2
logical extrap,noext
dimension alist(limit),blist(limit),elist(limit),iord(limit), &
level(limit),ndin(npts2),points(npts2),pts(npts2),res3la(3), &
rlist(limit),rlist2(52)
external f
epmach = epsilon ( epmach )
!
! test on validity of parameters
!
ier = 0
neval = 0
last = 0
result = 0.0D+00
abserr = 0.0D+00
alist(1) = a
blist(1) = b
rlist(1) = 0.0D+00
elist(1) = 0.0D+00
iord(1) = 0
level(1) = 0
npts = npts2-2
if(npts2.lt.2.or.limit.le.npts.or.(epsabs.le.0.0D+00.and. &
epsrel.lt. max ( 0.5D+02*epmach,0.5d-28))) ier = 6
if(ier.eq.6) then
return
end if
!
! if any break points are provided, sort them into an
! ascending sequence.
!
sgn = 1.0D+00
if(a.gt.b) sgn = -1.0D+00
pts(1) = min (a,b)
if(npts.eq.0) go to 15
do i = 1,npts
pts(i+1) = points(i)
end do
15 pts(npts+2) = max ( a,b)
nint = npts+1
a1 = pts(1)
if(npts.eq.0) go to 40
nintp1 = nint+1
do i = 1,nint
ip1 = i+1
do j = ip1,nintp1
if(pts(i).gt.pts(j)) then
temp = pts(i)
pts(i) = pts(j)
pts(j) = temp
end if
end do
end do
if(pts(1).ne. min (a,b).or.pts(nintp1).ne. max ( a,b)) ier = 6
if(ier.eq.6) then
return
end if
!
! compute first integral and error approximations.
!
40 resabs = 0.0D+00
do i = 1,nint
b1 = pts(i+1)
call dqk21(f,a1,b1,area1,error1,defabs,resa)
abserr = abserr+error1
result = result+area1
ndin(i) = 0
if(error1.eq.resa.and.error1.ne.0.0D+00) ndin(i) = 1
resabs = resabs+defabs
level(i) = 0
elist(i) = error1
alist(i) = a1
blist(i) = b1
rlist(i) = area1
iord(i) = i
a1 = b1
end do
errsum = 0.0D+00
do i = 1,nint
if(ndin(i).eq.1) elist(i) = abserr
errsum = errsum+elist(i)
end do
!
! test on accuracy.
!
last = nint
neval = 21*nint
dres = abs ( result)
errbnd = max ( epsabs,epsrel*dres)
if(abserr.le.0.1D+03*epmach*resabs.and.abserr.gt.errbnd) ier = 2
if(nint.eq.1) go to 80
do i = 1,npts
jlow = i+1
ind1 = iord(i)
do j = jlow,nint
ind2 = iord(j)
if(elist(ind1).le.elist(ind2)) then
ind1 = ind2
k = j
end if
end do
if(ind1.ne.iord(i)) then
iord(k) = iord(i)
iord(i) = ind1
end if
end do
if(limit.lt.npts2) ier = 1
80 if(ier.ne.0.or.abserr.le.errbnd) go to 210
!
! initialization
!
rlist2(1) = result
maxerr = iord(1)
errmax = elist(maxerr)
area = result
nrmax = 1
nres = 0
numrl2 = 1
ktmin = 0
extrap = .false.
noext = .false.
erlarg = errsum
ertest = errbnd
levmax = 1
iroff1 = 0
iroff2 = 0
iroff3 = 0
ierro = 0
uflow = tiny ( uflow )
oflow = huge ( oflow )
abserr = oflow
ksgn = -1
if(dres.ge.(0.1D+01-0.5D+02*epmach)*resabs) ksgn = 1
!
! main do-loop
!
do 160 last = npts2,limit
!
! bisect the subinterval with the nrmax-th largest error estimate.
!
levcur = level(maxerr)+1
a1 = alist(maxerr)
b1 = 0.5D+00*(alist(maxerr)+blist(maxerr))
a2 = b1
b2 = blist(maxerr)
erlast = errmax
call dqk21(f,a1,b1,area1,error1,resa,defab1)
call dqk21(f,a2,b2,area2,error2,resa,defab2)
!
! improve previous approximations to integral
! and error and test for accuracy.
!
neval = neval+42
area12 = area1+area2
erro12 = error1+error2
errsum = errsum+erro12-errmax
area = area+area12-rlist(maxerr)
if(defab1.eq.error1.or.defab2.eq.error2) go to 95
if( abs ( rlist(maxerr)-area12).gt.0.1D-04* abs ( area12) &
.or.erro12.lt.0.99D+00*errmax) go to 90
if(extrap) iroff2 = iroff2+1
if(.not.extrap) iroff1 = iroff1+1
90 if(last.gt.10.and.erro12.gt.errmax) iroff3 = iroff3+1
95 level(maxerr) = levcur
level(last) = levcur
rlist(maxerr) = area1
rlist(last) = area2
errbnd = max ( epsabs,epsrel* abs ( area))
!
! test for roundoff error and eventually set error flag.
!
if(iroff1+iroff2.ge.10.or.iroff3.ge.20) ier = 2
if(iroff2.ge.5) ierro = 3
!
! set error flag in the case that the number of
! subintervals equals limit.
!
if(last.eq.limit) ier = 1
!
! set error flag in the case of bad integrand behaviour
! at a point of the integration range
!
if( max ( abs ( a1), abs ( b2)).le.(0.1D+01+0.1D+03*epmach)* &
( abs ( a2)+0.1D+04*uflow)) ier = 4
!
! append the newly-created intervals to the list.
!
if(error2.gt.error1) go to 100
alist(last) = a2
blist(maxerr) = b1
blist(last) = b2
elist(maxerr) = error1
elist(last) = error2
go to 110
100 alist(maxerr) = a2
alist(last) = a1
blist(last) = b1
rlist(maxerr) = area2
rlist(last) = area1
elist(maxerr) = error2
elist(last) = error1
!
! call dqpsrt to maintain the descending ordering
! in the list of error estimates and select the subinterval
! with nrmax-th largest error estimate (to be bisected next).
!
110 call dqpsrt(limit,last,maxerr,errmax,elist,iord,nrmax)
if(errsum.le.errbnd) go to 190
if(ier.ne.0) go to 170
if(noext) go to 160
erlarg = erlarg-erlast
if(levcur+1.le.levmax) erlarg = erlarg+erro12
if(extrap) go to 120
!
! test whether the interval to be bisected next is the
! smallest interval.
!
if(level(maxerr)+1.le.levmax) go to 160
extrap = .true.
nrmax = 2
120 if(ierro.eq.3.or.erlarg.le.ertest) go to 140
!
! the smallest interval has the largest error.
! before bisecting decrease the sum of the errors over
! the larger intervals (erlarg) and perform extrapolation.
!
id = nrmax
jupbnd = last
if(last.gt.(2+limit/2)) jupbnd = limit+3-last
do k = id,jupbnd
maxerr = iord(nrmax)
errmax = elist(maxerr)
if(level(maxerr)+1.le.levmax) go to 160
nrmax = nrmax+1
end do
!
! perform extrapolation.
!
140 numrl2 = numrl2+1
rlist2(numrl2) = area
if(numrl2.le.2) go to 155
call dqelg(numrl2,rlist2,reseps,abseps,res3la,nres)
ktmin = ktmin+1
if(ktmin.gt.5.and.abserr.lt.0.1D-02*errsum) ier = 5
if(abseps.ge.abserr) go to 150
ktmin = 0
abserr = abseps
result = reseps
correc = erlarg
ertest = max ( epsabs,epsrel* abs ( reseps))
if(abserr.lt.ertest) go to 170
!
! prepare bisection of the smallest interval.
!
150 if(numrl2.eq.1) noext = .true.
if(ier.ge.5) go to 170
155 maxerr = iord(1)
errmax = elist(maxerr)
nrmax = 1
extrap = .false.
levmax = levmax+1
erlarg = errsum
160 continue
!
! set the final result.
!
170 continue
if(abserr.eq.oflow) go to 190
if((ier+ierro).eq.0) go to 180
if(ierro.eq.3) abserr = abserr+correc
if(ier.eq.0) ier = 3
if(result.ne.0.0D+00.and.area.ne.0.0D+00)go to 175
if(abserr.gt.errsum)go to 190
if(area.eq.0.0D+00) go to 210
go to 180
175 if(abserr/ abs ( result).gt.errsum/ abs ( area))go to 190
!
! test on divergence.
!
180 if(ksgn.eq.(-1).and. max ( abs ( result), abs ( area)).le. &
resabs*0.1D-01) go to 210
if(0.1D-01.gt.(result/area).or.(result/area).gt.0.1D+03.or. &
errsum.gt. abs ( area)) ier = 6
go to 210
!
! compute global integral sum.
!
190 result = 0.0D+00
do k = 1,last
result = result+rlist(k)
end do
abserr = errsum
210 if(ier.gt.2) ier = ier-1
result = result*sgn
return
end subroutine dqagpe
!----------------------------------------------------------------------------------------
!> DQAGP computes a definite integral.
!!
!! Modified:
!!
!! 11 September 2015
!!
!! Author:
!!
!! Robert Piessens, Elise de Doncker
!!
!!***purpose the routine calculates an approximation result to a given
!! definite integral i = integral of f over (a,b),
!! hopefully satisfying following claim for accuracy
!! break points of the integration interval, where local
!! difficulties of the integrand may occur (e.g.
!! singularities, discontinuities), are provided by the user.
!!
!! Parameters:
!!
!! on entry
!! f - real ( kind = 8 )
!! function subprogram defining the integrand
!! function f(x). the actual name for f needs to be
!! declared e x t e r n a l in the driver program.
!!
!! a - real ( kind = 8 )
!! lower limit of integration
!!
!! b - real ( kind = 8 )
!! upper limit of integration
!!
!! npts2 - integer ( kind = 4 )
!! number equal to two more than the number of
!! user-supplied break points within the integration
!! range, npts.ge.2.
!! if npts2.lt.2, the routine will end with ier = 6.
!!
!! points - real ( kind = 8 )
!! vector of dimension npts2, the first (npts2-2)
!! elements of which are the user provided break
!! points. if these points do not constitute an
!! ascending sequence there will be an automatic
!! sorting.
!!
!! epsabs - real ( kind = 8 )
!! absolute accuracy requested
!! epsrel - real ( kind = 8 )
!! relative accuracy requested
!! if epsabs.le.0
!! and epsrel.lt.max(50*rel.mach.acc.,0.5d-28),
!! the routine will end with ier = 6.
!!
!! on return
!! result - real ( kind = 8 )
!! approximation to the integral
!!
!! abserr - real ( kind = 8 )
!! estimate of the modulus of the absolute error,
!! which should equal or exceed abs(i-result)
!!
!! neval - integer ( kind = 4 )
!! number of integrand evaluations
!!
!! ier - integer ( kind = 4 )
!! ier = 0 normal and reliable termination of the
!! routine. it is assumed that the requested
!! accuracy has been achieved.
!! ier.gt.0 abnormal termination of the routine.
!! the estimates for integral and error are
!! less reliable. it is assumed that the
!! requested accuracy has not been achieved.
!! error messages
!! ier = 1 maximum number of subdivisions allowed
!! has been achieved. one can allow more
!! subdivisions by increasing the value of
!! limit (and taking the according dimension
!! adjustments into account). however, if
!! this yields no improvement it is advised
!! to analyze the integrand in order to
!! determine the integration difficulties. if
!! the position of a local difficulty can be
!! determined (i.e. singularity,
!! discontinuity within the interval), it
!! should be supplied to the routine as an
!! element of the vector points. if necessary
!! an appropriate special-purpose integrator
!! must be used, which is designed for
!! handling the type of difficulty involved.
!! = 2 the occurrence of roundoff error is
!! detected, which prevents the requested
!! tolerance from being achieved.
!! the error may be under-estimated.
!! = 3 extremely bad integrand behaviour occurs
!! at some points of the integration
!! interval.
!! = 4 the algorithm does not converge.
!! roundoff error is detected in the
!! extrapolation table.
!! it is presumed that the requested
!! tolerance cannot be achieved, and that
!! the returned result is the best which
!! can be obtained.
!! = 5 the integral is probably divergent, or
!! slowly convergent. it must be noted that
!! divergence can occur with any other value
!! of ier.gt.0.
!! = 6 the input is invalid because
!! npts2.lt.2 or
!! break points are specified outside
!! the integration range or
!! (epsabs.le.0 and
!! epsrel.lt.max(50*rel.mach.acc.,0.5d-28))
!! result, abserr, neval, last are set to
!! zero. exept when leniw or lenw or npts2 is
!! invalid, iwork(1), iwork(limit+1),
!! work(limit*2+1) and work(limit*3+1)
!! are set to zero.
!! work(1) is set to a and work(limit+1)
!! to b (where limit = (leniw-npts2)/2).
!!
!! dimensioning parameters
!! leniw - integer ( kind = 4 )
!! dimensioning parameter for iwork
!! leniw determines limit = (leniw-npts2)/2,
!! which is the maximum number of subintervals in the
!! partition of the given integration interval (a,b),
!! leniw.ge.(3*npts2-2).
!! if leniw.lt.(3*npts2-2), the routine will end with
!! ier = 6.
!!
!! lenw - integer ( kind = 4 )
!! dimensioning parameter for work
!! lenw must be at least leniw*2-npts2.
!! if lenw.lt.leniw*2-npts2, the routine will end
!! with ier = 6.
!!
!! last - integer ( kind = 4 )
!! on return, last equals the number of subintervals
!! produced in the subdivision process, which
!! determines the number of significant elements
!! actually in the work arrays.
!!
!! work arrays
!! iwork - integer ( kind = 4 )
!! vector of dimension at least leniw. on return,
!! the first k elements of which contain
!! pointers to the error estimates over the
!! subintervals, such that work(limit*3+iwork(1)),...,
!! work(limit*3+iwork(k)) form a decreasing
!! sequence, with k = last if last.le.(limit/2+2), and
!! k = limit+1-last otherwise
!! iwork(limit+1), ...,iwork(limit+last) contain the
!! subdivision levels of the subintervals, i.e.
!! if (aa,bb) is a subinterval of (p1,p2)
!! where p1 as well as p2 is a user-provided
!! break point or integration limit, then (aa,bb) has
!! level l if abs(bb-aa) = abs(p2-p1)*2**(-l),
!! iwork(limit*2+1), ..., iwork(limit*2+npts2) have
!! no significance for the user,
!! note that limit = (leniw-npts2)/2.
!!
!! work - real ( kind = 8 )
!! vector of dimension at least lenw
!! on return
!! work(1), ..., work(last) contain the left
!! end points of the subintervals in the
!! partition of (a,b),
!! work(limit+1), ..., work(limit+last) contain
!! the right end points,
!! work(limit*2+1), ..., work(limit*2+last) contain
!! the integral approximations over the subintervals,
!! work(limit*3+1), ..., work(limit*3+last)
!! contain the corresponding error estimates,
!! work(limit*4+1), ..., work(limit*4+npts2)
!! contain the integration limits and the
!! break points sorted in an ascending sequence.
!! note that limit = (leniw-npts2)/2.
!!
subroutine dqagp ( f, a, b, npts2, points, epsabs, epsrel, result, abserr, &
neval, ier, leniw, lenw, last, iwork, work )
implicit none
real ( kind = 8 ) a,abserr,b,epsabs,epsrel,f,points,result,work
integer ( kind = 4 ) ier,iwork,last,leniw,lenw,limit,lvl,l1,l2,l3, &
l4,neval,npts2
dimension iwork(leniw),points(npts2),work(lenw)
external f
!
! check validity of limit and lenw.
!
ier = 6
neval = 0
last = 0
result = 0.0D+00
abserr = 0.0D+00
if(leniw.lt.(3*npts2-2).or.lenw.lt.(leniw*2-npts2).or.npts2.lt.2) &
go to 10
!
! prepare call for dqagpe.
!
limit = (leniw-npts2)/2
l1 = limit+1
l2 = limit+l1
l3 = limit+l2
l4 = limit+l3
call dqagpe(f,a,b,npts2,points,epsabs,epsrel,limit,result,abserr, &
neval,ier,work(1),work(l1),work(l2),work(l3),work(l4), &
iwork(1),iwork(l1),iwork(l2),last)
!
! call error handler if necessary.
!
lvl = 0
10 if(ier.eq.6) lvl = 1
if(ier.ne.0) then
call xerror('abnormal return from dqagp',26,ier,lvl)
end if
return
end subroutine dqagp
!----------------------------------------------------------------------------------------
!> DQAGSE estimates the integral of a function.
!!
!! Modified:
!!
!! 11 September 2015
!!
!! Author:
!!
!! Robert Piessens, Elise de Doncker
!!
!!***purpose the routine calculates an approximation result to a given
!! definite integral i = integral of f over (a,b),
!! hopefully satisfying following claim for accuracy
!! abs(i-result).le.max(epsabs,epsrel*abs(i)).
!!
!! Parameters:
!!
!! on entry
!! f - real ( kind = 8 )
!! function subprogram defining the integrand
!! function f(x). the actual name for f needs to be
!! declared e x t e r n a l in the driver program.
!!
!! a - real ( kind = 8 )
!! lower limit of integration
!!
!! b - real ( kind = 8 )
!! upper limit of integration
!!
!! epsabs - real ( kind = 8 )
!! absolute accuracy requested
!! epsrel - real ( kind = 8 )
!! relative accuracy requested
!! if epsabs.le.0
!! and epsrel.lt.max(50*rel.mach.acc.,0.5d-28),
!! the routine will end with ier = 6.
!!
!! limit - integer ( kind = 4 )
!! gives an upperbound on the number of subintervals
!! in the partition of (a,b)
!!
!! on return
!! result - real ( kind = 8 )
!! approximation to the integral
!!
!! abserr - real ( kind = 8 )
!! estimate of the modulus of the absolute error,
!! which should equal or exceed abs(i-result)
!!
!! neval - integer ( kind = 4 )
!! number of integrand evaluations
!!
!! ier - integer ( kind = 4 )
!! ier = 0 normal and reliable termination of the
!! routine. it is assumed that the requested
!! accuracy has been achieved.
!! ier.gt.0 abnormal termination of the routine
!! the estimates for integral and error are
!! less reliable. it is assumed that the
!! requested accuracy has not been achieved.
!! error messages
!! = 1 maximum number of subdivisions allowed
!! has been achieved. one can allow more sub-
!! divisions by increasing the value of limit
!! (and taking the according dimension
!! adjustments into account). however, if
!! this yields no improvement it is advised
!! to analyze the integrand in order to
!! determine the integration difficulties. if
!! the position of a local difficulty can be
!! determined (e.g. singularity,
!! discontinuity within the interval) one
!! will probably gain from splitting up the
!! interval at this point and calling the
!! integrator on the subranges. if possible,
!! an appropriate special-purpose integrator
!! should be used, which is designed for
!! handling the type of difficulty involved.
!! = 2 the occurrence of roundoff error is detec-
!! ted, which prevents the requested
!! tolerance from being achieved.
!! the error may be under-estimated.
!! = 3 extremely bad integrand behaviour
!! occurs at some points of the integration
!! interval.
!! = 4 the algorithm does not converge.
!! roundoff error is detected in the
!! extrapolation table.
!! it is presumed that the requested
!! tolerance cannot be achieved, and that the
!! returned result is the best which can be
!! obtained.
!! = 5 the integral is probably divergent, or
!! slowly convergent. it must be noted that
!! divergence can occur with any other value
!! of ier.
!! = 6 the input is invalid, because
!! epsabs.le.0 and
!! epsrel.lt.max(50*rel.mach.acc.,0.5d-28).
!! result, abserr, neval, last, rlist(1),
!! iord(1) and elist(1) are set to zero.
!! alist(1) and blist(1) are set to a and b
!! respectively.
!!
!! alist - real ( kind = 8 )
!! vector of dimension at least limit, the first
!! last elements of which are the left end points
!! of the subintervals in the partition of the
!! given integration range (a,b)
!!
!! blist - real ( kind = 8 )
!! vector of dimension at least limit, the first
!! last elements of which are the right end points
!! of the subintervals in the partition of the given
!! integration range (a,b)
!!
!! rlist - real ( kind = 8 )
!! vector of dimension at least limit, the first
!! last elements of which are the integral
!! approximations on the subintervals
!!
!! elist - real ( kind = 8 )
!! vector of dimension at least limit, the first
!! last elements of which are the moduli of the
!! absolute error estimates on the subintervals
!!
!! iord - integer ( kind = 4 )
!! vector of dimension at least limit, the first k
!! elements of which are pointers to the
!! error estimates over the subintervals,
!! such that elist(iord(1)), ..., elist(iord(k))
!! form a decreasing sequence, with k = last
!! if last.le.(limit/2+2), and k = limit+1-last
!! otherwise
!!
!! last - integer ( kind = 4 )
!! number of subintervals actually produced in the
!! subdivision process
!!
!! Local parameters:
!!
!! the dimension of rlist2 is determined by the value of
!! limexp in routine dqelg (rlist2 should be of dimension
!! (limexp+2) at least).
!!
!! list of major variables
!!
!! alist - list of left end points of all subintervals
!! considered up to now
!! blist - list of right end points of all subintervals
!! considered up to now
!! rlist(i) - approximation to the integral over
!! (alist(i),blist(i))
!! rlist2 - array of dimension at least limexp+2 containing
!! the part of the epsilon table which is still
!! needed for further computations
!! elist(i) - error estimate applying to rlist(i)
!! maxerr - pointer to the interval with largest error
!! estimate
!! errmax - elist(maxerr)
!! erlast - error on the interval currently subdivided
!! (before that subdivision has taken place)
!! area - sum of the integrals over the subintervals
!! errsum - sum of the errors over the subintervals
!! errbnd - requested accuracy max(epsabs,epsrel*
!! abs(result))
!! *****1 - variable for the left interval
!! *****2 - variable for the right interval
!! last - index for subdivision
!! nres - number of calls to the extrapolation routine
!! numrl2 - number of elements currently in rlist2. if an
!! appropriate approximation to the compounded
!! integral has been obtained it is put in
!! rlist2(numrl2) after numrl2 has been increased
!! by one.
!! small - length of the smallest interval considered up
!! to now, multiplied by 1.5
!! erlarg - sum of the errors over the intervals larger
!! than the smallest interval considered up to now
!! extrap - logical variable denoting that the routine is
!! attempting to perform extrapolation i.e. before
!! subdividing the smallest interval we try to
!! decrease the value of erlarg.
!! noext - logical variable denoting that extrapolation
!! is no longer allowed (true value)
!!
!! machine dependent constants
!!
!! epmach is the largest relative spacing.
!! uflow is the smallest positive magnitude.
!! oflow is the largest positive magnitude.
!!
subroutine dqagse(f,a,b,epsabs,epsrel,limit,result,abserr,neval, &
ier,alist,blist,rlist,elist,iord,last)
implicit none
real ( kind = 8 ) a,abseps,abserr,alist,area,area1,area12,area2,a1, &
a2,b,blist,b1,b2,correc,defabs,defab1,defab2, &
dres,elist,epmach,epsabs,epsrel,erlarg,erlast,errbnd,errmax, &
error1,error2,erro12,errsum,ertest,f,oflow,resabs,reseps,result, &
res3la,rlist,rlist2,small,uflow
integer ( kind = 4 ) id,ier,ierro,iord,iroff1,iroff2,iroff3,jupbnd, &
k,ksgn,ktmin,last,limit,maxerr,neval,nres,nrmax,numrl2
logical extrap,noext
dimension alist(limit),blist(limit),elist(limit),iord(limit), &
res3la(3),rlist(limit),rlist2(52)
external f
epmach = epsilon ( epmach )
!
! test on validity of parameters
!
ier = 0
neval = 0
last = 0
result = 0.0D+00
abserr = 0.0D+00
alist(1) = a
blist(1) = b
rlist(1) = 0.0D+00
elist(1) = 0.0D+00
if(epsabs.le.0.0D+00.and.epsrel.lt. max ( 0.5D+02*epmach,0.5d-28)) then
ier = 6
return
end if
!
! first approximation to the integral
!
uflow = tiny ( uflow )
oflow = huge ( oflow )
ierro = 0
call dqk21(f,a,b,result,abserr,defabs,resabs)
!
! test on accuracy.
!
dres = abs ( result)
errbnd = max ( epsabs,epsrel*dres)
last = 1
rlist(1) = result
elist(1) = abserr
iord(1) = 1
if(abserr.le.1.0D+02*epmach*defabs.and.abserr.gt.errbnd) ier = 2
if(limit.eq.1) ier = 1
if(ier.ne.0.or.(abserr.le.errbnd.and.abserr.ne.resabs).or. &
abserr.eq.0.0D+00) go to 140
!
! initialization
!
rlist2(1) = result
errmax = abserr
maxerr = 1
area = result
errsum = abserr
abserr = oflow
nrmax = 1
nres = 0
numrl2 = 2
ktmin = 0
extrap = .false.
noext = .false.
iroff1 = 0
iroff2 = 0
iroff3 = 0
ksgn = -1
if(dres.ge.(0.1D+01-0.5D+02*epmach)*defabs) ksgn = 1
!
! main do-loop
!
do 90 last = 2,limit
!
! bisect the subinterval with the nrmax-th largest error estimate.
!
a1 = alist(maxerr)
b1 = 0.5D+00*(alist(maxerr)+blist(maxerr))
a2 = b1
b2 = blist(maxerr)
erlast = errmax
call dqk21(f,a1,b1,area1,error1,resabs,defab1)
call dqk21(f,a2,b2,area2,error2,resabs,defab2)
!
! improve previous approximations to integral
! and error and test for accuracy.
!
area12 = area1+area2
erro12 = error1+error2
errsum = errsum+erro12-errmax
area = area+area12-rlist(maxerr)
if(defab1.eq.error1.or.defab2.eq.error2) go to 15
if( abs ( rlist(maxerr)-area12).gt.0.1D-04* abs ( area12) &
.or.erro12.lt.0.99D+00*errmax) go to 10
if(extrap) iroff2 = iroff2+1
if(.not.extrap) iroff1 = iroff1+1
10 if(last.gt.10.and.erro12.gt.errmax) iroff3 = iroff3+1
15 rlist(maxerr) = area1
rlist(last) = area2
errbnd = max ( epsabs,epsrel* abs ( area))
!
! test for roundoff error and eventually set error flag.
!
if(iroff1+iroff2.ge.10.or.iroff3.ge.20) ier = 2
if(iroff2.ge.5) ierro = 3
!
! set error flag in the case that the number of subintervals
! equals limit.
!
if(last.eq.limit) ier = 1
!
! set error flag in the case of bad integrand behaviour
! at a point of the integration range.
!
if( max ( abs ( a1), abs ( b2)).le.(0.1D+01+0.1D+03*epmach)* &
( abs ( a2)+0.1D+04*uflow)) ier = 4
!
! append the newly-created intervals to the list.
!
if(error2.gt.error1) go to 20
alist(last) = a2
blist(maxerr) = b1
blist(last) = b2
elist(maxerr) = error1
elist(last) = error2
go to 30
20 alist(maxerr) = a2
alist(last) = a1
blist(last) = b1
rlist(maxerr) = area2
rlist(last) = area1
elist(maxerr) = error2
elist(last) = error1
!
! call dqpsrt to maintain the descending ordering
! in the list of error estimates and select the subinterval
! with nrmax-th largest error estimate (to be bisected next).
!
30 call dqpsrt(limit,last,maxerr,errmax,elist,iord,nrmax)
if(errsum.le.errbnd) go to 115
if(ier.ne.0) go to 100
if(last.eq.2) go to 80
if(noext) go to 90
erlarg = erlarg-erlast
if( abs ( b1-a1).gt.small) erlarg = erlarg+erro12
if(extrap) go to 40
!
! test whether the interval to be bisected next is the
! smallest interval.
!
if( abs ( blist(maxerr)-alist(maxerr)).gt.small) go to 90
extrap = .true.
nrmax = 2
40 if(ierro.eq.3.or.erlarg.le.ertest) go to 60
!
! the smallest interval has the largest error.
! before bisecting decrease the sum of the errors over the
! larger intervals (erlarg) and perform extrapolation.
!
id = nrmax
jupbnd = last
if(last.gt.(2+limit/2)) jupbnd = limit+3-last
do k = id,jupbnd
maxerr = iord(nrmax)
errmax = elist(maxerr)
if( abs ( blist(maxerr)-alist(maxerr)).gt.small) go to 90
nrmax = nrmax+1
end do
!
! perform extrapolation.
!
60 numrl2 = numrl2+1
rlist2(numrl2) = area
call dqelg(numrl2,rlist2,reseps,abseps,res3la,nres)
ktmin = ktmin+1
if(ktmin.gt.5.and.abserr.lt.0.1D-02*errsum) ier = 5
if(abseps.ge.abserr) go to 70
ktmin = 0
abserr = abseps
result = reseps
correc = erlarg
ertest = max ( epsabs,epsrel* abs ( reseps))
if(abserr.le.ertest) go to 100
!
! prepare bisection of the smallest interval.
!
70 if(numrl2.eq.1) noext = .true.
if(ier.eq.5) go to 100
maxerr = iord(1)
errmax = elist(maxerr)
nrmax = 1
extrap = .false.
small = small*0.5D+00
erlarg = errsum
go to 90
80 small = abs ( b-a)*0.375D+00
erlarg = errsum
ertest = errbnd
rlist2(2) = area
90 continue
!
! set final result and error estimate.
!
100 if(abserr.eq.oflow) go to 115
if(ier+ierro.eq.0) go to 110
if(ierro.eq.3) abserr = abserr+correc
if(ier.eq.0) ier = 3
if(result.ne.0.0D+00.and.area.ne.0.0D+00) go to 105
if(abserr.gt.errsum) go to 115
if(area.eq.0.0D+00) go to 130
go to 110
105 if(abserr/ abs ( result).gt.errsum/ abs ( area)) go to 115
!
! test on divergence.
!
110 if(ksgn.eq.(-1).and. max ( abs ( result), abs ( area)).le. &
defabs*0.1D-01) go to 130
if(0.1D-01.gt.(result/area).or.(result/area).gt.0.1D+03 &
.or.errsum.gt. abs ( area)) ier = 6
go to 130
!
! compute global integral sum.
!
115 result = 0.0D+00
do k = 1,last
result = result+rlist(k)
end do
abserr = errsum
130 if(ier.gt.2) ier = ier-1
140 neval = 42*last-21
return
end subroutine dqagse
!----------------------------------------------------------------------------------------
!> DQAGS estimates the integral of a function.
!!
!! Modified:
!!
!! 11 September 2015
!!
!! Author:
!!
!! Robert Piessens, Elise de Doncker
!!
!!***purpose the routine calculates an approximation result to a given
!! definite integral i = integral of f over (a,b),
!! hopefully satisfying following claim for accuracy
!! abs(i-result).le.max(epsabs,epsrel*abs(i)).
!!
!! Parameters:
!!
!! on entry
!! f - real ( kind = 8 )
!! function subprogram defining the integrand
!! function f(x). the actual name for f needs to be
!! declared e x t e r n a l in the driver program.
!!
!! a - real ( kind = 8 )
!! lower limit of integration
!!
!! b - real ( kind = 8 )
!! upper limit of integration
!!
!! epsabs - real ( kind = 8 )
!! absolute accuracy requested
!! epsrel - real ( kind = 8 )
!! relative accuracy requested
!! if epsabs.le.0
!! and epsrel.lt.max(50*rel.mach.acc.,0.5d-28),
!! the routine will end with ier = 6.
!!
!! on return
!! result - real ( kind = 8 )
!! approximation to the integral
!!
!! abserr - real ( kind = 8 )
!! estimate of the modulus of the absolute error,
!! which should equal or exceed abs(i-result)
!!
!! neval - integer ( kind = 4 )
!! number of integrand evaluations
!!
!! ier - integer ( kind = 4 )
!! ier = 0 normal and reliable termination of the
!! routine. it is assumed that the requested
!! accuracy has been achieved.
!! ier.gt.0 abnormal termination of the routine
!! the estimates for integral and error are
!! less reliable. it is assumed that the
!! requested accuracy has not been achieved.
!! error messages
!! ier = 1 maximum number of subdivisions allowed
!! has been achieved. one can allow more sub-
!! divisions by increasing the value of limit
!! (and taking the according dimension
!! adjustments into account. however, if
!! this yields no improvement it is advised
!! to analyze the integrand in order to
!! determine the integration difficulties. if
!! the position of a local difficulty can be
!! determined (e.g. singularity,
!! discontinuity within the interval) one
!! will probably gain from splitting up the
!! interval at this point and calling the
!! integrator on the subranges. if possible,
!! an appropriate special-purpose integrator
!! should be used, which is designed for
!! handling the type of difficulty involved.
!! = 2 the occurrence of roundoff error is detec-
!! ted, which prevents the requested
!! tolerance from being achieved.
!! the error may be under-estimated.
!! = 3 extremely bad integrand behaviour
!! occurs at some points of the integration
!! interval.
!! = 4 the algorithm does not converge.
!! roundoff error is detected in the
!! extrapolation table. it is presumed that
!! the requested tolerance cannot be
!! achieved, and that the returned result is
!! the best which can be obtained.
!! = 5 the integral is probably divergent, or
!! slowly convergent. it must be noted that
!! divergence can occur with any other value
!! of ier.
!! = 6 the input is invalid, because
!! (epsabs.le.0 and
!! epsrel.lt.max(50*rel.mach.acc.,0.5d-28)
!! or limit.lt.1 or lenw.lt.limit*4.
!! result, abserr, neval, last are set to
!! zero.except when limit or lenw is invalid,
!! iwork(1), work(limit*2+1) and
!! work(limit*3+1) are set to zero, work(1)
!! is set to a and work(limit+1) to b.
!!
!! dimensioning parameters
!! limit - integer ( kind = 4 )
!! dimensioning parameter for iwork
!! limit determines the maximum number of subintervals
!! in the partition of the given integration interval
!! (a,b), limit.ge.1.
!! if limit.lt.1, the routine will end with ier = 6.
!!
!! lenw - integer ( kind = 4 )
!! dimensioning parameter for work
!! lenw must be at least limit*4.
!! if lenw.lt.limit*4, the routine will end
!! with ier = 6.
!!
!! last - integer ( kind = 4 )
!! on return, last equals the number of subintervals
!! produced in the subdivision process, detemines the
!! number of significant elements actually in the work
!! arrays.
!!
!! work arrays
!! iwork - integer ( kind = 4 )
!! vector of dimension at least limit, the first k
!! elements of which contain pointers
!! to the error estimates over the subintervals
!! such that work(limit*3+iwork(1)),... ,
!! work(limit*3+iwork(k)) form a decreasing
!! sequence, with k = last if last.le.(limit/2+2),
!! and k = limit+1-last otherwise
!!
!! work - real ( kind = 8 )
!! vector of dimension at least lenw
!! on return
!! work(1), ..., work(last) contain the left
!! end-points of the subintervals in the
!! partition of (a,b),
!! work(limit+1), ..., work(limit+last) contain
!! the right end-points,
!! work(limit*2+1), ..., work(limit*2+last) contain
!! the integral approximations over the subintervals,
!! work(limit*3+1), ..., work(limit*3+last)
!! contain the error estimates.
!!
subroutine dqags ( f, a, b, epsabs, epsrel, result, abserr, neval, ier, &
limit, lenw, last, iwork, work )
implicit none
real ( kind = 8 ) a,abserr,b,epsabs,epsrel,f,result,work
integer ( kind = 4 ) ier,iwork,last,lenw,limit,lvl,l1,l2,l3,neval
dimension iwork(limit),work(lenw)
external f
!
! check validity of limit and lenw.
!
ier = 6
neval = 0
last = 0
result = 0.0D+00
abserr = 0.0D+00
if(limit.lt.1.or.lenw.lt.limit*4) go to 10
!
! prepare call for dqagse.
!
l1 = limit+1
l2 = limit+l1
l3 = limit+l2
call dqagse(f,a,b,epsabs,epsrel,limit,result,abserr,neval, &
ier,work(1),work(l1),work(l2),work(l3),iwork,last)
!
! call error handler if necessary.
!
lvl = 0
10 if(ier.eq.6) lvl = 1
if(ier.ne.0) call xerror('abnormal return from dqags',26,ier,lvl)
return
end subroutine dqags
!----------------------------------------------------------------------------------------
!> DQAWCE computes a Cauchy principal value.
!!
!! Modified:
!!
!! 11 September 2015
!!
!! Author:
!!
!! Robert Piessens, Elise de Doncker
!!
!!*** purpose the routine calculates an approximation result to a
!! cauchy principal value i = integral of f*w over (a,b)
!! (w(x) = 1/(x-c), (c.ne.a, c.ne.b), hopefully satisfying
!! following claim for accuracy
!! abs(i-result).le.max(epsabs,epsrel*abs(i))
!!
!! Parameters:
!!
!! on entry
!! f - real ( kind = 8 )
!! function subprogram defining the integrand
!! function f(x). the actual name for f needs to be
!! declared e x t e r n a l in the driver program.
!!
!! a - real ( kind = 8 )
!! lower limit of integration
!!
!! b - real ( kind = 8 )
!! upper limit of integration
!!
!! c - real ( kind = 8 )
!! parameter in the weight function, c.ne.a, c.ne.b
!! if c = a or c = b, the routine will end with
!! ier = 6.
!!
!! epsabs - real ( kind = 8 )
!! absolute accuracy requested
!! epsrel - real ( kind = 8 )
!! relative accuracy requested
!! if epsabs.le.0
!! and epsrel.lt.max(50*rel.mach.acc.,0.5d-28),
!! the routine will end with ier = 6.
!!
!! limit - integer ( kind = 4 )
!! gives an upper bound on the number of subintervals
!! in the partition of (a,b), limit.ge.1
!!
!! on return
!! result - real ( kind = 8 )
!! approximation to the integral
!!
!! abserr - real ( kind = 8 )
!! estimate of the modulus of the absolute error,
!! which should equal or exceed abs(i-result)
!!
!! neval - integer ( kind = 4 )
!! number of integrand evaluations
!!
!! ier - integer ( kind = 4 )
!! ier = 0 normal and reliable termination of the
!! routine. it is assumed that the requested
!! accuracy has been achieved.
!! ier.gt.0 abnormal termination of the routine
!! the estimates for integral and error are
!! less reliable. it is assumed that the
!! requested accuracy has not been achieved.
!! error messages
!! ier = 1 maximum number of subdivisions allowed
!! has been achieved. one can allow more sub-
!! divisions by increasing the value of
!! limit. however, if this yields no
!! improvement it is advised to analyze the
!! the integrand, in order to determine the
!! the integration difficulties. if the
!! position of a local difficulty can be
!! determined (e.g. singularity,
!! discontinuity within the interval) one
!! will probably gain from splitting up the
!! interval at this point and calling
!! appropriate integrators on the subranges.
!! = 2 the occurrence of roundoff error is detec-
!! ted, which prevents the requested
!! tolerance from being achieved.
!! = 3 extremely bad integrand behaviour
!! occurs at some interior points of
!! the integration interval.
!! = 6 the input is invalid, because
!! c = a or c = b or
!! (epsabs.le.0 and
!! epsrel.lt.max(50*rel.mach.acc.,0.5d-28))
!! or limit.lt.1.
!! result, abserr, neval, rlist(1), elist(1),
!! iord(1) and last are set to zero. alist(1)
!! and blist(1) are set to a and b
!! respectively.
!!
!! alist - real ( kind = 8 )
!! vector of dimension at least limit, the first
!! last elements of which are the left
!! end points of the subintervals in the partition
!! of the given integration range (a,b)
!!
!! blist - real ( kind = 8 )
!! vector of dimension at least limit, the first
!! last elements of which are the right
!! end points of the subintervals in the partition
!! of the given integration range (a,b)
!!
!! rlist - real ( kind = 8 )
!! vector of dimension at least limit, the first
!! last elements of which are the integral
!! approximations on the subintervals
!!
!! elist - real ( kind = 8 )
!! vector of dimension limit, the first last
!! elements of which are the moduli of the absolute
!! error estimates on the subintervals
!!
!! iord - integer ( kind = 4 )
!! vector of dimension at least limit, the first k
!! elements of which are pointers to the error
!! estimates over the subintervals, so that
!! elist(iord(1)), ..., elist(iord(k)) with k = last
!! if last.le.(limit/2+2), and k = limit+1-last
!! otherwise, form a decreasing sequence
!!
!! last - integer ( kind = 4 )
!! number of subintervals actually produced in
!! the subdivision process
!!
!! Local Parameters:
!!
!! alist - list of left end points of all subintervals
!! considered up to now
!! blist - list of right end points of all subintervals
!! considered up to now
!! rlist(i) - approximation to the integral over
!! (alist(i),blist(i))
!! elist(i) - error estimate applying to rlist(i)
!! maxerr - pointer to the interval with largest
!! error estimate
!! errmax - elist(maxerr)
!! area - sum of the integrals over the subintervals
!! errsum - sum of the errors over the subintervals
!! errbnd - requested accuracy max(epsabs,epsrel*
!! abs(result))
!! *****1 - variable for the left subinterval
!! *****2 - variable for the right subinterval
!! last - index for subdivision
!!
!!
!! machine dependent constants
!!
!! epmach is the largest relative spacing.
!! uflow is the smallest positive magnitude.
!!
subroutine dqawce(f,a,b,c,epsabs,epsrel,limit,result,abserr,neval, &
ier,alist,blist,rlist,elist,iord,last)
implicit none
real ( kind = 8 ) a,aa,abserr,alist,area,area1,area12,area2,a1,a2, &
b,bb,blist,b1,b2,c,elist,epmach,epsabs,epsrel, &
errbnd,errmax,error1,erro12,error2,errsum,f,result,rlist,uflow
integer ( kind = 4 ) ier,iord,iroff1,iroff2,k,krule,last,limit,&
maxerr, nev, &
neval,nrmax
dimension alist(limit),blist(limit),rlist(limit),elist(limit), &
iord(limit)
external f
epmach = epsilon ( epmach )
uflow = tiny ( uflow )
!
! test on validity of parameters
!
ier = 6
neval = 0
last = 0
alist(1) = a
blist(1) = b
rlist(1) = 0.0D+00
elist(1) = 0.0D+00
iord(1) = 0
result = 0.0D+00
abserr = 0.0D+00
if ( c.eq.a .or. &
c.eq.b .or. &
(epsabs.le.0.0D+00 .and. epsrel.lt. max ( 0.5D+02*epmach,0.5d-28)) ) then
ier = 6
return
end if
!
! first approximation to the integral
!
if ( a <= b ) then
aa=a
bb=b
else
aa=b
bb=a
end if
ier=0
krule = 1
call dqc25c(f,aa,bb,c,result,abserr,krule,neval)
last = 1
rlist(1) = result
elist(1) = abserr
iord(1) = 1
alist(1) = a
blist(1) = b
!
! test on accuracy
!
errbnd = max ( epsabs,epsrel* abs ( result))
if(limit.eq.1) ier = 1
if(abserr.lt. min (0.1D-01* abs ( result),errbnd) &
.or.ier.eq.1) go to 70
!
! initialization
!
alist(1) = aa
blist(1) = bb
rlist(1) = result
errmax = abserr
maxerr = 1
area = result
errsum = abserr
nrmax = 1
iroff1 = 0
iroff2 = 0
!
! main do-loop
!
do 40 last = 2,limit
!
! bisect the subinterval with nrmax-th largest error estimate.
!
a1 = alist(maxerr)
b1 = 0.5D+00*(alist(maxerr)+blist(maxerr))
b2 = blist(maxerr)
if(c.le.b1.and.c.gt.a1) b1 = 0.5D+00*(c+b2)
if(c.gt.b1.and.c.lt.b2) b1 = 0.5D+00*(a1+c)
a2 = b1
krule = 2
call dqc25c(f,a1,b1,c,area1,error1,krule,nev)
neval = neval+nev
call dqc25c(f,a2,b2,c,area2,error2,krule,nev)
neval = neval+nev
!
! improve previous approximations to integral
! and error and test for accuracy.
!
area12 = area1+area2
erro12 = error1+error2
errsum = errsum+erro12-errmax
area = area+area12-rlist(maxerr)
if( abs ( rlist(maxerr)-area12).lt.0.1D-04* abs ( area12) &
.and.erro12.ge.0.99D+00*errmax.and.krule.eq.0) &
iroff1 = iroff1+1
if(last.gt.10.and.erro12.gt.errmax.and.krule.eq.0) &
iroff2 = iroff2+1
rlist(maxerr) = area1
rlist(last) = area2
errbnd = max ( epsabs,epsrel* abs ( area))
if(errsum.le.errbnd) go to 15
!
! test for roundoff error and eventually set error flag.
!
if(iroff1.ge.6.and.iroff2.gt.20) ier = 2
!
! set error flag in the case that number of interval bisections exceeds limit.
!
if(last.eq.limit) ier = 1
!
! set error flag in the case of bad integrand behaviour
! at a point of the integration range.
!
if( max ( abs ( a1), abs ( b2)).le.(0.1D+01+0.1D+03*epmach) &
*( abs ( a2)+0.1D+04*uflow)) ier = 3
!
! append the newly-created intervals to the list.
!
15 continue
if ( error2 .le. error1 ) then
alist(last) = a2
blist(maxerr) = b1
blist(last) = b2
elist(maxerr) = error1
elist(last) = error2
else
alist(maxerr) = a2
alist(last) = a1
blist(last) = b1
rlist(maxerr) = area2
rlist(last) = area1
elist(maxerr) = error2
elist(last) = error1
end if
!
! call dqpsrt to maintain the descending ordering
! in the list of error estimates and select the subinterval
! with nrmax-th largest error estimate (to be bisected next).
!
call dqpsrt(limit,last,maxerr,errmax,elist,iord,nrmax)
if(ier.ne.0.or.errsum.le.errbnd) go to 50
40 continue
!
! compute final result.
!
50 continue
result = 0.0D+00
do k=1,last
result = result+rlist(k)
end do
abserr = errsum
70 if (aa.eq.b) result=-result
return
end subroutine dqawce
!----------------------------------------------------------------------------------------
!> DQAWC computes a Cauchy principal value.
!!
!! Modified:
!!
!! 11 September 2015
!!
!! Author:
!!
!! Robert Piessens, Elise de Doncker
!!
!!***purpose the routine calculates an approximation result to a
!! cauchy principal value i = integral of f*w over (a,b)
!! (w(x) = 1/((x-c), c.ne.a, c.ne.b), hopefully satisfying
!! following claim for accuracy
!! abs(i-result).le.max(epsabe,epsrel*abs(i)).
!!
!! Parameters:
!!
!! on entry
!! f - real ( kind = 8 )
!! function subprogram defining the integrand
!! function f(x). the actual name for f needs to be
!! declared e x t e r n a l in the driver program.
!!
!! a - real ( kind = 8 )
!! under limit of integration
!!
!! b - real ( kind = 8 )
!! upper limit of integration
!!
!! c - parameter in the weight function, c.ne.a, c.ne.b.
!! if c = a or c = b, the routine will end with
!! ier = 6 .
!!
!! epsabs - real ( kind = 8 )
!! absolute accuracy requested
!! epsrel - real ( kind = 8 )
!! relative accuracy requested
!! if epsabs.le.0
!! and epsrel.lt.max(50*rel.mach.acc.,0.5d-28),
!! the routine will end with ier = 6.
!!
!! on return
!! result - real ( kind = 8 )
!! approximation to the integral
!!
!! abserr - real ( kind = 8 )
!! estimate or the modulus of the absolute error,
!! which should equal or exceed abs(i-result)
!!
!! neval - integer ( kind = 4 )
!! number of integrand evaluations
!!
!! ier - integer ( kind = 4 )
!! ier = 0 normal and reliable termination of the
!! routine. it is assumed that the requested
!! accuracy has been achieved.
!! ier.gt.0 abnormal termination of the routine
!! the estimates for integral and error are
!! less reliable. it is assumed that the
!! requested accuracy has not been achieved.
!! error messages
!! ier = 1 maximum number of subdivisions allowed
!! has been achieved. one can allow more sub-
!! divisions by increasing the value of limit
!! (and taking the according dimension
!! adjustments into account). however, if
!! this yields no improvement it is advised
!! to analyze the integrand in order to
!! determine the integration difficulties.
!! if the position of a local difficulty
!! can be determined (e.g. singularity,
!! discontinuity within the interval) one
!! will probably gain from splitting up the
!! interval at this point and calling
!! appropriate integrators on the subranges.
!! = 2 the occurrence of roundoff error is detec-
!! ted, which prevents the requested
!! tolerance from being achieved.
!! = 3 extremely bad integrand behaviour occurs
!! at some points of the integration
!! interval.
!! = 6 the input is invalid, because
!! c = a or c = b or
!! (epsabs.le.0 and
!! epsrel.lt.max(50*rel.mach.acc.,0.5d-28))
!! or limit.lt.1 or lenw.lt.limit*4.
!! result, abserr, neval, last are set to
!! zero. exept when lenw or limit is invalid,
!! iwork(1), work(limit*2+1) and
!! work(limit*3+1) are set to zero, work(1)
!! is set to a and work(limit+1) to b.
!!
!! dimensioning parameters
!! limit - integer ( kind = 4 )
!! dimensioning parameter for iwork
!! limit determines the maximum number of subintervals
!! in the partition of the given integration interval
!! (a,b), limit.ge.1.
!! if limit.lt.1, the routine will end with ier = 6.
!!
!! lenw - integer ( kind = 4 )
!! dimensioning parameter for work
!! lenw must be at least limit*4.
!! if lenw.lt.limit*4, the routine will end with
!! ier = 6.
!!
!! last - integer ( kind = 4 )
!! on return, last equals the number of subintervals
!! produced in the subdivision process, which
!! determines the number of significant elements
!! actually in the work arrays.
!!
!! work arrays
!! iwork - integer ( kind = 4 )
!! vector of dimension at least limit, the first k
!! elements of which contain pointers
!! to the error estimates over the subintervals,
!! such that work(limit*3+iwork(1)), ... ,
!! work(limit*3+iwork(k)) form a decreasing
!! sequence, with k = last if last.le.(limit/2+2),
!! and k = limit+1-last otherwise
!!
!! work - real ( kind = 8 )
!! vector of dimension at least lenw
!! on return
!! work(1), ..., work(last) contain the left
!! end points of the subintervals in the
!! partition of (a,b),
!! work(limit+1), ..., work(limit+last) contain
!! the right end points,
!! work(limit*2+1), ..., work(limit*2+last) contain
!! the integral approximations over the subintervals,
!! work(limit*3+1), ..., work(limit*3+last)
!! contain the error estimates.
!!
subroutine dqawc ( f, a, b, c, epsabs, epsrel, result, abserr, neval, ier, &
limit, lenw, last, iwork, work )
implicit none
real ( kind = 8 ) a,abserr,b,c,epsabs,epsrel,f,result,work
integer ( kind = 4 ) ier,iwork,last,lenw,limit,lvl,l1,l2,l3,neval
dimension iwork(limit),work(lenw)
external f
!
! check validity of limit and lenw.
!
ier = 6
neval = 0
last = 0
result = 0.0D+00
abserr = 0.0D+00
if(limit.lt.1.or.lenw.lt.limit*4) go to 10
!
! prepare call for dqawce.
!
l1 = limit+1
l2 = limit+l1
l3 = limit+l2
call dqawce(f,a,b,c,epsabs,epsrel,limit,result,abserr,neval,ier, &
work(1),work(l1),work(l2),work(l3),iwork,last)
!
! call error handler if necessary.
!
lvl = 0
10 if(ier.eq.6) lvl = 1
if(ier.ne.0) then
call xerror('abnormal return from dqawc',26,ier,lvl)
end if
return
end subroutine dqawc
!----------------------------------------------------------------------------------------
!> DQAWFE computes Fourier integrals.
!!
!! Modified:
!!
!! 11 September 2015
!!
!! Author:
!!
!! Robert Piessens, Elise de Doncker
!!
!!***purpose the routine calculates an approximation result to a
!! given fourier integal
!! i = integral of f(x)*w(x) over (a,infinity)
!! where w(x)=cos(omega*x) or w(x)=sin(omega*x),
!! hopefully satisfying following claim for accuracy
!! abs(i-result).le.epsabs.
!!
!! Parameters:
!!
!! on entry
!! f - real ( kind = 8 )
!! function subprogram defining the integrand
!! function f(x). the actual name for f needs to
!! be declared e x t e r n a l in the driver program.
!!
!! a - real ( kind = 8 )
!! lower limit of integration
!!
!! omega - real ( kind = 8 )
!! parameter in the weight function
!!
!! integr - integer ( kind = 4 )
!! indicates which weight function is used
!! integr = 1 w(x) = cos(omega*x)
!! integr = 2 w(x) = sin(omega*x)
!! if integr.ne.1.and.integr.ne.2, the routine will
!! end with ier = 6.
!!
!! epsabs - real ( kind = 8 )
!! absolute accuracy requested, epsabs.gt.0
!! if epsabs.le.0, the routine will end with ier = 6.
!!
!! limlst - integer ( kind = 4 )
!! limlst gives an upper bound on the number of
!! cycles, limlst.ge.1.
!! if limlst.lt.3, the routine will end with ier = 6.
!!
!! limit - integer ( kind = 4 )
!! gives an upper bound on the number of subintervals
!! allowed in the partition of each cycle, limit.ge.1
!! each cycle, limit.ge.1.
!!
!! maxp1 - integer ( kind = 4 )
!! gives an upper bound on the number of
!! chebyshev moments which can be stored, i.e.
!! for the intervals of lengths abs(b-a)*2**(-l),
!! l=0,1, ..., maxp1-2, maxp1.ge.1
!!
!! on return
!! result - real ( kind = 8 )
!! approximation to the integral x
!!
!! abserr - real ( kind = 8 )
!! estimate of the modulus of the absolute error,
!! which should equal or exceed abs(i-result)
!!
!! neval - integer ( kind = 4 )
!! number of integrand evaluations
!!
!! ier - ier = 0 normal and reliable termination of
!! the routine. it is assumed that the
!! requested accuracy has been achieved.
!! ier.gt.0 abnormal termination of the routine. the
!! estimates for integral and error are less
!! reliable. it is assumed that the requested
!! accuracy has not been achieved.
!! error messages
!! if omega.ne.0
!! ier = 1 maximum number of cycles allowed
!! has been achieved., i.e. of subintervals
!! (a+(k-1)c,a+kc) where
!! c = (2*int(abs(omega))+1)*pi/abs(omega),
!! for k = 1, 2, ..., lst.
!! one can allow more cycles by increasing
!! the value of limlst (and taking the
!! according dimension adjustments into
!! account).
!! examine the array iwork which contains
!! the error flags on the cycles, in order to
!! look for eventual local integration
!! difficulties. if the position of a local
!! difficulty can be determined (e.g.
!! singularity, discontinuity within the
!! interval) one will probably gain from
!! splitting up the interval at this point
!! and calling appropriate integrators on
!! the subranges.
!! = 4 the extrapolation table constructed for
!! convergence acceleration of the series
!! formed by the integral contributions over
!! the cycles, does not converge to within
!! the requested accuracy. as in the case of
!! ier = 1, it is advised to examine the
!! array iwork which contains the error
!! flags on the cycles.
!! = 6 the input is invalid because
!! (integr.ne.1 and integr.ne.2) or
!! epsabs.le.0 or limlst.lt.3.
!! result, abserr, neval, lst are set
!! to zero.
!! = 7 bad integrand behaviour occurs within one
!! or more of the cycles. location and type
!! of the difficulty involved can be
!! determined from the vector ierlst. here
!! lst is the number of cycles actually
!! needed (see below).
!! ierlst(k) = 1 the maximum number of
!! subdivisions (= limit) has
!! been achieved on the k th
!! cycle.
!! = 2 occurrence of roundoff error
!! is detected and prevents the
!! tolerance imposed on the
!! k th cycle, from being
!! achieved.
!! = 3 extremely bad integrand
!! behaviour occurs at some
!! points of the k th cycle.
!! = 4 the integration procedure
!! over the k th cycle does
!! not converge (to within the
!! required accuracy) due to
!! roundoff in the
!! extrapolation procedure
!! invoked on this cycle. it
!! is assumed that the result
!! on this interval is the
!! best which can be obtained.
!! = 5 the integral over the k th
!! cycle is probably divergent
!! or slowly convergent. it
!! must be noted that
!! divergence can occur with
!! any other value of
!! ierlst(k).
!! if omega = 0 and integr = 1,
!! the integral is calculated by means of dqagie
!! and ier = ierlst(1) (with meaning as described
!! for ierlst(k), k = 1).
!!
!! rslst - real ( kind = 8 )
!! vector of dimension at least limlst
!! rslst(k) contains the integral contribution
!! over the interval (a+(k-1)c,a+kc) where
!! c = (2*int(abs(omega))+1)*pi/abs(omega),
!! k = 1, 2, ..., lst.
!! note that, if omega = 0, rslst(1) contains
!! the value of the integral over (a,infinity).
!!
!! erlst - real ( kind = 8 )
!! vector of dimension at least limlst
!! erlst(k) contains the error estimate corresponding
!! with rslst(k).
!!
!! ierlst - integer ( kind = 4 )
!! vector of dimension at least limlst
!! ierlst(k) contains the error flag corresponding
!! with rslst(k). for the meaning of the local error
!! flags see description of output parameter ier.
!!
!! lst - integer ( kind = 4 )
!! number of subintervals needed for the integration
!! if omega = 0 then lst is set to 1.
!!
!! alist, blist, rlist, elist - real ( kind = 8 )
!! vector of dimension at least limit,
!!
!! iord, nnlog - integer ( kind = 4 )
!! vector of dimension at least limit, providing
!! space for the quantities needed in the subdivision
!! process of each cycle
!!
!! chebmo - real ( kind = 8 )
!! array of dimension at least (maxp1,25), providing
!! space for the chebyshev moments needed within the
!! cycles
!!
!! Local Parameters:
!!
!! the dimension of psum is determined by the value of
!! limexp in routine dqelg (psum must be of dimension
!! (limexp+2) at least).
!!
!! c1, c2 - end points of subinterval (of length cycle)
!! cycle - (2*int(abs(omega))+1)*pi/abs(omega)
!! psum - vector of dimension at least (limexp+2)
!! (see routine dqelg)
!! psum contains the part of the epsilon table
!! which is still needed for further computations.
!! each element of psum is a partial sum of the
!! series which should sum to the value of the
!! integral.
!! errsum - sum of error estimates over the subintervals,
!! calculated cumulatively
!! epsa - absolute tolerance requested over current
!! subinterval
!! chebmo - array containing the modified chebyshev
!! moments (see also routine dqc25f)
!!
subroutine dqawfe(f,a,omega,integr,epsabs,limlst,limit,maxp1, &
result,abserr,neval,ier,rslst,erlst,ierlst,lst,alist,blist, &
rlist,elist,iord,nnlog,chebmo)
implicit none
real ( kind = 8 ) a,abseps,abserr,alist,blist,chebmo,correc,cycle, &
c1,c2,dl,dla,drl,elist,erlst,ep,eps,epsa, &
epsabs,errsum,f,fact,omega,p,pi,p1,psum,reseps,result,res3la, &
rlist,rslst,uflow
integer ( kind = 4 ) ier,ierlst,integr,iord,ktmin,l,last,lst,limit
integer ( kind = 4 ) limlst
integer ( kind = 4 ) ll
integer ( kind = 4 ) maxp1,momcom,nev,neval,nnlog,nres,numrl2
dimension alist(limit),blist(limit),chebmo(maxp1,25),elist(limit), &
erlst(limlst),ierlst(limlst),iord(limit),nnlog(limit),psum(52), &
res3la(3),rlist(limit),rslst(limlst)
external f
data p / 0.9D+00 /
data pi / 3.14159265358979323846264338327950D+00 /
!
! test on validity of parameters
!
result = 0.0D+00
abserr = 0.0D+00
neval = 0
lst = 0
ier = 0
if((integr.ne.1.and.integr.ne.2).or.epsabs.le.0.0D+00.or. &
limlst.lt.3) then
ier = 6
return
end if
if(omega.ne.0.0D+00) go to 10
!
! integration by dqagie if omega is zero
!
if(integr.eq.1) then
call dqagie(f,0.0D+00,1,epsabs,0.0D+00,limit, &
result,abserr,neval,ier,alist,blist,rlist,elist,iord,last)
end if
rslst(1) = result
erlst(1) = abserr
ierlst(1) = ier
lst = 1
go to 999
!
! initializations
!
10 l = abs ( omega)
dl = 2*l+1
cycle = dl*pi/ abs ( omega)
ier = 0
ktmin = 0
neval = 0
numrl2 = 0
nres = 0
c1 = a
c2 = cycle+a
p1 = 0.1D+01-p
uflow = tiny ( uflow )
eps = epsabs
if(epsabs.gt.uflow/p1) eps = epsabs*p1
ep = eps
fact = 0.1D+01
correc = 0.0D+00
abserr = 0.0D+00
errsum = 0.0D+00
!
! main do-loop
!
do lst = 1,limlst
!
! integrate over current subinterval.
!
dla = lst
epsa = eps*fact
call dqawoe(f,c1,c2,omega,integr,epsa,0.0D+00,limit,lst,maxp1, &
rslst(lst),erlst(lst),nev,ierlst(lst),last,alist,blist,rlist, &
elist,iord,nnlog,momcom,chebmo)
neval = neval+nev
fact = fact*p
errsum = errsum+erlst(lst)
drl = 0.5D+02* abs ( rslst(lst))
!
! test on accuracy with partial sum
!
if((errsum+drl).le.epsabs.and.lst.ge.6) go to 80
correc = max ( correc,erlst(lst))
if(ierlst(lst).ne.0) eps = max ( ep,correc*p1)
if(ierlst(lst).ne.0) ier = 7
if(ier.eq.7.and.(errsum+drl).le.correc*0.1D+02.and. &
lst.gt.5) go to 80
numrl2 = numrl2+1
if(lst.gt.1) go to 20
psum(1) = rslst(1)
go to 40
20 psum(numrl2) = psum(ll)+rslst(lst)
if(lst.eq.2) go to 40
!
! test on maximum number of subintervals
!
if(lst.eq.limlst) ier = 1
!
! perform new extrapolation
!
call dqelg(numrl2,psum,reseps,abseps,res3la,nres)
!
! test whether extrapolated result is influenced by roundoff
!
ktmin = ktmin+1
if(ktmin.ge.15.and.abserr.le.0.1D-02*(errsum+drl)) ier = 4
if(abseps.gt.abserr.and.lst.ne.3) go to 30
abserr = abseps
result = reseps
ktmin = 0
!
! if ier is not 0, check whether direct result (partial sum)
! or extrapolated result yields the best integral
! approximation
!
if((abserr+0.1D+02*correc).le.epsabs.or. &
(abserr.le.epsabs.and.0.1D+02*correc.ge.epsabs)) go to 60
30 if(ier.ne.0.and.ier.ne.7) go to 60
40 ll = numrl2
c1 = c2
c2 = c2+cycle
end do
!
! set final result and error estimate
!
60 abserr = abserr+0.1D+02*correc
if(ier.eq.0) go to 999
if(result.ne.0.0D+00.and.psum(numrl2).ne.0.0D+00) go to 70
if(abserr.gt.errsum) go to 80
if(psum(numrl2).eq.0.0D+00) go to 999
70 if(abserr/ abs ( result).gt.(errsum+drl)/ abs ( psum(numrl2))) &
go to 80
if(ier.ge.1.and.ier.ne.7) abserr = abserr+drl
go to 999
80 result = psum(numrl2)
abserr = errsum+drl
999 continue
return
end subroutine dqawfe
!----------------------------------------------------------------------------------------
!> DQAWF computes Fourier integrals over the interval [ A, +Infinity ).
!!
!! Modified:
!!
!! 11 September 2015
!!
!! Author:
!!
!! Robert Piessens, Elise de Doncker
!!
!!***purpose the routine calculates an approximation result to a given
!! fourier integral i=integral of f(x)*w(x) over (a,infinity)
!! where w(x) = cos(omega*x) or w(x) = sin(omega*x).
!! hopefully satisfying following claim for accuracy
!! abs(i-result).le.epsabs.
!!
!! Parameters:
!!
!! on entry
!! f - real ( kind = 8 )
!! function subprogram defining the integrand
!! function f(x). the actual name for f needs to be
!! declared e x t e r n a l in the driver program.
!!
!! a - real ( kind = 8 )
!! lower limit of integration
!!
!! omega - real ( kind = 8 )
!! parameter in the integrand weight function
!!
!! integr - integer ( kind = 4 )
!! indicates which of the weight functions is used
!! integr = 1 w(x) = cos(omega*x)
!! integr = 2 w(x) = sin(omega*x)
!! if integr.ne.1.and.integr.ne.2, the routine
!! will end with ier = 6.
!!
!! epsabs - real ( kind = 8 )
!! absolute accuracy requested, epsabs.gt.0.
!! if epsabs.le.0, the routine will end with ier = 6.
!!
!! on return
!! result - real ( kind = 8 )
!! approximation to the integral
!!
!! abserr - real ( kind = 8 )
!! estimate of the modulus of the absolute error,
!! which should equal or exceed abs(i-result)
!!
!! neval - integer ( kind = 4 )
!! number of integrand evaluations
!!
!! ier - integer ( kind = 4 )
!! ier = 0 normal and reliable termination of the
!! routine. it is assumed that the requested
!! accuracy has been achieved.
!! ier.gt.0 abnormal termination of the routine.
!! the estimates for integral and error are
!! less reliable. it is assumed that the
!! requested accuracy has not been achieved.
!! error messages
!! if omega.ne.0
!! ier = 1 maximum number of cycles allowed
!! has been achieved, i.e. of subintervals
!! (a+(k-1)c,a+kc) where
!! c = (2*int(abs(omega))+1)*pi/abs(omega),
!! for k = 1, 2, ..., lst.
!! one can allow more cycles by increasing
!! the value of limlst (and taking the
!! according dimension adjustments into
!! account). examine the array iwork which
!! contains the error flags on the cycles, in
!! order to look for eventual local
!! integration difficulties.
!! if the position of a local difficulty
!! can be determined (e.g. singularity,
!! discontinuity within the interval) one
!! will probably gain from splitting up the
!! interval at this point and calling
!! appropriate integrators on the subranges.
!! = 4 the extrapolation table constructed for
!! convergence accelaration of the series
!! formed by the integral contributions over
!! the cycles, does not converge to within
!! the requested accuracy.
!! as in the case of ier = 1, it is advised
!! to examine the array iwork which contains
!! the error flags on the cycles.
!! = 6 the input is invalid because
!! (integr.ne.1 and integr.ne.2) or
!! epsabs.le.0 or limlst.lt.1 or
!! leniw.lt.(limlst+2) or maxp1.lt.1 or
!! lenw.lt.(leniw*2+maxp1*25).
!! result, abserr, neval, lst are set to
!! zero.
!! = 7 bad integrand behaviour occurs within
!! one or more of the cycles. location and
!! type of the difficulty involved can be
!! determined from the first lst elements of
!! vector iwork. here lst is the number of
!! cycles actually needed (see below).
!! iwork(k) = 1 the maximum number of
!! subdivisions (=(leniw-limlst)
!! /2) has been achieved on the
!! k th cycle.
!! = 2 occurrence of roundoff error
!! is detected and prevents the
!! tolerance imposed on the k th
!! cycle, from being achieved
!! on this cycle.
!! = 3 extremely bad integrand
!! behaviour occurs at some
!! points of the k th cycle.
!! = 4 the integration procedure
!! over the k th cycle does
!! not converge (to within the
!! required accuracy) due to
!! roundoff in the extrapolation
!! procedure invoked on this
!! cycle. it is assumed that the
!! result on this interval is
!! the best which can be
!! obtained.
!! = 5 the integral over the k th
!! cycle is probably divergent
!! or slowly convergent. it must
!! be noted that divergence can
!! occur with any other value of
!! iwork(k).
!! if omega = 0 and integr = 1,
!! the integral is calculated by means of dqagie,
!! and ier = iwork(1) (with meaning as described
!! for iwork(k),k = 1).
!!
!! dimensioning parameters
!! limlst - integer ( kind = 4 )
!! limlst gives an upper bound on the number of
!! cycles, limlst.ge.3.
!! if limlst.lt.3, the routine will end with ier = 6.
!!
!! lst - integer ( kind = 4 )
!! on return, lst indicates the number of cycles
!! actually needed for the integration.
!! if omega = 0, then lst is set to 1.
!!
!! leniw - integer ( kind = 4 )
!! dimensioning parameter for iwork. on entry,
!! (leniw-limlst)/2 equals the maximum number of
!! subintervals allowed in the partition of each
!! cycle, leniw.ge.(limlst+2).
!! if leniw.lt.(limlst+2), the routine will end with
!! ier = 6.
!!
!! maxp1 - integer ( kind = 4 )
!! maxp1 gives an upper bound on the number of
!! chebyshev moments which can be stored, i.e. for
!! the intervals of lengths abs(b-a)*2**(-l),
!! l = 0,1, ..., maxp1-2, maxp1.ge.1.
!! if maxp1.lt.1, the routine will end with ier = 6.
!! lenw - integer ( kind = 4 )
!! dimensioning parameter for work
!! lenw must be at least leniw*2+maxp1*25.
!! if lenw.lt.(leniw*2+maxp1*25), the routine will
!! end with ier = 6.
!!
!! work arrays
!! iwork - integer ( kind = 4 )
!! vector of dimension at least leniw
!! on return, iwork(k) for k = 1, 2, ..., lst
!! contain the error flags on the cycles.
!!
!! work - real ( kind = 8 )
!! vector of dimension at least lenw
!! on return,
!! work(1), ..., work(lst) contain the integral
!! approximations over the cycles,
!! work(limlst+1), ..., work(limlst+lst) contain
!! the error extimates over the cycles.
!! further elements of work have no specific
!! meaning for the user.
!!
subroutine dqawf ( f, a, omega, integr, epsabs, result, abserr, neval, ier, &
limlst, lst, leniw, maxp1, lenw, iwork, work )
implicit none
integer ( kind = 4 ) leniw
integer ( kind = 4 ) lenw
real ( kind = 8 ) a
real ( kind = 8 ) abserr
real ( kind = 8 ) epsabs
real ( kind = 8 ), external :: f
integer ( kind = 4 ) ier
integer ( kind = 4 ) integr
integer ( kind = 4 ) iwork(leniw)
integer ( kind = 4 ) last
integer ( kind = 4 ) limit
integer ( kind = 4 ) limlst
integer ( kind = 4 ) ll2
integer ( kind = 4 ) lst
integer ( kind = 4 ) lvl
integer ( kind = 4 ) l1
integer ( kind = 4 ) l2
integer ( kind = 4 ) l3
integer ( kind = 4 ) l4
integer ( kind = 4 ) l5
integer ( kind = 4 ) l6
integer ( kind = 4 ) maxp1
integer ( kind = 4 ) neval
real ( kind = 8 ) omega
real ( kind = 8 ) result
real ( kind = 8 ) work(lenw)
!
! check validity of limlst, leniw, maxp1 and lenw.
!
ier = 6
neval = 0
last = 0
result = 0.0D+00
abserr = 0.0D+00
if(limlst.lt.3.or.leniw.lt.(limlst+2).or.maxp1.lt.1.or.lenw.lt. &
(leniw*2+maxp1*25)) go to 10
!
! prepare call for dqawfe
!
limit = (leniw-limlst)/2
l1 = limlst+1
l2 = limlst+l1
l3 = limit+l2
l4 = limit+l3
l5 = limit+l4
l6 = limit+l5
ll2 = limit+l1
call dqawfe(f,a,omega,integr,epsabs,limlst,limit,maxp1,result, &
abserr,neval,ier,work(1),work(l1),iwork(1),lst,work(l2), &
work(l3),work(l4),work(l5),iwork(l1),iwork(ll2),work(l6))
!
! call error handler if necessary
!
lvl = 0
10 continue
if(ier.eq.6) lvl = 1
if(ier.ne.0) call xerror('abnormal return from dqawf',26,ier,lvl)
return
end subroutine dqawf
!----------------------------------------------------------------------------------------
!> DQAWOE computes the integrals of oscillatory integrands.
!!
!! Modified:
!!
!! 11 September 2015
!!
!! Author:
!!
!! Robert Piessens, Elise de Doncker
!!
!!***purpose the routine calculates an approximation result to a given
!! definite integral
!! i = integral of f(x)*w(x) over (a,b)
!! where w(x) = cos(omega*x) or w(x)=sin(omega*x),
!! hopefully satisfying following claim for accuracy
!! abs(i-result).le.max(epsabs,epsrel*abs(i)).
!!
!! Parameters:
!!
!! on entry
!! f - real ( kind = 8 )
!! function subprogram defining the integrand
!! function f(x). the actual name for f needs to be
!! declared e x t e r n a l in the driver program.
!!
!! a - real ( kind = 8 )
!! lower limit of integration
!!
!! b - real ( kind = 8 )
!! upper limit of integration
!!
!! omega - real ( kind = 8 )
!! parameter in the integrand weight function
!!
!! integr - integer ( kind = 4 )
!! indicates which of the weight functions is to be
!! used
!! integr = 1 w(x) = cos(omega*x)
!! integr = 2 w(x) = sin(omega*x)
!! if integr.ne.1 and integr.ne.2, the routine
!! will end with ier = 6.
!!
!! epsabs - real ( kind = 8 )
!! absolute accuracy requested
!! epsrel - real ( kind = 8 )
!! relative accuracy requested
!! if epsabs.le.0
!! and epsrel.lt.max(50*rel.mach.acc.,0.5d-28),
!! the routine will end with ier = 6.
!!
!! limit - integer ( kind = 4 )
!! gives an upper bound on the number of subdivisions
!! in the partition of (a,b), limit.ge.1.
!!
!! icall - integer ( kind = 4 )
!! if dqawoe is to be used only once, icall must
!! be set to 1. assume that during this call, the
!! chebyshev moments (for clenshaw-curtis integration
!! of degree 24) have been computed for intervals of
!! lenghts (abs(b-a))*2**(-l), l=0,1,2,...momcom-1.
!! if icall.gt.1 this means that dqawoe has been
!! called twice or more on intervals of the same
!! length abs(b-a). the chebyshev moments already
!! computed are then re-used in subsequent calls.
!! if icall.lt.1, the routine will end with ier = 6.
!!
!! maxp1 - integer ( kind = 4 )
!! gives an upper bound on the number of chebyshev
!! moments which can be stored, i.e. for the
!! intervals of lenghts abs(b-a)*2**(-l),
!! l=0,1, ..., maxp1-2, maxp1.ge.1.
!! if maxp1.lt.1, the routine will end with ier = 6.
!!
!! on return
!! result - real ( kind = 8 )
!! approximation to the integral
!!
!! abserr - real ( kind = 8 )
!! estimate of the modulus of the absolute error,
!! which should equal or exceed abs(i-result)
!!
!! neval - integer ( kind = 4 )
!! number of integrand evaluations
!!
!! ier - integer ( kind = 4 )
!! ier = 0 normal and reliable termination of the
!! routine. it is assumed that the
!! requested accuracy has been achieved.
!! - ier.gt.0 abnormal termination of the routine.
!! the estimates for integral and error are
!! less reliable. it is assumed that the
!! requested accuracy has not been achieved.
!! error messages
!! ier = 1 maximum number of subdivisions allowed
!! has been achieved. one can allow more
!! subdivisions by increasing the value of
!! limit (and taking according dimension
!! adjustments into account). however, if
!! this yields no improvement it is advised
!! to analyze the integrand, in order to
!! determine the integration difficulties.
!! if the position of a local difficulty can
!! be determined (e.g. singularity,
!! discontinuity within the interval) one
!! will probably gain from splitting up the
!! interval at this point and calling the
!! integrator on the subranges. if possible,
!! an appropriate special-purpose integrator
!! should be used which is designed for
!! handling the type of difficulty involved.
!! = 2 the occurrence of roundoff error is
!! detected, which prevents the requested
!! tolerance from being achieved.
!! the error may be under-estimated.
!! = 3 extremely bad integrand behaviour occurs
!! at some points of the integration
!! interval.
!! = 4 the algorithm does not converge.
!! roundoff error is detected in the
!! extrapolation table.
!! it is presumed that the requested
!! tolerance cannot be achieved due to
!! roundoff in the extrapolation table,
!! and that the returned result is the
!! best which can be obtained.
!! = 5 the integral is probably divergent, or
!! slowly convergent. it must be noted that
!! divergence can occur with any other value
!! of ier.gt.0.
!! = 6 the input is invalid, because
!! (epsabs.le.0 and
!! epsrel.lt.max(50*rel.mach.acc.,0.5d-28))
!! or (integr.ne.1 and integr.ne.2) or
!! icall.lt.1 or maxp1.lt.1.
!! result, abserr, neval, last, rlist(1),
!! elist(1), iord(1) and nnlog(1) are set
!! to zero. alist(1) and blist(1) are set
!! to a and b respectively.
!!
!! last - integer ( kind = 4 )
!! on return, last equals the number of
!! subintervals produces in the subdivision
!! process, which determines the number of
!! significant elements actually in the
!! work arrays.
!! alist - real ( kind = 8 )
!! vector of dimension at least limit, the first
!! last elements of which are the left
!! end points of the subintervals in the partition
!! of the given integration range (a,b)
!!
!! blist - real ( kind = 8 )
!! vector of dimension at least limit, the first
!! last elements of which are the right
!! end points of the subintervals in the partition
!! of the given integration range (a,b)
!!
!! rlist - real ( kind = 8 )
!! vector of dimension at least limit, the first
!! last elements of which are the integral
!! approximations on the subintervals
!!
!! elist - real ( kind = 8 )
!! vector of dimension at least limit, the first
!! last elements of which are the moduli of the
!! absolute error estimates on the subintervals
!!
!! iord - integer ( kind = 4 )
!! vector of dimension at least limit, the first k
!! elements of which are pointers to the error
!! estimates over the subintervals,
!! such that elist(iord(1)), ...,
!! elist(iord(k)) form a decreasing sequence, with
!! k = last if last.le.(limit/2+2), and
!! k = limit+1-last otherwise.
!!
!! nnlog - integer ( kind = 4 )
!! vector of dimension at least limit, containing the
!! subdivision levels of the subintervals, i.e.
!! iwork(i) = l means that the subinterval
!! numbered i is of length abs(b-a)*2**(1-l)
!!
!! on entry and return
!! momcom - integer ( kind = 4 )
!! indicating that the chebyshev moments
!! have been computed for intervals of lengths
!! (abs(b-a))*2**(-l), l=0,1,2, ..., momcom-1,
!! momcom.lt.maxp1
!!
!! chebmo - real ( kind = 8 )
!! array of dimension (maxp1,25) containing the
!! chebyshev moments
!!
!! Local Parameters:
!!
!! the dimension of rlist2 is determined by the value of
!! limexp in routine dqelg (rlist2 should be of
!! dimension (limexp+2) at least).
!!
!! list of major variables
!!
!! alist - list of left end points of all subintervals
!! considered up to now
!! blist - list of right end points of all subintervals
!! considered up to now
!! rlist(i) - approximation to the integral over
!! (alist(i),blist(i))
!! rlist2 - array of dimension at least limexp+2
!! containing the part of the epsilon table
!! which is still needed for further computations
!! elist(i) - error estimate applying to rlist(i)
!! maxerr - pointer to the interval with largest
!! error estimate
!! errmax - elist(maxerr)
!! erlast - error on the interval currently subdivided
!! area - sum of the integrals over the subintervals
!! errsum - sum of the errors over the subintervals
!! errbnd - requested accuracy max(epsabs,epsrel*
!! abs(result))
!! *****1 - variable for the left subinterval
!! *****2 - variable for the right subinterval
!! last - index for subdivision
!! nres - number of calls to the extrapolation routine
!! numrl2 - number of elements in rlist2. if an appropriate
!! approximation to the compounded integral has
!! been obtained it is put in rlist2(numrl2) after
!! numrl2 has been increased by one
!! small - length of the smallest interval considered
!! up to now, multiplied by 1.5
!! erlarg - sum of the errors over the intervals larger
!! than the smallest interval considered up to now
!! extrap - logical variable denoting that the routine is
!! attempting to perform extrapolation, i.e. before
!! subdividing the smallest interval we try to
!! decrease the value of erlarg
!! noext - logical variable denoting that extrapolation
!! is no longer allowed (true value)
!!
!! machine dependent constants
!!
!! epmach is the largest relative spacing.
!! uflow is the smallest positive magnitude.
!! oflow is the largest positive magnitude.
!!
subroutine dqawoe ( f, a, b, omega, integr, epsabs, epsrel, limit, icall, &
maxp1, result, abserr, neval, ier, last, alist, blist, rlist, elist, iord, &
nnlog, momcom, chebmo )
implicit none
real ( kind = 8 ) a,abseps,abserr,alist,area,area1,area12,area2,a1, &
a2,b,blist,b1,b2,chebmo,correc,defab1,defab2,defabs, &
domega,dres,elist,epmach,epsabs,epsrel,erlarg,erlast, &
errbnd,errmax,error1,erro12,error2,errsum,ertest,f,oflow, &
omega,resabs,reseps,result,res3la,rlist,rlist2,small,uflow,width
integer ( kind = 4 ) icall,id,ier,ierro,integr,iord,iroff1,iroff2
integer ( kind = 4 ) iroff3
integer ( kind = 4 ) jupbnd
integer ( kind = 4 ) k,ksgn,ktmin,last,limit,maxerr,maxp1,momcom,nev,neval, &
nnlog,nres,nrmax,nrmom,numrl2
logical extrap,noext,extall
dimension alist(limit),blist(limit),rlist(limit),elist(limit), &
iord(limit),rlist2(52),res3la(3),chebmo(maxp1,25),nnlog(limit)
external f
epmach = epsilon ( epmach )
!
! test on validity of parameters
!
ier = 0
neval = 0
last = 0
result = 0.0D+00
abserr = 0.0D+00
alist(1) = a
blist(1) = b
rlist(1) = 0.0D+00
elist(1) = 0.0D+00
iord(1) = 0
nnlog(1) = 0
if((integr.ne.1.and.integr.ne.2).or.(epsabs.le.0.0D+00.and. &
epsrel.lt. max ( 0.5D+02*epmach,0.5D-28)).or.icall.lt.1.or. &
maxp1.lt.1) ier = 6
if(ier.eq.6) go to 999
!
! first approximation to the integral
!
domega = abs ( omega)
nrmom = 0
if (icall.gt.1) go to 5
momcom = 0
5 call dqc25f(f,a,b,domega,integr,nrmom,maxp1,0,result,abserr, &
neval,defabs,resabs,momcom,chebmo)
!
! test on accuracy.
!
dres = abs ( result)
errbnd = max ( epsabs,epsrel*dres)
rlist(1) = result
elist(1) = abserr
iord(1) = 1
if(abserr.le.0.1D+03*epmach*defabs.and.abserr.gt.errbnd) ier = 2
if(limit.eq.1) ier = 1
if(ier.ne.0.or.abserr.le.errbnd) go to 200
!
! initializations
!
uflow = tiny ( uflow )
oflow = huge ( oflow )
errmax = abserr
maxerr = 1
area = result
errsum = abserr
abserr = oflow
nrmax = 1
extrap = .false.
noext = .false.
ierro = 0
iroff1 = 0
iroff2 = 0
iroff3 = 0
ktmin = 0
small = abs ( b-a)*0.75D+00
nres = 0
numrl2 = 0
extall = .false.
if(0.5D+00* abs ( b-a)*domega.gt.0.2D+01) go to 10
numrl2 = 1
extall = .true.
rlist2(1) = result
10 if(0.25D+00* abs ( b-a)*domega.le.0.2D+01) extall = .true.
ksgn = -1
if(dres.ge.(0.1D+01-0.5D+02*epmach)*defabs) ksgn = 1
!
! main do-loop
!
do 140 last = 2,limit
!
! bisect the subinterval with the nrmax-th largest error estimate.
!
nrmom = nnlog(maxerr)+1
a1 = alist(maxerr)
b1 = 0.5D+00*(alist(maxerr)+blist(maxerr))
a2 = b1
b2 = blist(maxerr)
erlast = errmax
call dqc25f(f,a1,b1,domega,integr,nrmom,maxp1,0, &
area1,error1,nev,resabs,defab1,momcom,chebmo)
neval = neval+nev
call dqc25f(f,a2,b2,domega,integr,nrmom,maxp1,1, &
area2,error2,nev,resabs,defab2,momcom,chebmo)
neval = neval+nev
!
! improve previous approximations to integral
! and error and test for accuracy.
!
area12 = area1+area2
erro12 = error1+error2
errsum = errsum+erro12-errmax
area = area+area12-rlist(maxerr)
if(defab1.eq.error1.or.defab2.eq.error2) go to 25
if( abs ( rlist(maxerr)-area12).gt.0.1D-04* abs ( area12) &
.or.erro12.lt.0.99D+00*errmax) go to 20
if(extrap) iroff2 = iroff2+1
if(.not.extrap) iroff1 = iroff1+1
20 if(last.gt.10.and.erro12.gt.errmax) iroff3 = iroff3+1
25 rlist(maxerr) = area1
rlist(last) = area2
nnlog(maxerr) = nrmom
nnlog(last) = nrmom
errbnd = max ( epsabs,epsrel* abs ( area))
!
! test for roundoff error and eventually set error flag.
!
if(iroff1+iroff2.ge.10.or.iroff3.ge.20) ier = 2
if(iroff2.ge.5) ierro = 3
!
! set error flag in the case that the number of
! subintervals equals limit.
!
if(last.eq.limit) ier = 1
!
! set error flag in the case of bad integrand behaviour
! at a point of the integration range.
!
if( max ( abs ( a1), abs ( b2)).le.(0.1D+01+0.1D+03*epmach) &
*( abs ( a2)+0.1D+04*uflow)) ier = 4
!
! append the newly-created intervals to the list.
!
if(error2.gt.error1) go to 30
alist(last) = a2
blist(maxerr) = b1
blist(last) = b2
elist(maxerr) = error1
elist(last) = error2
go to 40
30 alist(maxerr) = a2
alist(last) = a1
blist(last) = b1
rlist(maxerr) = area2
rlist(last) = area1
elist(maxerr) = error2
elist(last) = error1
!
! call dqpsrt to maintain the descending ordering
! in the list of error estimates and select the subinterval
! with nrmax-th largest error estimate (to bisected next).
!
40 call dqpsrt(limit,last,maxerr,errmax,elist,iord,nrmax)
if(errsum.le.errbnd) go to 170
if(ier.ne.0) go to 150
if(last.eq.2.and.extall) go to 120
if(noext) go to 140
if(.not.extall) go to 50
erlarg = erlarg-erlast
if( abs ( b1-a1).gt.small) erlarg = erlarg+erro12
if(extrap) go to 70
!
! test whether the interval to be bisected next is the
! smallest interval.
!
50 width = abs ( blist(maxerr)-alist(maxerr))
if(width.gt.small) go to 140
if(extall) go to 60
!
! test whether we can start with the extrapolation procedure
! (we do this if we integrate over the next interval with
! use of a gauss-kronrod rule - see routine dqc25f).
!
small = small*0.5D+00
if(0.25D+00*width*domega.gt.0.2D+01) go to 140
extall = .true.
go to 130
60 extrap = .true.
nrmax = 2
70 if(ierro.eq.3.or.erlarg.le.ertest) go to 90
!
! the smallest interval has the largest error.
! before bisecting decrease the sum of the errors over
! the larger intervals (erlarg) and perform extrapolation.
!
jupbnd = last
if (last.gt.(limit/2+2)) jupbnd = limit+3-last
id = nrmax
do k = id,jupbnd
maxerr = iord(nrmax)
errmax = elist(maxerr)
if( abs ( blist(maxerr)-alist(maxerr)).gt.small) go to 140
nrmax = nrmax+1
end do
!
! perform extrapolation.
!
90 numrl2 = numrl2+1
rlist2(numrl2) = area
if(numrl2.lt.3) go to 110
call dqelg(numrl2,rlist2,reseps,abseps,res3la,nres)
ktmin = ktmin+1
if(ktmin.gt.5.and.abserr.lt.0.1D-02*errsum) ier = 5
if(abseps.ge.abserr) go to 100
ktmin = 0
abserr = abseps
result = reseps
correc = erlarg
ertest = max ( epsabs,epsrel* abs ( reseps))
if(abserr.le.ertest) go to 150
!
! prepare bisection of the smallest interval.
!
100 if(numrl2.eq.1) noext = .true.
if(ier.eq.5) go to 150
110 maxerr = iord(1)
errmax = elist(maxerr)
nrmax = 1
extrap = .false.
small = small*0.5D+00
erlarg = errsum
go to 140
120 small = small*0.5D+00
numrl2 = numrl2+1
rlist2(numrl2) = area
130 ertest = errbnd
erlarg = errsum
140 continue
!
! set the final result.-
!
150 if(abserr.eq.oflow.or.nres.eq.0) go to 170
if(ier+ierro.eq.0) go to 165
if(ierro.eq.3) abserr = abserr+correc
if(ier.eq.0) ier = 3
if(result.ne.0.0D+00.and.area.ne.0.0D+00) go to 160
if(abserr.gt.errsum) go to 170
if(area.eq.0.0D+00) go to 190
go to 165
160 if(abserr/ abs ( result).gt.errsum/ abs ( area)) go to 170
!
! test on divergence.
!
165 if(ksgn.eq.(-1).and. max ( abs ( result), abs ( area)).le. &
defabs*0.1D-01) go to 190
if(0.1D-01.gt.(result/area).or.(result/area).gt.0.1D+03 &
.or.errsum.ge. abs ( area)) ier = 6
go to 190
!
! compute global integral sum.
!
170 result = 0.0D+00
do k=1,last
result = result+rlist(k)
end do
abserr = errsum
190 if (ier.gt.2) ier=ier-1
200 if (integr.eq.2.and.omega.lt.0.0D+00) result=-result
999 continue
return
end subroutine dqawoe
!----------------------------------------------------------------------------------------
!> DQAWO computes the integrals of oscillatory integrands.
!!
!! Modified:
!!
!! 11 September 2015
!!
!! Author:
!!
!! Robert Piessens, Elise de Doncker
!!
!!***purpose the routine calculates an approximation result to a given
!! definite integral i=integral of f(x)*w(x) over (a,b)
!! where w(x) = cos(omega*x)
!! or w(x) = sin(omega*x),
!! hopefully satisfying following claim for accuracy
!! abs(i-result).le.max(epsabs,epsrel*abs(i)).
!!
!! Parameters:
!!
!! on entry
!! f - real ( kind = 8 )
!! function subprogram defining the function
!! f(x). the actual name for f needs to be
!! declared e x t e r n a l in the driver program.
!!
!! a - real ( kind = 8 )
!! lower limit of integration
!!
!! b - real ( kind = 8 )
!! upper limit of integration
!!
!! omega - real ( kind = 8 )
!! parameter in the integrand weight function
!!
!! integr - integer ( kind = 4 )
!! indicates which of the weight functions is used
!! integr = 1 w(x) = cos(omega*x)
!! integr = 2 w(x) = sin(omega*x)
!! if integr.ne.1.and.integr.ne.2, the routine will
!! end with ier = 6.
!!
!! epsabs - real ( kind = 8 )
!! absolute accuracy requested
!! epsrel - real ( kind = 8 )
!! relative accuracy requested
!! if epsabs.le.0 and
!! epsrel.lt.max(50*rel.mach.acc.,0.5d-28),
!! the routine will end with ier = 6.
!!
!! on return
!! result - real ( kind = 8 )
!! approximation to the integral
!!
!! abserr - real ( kind = 8 )
!! estimate of the modulus of the absolute error,
!! which should equal or exceed abs(i-result)
!!
!! neval - integer ( kind = 4 )
!! number of integrand evaluations
!!
!! ier - integer ( kind = 4 )
!! ier = 0 normal and reliable termination of the
!! routine. it is assumed that the requested
!! accuracy has been achieved.
!! - ier.gt.0 abnormal termination of the routine.
!! the estimates for integral and error are
!! less reliable. it is assumed that the
!! requested accuracy has not been achieved.
!! error messages
!! ier = 1 maximum number of subdivisions allowed
!! (= leniw/2) has been achieved. one can
!! allow more subdivisions by increasing the
!! value of leniw (and taking the according
!! dimension adjustments into account).
!! however, if this yields no improvement it
!! is advised to analyze the integrand in
!! order to determine the integration
!! difficulties. if the position of a local
!! difficulty can be determined (e.g.
!! singularity, discontinuity within the
!! interval) one will probably gain from
!! splitting up the interval at this point
!! and calling the integrator on the
!! subranges. if possible, an appropriate
!! special-purpose integrator should be used
!! which is designed for handling the type of
!! difficulty involved.
!! = 2 the occurrence of roundoff error is
!! detected, which prevents the requested
!! tolerance from being achieved.
!! the error may be under-estimated.
!! = 3 extremely bad integrand behaviour occurs
!! at some interior points of the
!! integration interval.
!! = 4 the algorithm does not converge.
!! roundoff error is detected in the
!! extrapolation table. it is presumed that
!! the requested tolerance cannot be achieved
!! due to roundoff in the extrapolation
!! table, and that the returned result is
!! the best which can be obtained.
!! = 5 the integral is probably divergent, or
!! slowly convergent. it must be noted that
!! divergence can occur with any other value
!! of ier.
!! = 6 the input is invalid, because
!! (epsabs.le.0 and
!! epsrel.lt.max(50*rel.mach.acc.,0.5d-28))
!! or (integr.ne.1 and integr.ne.2),
!! or leniw.lt.2 or maxp1.lt.1 or
!! lenw.lt.leniw*2+maxp1*25.
!! result, abserr, neval, last are set to
!! zero. except when leniw, maxp1 or lenw are
!! invalid, work(limit*2+1), work(limit*3+1),
!! iwork(1), iwork(limit+1) are set to zero,
!! work(1) is set to a and work(limit+1) to
!! b.
!!
!! dimensioning parameters
!! leniw - integer ( kind = 4 )
!! dimensioning parameter for iwork.
!! leniw/2 equals the maximum number of subintervals
!! allowed in the partition of the given integration
!! interval (a,b), leniw.ge.2.
!! if leniw.lt.2, the routine will end with ier = 6.
!!
!! maxp1 - integer ( kind = 4 )
!! gives an upper bound on the number of chebyshev
!! moments which can be stored, i.e. for the
!! intervals of lengths abs(b-a)*2**(-l),
!! l=0,1, ..., maxp1-2, maxp1.ge.1
!! if maxp1.lt.1, the routine will end with ier = 6.
!!
!! lenw - integer ( kind = 4 )
!! dimensioning parameter for work
!! lenw must be at least leniw*2+maxp1*25.
!! if lenw.lt.(leniw*2+maxp1*25), the routine will
!! end with ier = 6.
!!
!! last - integer ( kind = 4 )
!! on return, last equals the number of subintervals
!! produced in the subdivision process, which
!! determines the number of significant elements
!! actually in the work arrays.
!!
!! work arrays
!! iwork - integer ( kind = 4 )
!! vector of dimension at least leniw
!! on return, the first k elements of which contain
!! pointers to the error estimates over the
!! subintervals, such that work(limit*3+iwork(1)), ..
!! work(limit*3+iwork(k)) form a decreasing
!! sequence, with limit = lenw/2 , and k = last
!! if last.le.(limit/2+2), and k = limit+1-last
!! otherwise.
!! furthermore, iwork(limit+1), ..., iwork(limit+
!! last) indicate the subdivision levels of the
!! subintervals, such that iwork(limit+i) = l means
!! that the subinterval numbered i is of length
!! abs(b-a)*2**(1-l).
!!
!! work - real ( kind = 8 )
!! vector of dimension at least lenw
!! on return
!! work(1), ..., work(last) contain the left
!! end points of the subintervals in the
!! partition of (a,b),
!! work(limit+1), ..., work(limit+last) contain
!! the right end points,
!! work(limit*2+1), ..., work(limit*2+last) contain
!! the integral approximations over the
!! subintervals,
!! work(limit*3+1), ..., work(limit*3+last)
!! contain the error estimates.
!! work(limit*4+1), ..., work(limit*4+maxp1*25)
!! provide space for storing the chebyshev moments.
!! note that limit = lenw/2.
!!
subroutine dqawo ( f, a, b, omega, integr, epsabs, epsrel, result, abserr, &
neval, ier, leniw, maxp1, lenw, last, iwork, work )
implicit none
real ( kind = 8 ) a,abserr,b,epsabs,epsrel,f,omega,result,work
integer ( kind = 4 ) ier,integr,iwork,last,limit,lenw,leniw,lvl,l
integer ( kind = 4 ) l1
integer ( kind = 4 ) l2
integer ( kind = 4 ) l3
integer ( kind = 4 ) l4
integer ( kind = 4 ) maxp1,momcom,neval
dimension iwork(leniw),work(lenw)
external f
!
! check validity of leniw, maxp1 and lenw.
!
ier = 6
neval = 0
last = 0
result = 0.0D+00
abserr = 0.0D+00
if(leniw.lt.2.or.maxp1.lt.1.or.lenw.lt.(leniw*2+maxp1*25)) &
go to 10
!
! prepare call for dqawoe
!
limit = leniw/2
l1 = limit+1
l2 = limit+l1
l3 = limit+l2
l4 = limit+l3
call dqawoe(f,a,b,omega,integr,epsabs,epsrel,limit,1,maxp1,result, &
abserr,neval,ier,last,work(1),work(l1),work(l2),work(l3), &
iwork(1),iwork(l1),momcom,work(l4))
!
! call error handler if necessary
!
lvl = 0
10 if(ier.eq.6) lvl = 0
if(ier.ne.0) call xerror('abnormal return from dqawo',26,ier,lvl)
return
end subroutine dqawo
!----------------------------------------------------------------------------------------
!> DQAWSE estimates integrals with algebraico-logarithmic end singularities.
!!
!! Modified:
!!
!! 11 September 2015
!!
!! Author:
!!
!! Robert Piessens, Elise de Doncker
!!
!!***purpose the routine calculates an approximation result to a given
!! definite integral i = integral of f*w over (a,b),
!! (where w shows a singular behaviour at the end points,
!! see parameter integr).
!! hopefully satisfying following claim for accuracy
!! abs(i-result).le.max(epsabs,epsrel*abs(i)).
!!
!! Parameters:
!!
!! on entry
!! f - real ( kind = 8 )
!! function subprogram defining the integrand
!! function f(x). the actual name for f needs to be
!! declared e x t e r n a l in the driver program.
!!
!! a - real ( kind = 8 )
!! lower limit of integration
!!
!! b - real ( kind = 8 )
!! upper limit of integration, b.gt.a
!! if b.le.a, the routine will end with ier = 6.
!!
!! alfa - real ( kind = 8 )
!! parameter in the weight function, alfa.gt.(-1)
!! if alfa.le.(-1), the routine will end with
!! ier = 6.
!!
!! beta - real ( kind = 8 )
!! parameter in the weight function, beta.gt.(-1)
!! if beta.le.(-1), the routine will end with
!! ier = 6.
!!
!! integr - integer ( kind = 4 )
!! indicates which weight function is to be used
!! = 1 (x-a)**alfa*(b-x)**beta
!! = 2 (x-a)**alfa*(b-x)**beta*log(x-a)
!! = 3 (x-a)**alfa*(b-x)**beta*log(b-x)
!! = 4 (x-a)**alfa*(b-x)**beta*log(x-a)*log(b-x)
!! if integr.lt.1 or integr.gt.4, the routine
!! will end with ier = 6.
!!
!! epsabs - real ( kind = 8 )
!! absolute accuracy requested
!! epsrel - real ( kind = 8 )
!! relative accuracy requested
!! if epsabs.le.0
!! and epsrel.lt.max(50*rel.mach.acc.,0.5d-28),
!! the routine will end with ier = 6.
!!
!! limit - integer ( kind = 4 )
!! gives an upper bound on the number of subintervals
!! in the partition of (a,b), limit.ge.2
!! if limit.lt.2, the routine will end with ier = 6.
!!
!! on return
!! result - real ( kind = 8 )
!! approximation to the integral
!!
!! abserr - real ( kind = 8 )
!! estimate of the modulus of the absolute error,
!! which should equal or exceed abs(i-result)
!!
!! neval - integer ( kind = 4 )
!! number of integrand evaluations
!!
!! ier - integer ( kind = 4 )
!! ier = 0 normal and reliable termination of the
!! routine. it is assumed that the requested
!! accuracy has been achieved.
!! ier.gt.0 abnormal termination of the routine
!! the estimates for the integral and error
!! are less reliable. it is assumed that the
!! requested accuracy has not been achieved.
!! error messages
!! = 1 maximum number of subdivisions allowed
!! has been achieved. one can allow more
!! subdivisions by increasing the value of
!! limit. however, if this yields no
!! improvement, it is advised to analyze the
!! integrand in order to determine the
!! integration difficulties which prevent the
!! requested tolerance from being achieved.
!! in case of a jump discontinuity or a local
!! singularity of algebraico-logarithmic type
!! at one or more interior points of the
!! integration range, one should proceed by
!! splitting up the interval at these
!! points and calling the integrator on the
!! subranges.
!! = 2 the occurrence of roundoff error is
!! detected, which prevents the requested
!! tolerance from being achieved.
!! = 3 extremely bad integrand behaviour occurs
!! at some points of the integration
!! interval.
!! = 6 the input is invalid, because
!! b.le.a or alfa.le.(-1) or beta.le.(-1), or
!! integr.lt.1 or integr.gt.4, or
!! (epsabs.le.0 and
!! epsrel.lt.max(50*rel.mach.acc.,0.5d-28),
!! or limit.lt.2.
!! result, abserr, neval, rlist(1), elist(1),
!! iord(1) and last are set to zero. alist(1)
!! and blist(1) are set to a and b
!! respectively.
!!
!! alist - real ( kind = 8 )
!! vector of dimension at least limit, the first
!! last elements of which are the left
!! end points of the subintervals in the partition
!! of the given integration range (a,b)
!!
!! blist - real ( kind = 8 )
!! vector of dimension at least limit, the first
!! last elements of which are the right
!! end points of the subintervals in the partition
!! of the given integration range (a,b)
!!
!! rlist - real ( kind = 8 )
!! vector of dimension at least limit,the first
!! last elements of which are the integral
!! approximations on the subintervals
!!
!! elist - real ( kind = 8 )
!! vector of dimension at least limit, the first
!! last elements of which are the moduli of the
!! absolute error estimates on the subintervals
!!
!! iord - integer ( kind = 4 )
!! vector of dimension at least limit, the first k
!! of which are pointers to the error
!! estimates over the subintervals, so that
!! elist(iord(1)), ..., elist(iord(k)) with k = last
!! if last.le.(limit/2+2), and k = limit+1-last
!! otherwise form a decreasing sequence
!!
!! last - integer ( kind = 4 )
!! number of subintervals actually produced in
!! the subdivision process
!!
!! Local parameters:
!!
!! alist - list of left end points of all subintervals
!! considered up to now
!! blist - list of right end points of all subintervals
!! considered up to now
!! rlist(i) - approximation to the integral over
!! (alist(i),blist(i))
!! elist(i) - error estimate applying to rlist(i)
!! maxerr - pointer to the interval with largest
!! error estimate
!! errmax - elist(maxerr)
!! area - sum of the integrals over the subintervals
!! errsum - sum of the errors over the subintervals
!! errbnd - requested accuracy max(epsabs,epsrel*
!! abs(result))
!! *****1 - variable for the left subinterval
!! *****2 - variable for the right subinterval
!! last - index for subdivision
!!
!! machine dependent constants
!!
!! epmach is the largest relative spacing.
!! uflow is the smallest positive magnitude.
!!
subroutine dqawse(f,a,b,alfa,beta,integr,epsabs,epsrel,limit, &
result,abserr,neval,ier,alist,blist,rlist,elist,iord,last)
implicit none
real ( kind = 8 ) a,abserr,alfa,alist,area,area1,area12,area2,a1, &
a2,b,beta,blist,b1,b2,centre,elist,epmach, &
epsabs,epsrel,errbnd,errmax,error1,erro12,error2,errsum,f, &
resas1,resas2,result,rg,rh,ri,rj,rlist,uflow
integer ( kind = 4 ) ier,integr,iord,iroff1,iroff2,k,last,limit
integer ( kind = 4 )maxerr
integer ( kind = 4 ) nev
integer ( kind = 4 ) neval,nrmax
external f
dimension alist(limit),blist(limit),rlist(limit),elist(limit), &
iord(limit),ri(25),rj(25),rh(25),rg(25)
epmach = epsilon ( epmach )
uflow = tiny ( uflow )
!
! test on validity of parameters
!
neval = 0
last = 0
rlist(1) = 0.0D+00
elist(1) = 0.0D+00
iord(1) = 0
result = 0.0D+00
abserr = 0.0D+00
if ( b.le.a .or. &
(epsabs.eq.0.0D+00 .and. epsrel .lt. max ( 0.5D+02*epmach,0.5D-28) ) .or. &
alfa .le. (-0.1D+01) .or. &
beta .le. (-0.1D+01) .or. &
integr.lt.1 .or. &
integr.gt.4 .or. &
limit.lt.2 ) then
ier = 6
return
end if
ier = 0
!
! compute the modified chebyshev moments.
!
call dqmomo(alfa,beta,ri,rj,rg,rh,integr)
!
! integrate over the intervals (a,(a+b)/2) and ((a+b)/2,b).
!
centre = 0.5D+00*(b+a)
call dqc25s(f,a,b,a,centre,alfa,beta,ri,rj,rg,rh,area1, &
error1,resas1,integr,nev)
neval = nev
call dqc25s(f,a,b,centre,b,alfa,beta,ri,rj,rg,rh,area2, &
error2,resas2,integr,nev)
last = 2
neval = neval+nev
result = area1+area2
abserr = error1+error2
!
! test on accuracy.
!
errbnd = max ( epsabs,epsrel* abs ( result))
!
! initialization
!
if ( error2 .le. error1 ) then
alist(1) = a
alist(2) = centre
blist(1) = centre
blist(2) = b
rlist(1) = area1
rlist(2) = area2
elist(1) = error1
elist(2) = error2
else
alist(1) = centre
alist(2) = a
blist(1) = b
blist(2) = centre
rlist(1) = area2
rlist(2) = area1
elist(1) = error2
elist(2) = error1
end if
iord(1) = 1
iord(2) = 2
if(limit.eq.2) ier = 1
if(abserr.le.errbnd.or.ier.eq.1) then
return
end if
errmax = elist(1)
maxerr = 1
nrmax = 1
area = result
errsum = abserr
iroff1 = 0
iroff2 = 0
!
! main do-loop
!
do 60 last = 3,limit
!
! bisect the subinterval with largest error estimate.
!
a1 = alist(maxerr)
b1 = 0.5D+00*(alist(maxerr)+blist(maxerr))
a2 = b1
b2 = blist(maxerr)
call dqc25s(f,a,b,a1,b1,alfa,beta,ri,rj,rg,rh,area1, &
error1,resas1,integr,nev)
neval = neval+nev
call dqc25s(f,a,b,a2,b2,alfa,beta,ri,rj,rg,rh,area2, &
error2,resas2,integr,nev)
neval = neval+nev
!
! improve previous approximations integral and error and test for accuracy.
!
area12 = area1+area2
erro12 = error1+error2
errsum = errsum+erro12-errmax
area = area+area12-rlist(maxerr)
if(a.eq.a1.or.b.eq.b2) go to 30
if(resas1.eq.error1.or.resas2.eq.error2) go to 30
!
! test for roundoff error.
!
if( abs ( rlist(maxerr)-area12).lt.0.1D-04* abs ( area12) &
.and.erro12.ge.0.99D+00*errmax) iroff1 = iroff1+1
if(last.gt.10.and.erro12.gt.errmax) iroff2 = iroff2+1
30 rlist(maxerr) = area1
rlist(last) = area2
!
! test on accuracy.
!
errbnd = max ( epsabs,epsrel* abs ( area))
if(errsum.le.errbnd) go to 35
!
! set error flag in the case that the number of interval
! bisections exceeds limit.
!
if(last.eq.limit) ier = 1
!
! set error flag in the case of roundoff error.
!
if(iroff1.ge.6.or.iroff2.ge.20) ier = 2
!
! set error flag in the case of bad integrand behaviour
! at interior points of integration range.
!
if( max ( abs ( a1), abs ( b2)).le.(0.1D+01+0.1D+03*epmach)* &
( abs ( a2)+0.1D+04*uflow)) ier = 3
!
! append the newly-created intervals to the list.
!
35 if(error2.gt.error1) go to 40
alist(last) = a2
blist(maxerr) = b1
blist(last) = b2
elist(maxerr) = error1
elist(last) = error2
go to 50
40 alist(maxerr) = a2
alist(last) = a1
blist(last) = b1
rlist(maxerr) = area2
rlist(last) = area1
elist(maxerr) = error2
elist(last) = error1
!
! call dqpsrt to maintain the descending ordering
! in the list of error estimates and select the subinterval
! with largest error estimate (to be bisected next).
!
50 call dqpsrt(limit,last,maxerr,errmax,elist,iord,nrmax)
if (ier.ne.0.or.errsum.le.errbnd) go to 70
60 continue
!
! compute final result.
!
70 continue
result = 0.0D+00
do k=1,last
result = result+rlist(k)
end do
abserr = errsum
999 continue
return
end subroutine dqawse
!----------------------------------------------------------------------------------------
!> DQAWS estimates integrals with algebraico-logarithmic endpoint singularities.
!!
!! Modified:
!!
!! 12 September 2015
!!
!! Author:
!!
!! Robert Piessens, Elise de Doncker
!!
!!***purpose the routine calculates an approximation result to a given
!! definite integral i = integral of f*w over (a,b),
!! (where w shows a singular behaviour at the end points
!! see parameter integr).
!! hopefully satisfying following claim for accuracy
!! abs(i-result).le.max(epsabs,epsrel*abs(i)).
!!
!! Parameters:
!!
!! on entry
!! f - real ( kind = 8 )
!! function subprogram defining the integrand
!! function f(x). the actual name for f needs to be
!! declared e x t e r n a l in the driver program.
!!
!! a - real ( kind = 8 )
!! lower limit of integration
!!
!! b - real ( kind = 8 )
!! upper limit of integration, b.gt.a
!! if b.le.a, the routine will end with ier = 6.
!!
!! alfa - real ( kind = 8 )
!! parameter in the integrand function, alfa.gt.(-1)
!! if alfa.le.(-1), the routine will end with
!! ier = 6.
!!
!! beta - real ( kind = 8 )
!! parameter in the integrand function, beta.gt.(-1)
!! if beta.le.(-1), the routine will end with
!! ier = 6.
!!
!! integr - integer ( kind = 4 )
!! indicates which weight function is to be used
!! = 1 (x-a)**alfa*(b-x)**beta
!! = 2 (x-a)**alfa*(b-x)**beta*log(x-a)
!! = 3 (x-a)**alfa*(b-x)**beta*log(b-x)
!! = 4 (x-a)**alfa*(b-x)**beta*log(x-a)*log(b-x)
!! if integr.lt.1 or integr.gt.4, the routine
!! will end with ier = 6.
!!
!! epsabs - real ( kind = 8 )
!! absolute accuracy requested
!! epsrel - real ( kind = 8 )
!! relative accuracy requested
!! if epsabs.le.0
!! and epsrel.lt.max(50*rel.mach.acc.,0.5d-28),
!! the routine will end with ier = 6.
!!
!! on return
!! result - real ( kind = 8 )
!! approximation to the integral
!!
!! abserr - real ( kind = 8 )
!! estimate of the modulus of the absolute error,
!! which should equal or exceed abs(i-result)
!!
!! neval - integer ( kind = 4 )
!! number of integrand evaluations
!!
!! ier - integer ( kind = 4 )
!! ier = 0 normal and reliable termination of the
!! routine. it is assumed that the requested
!! accuracy has been achieved.
!! ier.gt.0 abnormal termination of the routine
!! the estimates for the integral and error
!! are less reliable. it is assumed that the
!! requested accuracy has not been achieved.
!! error messages
!! ier = 1 maximum number of subdivisions allowed
!! has been achieved. one can allow more
!! subdivisions by increasing the value of
!! limit (and taking the according dimension
!! adjustments into account). however, if
!! this yields no improvement it is advised
!! to analyze the integrand, in order to
!! determine the integration difficulties
!! which prevent the requested tolerance from
!! being achieved. in case of a jump
!! discontinuity or a local singularity
!! of algebraico-logarithmic type at one or
!! more interior points of the integration
!! range, one should proceed by splitting up
!! the interval at these points and calling
!! the integrator on the subranges.
!! = 2 the occurrence of roundoff error is
!! detected, which prevents the requested
!! tolerance from being achieved.
!! = 3 extremely bad integrand behaviour occurs
!! at some points of the integration
!! interval.
!! = 6 the input is invalid, because
!! b.le.a or alfa.le.(-1) or beta.le.(-1) or
!! or integr.lt.1 or integr.gt.4 or
!! (epsabs.le.0 and
!! epsrel.lt.max(50*rel.mach.acc.,0.5d-28))
!! or limit.lt.2 or lenw.lt.limit*4.
!! result, abserr, neval, last are set to
!! zero. except when lenw or limit is invalid
!! iwork(1), work(limit*2+1) and
!! work(limit*3+1) are set to zero, work(1)
!! is set to a and work(limit+1) to b.
!!
!! dimensioning parameters
!! limit - integer ( kind = 4 )
!! dimensioning parameter for iwork
!! limit determines the maximum number of
!! subintervals in the partition of the given
!! integration interval (a,b), limit.ge.2.
!! if limit.lt.2, the routine will end with ier = 6.
!!
!! lenw - integer ( kind = 4 )
!! dimensioning parameter for work
!! lenw must be at least limit*4.
!! if lenw.lt.limit*4, the routine will end
!! with ier = 6.
!!
!! last - integer ( kind = 4 )
!! on return, last equals the number of
!! subintervals produced in the subdivision process,
!! which determines the significant number of
!! elements actually in the work arrays.
!!
!! work arrays
!! iwork - integer ( kind = 4 )
!! vector of dimension limit, the first k
!! elements of which contain pointers
!! to the error estimates over the subintervals,
!! such that work(limit*3+iwork(1)), ...,
!! work(limit*3+iwork(k)) form a decreasing
!! sequence with k = last if last.le.(limit/2+2),
!! and k = limit+1-last otherwise
!!
!! work - real ( kind = 8 )
!! vector of dimension lenw
!! on return
!! work(1), ..., work(last) contain the left
!! end points of the subintervals in the
!! partition of (a,b),
!! work(limit+1), ..., work(limit+last) contain
!! the right end points,
!! work(limit*2+1), ..., work(limit*2+last)
!! contain the integral approximations over
!! the subintervals,
!! work(limit*3+1), ..., work(limit*3+last)
!! contain the error estimates.
!!
subroutine dqaws ( f, a, b, alfa, beta, integr, epsabs, epsrel, result, &
abserr, neval, ier, limit, lenw, last, iwork, work )
implicit none
real ( kind = 8 ) a,abserr,alfa,b,beta,epsabs,epsrel,f,result,work
integer ( kind = 4 ) ier,integr,iwork,last,lenw,limit,lvl,l1,l2,l3
integer ( kind = 4 ) neval
dimension iwork(limit),work(lenw)
external f
!
! check validity of limit and lenw.
!
ier = 6
neval = 0
last = 0
result = 0.0D+00
abserr = 0.0D+00
if(limit.lt.2.or.lenw.lt.limit*4) go to 10
!
! prepare call for dqawse.
!
l1 = limit+1
l2 = limit+l1
l3 = limit+l2
call dqawse(f,a,b,alfa,beta,integr,epsabs,epsrel,limit,result, &
abserr,neval,ier,work(1),work(l1),work(l2),work(l3),iwork,last)
!
! call error handler if necessary.
!
lvl = 0
10 if(ier.eq.6) lvl = 1
if(ier.ne.0) call xerror('abnormal return from dqaws',26,ier,lvl)
return
end subroutine dqaws
!----------------------------------------------------------------------------------------
!> DQC25C returns integration rules for Cauchy Principal Value integrals.
!!
!! Modified:
!!
!! 11 September 2015
!!
!! Author:
!!
!! Robert Piessens, Elise de Doncker
!!
!!***purpose to compute i = integral of f*w over (a,b) with
!! error estimate, where w(x) = 1/(x-c)
!!
!! Parameters:
!!
!! f - real ( kind = 8 )
!! function subprogram defining the integrand function
!! f(x). the actual name for f needs to be declared
!! e x t e r n a l in the driver program.
!!
!! a - real ( kind = 8 )
!! left end point of the integration interval
!!
!! b - real ( kind = 8 )
!! right end point of the integration interval, b.gt.a
!!
!! c - real ( kind = 8 )
!! parameter in the weight function
!!
!! result - real ( kind = 8 )
!! approximation to the integral
!! result is computed by using a generalized
!! clenshaw-curtis method if c lies within ten percent
!! of the integration interval. in the other case the
!! 15-point kronrod rule obtained by optimal addition
!! of abscissae to the 7-point gauss rule, is applied.
!!
!! abserr - real ( kind = 8 )
!! estimate of the modulus of the absolute error,
!! which should equal or exceed abs(i-result)
!!
!! krul - integer ( kind = 4 )
!! key which is decreased by 1 if the 15-point
!! gauss-kronrod scheme has been used
!!
!! neval - integer ( kind = 4 )
!! number of integrand evaluations
!!
!! Local Parameters:
!!
!! fval - value of the function f at the points
!! cos(k*pi/24), k = 0, ..., 24
!! cheb12 - chebyshev series expansion coefficients,
!! for the function f, of degree 12
!! cheb24 - chebyshev series expansion coefficients,
!! for the function f, of degree 24
!! res12 - approximation to the integral corresponding
!! to the use of cheb12
!! res24 - approximation to the integral corresponding
!! to the use of cheb24
!! dqwgtc - external function subprogram defining
!! the weight function
!! hlgth - half-length of the interval
!! centr - mid point of the interval
!!
!! the vector x contains the values cos(k*pi/24),
!! k = 1, ..., 11, to be used for the chebyshev series
!! expansion of f
!!
subroutine dqc25c(f,a,b,c,result,abserr,krul,neval)
implicit none
real ( kind = 8 ) a,abserr,ak22,amom0,amom1,amom2,b,c,cc,centr, &
cheb12,cheb24,dqwgtc,f,fval,hlgth,p2,p3,p4,resabs, &
resasc,result,res12,res24,u,x
integer ( kind = 4 ) i,isym,k,kp,krul,neval
dimension x(11),fval(25),cheb12(13),cheb24(25)
external f
external dqwgtc
data x(1) / 0.991444861373810411144557526928563d0 /
data x(2) / 0.965925826289068286749743199728897d0 /
data x(3) / 0.923879532511286756128183189396788d0 /
data x(4) / 0.866025403784438646763723170752936d0 /
data x(5) / 0.793353340291235164579776961501299d0 /
data x(6) / 0.707106781186547524400844362104849d0 /
data x(7) / 0.608761429008720639416097542898164d0 /
data x(8) / 0.500000000000000000000000000000000d0 /
data x(9) / 0.382683432365089771728459984030399d0 /
data x(10) / 0.258819045102520762348898837624048d0 /
data x(11) / 0.130526192220051591548406227895489d0 /
!
! check the position of c.
!
cc = (0.2D+01*c-b-a)/(b-a)
if( abs ( cc).lt.0.11D+01) go to 10
!
! apply the 15-point gauss-kronrod scheme.
!
krul = krul-1
call dqk15w(f,dqwgtc,c,p2,p3,p4,kp,a,b,result,abserr, &
resabs,resasc)
neval = 15
if (resasc.eq.abserr) krul = krul+1
go to 50
!
! use the generalized clenshaw-curtis method.
!
10 hlgth = 0.5D+00*(b-a)
centr = 0.5D+00*(b+a)
neval = 25
fval(1) = 0.5D+00*f(hlgth+centr)
fval(13) = f(centr)
fval(25) = 0.5D+00*f(centr-hlgth)
do i=2,12
u = hlgth*x(i-1)
isym = 26-i
fval(i) = f(u+centr)
fval(isym) = f(centr-u)
end do
!
! compute the chebyshev series expansion.
!
call dqcheb(x,fval,cheb12,cheb24)
!
! the modified chebyshev moments are computed by forward
! recursion, using amom0 and amom1 as starting values.
!
amom0 = log ( abs ( (0.1D+01-cc)/(0.1D+01+cc)))
amom1 = 0.2D+01+cc*amom0
res12 = cheb12(1)*amom0+cheb12(2)*amom1
res24 = cheb24(1)*amom0+cheb24(2)*amom1
do k=3,13
amom2 = 0.2D+01*cc*amom1-amom0
ak22 = (k-2)*(k-2)
if((k/2)*2.eq.k) amom2 = amom2-0.4D+01/(ak22-0.1D+01)
res12 = res12+cheb12(k)*amom2
res24 = res24+cheb24(k)*amom2
amom0 = amom1
amom1 = amom2
end do
do k=14,25
amom2 = 0.2D+01*cc*amom1-amom0
ak22 = (k-2)*(k-2)
if((k/2)*2.eq.k) amom2 = amom2-0.4D+01/(ak22-0.1D+01)
res24 = res24+cheb24(k)*amom2
amom0 = amom1
amom1 = amom2
end do
result = res24
abserr = abs ( res24-res12)
50 continue
return
end subroutine dqc25c
!----------------------------------------------------------------------------------------
!> DQC25F returns integration rules for functions with a COS or SIN factor.
!!
!! Modified:
!!
!! 11 September 2015
!!
!! Author:
!!
!! Robert Piessens, Elise de Doncker
!!
!!***purpose to compute the integral i=integral of f(x) over (a,b)
!! where w(x) = cos(omega*x) or w(x)=sin(omega*x) and to
!! compute j = integral of abs(f) over (a,b). for small value
!! of omega or small intervals (a,b) the 15-point gauss-kronro
!! rule is used. otherwise a generalized clenshaw-curtis
!! method is used.
!!
!! Parameters:
!!
!! on entry
!! f - real ( kind = 8 )
!! function subprogram defining the integrand
!! function f(x). the actual name for f needs to
!! be declared e x t e r n a l in the calling program.
!!
!! a - real ( kind = 8 )
!! lower limit of integration
!!
!! b - real ( kind = 8 )
!! upper limit of integration
!!
!! omega - real ( kind = 8 )
!! parameter in the weight function
!!
!! integr - integer ( kind = 4 )
!! indicates which weight function is to be used
!! integr = 1 w(x) = cos(omega*x)
!! integr = 2 w(x) = sin(omega*x)
!!
!! nrmom - integer ( kind = 4 )
!! the length of interval (a,b) is equal to the length
!! of the original integration interval divided by
!! 2**nrmom (we suppose that the routine is used in an
!! adaptive integration process, otherwise set
!! nrmom = 0). nrmom must be zero at the first call.
!!
!! maxp1 - integer ( kind = 4 )
!! gives an upper bound on the number of chebyshev
!! moments which can be stored, i.e. for the
!! intervals of lengths abs(bb-aa)*2**(-l),
!! l = 0,1,2, ..., maxp1-2.
!!
!! ksave - integer ( kind = 4 )
!! key which is one when the moments for the
!! current interval have been computed
!!
!! on return
!! result - real ( kind = 8 )
!! approximation to the integral i
!!
!! abserr - real ( kind = 8 )
!! estimate of the modulus of the absolute
!! error, which should equal or exceed abs(i-result)
!!
!! neval - integer ( kind = 4 )
!! number of integrand evaluations
!!
!! resabs - real ( kind = 8 )
!! approximation to the integral j
!!
!! resasc - real ( kind = 8 )
!! approximation to the integral of abs(f-i/(b-a))
!!
!! on entry and return
!! momcom - integer ( kind = 4 )
!! for each interval length we need to compute the
!! chebyshev moments. momcom counts the number of
!! intervals for which these moments have already been
!! computed. if nrmom.lt.momcom or ksave = 1, the
!! chebyshev moments for the interval (a,b) have
!! already been computed and stored, otherwise we
!! compute them and we increase momcom.
!!
!! chebmo - real ( kind = 8 )
!! array of dimension at least (maxp1,25) containing
!! the modified chebyshev moments for the first momcom
!! momcom interval lengths
!!
!! Local Parameters:
!!
!! the vector x contains the values cos(k*pi/24)
!! k = 1, ...,11, to be used for the chebyshev expansion of f
!!
!! centr - mid point of the integration interval
!! hlgth - half-length of the integration interval
!! fval - value of the function f at the points
!! (b-a)*0.5*cos(k*pi/12) + (b+a)*0.5, k = 0, ..., 24
!! cheb12 - coefficients of the chebyshev series expansion
!! of degree 12, for the function f, in the
!! interval (a,b)
!! cheb24 - coefficients of the chebyshev series expansion
!! of degree 24, for the function f, in the
!! interval (a,b)
!! resc12 - approximation to the integral of
!! cos(0.5*(b-a)*omega*x)*f(0.5*(b-a)*x+0.5*(b+a))
!! over (-1,+1), using the chebyshev series
!! expansion of degree 12
!! resc24 - approximation to the same integral, using the
!! chebyshev series expansion of degree 24
!! ress12 - the analogue of resc12 for the sine
!! ress24 - the analogue of resc24 for the sine
!!
!!
!! machine dependent constant
!!
!! oflow is the largest positive magnitude.
!!
subroutine dqc25f(f,a,b,omega,integr,nrmom,maxp1,ksave,result, &
abserr,neval,resabs,resasc,momcom,chebmo)
implicit none
real ( kind = 8 ) a,abserr,ac,an,an2,as,asap,ass,b,centr,chebmo, &
cheb12,cheb24,conc,cons,cospar,d,dqwgtf,d1, &
d2,estc,ests,f,fval,hlgth,oflow,omega,parint,par2,par22, &
p2,p3,p4,resabs,resasc,resc12,resc24,ress12,ress24,result, &
sinpar,v,x
integer ( kind = 4 ) i,iers,integr,isym,j,k,ksave,m,momcom,neval, maxp1,&
noequ,noeq1,nrmom
dimension chebmo(maxp1,25),cheb12(13),cheb24(25),d(25),d1(25), &
d2(25),fval(25),v(28),x(11)
external f,dqwgtf
data x(1) / 0.991444861373810411144557526928563d0 /
data x(2) / 0.965925826289068286749743199728897d0 /
data x(3) / 0.923879532511286756128183189396788d0 /
data x(4) / 0.866025403784438646763723170752936d0 /
data x(5) / 0.793353340291235164579776961501299d0 /
data x(6) / 0.707106781186547524400844362104849d0 /
data x(7) / 0.608761429008720639416097542898164d0 /
data x(8) / 0.500000000000000000000000000000000d0 /
data x(9) / 0.382683432365089771728459984030399d0 /
data x(10) / 0.258819045102520762348898837624048d0 /
data x(11) / 0.130526192220051591548406227895489d0 /
oflow = huge ( oflow )
centr = 0.5D+00*(b+a)
hlgth = 0.5D+00*(b-a)
parint = omega*hlgth
!
! compute the integral using the 15-point gauss-kronrod
! formula if the value of the parameter in the integrand is small.
!
if( abs ( parint).gt.0.2D+01) go to 10
call dqk15w(f,dqwgtf,omega,p2,p3,p4,integr,a,b,result, &
abserr,resabs,resasc)
neval = 15
go to 170
!
! compute the integral using the generalized clenshaw-
! curtis method.
!
10 conc = hlgth*dcos(centr*omega)
cons = hlgth*dsin(centr*omega)
resasc = oflow
neval = 25
!
! check whether the chebyshev moments for this interval
! have already been computed.
!
if(nrmom.lt.momcom.or.ksave.eq.1) go to 120
!
! compute a new set of chebyshev moments.
!
m = momcom+1
par2 = parint*parint
par22 = par2+0.2D+01
sinpar = dsin(parint)
cospar = dcos(parint)
!
! compute the chebyshev moments with respect to cosine.
!
v(1) = 0.2D+01*sinpar/parint
v(2) = (0.8D+01*cospar+(par2+par2-0.8D+01)*sinpar/parint)/par2
v(3) = (0.32D+02*(par2-0.12D+02)*cospar+(0.2D+01* &
((par2-0.80D+02)*par2+0.192D+03)*sinpar)/parint)/(par2*par2)
ac = 0.8D+01*cospar
as = 0.24D+02*parint*sinpar
if( abs ( parint).gt.0.24D+02) go to 30
!
! compute the chebyshev moments as the solutions of a
! boundary value problem with 1 initial value (v(3)) and 1
! end value (computed using an asymptotic formula).
!
noequ = 25
noeq1 = noequ-1
an = 0.6D+01
do k = 1,noeq1
an2 = an*an
d(k) = -0.2D+01*(an2-0.4D+01)*(par22-an2-an2)
d2(k) = (an-0.1D+01)*(an-0.2D+01)*par2
d1(k+1) = (an+0.3D+01)*(an+0.4D+01)*par2
v(k+3) = as-(an2-0.4D+01)*ac
an = an+0.2D+01
end do
an2 = an*an
d(noequ) = -0.2D+01*(an2-0.4D+01)*(par22-an2-an2)
v(noequ+3) = as-(an2-0.4D+01)*ac
v(4) = v(4)-0.56D+02*par2*v(3)
ass = parint*sinpar
asap = (((((0.210D+03*par2-0.1D+01)*cospar-(0.105D+03*par2 &
-0.63D+02)*ass)/an2-(0.1D+01-0.15D+02*par2)*cospar &
+0.15D+02*ass)/an2-cospar+0.3D+01*ass)/an2-cospar)/an2
v(noequ+3) = v(noequ+3)-0.2D+01*asap*par2*(an-0.1D+01)* &
(an-0.2D+01)
!
! solve the tridiagonal system by means of gaussian
! elimination with partial pivoting.
!
call dgtsl(noequ,d1,d,d2,v(4),iers)
go to 50
!
! compute the chebyshev moments by means of forward recursion.
!
30 an = 0.4D+01
do i = 4,13
an2 = an*an
v(i) = ((an2-0.4D+01)*(0.2D+01*(par22-an2-an2)*v(i-1)-ac) &
+as-par2*(an+0.1D+01)*(an+0.2D+01)*v(i-2))/ &
(par2*(an-0.1D+01)*(an-0.2D+01))
an = an+0.2D+01
end do
50 continue
do j = 1,13
chebmo(m,2*j-1) = v(j)
end do
!
! compute the chebyshev moments with respect to sine.
!
v(1) = 0.2D+01*(sinpar-parint*cospar)/par2
v(2) = (0.18D+02-0.48D+02/par2)*sinpar/par2 &
+(-0.2D+01+0.48D+02/par2)*cospar/parint
ac = -0.24D+02*parint*cospar
as = -0.8D+01*sinpar
if( abs ( parint).gt.0.24D+02) go to 80
!
! compute the chebyshev moments as the solutions of a boundary
! value problem with 1 initial value (v(2)) and 1 end value
! (computed using an asymptotic formula).
!
an = 0.5D+01
do k = 1,noeq1
an2 = an*an
d(k) = -0.2D+01*(an2-0.4D+01)*(par22-an2-an2)
d2(k) = (an-0.1D+01)*(an-0.2D+01)*par2
d1(k+1) = (an+0.3D+01)*(an+0.4D+01)*par2
v(k+2) = ac+(an2-0.4D+01)*as
an = an+0.2D+01
end do
an2 = an*an
d(noequ) = -0.2D+01*(an2-0.4D+01)*(par22-an2-an2)
v(noequ+2) = ac+(an2-0.4D+01)*as
v(3) = v(3)-0.42D+02*par2*v(2)
ass = parint*cospar
asap = (((((0.105D+03*par2-0.63D+02)*ass+(0.210D+03*par2 &
-0.1D+01)*sinpar)/an2+(0.15D+02*par2-0.1D+01)*sinpar- &
0.15D+02*ass)/an2-0.3D+01*ass-sinpar)/an2-sinpar)/an2
v(noequ+2) = v(noequ+2)-0.2D+01*asap*par2*(an-0.1D+01) &
*(an-0.2D+01)
!
! solve the tridiagonal system by means of gaussian
! elimination with partial pivoting.
!
call dgtsl(noequ,d1,d,d2,v(3),iers)
go to 100
!
! compute the chebyshev moments by means of forward recursion.
!
80 an = 0.3D+01
do i = 3,12
an2 = an*an
v(i) = ((an2-0.4D+01)*(0.2D+01*(par22-an2-an2)*v(i-1)+as) &
+ac-par2*(an+0.1D+01)*(an+0.2D+01)*v(i-2)) &
/(par2*(an-0.1D+01)*(an-0.2D+01))
an = an+0.2D+01
end do
100 continue
do j = 1,12
chebmo(m,2*j) = v(j)
end do
120 if (nrmom.lt.momcom) m = nrmom+1
if (momcom.lt.(maxp1-1).and.nrmom.ge.momcom) momcom = momcom+1
!
! compute the coefficients of the chebyshev expansions
! of degrees 12 and 24 of the function f.
!
fval(1) = 0.5D+00*f(centr+hlgth)
fval(13) = f(centr)
fval(25) = 0.5D+00*f(centr-hlgth)
do i = 2,12
isym = 26-i
fval(i) = f(hlgth*x(i-1)+centr)
fval(isym) = f(centr-hlgth*x(i-1))
end do
call dqcheb(x,fval,cheb12,cheb24)
!
! compute the integral and error estimates.
!
resc12 = cheb12(13)*chebmo(m,13)
ress12 = 0.0D+00
k = 11
do j = 1,6
resc12 = resc12+cheb12(k)*chebmo(m,k)
ress12 = ress12+cheb12(k+1)*chebmo(m,k+1)
k = k-2
end do
resc24 = cheb24(25)*chebmo(m,25)
ress24 = 0.0D+00
resabs = abs ( cheb24(25))
k = 23
do j = 1,12
resc24 = resc24+cheb24(k)*chebmo(m,k)
ress24 = ress24+cheb24(k+1)*chebmo(m,k+1)
resabs = abs ( cheb24(k))+ abs ( cheb24(k+1))
k = k-2
end do
estc = abs ( resc24-resc12)
ests = abs ( ress24-ress12)
resabs = resabs* abs ( hlgth)
if(integr.eq.2) go to 160
result = conc*resc24-cons*ress24
abserr = abs ( conc*estc)+ abs ( cons*ests)
go to 170
160 result = conc*ress24+cons*resc24
abserr = abs ( conc*ests)+ abs ( cons*estc)
170 continue
return
end subroutine dqc25f
!----------------------------------------------------------------------------------------
!> DQC25S returns rules for algebraico-logarithmic end point singularities.
!!
!! Modified:
!!
!! 11 September 2015
!!
!! Author:
!!
!! Robert Piessens, Elise de Doncker
!!
!!***purpose to compute i = integral of f*w over (bl,br), with error
!! estimate, where the weight function w has a singular
!! behaviour of algebraico-logarithmic type at the points
!! a and/or b. (bl,br) is a part of (a,b).
!!
!! Parameters:
!!
!! f - real ( kind = 8 )
!! function subprogram defining the integrand
!! f(x). the actual name for f needs to be declared
!! e x t e r n a l in the driver program.
!!
!! a - real ( kind = 8 )
!! left end point of the original interval
!!
!! b - real ( kind = 8 )
!! right end point of the original interval, b.gt.a
!!
!! bl - real ( kind = 8 )
!! lower limit of integration, bl.ge.a
!!
!! br - real ( kind = 8 )
!! upper limit of integration, br.le.b
!!
!! alfa - real ( kind = 8 )
!! parameter in the weight function
!!
!! beta - real ( kind = 8 )
!! parameter in the weight function
!!
!! ri,rj,rg,rh - real ( kind = 8 )
!! modified chebyshev moments for the application
!! of the generalized clenshaw-curtis
!! method (computed in routine dqmomo)
!!
!! result - real ( kind = 8 )
!! approximation to the integral
!! result is computed by using a generalized
!! clenshaw-curtis method if b1 = a or br = b.
!! in all other cases the 15-point kronrod
!! rule is applied, obtained by optimal addition of
!! abscissae to the 7-point gauss rule.
!!
!! abserr - real ( kind = 8 )
!! estimate of the modulus of the absolute error,
!! which should equal or exceed abs(i-result)
!!
!! resasc - real ( kind = 8 )
!! approximation to the integral of abs(f*w-i/(b-a))
!!
!! integr - integer ( kind = 4 )
!! which determines the weight function
!! = 1 w(x) = (x-a)**alfa*(b-x)**beta
!! = 2 w(x) = (x-a)**alfa*(b-x)**beta*log(x-a)
!! = 3 w(x) = (x-a)**alfa*(b-x)**beta*log(b-x)
!! = 4 w(x) = (x-a)**alfa*(b-x)**beta*log(x-a)*
!! log(b-x)
!!
!! nev - integer ( kind = 4 )
!! number of integrand evaluations
!!
!! Local Parameters:
!!
!! the vector x contains the values cos(k*pi/24)
!! k = 1, ..., 11, to be used for the computation of the
!! chebyshev series expansion of f.
!!
!! fval - value of the function f at the points
!! (br-bl)*0.5*cos(k*pi/24)+(br+bl)*0.5
!! k = 0, ..., 24
!! cheb12 - coefficients of the chebyshev series expansion
!! of degree 12, for the function f, in the
!! interval (bl,br)
!! cheb24 - coefficients of the chebyshev series expansion
!! of degree 24, for the function f, in the
!! interval (bl,br)
!! res12 - approximation to the integral obtained from cheb12
!! res24 - approximation to the integral obtained from cheb24
!! dqwgts - external function subprogram defining
!! the four possible weight functions
!! hlgth - half-length of the interval (bl,br)
!! centr - mid point of the interval (bl,br)
!!
subroutine dqc25s(f,a,b,bl,br,alfa,beta,ri,rj,rg,rh,result, &
abserr,resasc,integr,nev)
implicit none
real ( kind = 8 ) a,abserr,alfa,b,beta,bl,br,centr,cheb12,cheb24, &
dc,f,factor,fix,fval,hlgth,resabs,resasc,result,res12, &
res24,rg,rh,ri,rj,u,dqwgts,x
integer ( kind = 4 ) i,integr,isym,nev
dimension cheb12(13),cheb24(25),fval(25),rg(25),rh(25),ri(25), &
rj(25),x(11)
external f,dqwgts
data x(1) / 0.991444861373810411144557526928563d0 /
data x(2) / 0.965925826289068286749743199728897d0 /
data x(3) / 0.923879532511286756128183189396788d0 /
data x(4) / 0.866025403784438646763723170752936d0 /
data x(5) / 0.793353340291235164579776961501299d0 /
data x(6) / 0.707106781186547524400844362104849d0 /
data x(7) / 0.608761429008720639416097542898164d0 /
data x(8) / 0.500000000000000000000000000000000d0 /
data x(9) / 0.382683432365089771728459984030399d0 /
data x(10) / 0.258819045102520762348898837624048d0 /
data x(11) / 0.130526192220051591548406227895489d0 /
nev = 25
if(bl.eq.a.and.(alfa.ne.0.0D+00.or.integr.eq.2.or.integr.eq.4)) &
go to 10
if(br.eq.b.and.(beta.ne.0.0D+00.or.integr.eq.3.or.integr.eq.4)) &
go to 140
!
! if a.gt.bl and b.lt.br, apply the 15-point gauss-kronrod scheme.
!
!
call dqk15w(f,dqwgts,a,b,alfa,beta,integr,bl,br, &
result,abserr,resabs,resasc)
nev = 15
go to 270
!
! this part of the program is executed only if a = bl.
!
! compute the chebyshev series expansion of the
! following function
! f1 = (0.5*(b+b-br-a)-0.5*(br-a)*x)**beta
! *f(0.5*(br-a)*x+0.5*(br+a))
!
10 hlgth = 0.5D+00*(br-bl)
centr = 0.5D+00*(br+bl)
fix = b-centr
fval(1) = 0.5D+00*f(hlgth+centr)*(fix-hlgth)**beta
fval(13) = f(centr)*(fix**beta)
fval(25) = 0.5D+00*f(centr-hlgth)*(fix+hlgth)**beta
do i=2,12
u = hlgth*x(i-1)
isym = 26-i
fval(i) = f(u+centr)*(fix-u)**beta
fval(isym) = f(centr-u)*(fix+u)**beta
end do
factor = hlgth**(alfa+0.1D+01)
result = 0.0D+00
abserr = 0.0D+00
res12 = 0.0D+00
res24 = 0.0D+00
if(integr.gt.2) go to 70
call dqcheb(x,fval,cheb12,cheb24)
!
! integr = 1 (or 2)
!
do i=1,13
res12 = res12+cheb12(i)*ri(i)
res24 = res24+cheb24(i)*ri(i)
end do
do i=14,25
res24 = res24+cheb24(i)*ri(i)
end do
if(integr.eq.1) go to 130
!
! integr = 2
!
dc = log (br-bl)
result = res24*dc
abserr = abs ( (res24-res12)*dc)
res12 = 0.0D+00
res24 = 0.0D+00
do i=1,13
res12 = res12+cheb12(i)*rg(i)
res24 = res12+cheb24(i)*rg(i)
end do
do i=14,25
res24 = res24+cheb24(i)*rg(i)
end do
go to 130
!
! compute the chebyshev series expansion of the
! following function
! f4 = f1*log(0.5*(b+b-br-a)-0.5*(br-a)*x)
!
70 fval(1) = fval(1)* log (fix-hlgth)
fval(13) = fval(13)* log (fix)
fval(25) = fval(25)* log (fix+hlgth)
do i=2,12
u = hlgth*x(i-1)
isym = 26-i
fval(i) = fval(i)* log (fix-u)
fval(isym) = fval(isym)* log (fix+u)
end do
call dqcheb(x,fval,cheb12,cheb24)
!
! integr = 3 (or 4)
!
do i=1,13
res12 = res12+cheb12(i)*ri(i)
res24 = res24+cheb24(i)*ri(i)
end do
do i=14,25
res24 = res24+cheb24(i)*ri(i)
end do
if(integr.eq.3) go to 130
!
! integr = 4
!
dc = log (br-bl)
result = res24*dc
abserr = abs ( (res24-res12)*dc)
res12 = 0.0D+00
res24 = 0.0D+00
do i=1,13
res12 = res12+cheb12(i)*rg(i)
res24 = res24+cheb24(i)*rg(i)
end do
do i=14,25
res24 = res24+cheb24(i)*rg(i)
end do
130 result = (result+res24)*factor
abserr = (abserr+ abs ( res24-res12))*factor
go to 270
!
! this part of the program is executed only if b = br.
!
! compute the chebyshev series expansion of the following function:
!
! f2 = (0.5*(b+bl-a-a)+0.5*(b-bl)*x)**alfa*f(0.5*(b-bl)*x+0.5*(b+bl))
!
140 hlgth = 0.5D+00*(br-bl)
centr = 0.5D+00*(br+bl)
fix = centr-a
fval(1) = 0.5D+00*f(hlgth+centr)*(fix+hlgth)**alfa
fval(13) = f(centr)*(fix**alfa)
fval(25) = 0.5D+00*f(centr-hlgth)*(fix-hlgth)**alfa
do i=2,12
u = hlgth*x(i-1)
isym = 26-i
fval(i) = f(u+centr)*(fix+u)**alfa
fval(isym) = f(centr-u)*(fix-u)**alfa
end do
factor = hlgth**(beta+0.1D+01)
result = 0.0D+00
abserr = 0.0D+00
res12 = 0.0D+00
res24 = 0.0D+00
if(integr.eq.2.or.integr.eq.4) go to 200
!
! integr = 1 (or 3)
!
call dqcheb(x,fval,cheb12,cheb24)
do i=1,13
res12 = res12+cheb12(i)*rj(i)
res24 = res24+cheb24(i)*rj(i)
end do
do i=14,25
res24 = res24+cheb24(i)*rj(i)
end do
if(integr.eq.1) go to 260
!
! integr = 3
!
dc = log (br-bl)
result = res24*dc
abserr = abs ( (res24-res12)*dc)
res12 = 0.0D+00
res24 = 0.0D+00
do i=1,13
res12 = res12+cheb12(i)*rh(i)
res24 = res24+cheb24(i)*rh(i)
end do
do i=14,25
res24 = res24+cheb24(i)*rh(i)
end do
go to 260
!
! compute the chebyshev series expansion of the
! following function
! f3 = f2*log(0.5*(b-bl)*x+0.5*(b+bl-a-a))
!
200 fval(1) = fval(1)* log (hlgth+fix)
fval(13) = fval(13)* log (fix)
fval(25) = fval(25)* log (fix-hlgth)
do i=2,12
u = hlgth*x(i-1)
isym = 26-i
fval(i) = fval(i)* log (u+fix)
fval(isym) = fval(isym)* log (fix-u)
end do
call dqcheb(x,fval,cheb12,cheb24)
!
! integr = 2 (or 4)
!
do i=1,13
res12 = res12+cheb12(i)*rj(i)
res24 = res24+cheb24(i)*rj(i)
end do
do i=14,25
res24 = res24+cheb24(i)*rj(i)
end do
if(integr.eq.2) go to 260
dc = log (br-bl)
result = res24*dc
abserr = abs ( (res24-res12)*dc)
res12 = 0.0D+00
res24 = 0.0D+00
!
! integr = 4
!
do i=1,13
res12 = res12+cheb12(i)*rh(i)
res24 = res24+cheb24(i)*rh(i)
end do
do i=14,25
res24 = res24+cheb24(i)*rh(i)
end do
260 result = (result+res24)*factor
abserr = (abserr+ abs ( res24-res12))*factor
270 return
end subroutine dqc25s
!----------------------------------------------------------------------------------------
!> DQCHEB computes the Chebyshev series expansion.
!!
!! Modified:
!!
!! 11 September 2015
!!
!! Author:
!!
!! Robert Piessens, Elise de Doncker
!!
!!***purpose this routine computes the chebyshev series expansion
!! of degrees 12 and 24 of a function using a
!! fast fourier transform method
!! f(x) = sum(k=1,..,13) (cheb12(k)*t(k-1,x)),
!! f(x) = sum(k=1,..,25) (cheb24(k)*t(k-1,x)),
!! where t(k,x) is the chebyshev polynomial of degree k.
!!
!! Parameters:
!!
!! on entry
!! x - real ( kind = 8 )
!! vector of dimension 11 containing the
!! values cos(k*pi/24), k = 1, ..., 11
!!
!! fval - real ( kind = 8 )
!! vector of dimension 25 containing the
!! function values at the points
!! (b+a+(b-a)*cos(k*pi/24))/2, k = 0, ...,24,
!! where (a,b) is the approximation interval.
!! fval(1) and fval(25) are divided by two
!! (these values are destroyed at output).
!!
!! on return
!! cheb12 - real ( kind = 8 )
!! vector of dimension 13 containing the
!! chebyshev coefficients for degree 12
!!
!! cheb24 - real ( kind = 8 )
!! vector of dimension 25 containing the
!! chebyshev coefficients for degree 24
!!
subroutine dqcheb ( x, fval, cheb12, cheb24 )
implicit none
real ( kind = 8 ) alam,alam1,alam2,cheb12,cheb24,fval,part1,part2, &
part3,v,x
integer ( kind = 4 ) i,j
dimension cheb12(13),cheb24(25),fval(25),v(12),x(11)
do i=1,12
j = 26-i
v(i) = fval(i)-fval(j)
fval(i) = fval(i)+fval(j)
end do
alam1 = v(1)-v(9)
alam2 = x(6)*(v(3)-v(7)-v(11))
cheb12(4) = alam1+alam2
cheb12(10) = alam1-alam2
alam1 = v(2)-v(8)-v(10)
alam2 = v(4)-v(6)-v(12)
alam = x(3)*alam1+x(9)*alam2
cheb24(4) = cheb12(4)+alam
cheb24(22) = cheb12(4)-alam
alam = x(9)*alam1-x(3)*alam2
cheb24(10) = cheb12(10)+alam
cheb24(16) = cheb12(10)-alam
part1 = x(4)*v(5)
part2 = x(8)*v(9)
part3 = x(6)*v(7)
alam1 = v(1)+part1+part2
alam2 = x(2)*v(3)+part3+x(10)*v(11)
cheb12(2) = alam1+alam2
cheb12(12) = alam1-alam2
alam = x(1)*v(2)+x(3)*v(4)+x(5)*v(6)+x(7)*v(8) &
+x(9)*v(10)+x(11)*v(12)
cheb24(2) = cheb12(2)+alam
cheb24(24) = cheb12(2)-alam
alam = x(11)*v(2)-x(9)*v(4)+x(7)*v(6)-x(5)*v(8) &
+x(3)*v(10)-x(1)*v(12)
cheb24(12) = cheb12(12)+alam
cheb24(14) = cheb12(12)-alam
alam1 = v(1)-part1+part2
alam2 = x(10)*v(3)-part3+x(2)*v(11)
cheb12(6) = alam1+alam2
cheb12(8) = alam1-alam2
alam = x(5)*v(2)-x(9)*v(4)-x(1)*v(6) &
-x(11)*v(8)+x(3)*v(10)+x(7)*v(12)
cheb24(6) = cheb12(6)+alam
cheb24(20) = cheb12(6)-alam
alam = x(7)*v(2)-x(3)*v(4)-x(11)*v(6)+x(1)*v(8) &
-x(9)*v(10)-x(5)*v(12)
cheb24(8) = cheb12(8)+alam
cheb24(18) = cheb12(8)-alam
do i=1,6
j = 14-i
v(i) = fval(i)-fval(j)
fval(i) = fval(i)+fval(j)
end do
alam1 = v(1)+x(8)*v(5)
alam2 = x(4)*v(3)
cheb12(3) = alam1+alam2
cheb12(11) = alam1-alam2
cheb12(7) = v(1)-v(5)
alam = x(2)*v(2)+x(6)*v(4)+x(10)*v(6)
cheb24(3) = cheb12(3)+alam
cheb24(23) = cheb12(3)-alam
alam = x(6)*(v(2)-v(4)-v(6))
cheb24(7) = cheb12(7)+alam
cheb24(19) = cheb12(7)-alam
alam = x(10)*v(2)-x(6)*v(4)+x(2)*v(6)
cheb24(11) = cheb12(11)+alam
cheb24(15) = cheb12(11)-alam
do i=1,3
j = 8-i
v(i) = fval(i)-fval(j)
fval(i) = fval(i)+fval(j)
end do
cheb12(5) = v(1)+x(8)*v(3)
cheb12(9) = fval(1)-x(8)*fval(3)
alam = x(4)*v(2)
cheb24(5) = cheb12(5)+alam
cheb24(21) = cheb12(5)-alam
alam = x(8)*fval(2)-fval(4)
cheb24(9) = cheb12(9)+alam
cheb24(17) = cheb12(9)-alam
cheb12(1) = fval(1)+fval(3)
alam = fval(2)+fval(4)
cheb24(1) = cheb12(1)+alam
cheb24(25) = cheb12(1)-alam
cheb12(13) = v(1)-v(3)
cheb24(13) = cheb12(13)
alam = 0.1D+01/0.6D+01
do i=2,12
cheb12(i) = cheb12(i)*alam
end do
alam = 0.5D+00*alam
cheb12(1) = cheb12(1)*alam
cheb12(13) = cheb12(13)*alam
do i=2,24
cheb24(i) = cheb24(i)*alam
end do
cheb24(1) = 0.5D+00*alam*cheb24(1)
cheb24(25) = 0.5D+00*alam*cheb24(25)
return
end subroutine dqcheb
!----------------------------------------------------------------------------------------
!> DQELG carries out the Epsilon extrapolation algorithm.
!!
!! Modified:
!!
!! 11 September 2015
!!
!! Author:
!!
!! Robert Piessens, Elise de Doncker
!!
!!***purpose the routine determines the limit of a given sequence of
!! approximations, by means of the epsilon algorithm of
!! p.wynn. an estimate of the absolute error is also given.
!! the condensed epsilon table is computed. only those
!! elements needed for the computation of the next diagonal
!! are preserved.
!!
!! Parameters:
!!
!! n - integer ( kind = 4 )
!! epstab(n) contains the new element in the
!! first column of the epsilon table.
!!
!! epstab - real ( kind = 8 )
!! vector of dimension 52 containing the elements
!! of the two lower diagonals of the triangular
!! epsilon table. the elements are numbered
!! starting at the right-hand corner of the
!! triangle.
!!
!! result - real ( kind = 8 )
!! resulting approximation to the integral
!!
!! abserr - real ( kind = 8 )
!! estimate of the absolute error computed from
!! result and the 3 previous results
!!
!! res3la - real ( kind = 8 )
!! vector of dimension 3 containing the last 3
!! results
!!
!! nres - integer ( kind = 4 )
!! number of calls to the routine
!! (should be zero at first call)
!!
!! Local Parameters:
!!
!! e0 - the 4 elements on which the computation of a new
!! e1 element in the epsilon table is based
!! e2
!! e3 e0
!! e3 e1 new
!! e2
!! newelm - number of elements to be computed in the new
!! diagonal
!! error - error = abs(e1-e0)+abs(e2-e1)+abs(new-e2)
!! result - the element in the new diagonal with least value
!! of error
!!
!! machine dependent constants
!!
!! epmach is the largest relative spacing.
!! oflow is the largest positive magnitude.
!! limexp is the maximum number of elements the epsilon
!! table can contain. if this number is reached, the upper
!! diagonal of the epsilon table is deleted.
!!
subroutine dqelg ( n, epstab, result, abserr, res3la, nres )
implicit none
real ( kind = 8 ) abserr,delta1,delta2,delta3, &
epmach,epsinf,epstab,error,err1,err2,err3,e0,e1,e1abs,e2,e3, &
oflow,res,result,res3la,ss,tol1,tol2,tol3
integer ( kind = 4 ) i,ib,ib2,ie,indx,k1,k2,k3,limexp,n,newelm
integer ( kind = 4 ) nres
integer ( kind = 4 ) num
dimension epstab(52),res3la(3)
epmach = epsilon ( epmach )
oflow = huge ( oflow )
nres = nres+1
abserr = oflow
result = epstab(n)
if(n.lt.3) go to 100
limexp = 50
epstab(n+2) = epstab(n)
newelm = (n-1)/2
epstab(n) = oflow
num = n
k1 = n
do 40 i = 1,newelm
k2 = k1-1
k3 = k1-2
res = epstab(k1+2)
e0 = epstab(k3)
e1 = epstab(k2)
e2 = res
e1abs = abs ( e1)
delta2 = e2-e1
err2 = abs ( delta2)
tol2 = max ( abs ( e2),e1abs)*epmach
delta3 = e1 - e0
err3 = abs ( delta3)
tol3 = max ( e1abs, abs ( e0))*epmach
if(err2.gt.tol2.or.err3.gt.tol3) go to 10
!
! if e0, e1 and e2 are equal to machine accuracy, convergence is assumed.
!
result = res
abserr = err2+err3
go to 100
10 e3 = epstab(k1)
epstab(k1) = e1
delta1 = e1-e3
err1 = abs ( delta1)
tol1 = max ( e1abs, abs ( e3))*epmach
!
! if two elements are very close to each other, omit
! a part of the table by adjusting the value of n
!
if(err1.le.tol1.or.err2.le.tol2.or.err3.le.tol3) go to 20
ss = 0.1D+01/delta1+0.1D+01/delta2-0.1D+01/delta3
epsinf = abs ( ss*e1)
!
! test to detect irregular behaviour in the table, and
! eventually omit a part of the table adjusting the value
! of n.
!
if(epsinf.gt.0.1D-03) go to 30
20 n = i+i-1
go to 50
!
! compute a new element and eventually adjust
! the value of result.
!
30 res = e1+0.1D+01/ss
epstab(k1) = res
k1 = k1-2
error = err2 + abs ( res-e2 ) + err3
if ( error .le. abserr ) then
abserr = error
result = res
end if
40 continue
!
! shift the table.
!
50 if(n.eq.limexp) n = 2*(limexp/2)-1
ib = 1
if((num/2)*2.eq.num) ib = 2
ie = newelm+1
do i=1,ie
ib2 = ib+2
epstab(ib) = epstab(ib2)
ib = ib2
end do
if(num.eq.n) go to 80
indx = num-n+1
do i = 1,n
epstab(i)= epstab(indx)
indx = indx+1
end do
80 if(nres.ge.4) go to 90
res3la(nres) = result
abserr = oflow
go to 100
!
! compute error estimate
!
90 abserr = abs ( result-res3la(3))+ abs ( result-res3la(2)) &
+ abs ( result-res3la(1))
res3la(1) = res3la(2)
res3la(2) = res3la(3)
res3la(3) = result
100 continue
abserr = max ( abserr, 0.5D+01*epmach* abs ( result))
return
end subroutine dqelg
!----------------------------------------------------------------------------------------
!> DQK15 carries out a 15 point Gauss-Kronrod quadrature rule.
!!
!! the abscissae and weights are given for the interval (-1,1).
!! because of symmetry only the positive abscissae and their
!! corresponding weights are given.
!!
!! xgk - abscissae of the 15-point kronrod rule
!! xgk(2), xgk(4), ... abscissae of the 7-point
!! gauss rule
!! xgk(1), xgk(3), ... abscissae which are optimally
!! added to the 7-point gauss rule
!!
!! wgk - weights of the 15-point kronrod rule
!!
!! wg - weights of the 7-point gauss rule
!!
!!
!! gauss quadrature weights and kronron quadrature abscissae and weights
!! as evaluated with 80 decimal digit arithmetic by l. w. fullerton,
!! bell labs, nov. 1981.
!!
!! Modified:
!!
!! 11 September 2015
!!
!! Author:
!!
!! Robert Piessens, Elise de Doncker
!!
!!***purpose to compute i = integral of f over (a,b), with error
!! estimate
!! j = integral of abs(f) over (a,b)
!! Parameters:
!!
!! on entry
!! f - real ( kind = 8 )
!! function subprogram defining the integrand
!! function f(x). the actual name for f needs to be
!! declared e x t e r n a l in the calling program.
!!
!! a - real ( kind = 8 )
!! lower limit of integration
!!
!! b - real ( kind = 8 )
!! upper limit of integration
!!
!! on return
!! result - real ( kind = 8 )
!! approximation to the integral i
!! result is computed by applying the 15-point
!! kronrod rule (resk) obtained by optimal addition
!! of abscissae to the7-point gauss rule(resg).
!!
!! abserr - real ( kind = 8 )
!! estimate of the modulus of the absolute error,
!! which should not exceed abs(i-result)
!!
!! resabs - real ( kind = 8 )
!! approximation to the integral j
!!
!! resasc - real ( kind = 8 )
!! approximation to the integral of abs(f-i/(b-a))
!! over (a,b)
!!
!! Local Parameters:
!!
!! centr - mid point of the interval
!! hlgth - half-length of the interval
!! absc - abscissa
!! fval* - function value
!! resg - result of the 7-point gauss formula
!! resk - result of the 15-point kronrod formula
!! reskh - approximation to the mean value of f over (a,b),
!! i.e. to i/(b-a)
!!
!! machine dependent constants
!!
!! epmach is the largest relative spacing.
!! uflow is the smallest positive magnitude.
!!
subroutine dqk15(f,a,b,result,abserr,resabs,resasc)
implicit none
real ( kind = 8 ) a,absc,abserr,b,centr,dhlgth, &
epmach,f,fc,fsum,fval1,fval2,fv1,fv2,hlgth,resabs,resasc, &
resg,resk,reskh,result,uflow,wg,wgk,xgk
integer ( kind = 4 ) j,jtw,jtwm1
external f
dimension fv1(7),fv2(7),wg(4),wgk(8),xgk(8)
data wg ( 1) / 0.129484966168869693270611432679082d0 /
data wg ( 2) / 0.279705391489276667901467771423780d0 /
data wg ( 3) / 0.381830050505118944950369775488975d0 /
data wg ( 4) / 0.417959183673469387755102040816327d0 /
data xgk ( 1) / 0.991455371120812639206854697526329d0 /
data xgk ( 2) / 0.949107912342758524526189684047851d0 /
data xgk ( 3) / 0.864864423359769072789712788640926d0 /
data xgk ( 4) / 0.741531185599394439863864773280788d0 /
data xgk ( 5) / 0.586087235467691130294144838258730d0 /
data xgk ( 6) / 0.405845151377397166906606412076961d0 /
data xgk ( 7) / 0.207784955007898467600689403773245d0 /
data xgk ( 8) / 0.000000000000000000000000000000000d0 /
data wgk ( 1) / 0.022935322010529224963732008058970d0 /
data wgk ( 2) / 0.063092092629978553290700663189204d0 /
data wgk ( 3) / 0.104790010322250183839876322541518d0 /
data wgk ( 4) / 0.140653259715525918745189590510238d0 /
data wgk ( 5) / 0.169004726639267902826583426598550d0 /
data wgk ( 6) / 0.190350578064785409913256402421014d0 /
data wgk ( 7) / 0.204432940075298892414161999234649d0 /
data wgk ( 8) / 0.209482141084727828012999174891714d0 /
epmach = epsilon ( epmach )
uflow = tiny ( uflow )
centr = 0.5D+00*(a+b)
hlgth = 0.5D+00*(b-a)
dhlgth = abs ( hlgth)
!
! compute the 15-point kronrod approximation to
! the integral, and estimate the absolute error.
!
fc = f(centr)
resg = fc*wg(4)
resk = fc*wgk(8)
resabs = abs ( resk)
do j=1,3
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,4
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.5D+00
resasc = wgk(8)* abs ( fc-reskh)
do j=1,7
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.ne.0.0D+00.and.abserr.ne.0.0D+00) &
abserr = resasc* min (0.1D+01,(0.2D+03*abserr/resasc)**1.5D+00)
if(resabs.gt.uflow/(0.5D+02*epmach)) abserr = max &
((epmach*0.5D+02)*resabs,abserr)
return
end subroutine dqk15
!----------------------------------------------------------------------------------------
!> DQK15I applies a 15 point Gauss-Kronrod quadrature on an infinite interval.
!!
!!
!! the abscissae and weights are supplied for the interval
!! (-1,1). because of symmetry only the positive abscissae and
!! their corresponding weights are given.
!!
!! xgk - abscissae of the 15-point kronrod rule
!! xgk(2), xgk(4), ... abscissae of the 7-point
!! gauss rule
!! xgk(1), xgk(3), ... abscissae which are optimally
!! added to the 7-point gauss rule
!!
!! wgk - weights of the 15-point kronrod rule
!!
!! wg - weights of the 7-point gauss rule, corresponding
!! to the abscissae xgk(2), xgk(4), ...
!! wg(1), wg(3), ... are set to zero.
!!
!! Modified:
!!
!! 11 September 2015
!!
!! Author:
!!
!! Robert Piessens, Elise de Doncker
!!
!!***purpose the original (infinite integration range is mapped
!! onto the interval (0,1) and (a,b) is a part of (0,1).
!! it is the purpose to compute
!! i = integral of transformed integrand over (a,b),
!! j = integral of abs(transformed integrand) over (a,b).
!!
!! Parameters:
!!
!! on entry
!! f - real ( kind = 8 )
!! fuction subprogram defining the integrand
!! function f(x). the actual name for f needs to be
!! declared e x t e r n a l in the calling program.
!!
!! boun - real ( kind = 8 )
!! finite bound of original integration
!! range (set to zero if inf = +2)
!!
!! inf - integer ( kind = 4 )
!! if inf = -1, the original interval is
!! (-infinity,bound),
!! if inf = +1, the original interval is
!! (bound,+infinity),
!! if inf = +2, the original interval is
!! (-infinity,+infinity) and
!! the integral is computed as the sum of two
!! integrals, one over (-infinity,0) and one over
!! (0,+infinity).
!!
!! a - real ( kind = 8 )
!! lower limit for integration over subrange
!! of (0,1)
!!
!! b - real ( kind = 8 )
!! upper limit for integration over subrange
!! of (0,1)
!!
!! on return
!! result - real ( kind = 8 )
!! approximation to the integral i
!! result is computed by applying the 15-point
!! kronrod rule(resk) obtained by optimal addition
!! of abscissae to the 7-point gauss rule(resg).
!!
!! abserr - real ( kind = 8 )
!! estimate of the modulus of the absolute error,
!! which should equal or exceed abs(i-result)
!!
!! resabs - real ( kind = 8 )
!! approximation to the integral j
!!
!! resasc - real ( kind = 8 )
!! approximation to the integral of
!! abs((transformed integrand)-i/(b-a)) over (a,b)
!!
!! Local Parameters:
!!
!! centr - mid point of the interval
!! hlgth - half-length of the interval
!! absc* - abscissa
!! tabsc* - transformed abscissa
!! fval* - function value
!! resg - result of the 7-point gauss formula
!! resk - result of the 15-point kronrod formula
!! reskh - approximation to the mean value of the transformed
!! integrand over (a,b), i.e. to i/(b-a)
!!
!! machine dependent constants
!!
!! epmach is the largest relative spacing.
!! uflow is the smallest positive magnitude.
!!
subroutine dqk15i(f,boun,inf,a,b,result,abserr,resabs,resasc)
implicit none
real ( kind = 8 ) a,absc,absc1,absc2,abserr,b,boun,centr,dinf, &
epmach,f,fc,fsum,fval1,fval2,fv1,fv2,hlgth, &
resabs,resasc,resg,resk,reskh,result,tabsc1,tabsc2,uflow,wg,wgk, &
xgk
integer ( kind = 4 ) inf,j
external f
dimension fv1(7),fv2(7),xgk(8),wgk(8),wg(8)
data wg(1) / 0.0d0 /
data wg(2) / 0.129484966168869693270611432679082d0 /
data wg(3) / 0.0d0 /
data wg(4) / 0.279705391489276667901467771423780d0 /
data wg(5) / 0.0d0 /
data wg(6) / 0.381830050505118944950369775488975d0 /
data wg(7) / 0.0d0 /
data wg(8) / 0.417959183673469387755102040816327d0 /
data xgk(1) / 0.991455371120812639206854697526329d0 /
data xgk(2) / 0.949107912342758524526189684047851d0 /
data xgk(3) / 0.864864423359769072789712788640926d0 /
data xgk(4) / 0.741531185599394439863864773280788d0 /
data xgk(5) / 0.586087235467691130294144838258730d0 /
data xgk(6) / 0.405845151377397166906606412076961d0 /
data xgk(7) / 0.207784955007898467600689403773245d0 /
data xgk(8) / 0.000000000000000000000000000000000d0 /
data wgk(1) / 0.022935322010529224963732008058970d0 /
data wgk(2) / 0.063092092629978553290700663189204d0 /
data wgk(3) / 0.104790010322250183839876322541518d0 /
data wgk(4) / 0.140653259715525918745189590510238d0 /
data wgk(5) / 0.169004726639267902826583426598550d0 /
data wgk(6) / 0.190350578064785409913256402421014d0 /
data wgk(7) / 0.204432940075298892414161999234649d0 /
data wgk(8) / 0.209482141084727828012999174891714d0 /
epmach = epsilon ( epmach )
uflow = tiny ( uflow )
dinf = min ( 1, inf )
centr = 0.5D+00*(a+b)
hlgth = 0.5D+00*(b-a)
tabsc1 = boun+dinf*(0.1D+01-centr)/centr
fval1 = f(tabsc1)
if(inf.eq.2) fval1 = fval1+f(-tabsc1)
fc = (fval1/centr)/centr
!
! compute the 15-point kronrod approximation to
! the integral, and estimate the error.
!
resg = wg(8)*fc
resk = wgk(8)*fc
resabs = abs ( resk)
do j=1,7
absc = hlgth*xgk(j)
absc1 = centr-absc
absc2 = centr+absc
tabsc1 = boun+dinf*(0.1D+01-absc1)/absc1
tabsc2 = boun+dinf*(0.1D+01-absc2)/absc2
fval1 = f(tabsc1)
fval2 = f(tabsc2)
if(inf.eq.2) fval1 = fval1+f(-tabsc1)
if(inf.eq.2) fval2 = fval2+f(-tabsc2)
fval1 = (fval1/absc1)/absc1
fval2 = (fval2/absc2)/absc2
fv1(j) = fval1
fv2(j) = fval2
fsum = fval1+fval2
resg = resg+wg(j)*fsum
resk = resk+wgk(j)*fsum
resabs = resabs+wgk(j)*( abs ( fval1)+ abs ( fval2))
end do
reskh = resk*0.5D+00
resasc = wgk(8)* abs ( fc-reskh)
do j=1,7
resasc = resasc+wgk(j)*( abs ( fv1(j)-reskh)+ abs ( fv2(j)-reskh))
end do
result = resk*hlgth
resasc = resasc*hlgth
resabs = resabs*hlgth
abserr = abs ( (resk-resg)*hlgth)
if(resasc.ne.0.0D+00.and.abserr.ne.0.d0) abserr = resasc* &
min (0.1D+01,(0.2D+03*abserr/resasc)**1.5D+00)
if(resabs.gt.uflow/(0.5D+02*epmach)) abserr = max &
((epmach*0.5D+02)*resabs,abserr)
return
end subroutine dqk15i
!----------------------------------------------------------------------------------------
!> DQK15W applies a 15 point Gauss-Kronrod rule for a weighted integrand.
!!
!! Modified:
!!
!! 11 September 2015
!!
!! Author:
!!
!! Robert Piessens, Elise de Doncker
!!
!!***purpose to compute i = integral of f*w over (a,b), with error
!! estimate
!! j = integral of abs(f*w) over (a,b)
!!
!! Parameters:
!!
!! on entry
!! f - real ( kind = 8 )
!! function subprogram defining the integrand
!! function f(x). the actual name for f needs to be
!! declared e x t e r n a l in the driver program.
!!
!! w - real ( kind = 8 )
!! function subprogram defining the integrand
!! weight function w(x). the actual name for w
!! needs to be declared e x t e r n a l in the
!! calling program.
!!
!! p1, p2, p3, p4 - real ( kind = 8 )
!! parameters in the weight function
!!
!! kp - integer ( kind = 4 )
!! key for indicating the type of weight function
!!
!! a - real ( kind = 8 )
!! lower limit of integration
!!
!! b - real ( kind = 8 )
!! upper limit of integration
!!
!! on return
!! result - real ( kind = 8 )
!! approximation to the integral i
!! result is computed by applying the 15-point
!! kronrod rule (resk) obtained by optimal addition
!! of abscissae to the 7-point gauss rule (resg).
!!
!! abserr - real ( kind = 8 )
!! estimate of the modulus of the absolute error,
!! which should equal or exceed abs(i-result)
!!
!! resabs - real ( kind = 8 )
!! approximation to the integral of abs(f)
!!
!! resasc - real ( kind = 8 )
!! approximation to the integral of abs(f-i/(b-a))
!!
!! Local Parameters:
!!
!! the abscissae and weights are given for the interval (-1,1).
!! because of symmetry only the positive abscissae and their
!! corresponding weights are given.
!!
!! xgk - abscissae of the 15-point gauss-kronrod rule
!! xgk(2), xgk(4), ... abscissae of the 7-point
!! gauss rule
!! xgk(1), xgk(3), ... abscissae which are optimally
!! added to the 7-point gauss rule
!!
!! wgk - weights of the 15-point gauss-kronrod rule
!!
!! wg - weights of the 7-point gauss rule
!!
!! centr - mid point of the interval
!! hlgth - half-length of the interval
!! absc* - abscissa
!! fval* - function value
!! resg - result of the 7-point gauss formula
!! resk - result of the 15-point kronrod formula
!! reskh - approximation to the mean value of f*w over (a,b),
!! i.e. to i/(b-a)
!!
!! machine dependent constants
!!
!! epmach is the largest relative spacing.
!! uflow is the smallest positive magnitude.
!!
subroutine dqk15w(f,w,p1,p2,p3,p4,kp,a,b,result,abserr, resabs,resasc)
implicit none
real ( kind = 8 ) a,absc,absc1,absc2,abserr,b,centr,dhlgth, &
epmach,f,fc,fsum,fval1,fval2,fv1,fv2,hlgth, &
p1,p2,p3,p4,resabs,resasc,resg,resk,reskh,result,uflow,w,wg,wgk, &
xgk
integer ( kind = 4 ) j,jtw,jtwm1,kp
external f,w
dimension fv1(7),fv2(7),xgk(8),wgk(8),wg(4)
data xgk(1),xgk(2),xgk(3),xgk(4),xgk(5),xgk(6),xgk(7),xgk(8)/ &
0.9914553711208126D+00, 0.9491079123427585D+00, &
0.8648644233597691D+00, 0.7415311855993944D+00, &
0.5860872354676911D+00, 0.4058451513773972D+00, &
0.2077849550078985D+00, 0.0000000000000000D+00/
data wgk(1),wgk(2),wgk(3),wgk(4),wgk(5),wgk(6),wgk(7),wgk(8)/ &
0.2293532201052922D-01, 0.6309209262997855D-01, &
0.1047900103222502D+00, 0.1406532597155259D+00, &
0.1690047266392679D+00, 0.1903505780647854D+00, &
0.2044329400752989D+00, 0.2094821410847278D+00/
data wg(1),wg(2),wg(3),wg(4)/ &
0.1294849661688697D+00, 0.2797053914892767D+00, &
0.3818300505051889D+00, 0.4179591836734694D+00/
epmach = epsilon ( epmach )
uflow = tiny ( uflow )
centr = 0.5D+00*(a+b)
hlgth = 0.5D+00*(b-a)
dhlgth = abs ( hlgth)
!
! compute the 15-point kronrod approximation to the
! integral, and estimate the error.
!
fc = f(centr)*w(centr,p1,p2,p3,p4,kp)
resg = wg(4)*fc
resk = wgk(8)*fc
resabs = abs ( resk)
do j=1,3
jtw = j*2
absc = hlgth*xgk(jtw)
absc1 = centr-absc
absc2 = centr+absc
fval1 = f(absc1)*w(absc1,p1,p2,p3,p4,kp)
fval2 = f(absc2)*w(absc2,p1,p2,p3,p4,kp)
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,4
jtwm1 = j*2-1
absc = hlgth*xgk(jtwm1)
absc1 = centr-absc
absc2 = centr+absc
fval1 = f(absc1)*w(absc1,p1,p2,p3,p4,kp)
fval2 = f(absc2)*w(absc2,p1,p2,p3,p4,kp)
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.5D+00
resasc = wgk(8)* abs ( fc-reskh)
do j=1,7
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.ne.0.0D+00.and.abserr.ne.0.0D+00) &
abserr = resasc* min (0.1D+01,(0.2D+03*abserr/resasc)**1.5D+00)
if(resabs.gt.uflow/(0.5D+02*epmach)) abserr = max ( (epmach* &
0.5D+02)*resabs,abserr)
return
end subroutine dqk15w
!----------------------------------------------------------------------------------------
!> DQK21 carries out a 21 point Gauss-Kronrod quadrature rule.
!!
!! Modified:
!!
!! 11 September 2015
!!
!! Author:
!!
!! Robert Piessens, Elise de Doncker
!!
!!***purpose to compute i = integral of f over (a,b), with error
!! estimate
!! j = integral of abs(f) over (a,b)
!!
!! Parameters:
!!
!! on entry
!! f - real ( kind = 8 )
!! function subprogram defining the integrand
!! function f(x). the actual name for f needs to be
!! declared e x t e r n a l in the driver program.
!!
!! a - real ( kind = 8 )
!! lower limit of integration
!!
!! b - real ( kind = 8 )
!! upper limit of integration
!!
!! on return
!! result - real ( kind = 8 )
!! approximation to the integral i
!! result is computed by applying the 21-point
!! kronrod rule (resk) obtained by optimal addition
!! of abscissae to the 10-point gauss rule (resg).
!!
!! abserr - real ( kind = 8 )
!! estimate of the modulus of the absolute error,
!! which should not exceed abs(i-result)
!!
!! resabs - real ( kind = 8 )
!! approximation to the integral j
!!
!! resasc - real ( kind = 8 )
!! approximation to the integral of abs(f-i/(b-a))
!! over (a,b)
!!
!! Local Parameters:
!!
!!
!! the abscissae and weights are given for the interval (-1,1).
!! because of symmetry only the positive abscissae and their
!! corresponding weights are given.
!!
!! xgk - abscissae of the 21-point kronrod rule
!! xgk(2), xgk(4), ... abscissae of the 10-point
!! gauss rule
!! xgk(1), xgk(3), ... abscissae which are optimally
!! added to the 10-point gauss rule
!!
!! wgk - weights of the 21-point kronrod rule
!!
!! wg - weights of the 10-point gauss rule
!!
!!
!! gauss quadrature weights and kronron quadrature abscissae and weights
!! as evaluated with 80 decimal digit arithmetic by l. w. fullerton,
!! bell labs, nov. 1981.
!!
!! centr - mid point of the interval
!! hlgth - half-length of the interval
!! absc - abscissa
!! fval* - function value
!! resg - result of the 10-point gauss formula
!! resk - result of the 21-point kronrod formula
!! reskh - approximation to the mean value of f over (a,b),
!! i.e. to i/(b-a)
!!
!!
!! machine dependent constants
!!
!! epmach is the largest relative spacing.
!! uflow is the smallest positive magnitude.
!!
subroutine dqk21(f,a,b,result,abserr,resabs,resasc)
implicit none
real ( kind = 8 ) a,absc,abserr,b,centr,dhlgth, &
epmach,f,fc,fsum,fval1,fval2,fv1,fv2,hlgth,resabs,resasc, &
resg,resk,reskh,result,uflow,wg,wgk,xgk
integer ( kind = 4 ) j,jtw,jtwm1
external f
dimension fv1(10),fv2(10),wg(5),wgk(11),xgk(11)
data wg ( 1) / 0.066671344308688137593568809893332d0 /
data wg ( 2) / 0.149451349150580593145776339657697d0 /
data wg ( 3) / 0.219086362515982043995534934228163d0 /
data wg ( 4) / 0.269266719309996355091226921569469d0 /
data wg ( 5) / 0.295524224714752870173892994651338d0 /
data xgk ( 1) / 0.995657163025808080735527280689003d0 /
data xgk ( 2) / 0.973906528517171720077964012084452d0 /
data xgk ( 3) / 0.930157491355708226001207180059508d0 /
data xgk ( 4) / 0.865063366688984510732096688423493d0 /
data xgk ( 5) / 0.780817726586416897063717578345042d0 /
data xgk ( 6) / 0.679409568299024406234327365114874d0 /
data xgk ( 7) / 0.562757134668604683339000099272694d0 /
data xgk ( 8) / 0.433395394129247190799265943165784d0 /
data xgk ( 9) / 0.294392862701460198131126603103866d0 /
data xgk ( 10) / 0.148874338981631210884826001129720d0 /
data xgk ( 11) / 0.000000000000000000000000000000000d0 /
data wgk ( 1) / 0.011694638867371874278064396062192d0 /
data wgk ( 2) / 0.032558162307964727478818972459390d0 /
data wgk ( 3) / 0.054755896574351996031381300244580d0 /
data wgk ( 4) / 0.075039674810919952767043140916190d0 /
data wgk ( 5) / 0.093125454583697605535065465083366d0 /
data wgk ( 6) / 0.109387158802297641899210590325805d0 /
data wgk ( 7) / 0.123491976262065851077958109831074d0 /
data wgk ( 8) / 0.134709217311473325928054001771707d0 /
data wgk ( 9) / 0.142775938577060080797094273138717d0 /
data wgk ( 10) / 0.147739104901338491374841515972068d0 /
data wgk ( 11) / 0.149445554002916905664936468389821d0 /
epmach = epsilon ( epmach )
uflow = tiny ( uflow )
centr = 0.5D+00*(a+b)
hlgth = 0.5D+00*(b-a)
dhlgth = abs ( hlgth)
!
! compute the 21-point kronrod approximation to
! the integral, and estimate the absolute error.
!
resg = 0.0D+00
fc = f(centr)
resk = wgk(11)*fc
resabs = abs ( resk)
do j=1,5
jtw = 2*j
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,5
jtwm1 = 2*j-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.5D+00
resasc = wgk(11)* abs ( fc-reskh)
do j=1,10
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.ne.0.0D+00.and.abserr.ne.0.0D+00) &
abserr = resasc*min(0.1D+01,(0.2D+03*abserr/resasc)**1.5D+00)
if(resabs.gt.uflow/(0.5D+02*epmach)) abserr = max &
((epmach*0.5D+02)*resabs,abserr)
return
end subroutine dqk21
!----------------------------------------------------------------------------------------
!> DQK31 carries out a 31 point Gauss-Kronrod quadrature rule.
!!
!! Modified:
!!
!! 11 September 2015
!!
!! Author:
!!
!! Robert Piessens, Elise de Doncker
!!
!!***purpose to compute i = integral of f over (a,b) with error
!! estimate
!! j = integral of abs(f) over (a,b)
!!
!! Parameters:
!!
!! on entry
!! f - real ( kind = 8 )
!! function subprogram defining the integrand
!! function f(x). the actual name for f needs to be
!! declared e x t e r n a l in the calling program.
!!
!! a - real ( kind = 8 )
!! lower limit of integration
!!
!! b - real ( kind = 8 )
!! upper limit of integration
!!
!! on return
!! result - real ( kind = 8 )
!! approximation to the integral i
!! result is computed by applying the 31-point
!! gauss-kronrod rule (resk), obtained by optimal
!! addition of abscissae to the 15-point gauss
!! rule (resg).
!!
!! abserr - double precison
!! estimate of the modulus of the modulus,
!! which should not exceed abs(i-result)
!!
!! resabs - real ( kind = 8 )
!! approximation to the integral j
!!
!! resasc - real ( kind = 8 )
!! approximation to the integral of abs(f-i/(b-a))
!! over (a,b)
!!
!! Local Parameters:
!!
!!
!! the abscissae and weights are given for the interval (-1,1).
!! because of symmetry only the positive abscissae and their
!! corresponding weights are given.
!!
!! xgk - abscissae of the 31-point kronrod rule
!! xgk(2), xgk(4), ... abscissae of the 15-point
!! gauss rule
!! xgk(1), xgk(3), ... abscissae which are optimally
!! added to the 15-point gauss rule
!!
!! wgk - weights of the 31-point kronrod rule
!!
!! wg - weights of the 15-point gauss rule
!!
!!
!! gauss quadrature weights and kronron quadrature abscissae and weights
!! as evaluated with 80 decimal digit arithmetic by l. w. fullerton,
!! bell labs, nov. 1981.
!!
!! centr - mid point of the interval
!! hlgth - half-length of the interval
!! absc - abscissa
!! fval* - function value
!! resg - result of the 15-point gauss formula
!! resk - result of the 31-point kronrod formula
!! reskh - approximation to the mean value of f over (a,b),
!! i.e. to i/(b-a)
!!
!! machine dependent constants
!!
!! epmach is the largest relative spacing.
!! uflow is the smallest positive magnitude.
!!
subroutine dqk31(f,a,b,result,abserr,resabs,resasc)
implicit none
real ( kind = 8 ) a,absc,abserr,b,centr,dhlgth, &
epmach,f,fc,fsum,fval1,fval2,fv1,fv2,hlgth,resabs,resasc, &
resg,resk,reskh,result,uflow,wg,wgk,xgk
integer ( kind = 4 ) j,jtw,jtwm1
external f
dimension fv1(15),fv2(15),xgk(16),wgk(16),wg(8)
data wg ( 1) / 0.030753241996117268354628393577204d0 /
data wg ( 2) / 0.070366047488108124709267416450667d0 /
data wg ( 3) / 0.107159220467171935011869546685869d0 /
data wg ( 4) / 0.139570677926154314447804794511028d0 /
data wg ( 5) / 0.166269205816993933553200860481209d0 /
data wg ( 6) / 0.186161000015562211026800561866423d0 /
data wg ( 7) / 0.198431485327111576456118326443839d0 /
data wg ( 8) / 0.202578241925561272880620199967519d0 /
data xgk ( 1) / 0.998002298693397060285172840152271d0 /
data xgk ( 2) / 0.987992518020485428489565718586613d0 /
data xgk ( 3) / 0.967739075679139134257347978784337d0 /
data xgk ( 4) / 0.937273392400705904307758947710209d0 /
data xgk ( 5) / 0.897264532344081900882509656454496d0 /
data xgk ( 6) / 0.848206583410427216200648320774217d0 /
data xgk ( 7) / 0.790418501442465932967649294817947d0 /
data xgk ( 8) / 0.724417731360170047416186054613938d0 /
data xgk ( 9) / 0.650996741297416970533735895313275d0 /
data xgk ( 10) / 0.570972172608538847537226737253911d0 /
data xgk ( 11) / 0.485081863640239680693655740232351d0 /
data xgk ( 12) / 0.394151347077563369897207370981045d0 /
data xgk ( 13) / 0.299180007153168812166780024266389d0 /
data xgk ( 14) / 0.201194093997434522300628303394596d0 /
data xgk ( 15) / 0.101142066918717499027074231447392d0 /
data xgk ( 16) / 0.000000000000000000000000000000000d0 /
data wgk ( 1) / 0.005377479872923348987792051430128d0 /
data wgk ( 2) / 0.015007947329316122538374763075807d0 /
data wgk ( 3) / 0.025460847326715320186874001019653d0 /
data wgk ( 4) / 0.035346360791375846222037948478360d0 /
data wgk ( 5) / 0.044589751324764876608227299373280d0 /
data wgk ( 6) / 0.053481524690928087265343147239430d0 /
data wgk ( 7) / 0.062009567800670640285139230960803d0 /
data wgk ( 8) / 0.069854121318728258709520077099147d0 /
data wgk ( 9) / 0.076849680757720378894432777482659d0 /
data wgk ( 10) / 0.083080502823133021038289247286104d0 /
data wgk ( 11) / 0.088564443056211770647275443693774d0 /
data wgk ( 12) / 0.093126598170825321225486872747346d0 /
data wgk ( 13) / 0.096642726983623678505179907627589d0 /
data wgk ( 14) / 0.099173598721791959332393173484603d0 /
data wgk ( 15) / 0.100769845523875595044946662617570d0 /
data wgk ( 16) / 0.101330007014791549017374792767493d0 /
epmach = epsilon ( epmach )
uflow = tiny ( uflow )
centr = 0.5D+00*(a+b)
hlgth = 0.5D+00*(b-a)
dhlgth = abs ( hlgth)
!
! compute the 31-point kronrod approximation to
! the integral, and estimate the absolute error.
!
fc = f(centr)
resg = wg(8)*fc
resk = wgk(16)*fc
resabs = abs ( resk)
do j=1,7
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,8
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.5D+00
resasc = wgk(16)* abs ( fc-reskh)
do j=1,15
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.ne.0.0D+00.and.abserr.ne.0.0D+00) &
abserr = resasc* min (0.1D+01,(0.2D+03*abserr/resasc)**1.5D+00)
if(resabs.gt.uflow/(0.5D+02*epmach)) abserr = max &
((epmach*0.5D+02)*resabs,abserr)
return
end subroutine dqk31
!----------------------------------------------------------------------------------------
!> DQK41 carries out a 41 point Gauss-Kronrod quadrature rule.
!!
!! Modified:
!!
!! 11 September 2015
!!
!! Author:
!!
!! Robert Piessens, Elise de Doncker
!!
!!***purpose to compute i = integral of f over (a,b), with error
!! estimate
!! j = integral of abs(f) over (a,b)
!!
!! Parameters:
!!
!! on entry
!! f - real ( kind = 8 )
!! function subprogram defining the integrand
!! function f(x). the actual name for f needs to be
!! declared e x t e r n a l in the calling program.
!!
!! a - real ( kind = 8 )
!! lower limit of integration
!!
!! b - real ( kind = 8 )
!! upper limit of integration
!!
!! on return
!! result - real ( kind = 8 )
!! approximation to the integral i
!! result is computed by applying the 41-point
!! gauss-kronrod rule (resk) obtained by optimal
!! addition of abscissae to the 20-point gauss
!! rule (resg).
!!
!! abserr - real ( kind = 8 )
!! estimate of the modulus of the absolute error,
!! which should not exceed abs(i-result)
!!
!! resabs - real ( kind = 8 )
!! approximation to the integral j
!!
!! resasc - real ( kind = 8 )
!! approximation to the integal of abs(f-i/(b-a))
!! over (a,b)
!!
!! Local Parameters:
!!
!!
!! the abscissae and weights are given for the interval (-1,1).
!! because of symmetry only the positive abscissae and their
!! corresponding weights are given.
!!
!! xgk - abscissae of the 41-point gauss-kronrod rule
!! xgk(2), xgk(4), ... abscissae of the 20-point
!! gauss rule
!! xgk(1), xgk(3), ... abscissae which are optimally
!! added to the 20-point gauss rule
!!
!! wgk - weights of the 41-point gauss-kronrod rule
!!
!! wg - weights of the 20-point gauss rule
!!
!!
!! gauss quadrature weights and kronron quadrature abscissae and weights
!! as evaluated with 80 decimal digit arithmetic by l. w. fullerton,
!! bell labs, nov. 1981.
!!
!! centr - mid point of the interval
!! hlgth - half-length of the interval
!! absc - abscissa
!! fval* - function value
!! resg - result of the 20-point gauss formula
!! resk - result of the 41-point kronrod formula
!! reskh - approximation to mean value of f over (a,b), i.e.
!! to i/(b-a)
!!
!! machine dependent constants
!!
!! epmach is the largest relative spacing.
!! uflow is the smallest positive magnitude.
!!
subroutine dqk41 ( f, a, b, result, abserr, resabs, resasc )
implicit none
real ( kind = 8 ) a,absc,abserr,b,centr,dhlgth, &
epmach,f,fc,fsum,fval1,fval2,fv1,fv2,hlgth,resabs,resasc, &
resg,resk,reskh,result,uflow,wg,wgk,xgk
integer ( kind = 4 ) j,jtw,jtwm1
external f
dimension fv1(20),fv2(20),xgk(21),wgk(21),wg(10)
data wg ( 1) / 0.017614007139152118311861962351853d0 /
data wg ( 2) / 0.040601429800386941331039952274932d0 /
data wg ( 3) / 0.062672048334109063569506535187042d0 /
data wg ( 4) / 0.083276741576704748724758143222046d0 /
data wg ( 5) / 0.101930119817240435036750135480350d0 /
data wg ( 6) / 0.118194531961518417312377377711382d0 /
data wg ( 7) / 0.131688638449176626898494499748163d0 /
data wg ( 8) / 0.142096109318382051329298325067165d0 /
data wg ( 9) / 0.149172986472603746787828737001969d0 /
data wg ( 10) / 0.152753387130725850698084331955098d0 /
data xgk ( 1) / 0.998859031588277663838315576545863d0 /
data xgk ( 2) / 0.993128599185094924786122388471320d0 /
data xgk ( 3) / 0.981507877450250259193342994720217d0 /
data xgk ( 4) / 0.963971927277913791267666131197277d0 /
data xgk ( 5) / 0.940822633831754753519982722212443d0 /
data xgk ( 6) / 0.912234428251325905867752441203298d0 /
data xgk ( 7) / 0.878276811252281976077442995113078d0 /
data xgk ( 8) / 0.839116971822218823394529061701521d0 /
data xgk ( 9) / 0.795041428837551198350638833272788d0 /
data xgk ( 10) / 0.746331906460150792614305070355642d0 /
data xgk ( 11) / 0.693237656334751384805490711845932d0 /
data xgk ( 12) / 0.636053680726515025452836696226286d0 /
data xgk ( 13) / 0.575140446819710315342946036586425d0 /
data xgk ( 14) / 0.510867001950827098004364050955251d0 /
data xgk ( 15) / 0.443593175238725103199992213492640d0 /
data xgk ( 16) / 0.373706088715419560672548177024927d0 /
data xgk ( 17) / 0.301627868114913004320555356858592d0 /
data xgk ( 18) / 0.227785851141645078080496195368575d0 /
data xgk ( 19) / 0.152605465240922675505220241022678d0 /
data xgk ( 20) / 0.076526521133497333754640409398838d0 /
data xgk ( 21) / 0.000000000000000000000000000000000d0 /
data wgk ( 1) / 0.003073583718520531501218293246031d0 /
data wgk ( 2) / 0.008600269855642942198661787950102d0 /
data wgk ( 3) / 0.014626169256971252983787960308868d0 /
data wgk ( 4) / 0.020388373461266523598010231432755d0 /
data wgk ( 5) / 0.025882133604951158834505067096153d0 /
data wgk ( 6) / 0.031287306777032798958543119323801d0 /
data wgk ( 7) / 0.036600169758200798030557240707211d0 /
data wgk ( 8) / 0.041668873327973686263788305936895d0 /
data wgk ( 9) / 0.046434821867497674720231880926108d0 /
data wgk ( 10) / 0.050944573923728691932707670050345d0 /
data wgk ( 11) / 0.055195105348285994744832372419777d0 /
data wgk ( 12) / 0.059111400880639572374967220648594d0 /
data wgk ( 13) / 0.062653237554781168025870122174255d0 /
data wgk ( 14) / 0.065834597133618422111563556969398d0 /
data wgk ( 15) / 0.068648672928521619345623411885368d0 /
data wgk ( 16) / 0.071054423553444068305790361723210d0 /
data wgk ( 17) / 0.073030690332786667495189417658913d0 /
data wgk ( 18) / 0.074582875400499188986581418362488d0 /
data wgk ( 19) / 0.075704497684556674659542775376617d0 /
data wgk ( 20) / 0.076377867672080736705502835038061d0 /
data wgk ( 21) / 0.076600711917999656445049901530102d0 /
epmach = epsilon ( epmach )
uflow = tiny ( uflow )
centr = 0.5D+00*(a+b)
hlgth = 0.5D+00*(b-a)
dhlgth = abs ( hlgth)
!
! compute the 41-point gauss-kronrod approximation to
! the integral, and estimate the absolute error.
!
resg = 0.0D+00
fc = f(centr)
resk = wgk(21)*fc
resabs = abs ( resk)
do j=1,10
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,10
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.5D+00
resasc = wgk(21)* abs ( fc-reskh)
do j=1,20
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.ne.0.0D+00.and.abserr.ne.0.D+00) &
abserr = resasc* min (0.1D+01,(0.2D+03*abserr/resasc)**1.5D+00)
if(resabs.gt.uflow/(0.5D+02*epmach)) abserr = max &
((epmach*0.5D+02)*resabs,abserr)
return
end subroutine dqk41
!----------------------------------------------------------------------------------------
!> DQK51 carries out a 51 point Gauss-Kronrod quadrature rule.
!!
!! Modified:
!!
!! 11 September 2015
!!
!! Author:
!!
!! Robert Piessens, Elise de Doncker
!!
!!***purpose to compute i = integral of f over (a,b) with error
!! estimate
!! j = integral of abs(f) over (a,b)
!!
!! Parameters:
!!
!! on entry
!! f - real ( kind = 8 )
!! function defining the integrand
!! function f(x). the actual name for f needs to be
!! declared e x t e r n a l in the calling program.
!!
!! a - real ( kind = 8 )
!! lower limit of integration
!!
!! b - real ( kind = 8 )
!! upper limit of integration
!!
!! on return
!! result - real ( kind = 8 )
!! 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).
!!
!! abserr - real ( kind = 8 )
!! estimate of the modulus of the absolute error,
!! which should not exceed abs(i-result)
!!
!! resabs - real ( kind = 8 )
!! approximation to the integral j
!!
!! resasc - real ( kind = 8 )
!! approximation to the integral of abs(f-i/(b-a))
!! over (a,b)
!!
!! Local Parameters:
!!
!! the abscissae and weights are given for the interval (-1,1).
!! because of symmetry only the positive abscissae and their
!! corresponding weights are given.
!!
!! xgk - 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
!!
!! wgk - weights of the 51-point kronrod rule
!!
!! wg - weights of the 25-point gauss rule
!!
!! gauss quadrature weights and kronron quadrature abscissae and weights
!! as evaluated with 80 decimal digit arithmetic by l. w. fullerton,
!! bell labs, nov. 1981.
!!
!! centr - mid point of the interval
!! hlgth - half-length of the interval
!! absc - abscissa
!! fval* - function value
!! resg - result of the 25-point gauss formula
!! resk - result of the 51-point kronrod formula
!! reskh - approximation to the mean value of f over (a,b),
!! i.e. to i/(b-a)
!!
!! machine dependent constants
!!
!! epmach is the largest relative spacing.
!! uflow is the smallest positive magnitude.
!!
subroutine dqk51(f,a,b,result,abserr,resabs,resasc)
implicit none
real ( kind = 8 ) a,absc,abserr,b,centr,dhlgth, &
epmach,f,fc,fsum,fval1,fval2,fv1,fv2,hlgth,resabs,resasc, &
resg,resk,reskh,result,uflow,wg,wgk,xgk
integer ( kind = 4 ) j,jtw,jtwm1
external f
dimension fv1(25),fv2(25),xgk(26),wgk(26),wg(13)
data wg ( 1) / 0.011393798501026287947902964113235d0 /
data wg ( 2) / 0.026354986615032137261901815295299d0 /
data wg ( 3) / 0.040939156701306312655623487711646d0 /
data wg ( 4) / 0.054904695975835191925936891540473d0 /
data wg ( 5) / 0.068038333812356917207187185656708d0 /
data wg ( 6) / 0.080140700335001018013234959669111d0 /
data wg ( 7) / 0.091028261982963649811497220702892d0 /
data wg ( 8) / 0.100535949067050644202206890392686d0 /
data wg ( 9) / 0.108519624474263653116093957050117d0 /
data wg ( 10) / 0.114858259145711648339325545869556d0 /
data wg ( 11) / 0.119455763535784772228178126512901d0 /
data wg ( 12) / 0.122242442990310041688959518945852d0 /
data wg ( 13) / 0.123176053726715451203902873079050d0 /
data xgk ( 1) / 0.999262104992609834193457486540341d0 /
data xgk ( 2) / 0.995556969790498097908784946893902d0 /
data xgk ( 3) / 0.988035794534077247637331014577406d0 /
data xgk ( 4) / 0.976663921459517511498315386479594d0 /
data xgk ( 5) / 0.961614986425842512418130033660167d0 /
data xgk ( 6) / 0.942974571228974339414011169658471d0 /
data xgk ( 7) / 0.920747115281701561746346084546331d0 /
data xgk ( 8) / 0.894991997878275368851042006782805d0 /
data xgk ( 9) / 0.865847065293275595448996969588340d0 /
data xgk ( 10) / 0.833442628760834001421021108693570d0 /
data xgk ( 11) / 0.797873797998500059410410904994307d0 /
data xgk ( 12) / 0.759259263037357630577282865204361d0 /
data xgk ( 13) / 0.717766406813084388186654079773298d0 /
data xgk ( 14) / 0.673566368473468364485120633247622d0 /
data xgk ( 15) / 0.626810099010317412788122681624518d0 /
data xgk ( 16) / 0.577662930241222967723689841612654d0 /
data xgk ( 17) / 0.526325284334719182599623778158010d0 /
data xgk ( 18) / 0.473002731445714960522182115009192d0 /
data xgk ( 19) / 0.417885382193037748851814394594572d0 /
data xgk ( 20) / 0.361172305809387837735821730127641d0 /
data xgk ( 21) / 0.303089538931107830167478909980339d0 /
data xgk ( 22) / 0.243866883720988432045190362797452d0 /
data xgk ( 23) / 0.183718939421048892015969888759528d0 /
data xgk ( 24) / 0.122864692610710396387359818808037d0 /
data xgk ( 25) / 0.061544483005685078886546392366797d0 /
data xgk ( 26) / 0.000000000000000000000000000000000d0 /
data wgk ( 1) / 0.001987383892330315926507851882843d0 /
data wgk ( 2) / 0.005561932135356713758040236901066d0 /
data wgk ( 3) / 0.009473973386174151607207710523655d0 /
data wgk ( 4) / 0.013236229195571674813656405846976d0 /
data wgk ( 5) / 0.016847817709128298231516667536336d0 /
data wgk ( 6) / 0.020435371145882835456568292235939d0 /
data wgk ( 7) / 0.024009945606953216220092489164881d0 /
data wgk ( 8) / 0.027475317587851737802948455517811d0 /
data wgk ( 9) / 0.030792300167387488891109020215229d0 /
data wgk ( 10) / 0.034002130274329337836748795229551d0 /
data wgk ( 11) / 0.037116271483415543560330625367620d0 /
data wgk ( 12) / 0.040083825504032382074839284467076d0 /
data wgk ( 13) / 0.042872845020170049476895792439495d0 /
data wgk ( 14) / 0.045502913049921788909870584752660d0 /
data wgk ( 15) / 0.047982537138836713906392255756915d0 /
data wgk ( 16) / 0.050277679080715671963325259433440d0 /
data wgk ( 17) / 0.052362885806407475864366712137873d0 /
data wgk ( 18) / 0.054251129888545490144543370459876d0 /
data wgk ( 19) / 0.055950811220412317308240686382747d0 /
data wgk ( 20) / 0.057437116361567832853582693939506d0 /
data wgk ( 21) / 0.058689680022394207961974175856788d0 /
data wgk ( 22) / 0.059720340324174059979099291932562d0 /
data wgk ( 23) / 0.060539455376045862945360267517565d0 /
data wgk ( 24) / 0.061128509717053048305859030416293d0 /
data wgk ( 25) / 0.061471189871425316661544131965264d0 /
data wgk ( 26) / 0.061580818067832935078759824240066d0 /
epmach = epsilon ( epmach )
uflow = tiny ( uflow )
centr = 0.5D+00*(a+b)
hlgth = 0.5D+00*(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.5D+00
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.ne.0.0D+00.and.abserr.ne.0.0D+00) &
abserr = resasc* min (0.1D+01,(0.2D+03*abserr/resasc)**1.5D+00)
if(resabs.gt.uflow/(0.5D+02*epmach)) abserr = max &
((epmach*0.5D+02)*resabs,abserr)
return
end subroutine dqk51
!----------------------------------------------------------------------------------------
!> DQK61 carries out a 61 point Gauss-Kronrod quadrature rule.
!!
!! Modified:
!!
!! 11 September 2015
!!
!! Author:
!!
!! Robert Piessens, Elise de Doncker
!!
!!***purpose to compute i = integral of f over (a,b) with error
!! estimate
!! j = integral of abs ( f) over (a,b)
!!
!! Parameters:
!!
!! on entry
!! f - real ( kind = 8 )
!! function subprogram defining the integrand
!! function f(x). the actual name for f needs to be
!! declared e x t e r n a l in the calling program.
!!
!! a - real ( kind = 8 )
!! lower limit of integration
!!
!! b - real ( kind = 8 )
!! upper limit of integration
!!
!! on return
!! result - real ( kind = 8 )
!! approximation to the integral i
!! result is computed by applying the 61-point
!! kronrod rule (resk) obtained by optimal addition of
!! abscissae to the 30-point gauss rule (resg).
!!
!! abserr - real ( kind = 8 )
!! estimate of the modulus of the absolute error,
!! which should equal or exceed abs ( i-result)
!!
!! resabs - real ( kind = 8 )
!! approximation to the integral j
!!
!! resasc - real ( kind = 8 )
!! approximation to the integral of abs ( f-i/(b-a))
!!
!! Local Parameters:
!!
!! the abscissae and weights are given for the
!! interval (-1,1). because of symmetry only the positive
!! abscissae and their corresponding weights are given.
!!
!! xgk - abscissae of the 61-point kronrod rule
!! xgk(2), xgk(4) ... abscissae of the 30-point
!! gauss rule
!! xgk(1), xgk(3) ... optimally added abscissae
!! to the 30-point gauss rule
!!
!! wgk - weights of the 61-point kronrod rule
!!
!! wg - weigths of the 30-point gauss rule
!!
!!
!! gauss quadrature weights and kronron quadrature abscissae and weights
!! as evaluated with 80 decimal digit arithmetic by l. w. fullerton,
!! bell labs, nov. 1981.
!!
!! centr - mid point of the interval
!! hlgth - half-length of the interval
!! dabsc - abscissa
!! fval* - function value
!! resg - result of the 30-point gauss rule
!! resk - result of the 61-point kronrod rule
!! reskh - approximation to the mean value of f
!! over (a,b), i.e. to i/(b-a)
!!
!! machine dependent constants
!!
!! epmach is the largest relative spacing.
!! uflow is the smallest positive magnitude.
!!
subroutine dqk61(f,a,b,result,abserr,resabs,resasc)
implicit none
real ( kind = 8 ) a,dabsc,abserr,b,centr,dhlgth, &
epmach,f,fc,fsum,fval1,fval2,fv1,fv2,hlgth,resabs,resasc, &
resg,resk,reskh,result,uflow,wg,wgk,xgk
integer ( kind = 4 ) j,jtw,jtwm1
external f
dimension fv1(30),fv2(30),xgk(31),wgk(31),wg(15)
data wg ( 1) / 0.007968192496166605615465883474674d0 /
data wg ( 2) / 0.018466468311090959142302131912047d0 /
data wg ( 3) / 0.028784707883323369349719179611292d0 /
data wg ( 4) / 0.038799192569627049596801936446348d0 /
data wg ( 5) / 0.048402672830594052902938140422808d0 /
data wg ( 6) / 0.057493156217619066481721689402056d0 /
data wg ( 7) / 0.065974229882180495128128515115962d0 /
data wg ( 8) / 0.073755974737705206268243850022191d0 /
data wg ( 9) / 0.080755895229420215354694938460530d0 /
data wg ( 10) / 0.086899787201082979802387530715126d0 /
data wg ( 11) / 0.092122522237786128717632707087619d0 /
data wg ( 12) / 0.096368737174644259639468626351810d0 /
data wg ( 13) / 0.099593420586795267062780282103569d0 /
data wg ( 14) / 0.101762389748405504596428952168554d0 /
data wg ( 15) / 0.102852652893558840341285636705415d0 /
data xgk ( 1) / 0.999484410050490637571325895705811d0 /
data xgk ( 2) / 0.996893484074649540271630050918695d0 /
data xgk ( 3) / 0.991630996870404594858628366109486d0 /
data xgk ( 4) / 0.983668123279747209970032581605663d0 /
data xgk ( 5) / 0.973116322501126268374693868423707d0 /
data xgk ( 6) / 0.960021864968307512216871025581798d0 /
data xgk ( 7) / 0.944374444748559979415831324037439d0 /
data xgk ( 8) / 0.926200047429274325879324277080474d0 /
data xgk ( 9) / 0.905573307699907798546522558925958d0 /
data xgk ( 10) / 0.882560535792052681543116462530226d0 /
data xgk ( 11) / 0.857205233546061098958658510658944d0 /
data xgk ( 12) / 0.829565762382768397442898119732502d0 /
data xgk ( 13) / 0.799727835821839083013668942322683d0 /
data xgk ( 14) / 0.767777432104826194917977340974503d0 /
data xgk ( 15) / 0.733790062453226804726171131369528d0 /
data xgk ( 16) / 0.697850494793315796932292388026640d0 /
data xgk ( 17) / 0.660061064126626961370053668149271d0 /
data xgk ( 18) / 0.620526182989242861140477556431189d0 /
data xgk ( 19) / 0.579345235826361691756024932172540d0 /
data xgk ( 20) / 0.536624148142019899264169793311073d0 /
data xgk ( 21) / 0.492480467861778574993693061207709d0 /
data xgk ( 22) / 0.447033769538089176780609900322854d0 /
data xgk ( 23) / 0.400401254830394392535476211542661d0 /
data xgk ( 24) / 0.352704725530878113471037207089374d0 /
data xgk ( 25) / 0.304073202273625077372677107199257d0 /
data xgk ( 26) / 0.254636926167889846439805129817805d0 /
data xgk ( 27) / 0.204525116682309891438957671002025d0 /
data xgk ( 28) / 0.153869913608583546963794672743256d0 /
data xgk ( 29) / 0.102806937966737030147096751318001d0 /
data xgk ( 30) / 0.051471842555317695833025213166723d0 /
data xgk ( 31) / 0.000000000000000000000000000000000d0 /
data wgk ( 1) / 0.001389013698677007624551591226760d0 /
data wgk ( 2) / 0.003890461127099884051267201844516d0 /
data wgk ( 3) / 0.006630703915931292173319826369750d0 /
data wgk ( 4) / 0.009273279659517763428441146892024d0 /
data wgk ( 5) / 0.011823015253496341742232898853251d0 /
data wgk ( 6) / 0.014369729507045804812451432443580d0 /
data wgk ( 7) / 0.016920889189053272627572289420322d0 /
data wgk ( 8) / 0.019414141193942381173408951050128d0 /
data wgk ( 9) / 0.021828035821609192297167485738339d0 /
data wgk ( 10) / 0.024191162078080601365686370725232d0 /
data wgk ( 11) / 0.026509954882333101610601709335075d0 /
data wgk ( 12) / 0.028754048765041292843978785354334d0 /
data wgk ( 13) / 0.030907257562387762472884252943092d0 /
data wgk ( 14) / 0.032981447057483726031814191016854d0 /
data wgk ( 15) / 0.034979338028060024137499670731468d0 /
data wgk ( 16) / 0.036882364651821229223911065617136d0 /
data wgk ( 17) / 0.038678945624727592950348651532281d0 /
data wgk ( 18) / 0.040374538951535959111995279752468d0 /
data wgk ( 19) / 0.041969810215164246147147541285970d0 /
data wgk ( 20) / 0.043452539701356069316831728117073d0 /
data wgk ( 21) / 0.044814800133162663192355551616723d0 /
data wgk ( 22) / 0.046059238271006988116271735559374d0 /
data wgk ( 23) / 0.047185546569299153945261478181099d0 /
data wgk ( 24) / 0.048185861757087129140779492298305d0 /
data wgk ( 25) / 0.049055434555029778887528165367238d0 /
data wgk ( 26) / 0.049795683427074206357811569379942d0 /
data wgk ( 27) / 0.050405921402782346840893085653585d0 /
data wgk ( 28) / 0.050881795898749606492297473049805d0 /
data wgk ( 29) / 0.051221547849258772170656282604944d0 /
data wgk ( 30) / 0.051426128537459025933862879215781d0 /
data wgk ( 31) / 0.051494729429451567558340433647099d0 /
epmach = epsilon ( epmach )
uflow = tiny ( uflow )
centr = 0.5D+00*(b+a)
hlgth = 0.5D+00*(b-a)
dhlgth = abs ( hlgth)
!
! compute the 61-point kronrod approximation to the
! integral, and estimate the absolute error.
!
resg = 0.0D+00
fc = f(centr)
resk = wgk(31)*fc
resabs = abs ( resk)
do j=1,15
jtw = j*2
dabsc = hlgth*xgk(jtw)
fval1 = f(centr-dabsc)
fval2 = f(centr+dabsc)
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,15
jtwm1 = j*2-1
dabsc = hlgth*xgk(jtwm1)
fval1 = f(centr-dabsc)
fval2 = f(centr+dabsc)
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.5D+00
resasc = wgk(31)* abs ( fc-reskh)
do j=1,30
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.ne.0.0D+00.and.abserr.ne.0.0D+00) &
abserr = resasc* min (0.1D+01,(0.2D+03*abserr/resasc)**1.5D+00)
if(resabs.gt.uflow/(0.5D+02*epmach)) abserr = max &
((epmach*0.5D+02)*resabs,abserr)
return
end subroutine dqk61
!----------------------------------------------------------------------------------------
!> DQMOMO computes modified Chebyshev moments.
!!
!! Modified:
!!
!! 11 September 2015
!!
!! Author:
!!
!! Robert Piessens, Elise de Doncker
!!
!!***purpose this routine computes modified chebsyshev moments. the k-th
!! modified chebyshev moment is defined as the integral over
!! (-1,1) of w(x)*t(k,x), where t(k,x) is the chebyshev
!! polynomial of degree k.
!!
!! Parameters:
!!
!! alfa - real ( kind = 8 )
!! parameter in the weight function w(x), alfa.gt.(-1)
!!
!! beta - real ( kind = 8 )
!! parameter in the weight function w(x), beta.gt.(-1)
!!
!! ri - real ( kind = 8 )
!! vector of dimension 25
!! ri(k) is the integral over (-1,1) of
!! (1+x)**alfa*t(k-1,x), k = 1, ..., 25.
!!
!! rj - real ( kind = 8 )
!! vector of dimension 25
!! rj(k) is the integral over (-1,1) of
!! (1-x)**beta*t(k-1,x), k = 1, ..., 25.
!!
!! rg - real ( kind = 8 )
!! vector of dimension 25
!! rg(k) is the integral over (-1,1) of
!! (1+x)**alfa*log((1+x)/2)*t(k-1,x), k = 1, ..., 25.
!!
!! rh - real ( kind = 8 )
!! vector of dimension 25
!! rh(k) is the integral over (-1,1) of
!! (1-x)**beta*log((1-x)/2)*t(k-1,x), k = 1, ..., 25.
!!
!! integr - integer ( kind = 4 )
!! input parameter indicating the modified
!! moments to be computed
!! integr = 1 compute ri, rj
!! = 2 compute ri, rj, rg
!! = 3 compute ri, rj, rh
!! = 4 compute ri, rj, rg, rh
!!
subroutine dqmomo(alfa,beta,ri,rj,rg,rh,integr)
implicit none
real ( kind = 8 ) alfa,alfp1,alfp2,an,anm1,beta,betp1,betp2,ralf, &
rbet,rg,rh,ri,rj
integer ( kind = 4 ) i,im1,integr
dimension rg(25),rh(25),ri(25),rj(25)
alfp1 = alfa+0.1D+01
betp1 = beta+0.1D+01
alfp2 = alfa+0.2D+01
betp2 = beta+0.2D+01
ralf = 0.2D+01**alfp1
rbet = 0.2D+01**betp1
!
! compute ri, rj using a forward recurrence relation.
!
ri(1) = ralf/alfp1
rj(1) = rbet/betp1
ri(2) = ri(1)*alfa/alfp2
rj(2) = rj(1)*beta/betp2
an = 0.2D+01
anm1 = 0.1D+01
do i=3,25
ri(i) = -(ralf+an*(an-alfp2)*ri(i-1))/(anm1*(an+alfp1))
rj(i) = -(rbet+an*(an-betp2)*rj(i-1))/(anm1*(an+betp1))
anm1 = an
an = an+0.1D+01
end do
if(integr.eq.1) go to 70
if(integr.eq.3) go to 40
!
! compute rg using a forward recurrence relation.
!
rg(1) = -ri(1)/alfp1
rg(2) = -(ralf+ralf)/(alfp2*alfp2)-rg(1)
an = 0.2D+01
anm1 = 0.1D+01
im1 = 2
do i=3,25
rg(i) = -(an*(an-alfp2)*rg(im1)-an*ri(im1)+anm1*ri(i))/ &
(anm1*(an+alfp1))
anm1 = an
an = an+0.1D+01
im1 = i
end do
if(integr.eq.2) go to 70
!
! compute rh using a forward recurrence relation.
!
40 rh(1) = -rj(1)/betp1
rh(2) = -(rbet+rbet)/(betp2*betp2)-rh(1)
an = 0.2D+01
anm1 = 0.1D+01
im1 = 2
do i=3,25
rh(i) = -(an*(an-betp2)*rh(im1)-an*rj(im1)+ &
anm1*rj(i))/(anm1*(an+betp1))
anm1 = an
an = an+0.1D+01
im1 = i
end do
do i=2,25,2
rh(i) = -rh(i)
end do
70 continue
do i=2,25,2
rj(i) = -rj(i)
end do
90 continue
return
end subroutine dqmomo
!----------------------------------------------------------------------------------------
!> DQNG estimates an integral, using non-adaptive integration.
!!
!! Modified:
!!
!! 11 September 2015
!!
!! Author:
!!
!! Robert Piessens, Elise de Doncker
!!
!!***purpose the routine calculates an approximation result to a
!! given definite integral i = integral of f over (a,b),
!! hopefully satisfying following claim for accuracy
!! abs(i-result).le.max(epsabs,epsrel*abs(i)).
!!
!! Parameters:
!!
!! f - real ( kind = 8 )
!! function subprogram defining the integrand function
!! f(x). the actual name for f needs to be declared
!! e x t e r n a l in the driver program.
!!
!! a - real ( kind = 8 )
!! lower limit of integration
!!
!! b - real ( kind = 8 )
!! upper limit of integration
!!
!! epsabs - real ( kind = 8 )
!! absolute accuracy requested
!! epsrel - real ( kind = 8 )
!! relative accuracy requested
!! if epsabs.le.0
!! and epsrel.lt.max(50*rel.mach.acc.,0.5d-28),
!! the routine will end with ier = 6.
!!
!! on return
!! result - real ( kind = 8 )
!! approximation to the integral i
!! result is obtained by applying the 21-point
!! gauss-kronrod rule (res21) obtained by optimal
!! addition of abscissae to the 10-point gauss rule
!! (res10), or by applying the 43-point rule (res43)
!! obtained by optimal addition of abscissae to the
!! 21-point gauss-kronrod rule, or by applying the
!! 87-point rule (res87) obtained by optimal addition
!! of abscissae to the 43-point rule.
!!
!! abserr - real ( kind = 8 )
!! estimate of the modulus of the absolute error,
!! which should equal or exceed abs(i-result)
!!
!! neval - integer ( kind = 4 )
!! number of integrand evaluations
!!
!! ier - ier = 0 normal and reliable termination of the
!! routine. it is assumed that the requested
!! accuracy has been achieved.
!! ier.gt.0 abnormal termination of the routine. it is
!! assumed that the requested accuracy has
!! not been achieved.
!! error messages
!! ier = 1 the maximum number of steps has been
!! executed. the integral is probably too
!! difficult to be calculated by dqng.
!! = 6 the input is invalid, because
!! epsabs.le.0 and
!! epsrel.lt.max(50*rel.mach.acc.,0.5d-28).
!! result, abserr and neval are set to zero.
!!
!! Local Parameters:
!!
!! the data statements contain the
!! abscissae and weights of the integration rules used.
!!
!! x1 abscissae common to the 10-, 21-, 43- and 87-
!! point rule
!! x2 abscissae common to the 21-, 43- and 87-point rule
!! x3 abscissae common to the 43- and 87-point rule
!! x4 abscissae of the 87-point rule
!! w10 weights of the 10-point formula
!! w21a weights of the 21-point formula for abscissae x1
!! w21b weights of the 21-point formula for abscissae x2
!! w43a weights of the 43-point formula for abscissae x1, x3
!! w43b weights of the 43-point formula for abscissae x3
!! w87a weights of the 87-point formula for abscissae x1,
!! x2, x3
!! w87b weights of the 87-point formula for abscissae x4
!!
!!
!! gauss-kronrod-patterson quadrature coefficients for use in
!! quadpack routine qng. these coefficients were calculated with
!! 101 decimal digit arithmetic by l. w. fullerton, bell labs, nov 1981.
!!
!! centr - mid point of the integration interval
!! hlgth - half-length of the integration interval
!! fcentr - function value at mid point
!! absc - abscissa
!! fval - function value
!! savfun - array of function values which have already been
!! computed
!! res10 - 10-point gauss result
!! res21 - 21-point kronrod result
!! res43 - 43-point result
!! res87 - 87-point result
!! resabs - approximation to the integral of abs(f)
!! resasc - approximation to the integral of abs(f-i/(b-a))
!!
!! machine dependent constants
!!
!! epmach is the largest relative spacing.
!! uflow is the smallest positive magnitude.
!!
subroutine dqng ( f, a, b, epsabs, epsrel, result, abserr, neval, ier )
implicit none
real ( kind = 8 ) a,absc,abserr,b,centr,dhlgth, &
epmach,epsabs,epsrel,f,fcentr,fval,fval1,fval2,fv1,fv2, &
fv3,fv4,hlgth,result,res10,res21,res43,res87,resabs,resasc, &
reskh,savfun,uflow,w10,w21a,w21b,w43a,w43b,w87a,w87b,x1,x2,x3,x4
integer ( kind = 4 ) ier,ipx,k,l,neval
external f
dimension fv1(5),fv2(5),fv3(5),fv4(5),x1(5),x2(5),x3(11),x4(22), &
w10(5),w21a(5),w21b(6),w43a(10),w43b(12),w87a(21),w87b(23), &
savfun(21)
data x1 ( 1) / 0.973906528517171720077964012084452d0 /
data x1 ( 2) / 0.865063366688984510732096688423493d0 /
data x1 ( 3) / 0.679409568299024406234327365114874d0 /
data x1 ( 4) / 0.433395394129247190799265943165784d0 /
data x1 ( 5) / 0.148874338981631210884826001129720d0 /
data w10 ( 1) / 0.066671344308688137593568809893332d0 /
data w10 ( 2) / 0.149451349150580593145776339657697d0 /
data w10 ( 3) / 0.219086362515982043995534934228163d0 /
data w10 ( 4) / 0.269266719309996355091226921569469d0 /
data w10 ( 5) / 0.295524224714752870173892994651338d0 /
data x2 ( 1) / 0.995657163025808080735527280689003d0 /
data x2 ( 2) / 0.930157491355708226001207180059508d0 /
data x2 ( 3) / 0.780817726586416897063717578345042d0 /
data x2 ( 4) / 0.562757134668604683339000099272694d0 /
data x2 ( 5) / 0.294392862701460198131126603103866d0 /
data w21a ( 1) / 0.032558162307964727478818972459390d0 /
data w21a ( 2) / 0.075039674810919952767043140916190d0 /
data w21a ( 3) / 0.109387158802297641899210590325805d0 /
data w21a ( 4) / 0.134709217311473325928054001771707d0 /
data w21a ( 5) / 0.147739104901338491374841515972068d0 /
data w21b ( 1) / 0.011694638867371874278064396062192d0 /
data w21b ( 2) / 0.054755896574351996031381300244580d0 /
data w21b ( 3) / 0.093125454583697605535065465083366d0 /
data w21b ( 4) / 0.123491976262065851077958109831074d0 /
data w21b ( 5) / 0.142775938577060080797094273138717d0 /
data w21b ( 6) / 0.149445554002916905664936468389821d0 /
!
data x3 ( 1) / 0.999333360901932081394099323919911d0 /
data x3 ( 2) / 0.987433402908088869795961478381209d0 /
data x3 ( 3) / 0.954807934814266299257919200290473d0 /
data x3 ( 4) / 0.900148695748328293625099494069092d0 /
data x3 ( 5) / 0.825198314983114150847066732588520d0 /
data x3 ( 6) / 0.732148388989304982612354848755461d0 /
data x3 ( 7) / 0.622847970537725238641159120344323d0 /
data x3 ( 8) / 0.499479574071056499952214885499755d0 /
data x3 ( 9) / 0.364901661346580768043989548502644d0 /
data x3 ( 10) / 0.222254919776601296498260928066212d0 /
data x3 ( 11) / 0.074650617461383322043914435796506d0 /
data w43a ( 1) / 0.016296734289666564924281974617663d0 /
data w43a ( 2) / 0.037522876120869501461613795898115d0 /
data w43a ( 3) / 0.054694902058255442147212685465005d0 /
data w43a ( 4) / 0.067355414609478086075553166302174d0 /
data w43a ( 5) / 0.073870199632393953432140695251367d0 /
data w43a ( 6) / 0.005768556059769796184184327908655d0 /
data w43a ( 7) / 0.027371890593248842081276069289151d0 /
data w43a ( 8) / 0.046560826910428830743339154433824d0 /
data w43a ( 9) / 0.061744995201442564496240336030883d0 /
data w43a ( 10) / 0.071387267268693397768559114425516d0 /
data w43b ( 1) / 0.001844477640212414100389106552965d0 /
data w43b ( 2) / 0.010798689585891651740465406741293d0 /
data w43b ( 3) / 0.021895363867795428102523123075149d0 /
data w43b ( 4) / 0.032597463975345689443882222526137d0 /
data w43b ( 5) / 0.042163137935191811847627924327955d0 /
data w43b ( 6) / 0.050741939600184577780189020092084d0 /
data w43b ( 7) / 0.058379395542619248375475369330206d0 /
data w43b ( 8) / 0.064746404951445885544689259517511d0 /
data w43b ( 9) / 0.069566197912356484528633315038405d0 /
data w43b ( 10) / 0.072824441471833208150939535192842d0 /
data w43b ( 11) / 0.074507751014175118273571813842889d0 /
data w43b ( 12) / 0.074722147517403005594425168280423d0 /
data x4 ( 1) / 0.999902977262729234490529830591582d0 /
data x4 ( 2) / 0.997989895986678745427496322365960d0 /
data x4 ( 3) / 0.992175497860687222808523352251425d0 /
data x4 ( 4) / 0.981358163572712773571916941623894d0 /
data x4 ( 5) / 0.965057623858384619128284110607926d0 /
data x4 ( 6) / 0.943167613133670596816416634507426d0 /
data x4 ( 7) / 0.915806414685507209591826430720050d0 /
data x4 ( 8) / 0.883221657771316501372117548744163d0 /
data x4 ( 9) / 0.845710748462415666605902011504855d0 /
data x4 ( 10) / 0.803557658035230982788739474980964d0 /
data x4 ( 11) / 0.757005730685495558328942793432020d0 /
data x4 ( 12) / 0.706273209787321819824094274740840d0 /
data x4 ( 13) / 0.651589466501177922534422205016736d0 /
data x4 ( 14) / 0.593223374057961088875273770349144d0 /
data x4 ( 15) / 0.531493605970831932285268948562671d0 /
data x4 ( 16) / 0.466763623042022844871966781659270d0 /
data x4 ( 17) / 0.399424847859218804732101665817923d0 /
data x4 ( 18) / 0.329874877106188288265053371824597d0 /
data x4 ( 19) / 0.258503559202161551802280975429025d0 /
data x4 ( 20) / 0.185695396568346652015917141167606d0 /
data x4 ( 21) / 0.111842213179907468172398359241362d0 /
data x4 ( 22) / 0.037352123394619870814998165437704d0 /
data w87a ( 1) / 0.008148377384149172900002878448190d0 /
data w87a ( 2) / 0.018761438201562822243935059003794d0 /
data w87a ( 3) / 0.027347451050052286161582829741283d0 /
data w87a ( 4) / 0.033677707311637930046581056957588d0 /
data w87a ( 5) / 0.036935099820427907614589586742499d0 /
data w87a ( 6) / 0.002884872430211530501334156248695d0 /
data w87a ( 7) / 0.013685946022712701888950035273128d0 /
data w87a ( 8) / 0.023280413502888311123409291030404d0 /
data w87a ( 9) / 0.030872497611713358675466394126442d0 /
data w87a ( 10) / 0.035693633639418770719351355457044d0 /
data w87a ( 11) / 0.000915283345202241360843392549948d0 /
data w87a ( 12) / 0.005399280219300471367738743391053d0 /
data w87a ( 13) / 0.010947679601118931134327826856808d0 /
data w87a ( 14) / 0.016298731696787335262665703223280d0 /
data w87a ( 15) / 0.021081568889203835112433060188190d0 /
data w87a ( 16) / 0.025370969769253827243467999831710d0 /
data w87a ( 17) / 0.029189697756475752501446154084920d0 /
data w87a ( 18) / 0.032373202467202789685788194889595d0 /
data w87a ( 19) / 0.034783098950365142750781997949596d0 /
data w87a ( 20) / 0.036412220731351787562801163687577d0 /
data w87a ( 21) / 0.037253875503047708539592001191226d0 /
data w87b ( 1) / 0.000274145563762072350016527092881d0 /
data w87b ( 2) / 0.001807124155057942948341311753254d0 /
data w87b ( 3) / 0.004096869282759164864458070683480d0 /
data w87b ( 4) / 0.006758290051847378699816577897424d0 /
data w87b ( 5) / 0.009549957672201646536053581325377d0 /
data w87b ( 6) / 0.012329447652244853694626639963780d0 /
data w87b ( 7) / 0.015010447346388952376697286041943d0 /
data w87b ( 8) / 0.017548967986243191099665352925900d0 /
data w87b ( 9) / 0.019938037786440888202278192730714d0 /
data w87b ( 10) / 0.022194935961012286796332102959499d0 /
data w87b ( 11) / 0.024339147126000805470360647041454d0 /
data w87b ( 12) / 0.026374505414839207241503786552615d0 /
data w87b ( 13) / 0.028286910788771200659968002987960d0 /
data w87b ( 14) / 0.030052581128092695322521110347341d0 /
data w87b ( 15) / 0.031646751371439929404586051078883d0 /
data w87b ( 16) / 0.033050413419978503290785944862689d0 /
data w87b ( 17) / 0.034255099704226061787082821046821d0 /
data w87b ( 18) / 0.035262412660156681033782717998428d0 /
data w87b ( 19) / 0.036076989622888701185500318003895d0 /
data w87b ( 20) / 0.036698604498456094498018047441094d0 /
data w87b ( 21) / 0.037120549269832576114119958413599d0 /
data w87b ( 22) / 0.037334228751935040321235449094698d0 /
data w87b ( 23) / 0.037361073762679023410321241766599d0 /
epmach = epsilon ( epmach )
uflow = tiny ( uflow )
!
! test on validity of parameters
!
result = 0.0D+00
abserr = 0.0D+00
neval = 0
ier = 6
if(epsabs.le.0.0D+00.and.epsrel.lt. max ( 0.5D+02*epmach,0.5d-28)) &
go to 80
hlgth = 0.5D+00*(b-a)
dhlgth = abs ( hlgth)
centr = 0.5D+00*(b+a)
fcentr = f(centr)
neval = 21
ier = 1
!
! compute the integral using the 10- and 21-point formula.
!
do 70 l = 1,3
go to (5,25,45),l
5 res10 = 0.0D+00
res21 = w21b(6)*fcentr
resabs = w21b(6)* abs ( fcentr)
do k=1,5
absc = hlgth*x1(k)
fval1 = f(centr+absc)
fval2 = f(centr-absc)
fval = fval1+fval2
res10 = res10+w10(k)*fval
res21 = res21+w21a(k)*fval
resabs = resabs+w21a(k)*( abs ( fval1)+ abs ( fval2))
savfun(k) = fval
fv1(k) = fval1
fv2(k) = fval2
end do
ipx = 5
do k=1,5
ipx = ipx+1
absc = hlgth*x2(k)
fval1 = f(centr+absc)
fval2 = f(centr-absc)
fval = fval1+fval2
res21 = res21+w21b(k)*fval
resabs = resabs+w21b(k)*( abs ( fval1)+ abs ( fval2))
savfun(ipx) = fval
fv3(k) = fval1
fv4(k) = fval2
end do
!
! test for convergence.
!
result = res21*hlgth
resabs = resabs*dhlgth
reskh = 0.5D+00*res21
resasc = w21b(6)* abs ( fcentr-reskh)
do k = 1,5
resasc = resasc+w21a(k)*( abs ( fv1(k)-reskh)+ abs ( fv2(k)-reskh)) &
+w21b(k)*( abs ( fv3(k)-reskh)+ abs ( fv4(k)-reskh))
end do
abserr = abs ( (res21-res10)*hlgth)
resasc = resasc*dhlgth
go to 65
!
! compute the integral using the 43-point formula.
!
25 res43 = w43b(12)*fcentr
neval = 43
do k=1,10
res43 = res43+savfun(k)*w43a(k)
end do
do k=1,11
ipx = ipx+1
absc = hlgth*x3(k)
fval = f(absc+centr)+f(centr-absc)
res43 = res43+fval*w43b(k)
savfun(ipx) = fval
end do
!
! test for convergence.
!
result = res43*hlgth
abserr = abs ( (res43-res21)*hlgth)
go to 65
!
! compute the integral using the 87-point formula.
!
45 res87 = w87b(23)*fcentr
neval = 87
do k=1,21
res87 = res87+savfun(k)*w87a(k)
end do
do k=1,22
absc = hlgth*x4(k)
res87 = res87+w87b(k)*(f(absc+centr)+f(centr-absc))
end do
result = res87*hlgth
abserr = abs ( (res87-res43)*hlgth)
65 continue
if(resasc.ne.0.0D+00.and.abserr.ne.0.0D+00) then
abserr = resasc* min (0.1D+01,(0.2D+03*abserr/resasc)**1.5D+00)
end if
if (resabs.gt.uflow/(0.5D+02*epmach)) then
abserr = max ((epmach*0.5D+02)*resabs,abserr)
end if
if (abserr.le. max ( epsabs,epsrel* abs ( result))) then
ier = 0
return
end if
70 continue
80 call xerror('abnormal return from dqng ',26,ier,0)
999 continue
return
end subroutine dqng
!----------------------------------------------------------------------------------------
!> DQPSRT maintains the order of a list of local error estimates.
!!
!! Modified:
!!
!! 11 September 2015
!!
!! Author:
!!
!! Robert Piessens, Elise de Doncker
!!
!!***purpose this routine maintains the descending ordering in the
!! list of the local error estimated resulting from the
!! interval subdivision process. at each call two error
!! estimates are inserted using the sequential search
!! method, top-down for the largest error estimate and
!! bottom-up for the smallest error estimate.
!!
!! Parameters:
!!
!! limit - integer ( kind = 4 )
!! maximum number of error estimates the list
!! can contain
!!
!! last - integer ( kind = 4 )
!! number of error estimates currently in the list
!!
!! maxerr - integer ( kind = 4 )
!! maxerr points to the nrmax-th largest error
!! estimate currently in the list
!!
!! ermax - real ( kind = 8 )
!! nrmax-th largest error estimate
!! ermax = elist(maxerr)
!!
!! elist - real ( kind = 8 )
!! vector of dimension last containing
!! the error estimates
!!
!! iord - integer ( kind = 4 )
!! vector of dimension last, the first k elements
!! of which contain pointers to the error
!! estimates, such that
!! elist(iord(1)),..., elist(iord(k))
!! form a decreasing sequence, with
!! k = last if last.le.(limit/2+2), and
!! k = limit+1-last otherwise
!!
!! nrmax - integer ( kind = 4 )
!! maxerr = iord(nrmax)
!!
subroutine dqpsrt ( limit, last, maxerr, ermax, elist, iord, nrmax )
implicit none
real ( kind = 8 ) elist,ermax,errmax,errmin
integer ( kind = 4 ) i,ibeg,ido,iord,isucc,j,jbnd,jupbn,k,last, &
lim
integer ( kind = 4 ) limit
integer ( kind = 4 ) maxerr
integer ( kind = 4 ) nrmax
dimension elist(last),iord(last)
!
! check whether the list contains more than
! two error estimates.
!
if(last.gt.2) go to 10
iord(1) = 1
iord(2) = 2
go to 90
!
! this part of the routine is only executed if, due to a
! difficult integrand, subdivision increased the error
! estimate. in the normal case the insert procedure should
! start after the nrmax-th largest error estimate.
!
10 errmax = elist(maxerr)
ido = nrmax-1
do i = 1,ido
isucc = iord(nrmax-1)
if(errmax.le.elist(isucc)) go to 30
iord(nrmax) = isucc
nrmax = nrmax-1
end do
!
! compute the number of elements in the list to be maintained
! in descending order. this number depends on the number of
! subdivisions still allowed.
!
30 jupbn = last
if(last.gt.(limit/2+2)) jupbn = limit+3-last
errmin = elist(last)
!
! insert errmax by traversing the list top-down,
! starting comparison from the element elist(iord(nrmax+1)).
!
jbnd = jupbn-1
ibeg = nrmax+1
do i=ibeg,jbnd
isucc = iord(i)
if(errmax.ge.elist(isucc)) go to 60
iord(i-1) = isucc
end do
iord(jbnd) = maxerr
iord(jupbn) = last
go to 90
!
! insert errmin by traversing the list bottom-up.
!
60 iord(i-1) = maxerr
k = jbnd
do j=i,jbnd
isucc = iord(k)
if(errmin.lt.elist(isucc)) go to 80
iord(k+1) = isucc
k = k-1
end do
iord(i) = last
go to 90
80 iord(k+1) = last
!
! set maxerr and ermax.
!
90 maxerr = iord(nrmax)
ermax = elist(maxerr)
return
end subroutine dqpsrt
!----------------------------------------------------------------------------------------
!> DQWGTC defines the weight function used by DQC25C.
!!
!! Modified:
!!
!! 11 September 2015
!!
!! Author:
!!
!! Robert Piessens, Elise de Doncker
!!
function dqwgtc ( x, c, p2, p3, p4, kp )
implicit none
real ( kind = 8 ) dqwgtc
real ( kind = 8 ) c,p2,p3,p4,x
integer ( kind = 4 ) kp
dqwgtc = 0.1D+01 / ( x - c )
return
end function dqwgtc
!----------------------------------------------------------------------------------------
!> DQWGTF defines the weight functions used by DQC25F.
!!
!! Modified:
!!
!! 11 September 2015
!!
!! Author:
!!
!! Robert Piessens, Elise de Doncker
!!
function dqwgtf(x,omega,p2,p3,p4,integr)
implicit none
real ( kind = 8 ) dqwgtf
real ( kind = 8 ) dcos,dsin,omega,omx,p2,p3,p4,x
integer ( kind = 4 ) integr
omx = omega * x
if ( integr == 1 ) then
dqwgtf = cos ( omx )
else
dqwgtf = sin ( omx )
end if
return
end function dqwgtf
!----------------------------------------------------------------------------------------
!> DQWGTS defines the weight functions used by DQC25S.
!!
!! Modified:
!!
!! 11 September 2015
!!
!! Author:
!!
!! Robert Piessens, Elise de Doncker
!!
function dqwgts ( x, a, b, alfa, beta, integr )
implicit none
real dqwgts
real ( kind = 8 ) a,alfa,b,beta,bmx,x,xma
integer ( kind = 4 ) integr
xma = x - a
bmx = b - x
dqwgts = xma ** alfa * bmx ** beta
go to (40,10,20,30),integr
10 dqwgts = dqwgts* log ( xma )
go to 40
20 dqwgts = dqwgts* log ( bmx )
go to 40
30 dqwgts = dqwgts* log ( xma ) * log ( bmx )
40 continue
return
end function dqwgts
!----------------------------------------------------------------------------------------
!> XERROR replaces the SLATEC XERROR routine.
!!
!! Modified:
!!
!! 12 September 2015
!!
subroutine xerror ( xmess, nmess, nerr, level )
implicit none
integer ( kind = 4 ) level
integer ( kind = 4 ) nerr
integer ( kind = 4 ) nmess
character ( len = * ) xmess
if ( 1 <= LEVEL ) then
WRITE ( *,'(1X,A)') XMESS(1:NMESS)
WRITE ( *,'('' ERROR NUMBER = '',I5,'', MESSAGE LEVEL = '',I5)') &
NERR,LEVEL
end if
return
end subroutine xerror
end module quadpack