      double precision function bvalue(t,lent,bcoef,n,k,x,jderiv)

c Calculates value at  x  of  jderiv-th derivative of spline from B-repr.
c The spline is taken to be continuous from the right.
c
C calls  interv
c
c******  i n p u t ******
c  t, bcoef, n, k......forms the b-representation of the spline  f  to
c        be evaluated. specifically,
c  t.....knot sequence, of length  n+k, assumed nondecreasing.
c  bcoef.....b-coefficient sequence, of length  n .
c  n.....length of  bcoef  and dimension of s(k,t),
c        a s s u m e d  positive .
c  k.....order of the spline .
c
c  w a r n i n g . . .   the restriction  k <= kmax (=20)  is imposed
c        arbitrarily by the dimension statement for  aj, dm, dm  below,
c        but is  n o w h e r e  c h e c k e d  for.
c  however in R, this is only called from bvalus() with k=4 anyway!
c
c  x.....the point at which to evaluate .
c  jderiv.....integer giving the order of the derivative to be evaluated
c        a s s u m e d  to be zero or positive.
c
c******  o u t p u t  ******
c  bvalue.....the value of the (jderiv)-th derivative of  f  at  x .
c
c******  m e t h o d  ******
c     the nontrivial knot interval  (t(i),t(i+1))  containing  x  is lo-
c  cated with the aid of  interv(). the  k  b-coeffs of  f  relevant for
c  this interval are then obtained from  bcoef (or taken to be zero if
c  not explicitly available) and are then differenced  jderiv  times to
c  obtain the b-coeffs of  (d^jderiv)f  relevant for that interval.
c  precisely, with  j = jderiv, we have from x.(12) of the text that
c
c     (d^j)f  =  sum ( bcoef(.,j)*b(.,k-j,t) )
c
c  where
c                   / bcoef(.),                     ,  j .eq. 0
c                   /
c    bcoef(.,j)  =  / bcoef(.,j-1) - bcoef(.-1,j-1)
c                   / ----------------------------- ,  j > 0
c                   /    (t(.+k-j) - t(.))/(k-j)
c
c     then, we use repeatedly the fact that
c
c    sum ( a(.)*b(.,m,t)(x) )  =  sum ( a(.,x)*b(.,m-1,t)(x) )
c  with
c                 (x - t(.))*a(.) + (t(.+m-1) - x)*a(.-1)
c    a(.,x)  =    ---------------------------------------
c                 (x - t(.))      + (t(.+m-1) - x)
c
c  to write  (d^j)f(x)  eventually as a linear combination of b-splines
c  of order  1 , and the coefficient for  b(i,1,t)(x)  must then
c  be the desired number  (d^j)f(x). (see x.(17)-(19) of text).
c
C Arguments
      integer lent, n,k, jderiv
      DOUBLE precision t(*),bcoef(n),x
c     dimension t(n+k)
c  current fortran standard makes it impossible to specify the length of
c  t  precisely without the introduction of otherwise superfluous
c  additional arguments.

C Local Variables
      integer kmax
      parameter(kmax = 20)

      DOUBLE precision aj(kmax),dm(kmax),dp(kmax),fkmj

      integer i,ilo,imk,j,jc,jcmin,jcmax,jj,km1,kmj,mflag,nmi, jdrvp1
c
      integer interv
      external interv

c     initialize
      data i/1/

      bvalue = 0.
      if (jderiv .ge. k) go to 99
c
c  *** find  i	s.t.  1 <= i < n+k  and	 t(i) < t(i+1) and
c      t(i) <= x < t(i+1) . if no such i can be found,	x  lies
c      outside the support of  the spline  f  and  bvalue = 0.
c  {this case is handled in the calling R code}
c      (the asymmetry in this choice of	 i  makes  f  rightcontinuous)
      if( (x.ne.t(n+1)) .or. (t(n+1).ne.t(n+k)) ) then
         i = interv ( t, n+k, x, 0, 0, i, mflag)
         if (mflag .ne. 0) then
            call rwarn("bvalue()  mflag != 0: should never happen!")
            go to 99
         endif
      else
         i = n
      endif

c  *** if k = 1 (and jderiv = 0), bvalue = bcoef(i).
      km1 = k - 1
      if (km1 .le. 0) then
         bvalue = bcoef(i)
         go to 99
      endif
c
c  *** store the k b-spline coefficients relevant for the knot interval
c     (t(i),t(i+1)) in aj(1),...,aj(k) and compute dm(j) = x - t(i+1-j),
c     dp(j) = t(i+j) - x, j=1,...,k-1 . set any of the aj not obtainable
c     from input to zero. set any t.s not obtainable equal to t(1) or
c     to t(n+k) appropriately.
      jcmin = 1
      imk = i - k
      if (imk .ge. 0) then
         do 9 j=1,km1
            dm(j) = x - t(i+1-j)
 9       continue
      else
         jcmin = 1 - imk
         do 5 j=1,i
            dm(j) = x - t(i+1-j)
 5       continue
         do 6 j=i,km1
            aj(k-j) = 0.
            dm(j) = dm(i)
 6       continue
      endif
c
      jcmax = k
      nmi = n - i
      if (nmi .ge. 0) then
         do 19 j=1,km1
C     the following if() happens; e.g. in   pp <- predict(cars.spl, xx)
c     -       if( (i+j) .gt. lent) write(6,9911) i+j,lent
c     -  9911         format(' i+j, lent ',2(i6,1x))
            dp(j) = t(i+j) - x
 19      continue
      else
         jcmax = k + nmi
         do 15 j=1,jcmax
            dp(j) = t(i+j) - x
 15      continue
         do 16 j=jcmax,km1
            aj(j+1) = 0.
            dp(j) = dp(jcmax)
 16      continue
      endif

c
      do 21 jc=jcmin,jcmax
         aj(jc) = bcoef(imk + jc)
 21   continue
c
c               *** difference the coefficients  jderiv  times.
      if (jderiv .ge. 1) then
         do 23 j=1,jderiv
            kmj = k-j
            fkmj = dble(kmj)
            ilo = kmj
            do 24 jj=1,kmj
               aj(jj) = ((aj(jj+1) - aj(jj))/(dm(ilo) + dp(jj)))*fkmj
               ilo = ilo - 1
 24         continue
 23      continue
      endif

c
c  *** compute value at  x  in (t(i),t(i+1)) of jderiv-th derivative,
c     given its relevant b-spline coeffs in aj(1),...,aj(k-jderiv).

      if (jderiv .ne. km1) then
         jdrvp1 = jderiv + 1
         do 33 j=jdrvp1,km1
            kmj = k-j
            ilo = kmj
            do 34 jj=1,kmj
               aj(jj) = (aj(jj+1)*dm(ilo) + aj(jj)*dp(jj)) /
     *              (dm(ilo)+dp(jj))
               ilo = ilo - 1
 34         continue
 33      continue
      endif

      bvalue = aj(1)
c
   99 return
      end
