Computes the largest integer ileft
in 1
ileft
lxt
such that xt(ileft)
x
where xt(*)
is a subdivision of
the x
interval.
precisely,
if x < xt(1) then ileft=1, mflag=-1
if xt(i) <= x < xt(i+1) then ileft=i, mflag=0
if xt(lxt) <= x then ileft=lxt, mflag=-2
that is, when multiplicities are present in the break point
to the left of x
, the largest index is taken for ileft
.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
real(kind=wp), | intent(in), | dimension(:) | :: | xt |
a knot or break point vector of length |
|
integer(kind=ip), | intent(in) | :: | lxt |
length of the |
||
real(kind=wp), | intent(in) | :: | xx |
argument |
||
integer(kind=ip), | intent(inout) | :: | ilo |
an initialization parameter which must be set
to 1 the first time the spline array |
||
integer(kind=ip), | intent(out) | :: | ileft |
largest integer satisfying |
||
integer(kind=ip), | intent(out) | :: | mflag |
signals when |
||
logical, | intent(in), | optional | :: | extrap |
if extrapolation is allowed (if not present, default is False) |
pure subroutine dintrv(xt,lxt,xx,ilo,ileft,mflag,extrap) implicit none integer(ip),intent(in) :: lxt !! length of the `xt` vector real(wp),dimension(:),intent(in) :: xt !! a knot or break point vector of length `lxt` real(wp),intent(in) :: xx !! argument integer(ip),intent(inout) :: ilo !! an initialization parameter which must be set !! to 1 the first time the spline 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. distinct splines !! require distinct `ilo` parameters. integer(ip),intent(out) :: ileft !! largest integer satisfying `xt(ileft)` \( \le \) `x` integer(ip),intent(out) :: mflag !! signals when `x` lies out of bounds logical,intent(in),optional :: extrap !! if extrapolation is allowed !! (if not present, default is False) integer(ip) :: ihi, istep, middle real(wp) :: x x = get_temp_x_for_extrap(xx,xt(1_ip),xt(lxt),extrap) ihi = ilo + 1_ip if ( ihi>=lxt ) then if ( x>=xt(lxt) ) then mflag = -2_ip ileft = lxt return end if if ( lxt<=1 ) then mflag = -1_ip ileft = 1_ip return end if ilo = lxt - 1_ip ihi = lxt end if if ( x>=xt(ihi) ) then ! now x >= xt(ilo). find upper bound istep = 1_ip do ilo = ihi ihi = ilo + istep if ( ihi>=lxt ) then if ( x>=xt(lxt) ) then mflag = -2_ip ileft = lxt return end if ihi = lxt else if ( x>=xt(ihi) ) then istep = istep*2_ip cycle end if exit end do else if ( x>=xt(ilo) ) then mflag = 0_ip ileft = ilo return end if ! now x <= xt(ihi). find lower bound istep = 1_ip do ihi = ilo ilo = ihi - istep if ( ilo<=1_ip ) then ilo = 1_ip if ( x<xt(1_ip) ) then mflag = -1_ip ileft = 1_ip return end if else if ( x<xt(ilo) ) then istep = istep*2_ip cycle end if exit end do end if ! now xt(ilo) <= x < xt(ihi). narrow the interval do middle = (ilo+ihi)/2_ip if ( middle==ilo ) then mflag = 0_ip ileft = ilo return end if ! note. it is assumed that middle = ilo in case ihi = ilo+1 if ( x<xt(middle) ) then ihi = middle else ilo = middle end if end do end subroutine dintrv