dbfqad computes the integral on (x1,x2)
of a product of a
function f
and the id
-th derivative of a k
-th order b-spline,
using the b-representation (t,bcoef,n,k)
. (x1,x2)
must be a
subinterval of t(k) <= x <= t(n+1)
. an integration routine,
dbsgq8 (a modification of gaus8
), integrates the product
on subintervals of (x1,x2)
formed by included (distinct) knots
Note
the maximum number of significant digits obtainable in
dbsqad is the smaller of ~300 and the number of digits
carried in real(wp)
arithmetic.
Note
Extrapolation is not enabled for this routine.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
procedure(b1fqad_func) | :: | f |
external function of one argument for the
integrand |
|||
real(kind=wp), | intent(in), | dimension(n+k) | :: | t |
knot array |
|
real(kind=wp), | intent(in), | dimension(n) | :: | bcoef |
coefficient array |
|
integer(kind=ip), | intent(in) | :: | n |
length of coefficient array |
||
integer(kind=ip), | intent(in) | :: | k |
order of b-spline, |
||
integer(kind=ip), | intent(in) | :: | id |
order of the spline derivative, |
||
real(kind=wp), | intent(in) | :: | x1 |
left point of quadrature interval in |
||
real(kind=wp), | intent(in) | :: | x2 |
right point of quadrature interval in |
||
real(kind=wp), | intent(in) | :: | tol |
desired accuracy for the quadrature, suggest
|
||
real(kind=wp), | intent(out) | :: | quad |
integral of |
||
integer(kind=ip), | intent(out) | :: | iflag |
status flag:
|
||
real(kind=wp), | intent(inout), | dimension(:) | :: | work |
work vector of length |
subroutine dbfqad(f,t,bcoef,n,k,id,x1,x2,tol,quad,iflag,work) implicit none procedure(b1fqad_func) :: f !! external function of one argument for the !! integrand `bf(x)=f(x)*dbvalu(t,bcoef,n,k,id,x,inbv,work)` integer(ip),intent(in) :: n !! length of coefficient array integer(ip),intent(in) :: k !! order of b-spline, `k >= 1` real(wp),dimension(n+k),intent(in) :: t !! knot array real(wp),dimension(n),intent(in) :: bcoef !! coefficient array integer(ip),intent(in) :: id !! order of the spline derivative, `0 <= id <= k-1` !! `id=0` gives the spline function real(wp),intent(in) :: x1 !! left point of quadrature interval in `t(k) <= x <= t(n+1)` real(wp),intent(in) :: x2 !! right point of quadrature interval in `t(k) <= x <= t(n+1)` real(wp),intent(in) :: tol !! desired accuracy for the quadrature, suggest !! `10*dtol < tol <= 0.1` where `dtol` is the maximum !! of `1.0e-300` and real(wp) unit roundoff for !! the machine real(wp),intent(out) :: quad !! integral of `bf(x)` on `(x1,x2)` real(wp),dimension(:),intent(inout) :: work !! work vector of length `3*k` integer(ip),intent(out) :: iflag !! status flag: !! !! * 0: no errors !! * 1001: `k` does not satisfy `k>=1` !! * 1002: `n` does not satisfy `n>=k` !! * 1003: `d` does not satisfy `0<=id<k` !! * 1004: `x1` or `x2` or both do not !! satisfy `t(k)<=x<=t(n+1)` !! * 1005: `tol` is less than `dtol` !! or greater than 0.1 integer(ip) :: inbv,ilo,il1,il2,left,mflag,npk,np1 real(wp) :: a,aa,ans,b,bb,q,ta,tb,err real(wp),parameter :: min_tol = max(epsilon(1.0_wp),1.0e-300_wp) !! minimum allowed `tol` iflag = 0_ip quad = 0.0_wp err = tol if ( k<1_ip ) then iflag = 1001_ip ! error elseif ( n<k ) then iflag = 1002_ip ! error elseif ( id<0_ip .or. id>=k ) then iflag = 1003_ip ! error else if ( tol>=min_tol .and. tol<=0.1_wp ) then aa = min(x1,x2) bb = max(x1,x2) if ( aa>=t(k) ) then np1 = n + 1_ip if ( bb<=t(np1) ) then if ( aa==bb ) return npk = n + k ilo = 1_ip call dintrv(t,npk,aa,ilo,il1,mflag) call dintrv(t,npk,bb,ilo,il2,mflag) if ( il2>=np1 ) il2 = n inbv = 1_ip q = 0.0_wp do left = il1 , il2 ta = t(left) tb = t(left+1_ip) if ( ta/=tb ) then a = max(aa,ta) b = min(bb,tb) call dbsgq8(f,t,bcoef,n,k,id,a,b,inbv,err,ans,iflag,work) if ( iflag/=0_ip .and. iflag/=1101_ip ) return q = q + ans end if end do if ( x1>x2 ) q = -q quad = q end if else iflag = 1004_ip ! error end if else iflag = 1005_ip ! error end if end if end subroutine dbfqad