        subroutine intrp (itab, xtab, ytab, ntab, x, y, ierr)
c
c Interpolator using CODIM1 algorithm which is admittedly
c obscure  but works well.
c
c       itab - a label between 1 and 20 to identify the table and its
c              most recent search index
c       xtab - array of length ntab containing the x-values
c       ytab -                                     y-values
c       ntab - number of x,y pairs in the table
c          x - independent for which a y-value is desired
c          y - returned interpolated (or extrapolated) value
c       ierr - =0 for ok, -1 for extrapolation
c
        double precision xtab(ntab), ytab(ntab), x, y
        integer itab, ierr, index
        double precision t(4), u(4)
c       integer savind
c       data savind/-1/
c
c----- Only 1 pt in table
        if (ntab .eq. 1) then
                y = ytab(1)
                ierr = 0
                return
        endif
c
c-----
c Locate search index
        call srch (itab, x, xtab, ntab, index, ierr)
c       if (index .eq. savind) go to 2000
c       savind = index
c
c-----
c Set interpolator index flags
        i1 = 2
        i2 = 3
        iload = max0 (index-2, 1)
c
        if (ntab .gt. 2) then
                if (index.eq.   2) i2 = 4
c
                if (index.eq.ntab) i1 = 1
        endif
c
        if (index.gt.2 .and. index.lt.ntab) then
                i1 = 1
                i2 = 4
        endif
c-----
c Load interpolation arrays
        do 1000 i = i1, i2
                j = iload + (i-i1)
                t(i) = xtab (j)
                u(i) = ytab (j)
1000    continue
c
c-----
c Get interpolated value
2000    call codim1 (x, t, u, i1, i2, y)
        return
        end
c
c--------------------------------------------------------------
c
        subroutine srch (itab, x, xtab, ntab, index, ierr)
c
c Search table of x-values to bracket the desired interpolant, x
c
c The returned search index will be:
c       2 - if extrapolation below the table is required
c    ntab -                  above
c   index - points to value just above x in the table if bounded.
c
c The index is saved as a starting point for subsequent entries
c in an array indexed through 'itab' which serves to label the
c set of saved search indices. Itab may be between 1 and 20.
c
c       itab - The table identifier (1-20)
c          x - The value for which an index is desired
c       xtab - The table containing the x-values (array of length ntab)
c       ntab - number of elements in the table
c      index - returned index into the table (points just above x)
c       ierr - 0 for ok, -1 for extrapolation
c
c       Modified to remove entry points.  3/20/86 Valdes
c
        integer ntab, index, init
        double precision xtab(ntab), x
c
c common for subroutines intrp0 and intrpi
c
        common /insvcm/ insave(20)
c
c initialize
        data init/0/
c
c-----
c Initialize
        if (init.eq.0) then
            do 1110 i = 1, 20
1110            insave(i) = 0
            init = 1
        endif
c
c Determine direction of table, ascending or descending
        idir = sign (1.0d0, xtab(ntab) - xtab(1))
c
c-----
c Reset error flag
        ierr = 0
c
c-----
c Check for previous insaved index
        last = insave(itab)
        if (last .eq. 0 .or. last .gt. ntab) then
c
c-----
c no previous entry
                isrch = 1
c check for extrapolation
                if ((x-xtab(   1)) * idir .lt. 0.0d0) go to 2000
                if ((x-xtab(ntab)) * idir .gt. 0.0d0) go to 2100
        else
c
c-----
c previous entry left a valid index
                isrch = last
c
c check for still wihin bounds - difference from above should be opposite
c                                sign of difference from below
c
                if ((xtab(last)-x) * (xtab(last-1)-x) .lt. 0.0d0) then
                        index = last
                        return
                endif
        endif
c
c -----
c Begin searching - first determine direction
c
c This change made because x = xtab(1) was considered extrapolation.
c       if ((x - xtab(isrch)) * idir .gt. 0.0d0) then
        if ((x - xtab(isrch)) * idir .ge. 0.0d0) then
c forward
                do 1100 i = isrch+1, ntab
                        if ((x-xtab(i)) * idir .gt. 0.0d0) go to 1100
                        go to 1500
1100            continue
c fall thru implies extrapolation required at high end
                go to 2100
        else
c
c-----
c negative direction search
                do 1200 i = isrch-1,1,-1
                        if ((x-xtab(i)) * idir .lt. 0.0d0) go to 1200
                        go to 1400
1200            continue
c fall through implies extrapolation at low end
                go to 2000
        endif
c
c-----
c point has been bounded
1400    index = i + 1
        go to 3000
1500    index = i
        go to 3000
c
c-----
c extrapolations
2000    index = 2
        ierr = -1
        go to 3000
2100    index = ntab
        ierr = -1
        go to 3000
