Returns the indices in xt
that bound x
, to use for interpolation.
If outside the range, then the indices are returned that can
be used for extrapolation.
Precisely,
if x < xt(1) then ileft=1, iright=2, mflag=-1
if xt(i) <= x < xt(i+1) then ileft=i, iright=i+1, mflag=0
if xt(n) <= x then ileft=n-1, iright=n, mflag=1
dintrv
routine for
linear interpolation/extrapolation use.inearest
output.Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
real(kind=wp), | intent(in), | dimension(:) | :: | xt |
a knot or break point vector |
|
real(kind=wp), | intent(in) | :: | x |
argument |
||
integer, | intent(inout) | :: | ilo |
an initialization parameter which must be set
to 1 the first time the array |
||
integer, | intent(out) | :: | ileft |
left index |
||
integer, | intent(out) | :: | iright |
right index |
||
integer, | intent(out) | :: | mflag |
signals when |
||
integer, | intent(out), | optional | :: | inearest |
nearest index |
pure subroutine dintrv(xt,x,ilo,ileft,iright,mflag,inearest) implicit none real(wp),dimension(:),intent(in) :: xt !! a knot or break point vector real(wp),intent(in) :: x !! argument integer,intent(inout) :: ilo !! an initialization parameter which must be set !! to 1 the first time the array `xt` is !! processed by dintrv. `ilo` contains information for !! efficient processing after the initial call and `ilo` !! must not be changed by the user. each dimension !! requires a distinct `ilo` parameter. integer,intent(out) :: ileft !! left index integer,intent(out) :: iright !! right index integer,intent(out) :: mflag !! signals when `x` lies out of bounds integer,intent(out),optional :: inearest !! nearest index integer :: ihi, istep, imid, n n = size(xt) if (n==1) then ! this is only allowed for nearest interpolation if (present(inearest)) then inearest = 1 return end if end if ihi = ilo + 1 if ( ihi>=n ) then if ( x>=xt(n) ) then mflag = 1 ileft = n-1 iright= n if (present(inearest)) inearest = n return end if if ( n<=1 ) then mflag = -1 ileft = 1 iright= 2 if (present(inearest)) inearest = 1 return end if ilo = n - 1 ihi = n endif if ( x>=xt(ihi) ) then ! now x >= xt(ilo). find upper bound istep = 1 do ilo = ihi ihi = ilo + istep if ( ihi>=n ) then if ( x>=xt(n) ) then mflag = 1 ileft = n-1 iright= n if (present(inearest)) inearest = n return end if ihi = n elseif ( x>=xt(ihi) ) then istep = istep*2 cycle endif exit end do else if ( x>=xt(ilo) ) then mflag = 0 ileft = ilo iright= ilo+1 if (present(inearest)) then if ( abs(x-xt(ileft)) <= abs(x-xt(iright)) ) then inearest = ileft else inearest = iright end if end if return end if ! now x <= xt(ihi). find lower bound istep = 1 do ihi = ilo ilo = ihi - istep if ( ilo<=1 ) then ilo = 1 if ( x<xt(1) ) then mflag = -1 ileft = 1 iright= 2 if (present(inearest)) inearest = 1 return end if elseif ( x<xt(ilo) ) then istep = istep*2 cycle endif exit end do endif ! now xt(ilo) <= x < xt(ihi). narrow the interval do imid = (ilo+ihi)/2 if ( imid==ilo ) then mflag = 0 ileft = ilo iright= ilo+1 if (present(inearest)) then if ( abs(x-xt(ileft)) <= abs(x-xt(iright)) ) then inearest = ileft else inearest = iright end if end if return end if ! note. it is assumed that imid = ilo in case ihi = ilo+1 if ( x<xt(imid) ) then ihi = imid else ilo = imid endif end do end subroutine dintrv