C******************** START FILE XINTER.FOR ; GROUP XINTER ******************
C-------------------------------------------------------------------
C&  XINTER LINEAR INTERPOLATION DEFINITION SUBROUTINE
C
C  INTERPOLATION UTILITY
C  DEFINE LINEAR INTERPOLATION IN ONE DIMENSION
C
      SUBROUTINE XINTER(ORDER,TARGET,X,NX,IX0,IX0P1,XI,XIC,IEX)
C
      REAL X(NX)
C
C  INPUT
C
C   ORDER  *EXTERNAL FUNCTION* ORDERING FUNCTION ON X
C    ***   THE EXPRESSION ORDER(X(IX)) MUST BE MONOTONIC WITH RESPECT
C          TO THE INDEX IX, BUT MAY BE INCREASING OR DECREASING
C
C  THE CALLING PROGRAM MUST DECLARE THE ORDER FUNCTION EXTERNAL ***
C
C   NOTE FUNCTION XIDENT, THE IDENTITY FUNCTION, MAY BE CONVENIENT
C    (SEE BOTTOM OF THIS SOURCE FILE)
C
C   TARGET
C          TARGET OF INTERPOLATION **IN UNITS OF ORDERING FUNCTION**
C
C   X(NX)  DOMAIN OF DATA ON WHICH INTERPOLATION IS TO BE PERFORMED
C
C
C  OUTPUT
C   IX0    INDEX TO NEAREST X BELOW TARGET (AS DEFN BY ORDER FCN ***)
C   IX0P1  IX0+1
C   XI     INTERPOLATION FACTOR
C                                   (TARGET-ORDER(X(IX0)))
C                               ------------------------------
C                               (ORDER(X(IX0P1))-ORDER(X(IX0)))
C
C          I.E. --> 0.0 IF ORDER(X(IX0)) IS NEAR TARGET
C          AND --> 1.0 IF ORDER(X(IX0P1)) IS NEAR TARGET
C
C   XIC    COMPLIMENTARY FACTOR XIC=1.0-XI
C   IEX    FLAG 0=NORMAL, 1=TARGET OUT OF RANGE, EXTRAPOLATION EXPECTED
C
C  INTERPOLATION FORMULA WILL BE
C   F0=F(IX0)*XIC + F(IX0P1)*XI
C
C  IF F(NX) DEFINED AT X(NX) IS THE FUNCTION BEING INTERPOLATED
C
C  IF CALLER KEEPS INTERPOLATION INDEX IX0 FROM PRIOR CALL, SEARCH FOR
C  NEW INTERPOLATION INDEX WILL PROCEED FROM THAT POINT AFTER A LIMIT
C  CHECK
C
C---------------------------------------------------------------------
C
C  LOGICAL STATEMENT FUNCTION-- ORDER TEST
C   .TRUE. IF:
C     IDIR=1 AND O1.LT.O2
C       OR
C     IDIR=-1 AND O1.GT.O2
C       OR
C     IEQ=1 AND O1.E1.O2
C
      EXTERNAL ORDER
      LOGICAL LORDER
      LORDER(O1,O2,IDIR,IEQ)=((IEQ.EQ.1).AND.(O1.EQ.O2)) .OR.
     >         ((O2-O1)*IDIR.GT.0.0)
C
C---------------------------------------------------------------------
C  START
C
      IEX=0
C
      IX0=MIN0(NX,MAX0(1,IX0))
C
      ORD1=ORDER(X(1))
      ORDN=ORDER(X(NX))
C
C  ASSUME MONOTONICITY, DEFINE DIRECTION
C
      IF(ORD1.GT.ORDN) THEN
        IDIR=-1
      ELSE
        IDIR=1
      ENDIF
C
C  CHECK FOR EXTRAPOLATION
      IF(LORDER(TARGET,ORD1,IDIR,1)) THEN
C  AT LOW INDEX EXTREME...
        IX0=1
        XI=0.0
        IF(TARGET.NE.ORD1) IEX=1
      ELSE IF(LORDER(ORDN,TARGET,IDIR,1)) THEN
C  AT HIGH INDEX EXTREME...
        IF(TARGET.NE.ORDN) THEN
C  EXTRAPOLATION
          IX0=NX
          XI=0.0
          IEX=1
        ELSE
C  EXACT ENDPOINT MATCH
          IX0=NX-1
          XI=1.0
        ENDIF
      ELSE
C  INBETWEEN
C   DETERMINE DIRECTION OF SEARCH (INDEX)
        ORDIX0=ORDER(X(IX0))
        IF(LORDER(ORDIX0,TARGET,IDIR,2)) THEN
C   SEARCH FORWARD
          I=IX0+1
          ORDI=ORDER(X(I))
          DO WHILE (LORDER(ORDI,TARGET,IDIR,2))
            ORDIX0=ORDI
            I=I+1
            ORDI=ORDER(X(I))
          ENDDO
          IX0=I-1
          XI=(TARGET-ORDIX0)/(ORDI-ORDIX0)
        ELSE IF(LORDER(TARGET,ORDIX0,IDIR,2)) THEN
C   SEARCH BACK
          I=IX0-1
          ORDI=ORDER(X(I))
          DO WHILE (LORDER(TARGET,ORDI,IDIR,2))
            ORDIX0=ORDI
            I=I-1
            ORDI=ORDER(X(I))
          ENDDO
          IX0=I
          I=I+1
          XI=(TARGET-ORDI)/(ORDIX0-ORDI)
        ELSE
C   BULL'S EYE
          XI=0.0
        ENDIF
      ENDIF
C
C  FINISH UP
C
      IX0P1=MIN0(NX,(IX0+1))
      XIC=1.0-XI
C
      RETURN
      END
C******************** END FILE XINTER.FOR ; GROUP XINTER ******************
