*------------- Telecommunications & Signal Processing Lab --------------
*                          McGill University
*
*
* Module:
*     SUBROUTINE PMCINT (X, Y, N, XI, YI, NI)
*
*
* Purpose:
*     Generate a piecewise monotonic cubic interpolant
*
*
* Description:
*     This routine calculates interpolated values. The sampled values
*     are found by passing a piecewise monotonic cubic interpolant
*     through the reference data points. The monotonicity requirement
*     guarantees that the interpolated data values do not go outside
*     the range of the bracketing reference data values.
*
*     References:
*       Subroutine PCHIM, F.N. Fritsch, Lawrence Livermore National
*       Laboratory.
*       F.N. Fritsch and J. Butland, "A method for constructing local
*       monotone piecewise cubic interpolants", SIAM J. Sci. Stat.
*       Comput., Vol. 5, pp. 300-304, June 1984.
*
*
* Parameters:
* R ->  X      - Input abscissa values for the reference points.  These
*                values must be in increasing order.
* R ->  Y      - Input ordinate values for the reference points
* I ->  N      - Number of reference points
* R ->  XI     - Abscissa values for the interpolated points.  These
*                values must be bounded by X(1) and X(N).  The values
*                XI(i), need not be in any particular order, although
*                some efficiency is gained if they are in increasing
*                or decreasing order.
* R <-  YI     - Resulting interpolated ordinate values
* I ->  NI     - Number of interpolated values
*
*
* Author / revision:
*     P. Kabal
*     $Revision: 1.5 $  $Date: 1995/03/08 15:24:27 $
*
*
*-----------------------------------------------------------------------

      SUBROUTINE PMCINT (X, Y, N, XI, YI, NI)


      INTEGER N,NI
      INTEGER K,I,KP
      INTEGER LQUANT

      REAL DL,DH
      REAL X(N),Y(N),XI(NI),YI(NI)
      REAL DMCINT,EVCINT


* Check the reference abscissa values
      DO 100 K=1,N-1
        IF (X(K+1).LT.X(K))
     -    CALL HALT('PMCINT - Reference abscissa values not in '//
     -              'increasing order')
 100  CONTINUE


* Special case: only one reference point
      IF (N.EQ.1) THEN

        DO 120 I=1,NI
          IF (XI(I).NE.X(1))
     -      CALL HALT('PMCINT - Abscissa value out of range')
          YI(I)=Y(1)
 120    CONTINUE


* General case: 2 or more reference points
      ELSE

        KP=-1
        DO 160 I=1,NI

* Search for the bracketing interval
          K=LQUANT(XI(I),X,N+1)-1
          IF (K.EQ.0 .AND. XI(I).EQ.X(1)) K=1
          IF (K.LE.0 .OR. K.GE.N)
     -      CALL HALT('PMCINT - Abscissa value out of range')

* Interval found: X(k) <= XI(i) <= X(k+1)
* Find the derivatives at the bracketing points, and then
* evaluate the cubic at the interpolation point
          IF (K.EQ.KP) THEN
            CONTINUE
          ELSE IF (KP.EQ.K-1) THEN
            DL=DH
            DH=DMCINT(K+1,X,Y,N)
          ELSE IF (KP.EQ.K+1) THEN
            DH=DL
            DL=DMCINT(K,X,Y,N)
          ELSE
            DL=DMCINT(K,X,Y,N)
            DH=DMCINT(K+1,X,Y,N)
          END IF
          YI(I)=EVCINT(XI(I),X(K),X(K+1),Y(K),Y(K+1),DL,DH)
          KP=K

 160    CONTINUE

      END IF


      RETURN

      END