c
c-----
c insave index
3000    insave(itab) = index
        end
c
c------
c Subroutine to reset saved index
        subroutine intrp0 (itab)
        integer itab
        common /insvcm/ insave(20)
c
        insave(itab) = 0
        end
c
c-----
c Subroutine to return current index
        subroutine intrpi (itab, ind)
        integer itab, ind
        common /insvcm/ insave(20)
c
        ind = insave(itab)
        end
c
c-------------------------------------------------------------------
c
        subroutine codim1 (x, t, u, i1, i2, y)
c
c this subroutine performs an interposlation in a fashion
c not really understandable, but it works well.
c
c       x - input independent variable
c       t - array of 4 table independents surrounding x if possible
c       u - array of 4 table dependents corresponding to the t array
c
c  i1, i2 - indicators as follows:
c
c           i1 = 1, i2 = 4  :  4 pts available in t and u arrays
c           i1 = 1, i2 = 3  :  3 pts available (x near right edge of table)
c           i1 = 2, i2 = 4  :                  (x near left  edge of table)
c           i1 = 2, i2 = 3  :  2 pts available
c           i1 = 3, i3 = 3  :  1 pt  available
c
c       y - output interpolated (or extrapolated) dependent value
c
        double precision t(4), u(4), x, y
        integer i1, i2
        double precision s, v, z, a1, a2, a3, c1, c2, c3, a4, c4, c5, c6
	double precision e1, e2, p1, p2, slope1, slope2, al, bt, xe

c
c variable xk affects the extrapolation procedure. a value of -1.0
c appears to be a reliable value.
c
        data xk/-1.0d0/
c
        v = x
c the following code is extracted from an original source
c
      a2=v-t(2)
      al=a2/(t(3)-t(2))
      s=al*u(3)+(1.-al)*u(2)
      if(i1.gt.1.and.i2.lt.4)goto1530
      a3=v-t(3)
      if(i1.gt.1)goto1185
1180  a1=v-t(1)
      c1=a2/(t(1)-t(2))*a3/(t(1)-t(3))
      c2=a1/(t(2)-t(1))*a3/(t(2)-t(3))
      c3=a1/(t(3)-t(1))*a2/(t(3)-t(2))
      p1=c1*u(1)+c2*u(2)+c3*u(3)
      if(i2.lt.4)goto1400
1185  a4=v-t(4)
      c4=a3/(t(2)-t(3))*a4/(t(2)-t(4))
      c5=a2/(t(3)-t(2))*a4/(t(3)-t(4))
      c6=a2/(t(4)-t(2))*a3/(t(4)-t(3))
      p2=c4*u(2)+c5*u(3)+c6*u(4)
      if(i1.eq.1)goto1500
1200  if(xk.lt.0.)goto1230
      xe=xk
      goto1260
1230  slope1=abs((u(4)-u(3))/(t(4)-t(3)))
      slope2=abs((u(3)-u(2))/(t(3)-t(2)))
      xe=1.0d0
      if(slope1+slope2.ne.0.)xe=1.-abs(slope1-slope2)/(slope1+slope2)
1260  p1=s+xe*(p2-s)
      goto1500
1400  if(xk.lt.0.)goto1430
      xe=xk
      goto1460
1430  slope1=abs((u(2)-u(1))/(t(2)-t(1)))
      slope2=abs((u(3)-u(2))/(t(3)-t(2)))
      xe=1.0d0
      if(slope1+slope2.ne.0.)xe=1.-abs(slope1-slope2)/(slope1+slope2)
1460  p2=s+xe*(p1-s)
1500  e1=abs(p1-s)
      e2=abs(p2-s)
      if(e1+e2.gt.0.)goto1560
1530  z=s
      goto1700
1560  bt=(e1*al)/(e1*al+(1.-al)*e2)
      z=bt*p2+(1.-bt)*p1
c
1700    y = z
        return
        end
c
c----------------------------------------------------------------------
c
        subroutine lintrp (itab, xtab, ytab, ntab, x, y, ierr)
c
c Linear interpolator with last index save
c
c Arguments are identical to INTRP, and uses the same index search
c scheme so that values for ITAB should not clash with calls
c to INTRP and LINTRP.
c
        double precision xtab(ntab), ytab(ntab), x , y
        integer itab, ierr
c
c----- Only 1 pt in table
        if (ntab .eq. 1) then
                y = ytab (1)
                ierr = 0
                return
        endif
c
c-----locate search index
        call srch (itab, x, xtab, ntab, index, ierr)
c
c----- index points just above x
        y = ytab(index-1) + (x - xtab(index-1)) * 
     1   (ytab(index) - ytab(index-1)) / (xtab(index) - xtab(index-1))
c
        return
        end
