      SUBROUTINE ADAPT1(F, XKNOTS, COEFS, KDIMEN, KMAX, NDIMEN, IERR)
C
C     THIS ALGORITHM COMPUTES A PIECEWISE POLYNOMIAL APPROXIMATION
C  OF SPECIFIED SMOOTHNESS, ACCURACY AND DEGREE.  THE INPUT TO THE
C  COMPUTATION IS
C
C   F      - FUNCTION BEING APPROXIMATED. IT MUST PROVIDE VALUES OF
C            DERIVATIVES UP TO THE ORDER OF SMOOTHNESS SPECIFIED FOR
C            THE APPROXIMATION.  THE CALLING SEQUENCE IS F(X,FDERV) AND
C            FDERV CONTAINS THE DERIVATIVES( SEE CONSTRAINT BELOW)
C   A,B    - THE ENDPOINTS OF THE INTERVAL OF APPROXIMATION
C   ACCUR  - THE ACCURACY REQUIRED FOR THE APPROXIMATION
C   SMOOTH - THE SMOOTHNESS REQUIRED FOR THE APPROXIMATION
C              = 0  MEANS CONTINUOUS
C              = 1  MEANS CONTINUOUS SLOPE
C              = 2  MEANS CONTINUOUS SECOND DERIVATIVE, ETC.
C   DEGREE - THE DEGREE OF THE POLYNOMIAL PIECES.
C            MUST HAVE DEGREE GT 2*SMOOTH
C   CHARF  - CHARACTERISTIC LENGTH OF THE FUNCTION F(X). PIECES ARE NOT
C            LONGER THAN THIS LENGTH.
C   NORM   - NORM TO MEASURE THE APPROXIMATION ERROR
C              = 1  L1 APPROXIMATION (LEAST DEVIATIONS)
C              = 2  L2 APPROXIMATION (LEAST SQUARES)
C              = 3  TCHEBYCHEFF (MINIMAX) APPROXIMATION
C              =-P  (NEGATIVE VALUE) GENERAL LP APPROXIMATION
C   NBREAK - NUMBER OF SPECIAL BREAK POINTS IN THE APPROXIMATION.
C            ASSOCIATED INPUT VARIABLES ARE
C              XBREAK(J)  - LOCATION OF BREAK POINTS
C              DBREAK(J)  - DERIVATIVE BROKEN AT XBREAK
C              BLEFT (J)  - VALUE FROM LEFT FOR DBREAK DERIVATIVE
C              BRIGHT(J)  -   -    -   RIGHT -    -        -
C   EDIST  - SWITCH TO CHANGE FROM PROPORTIONAL ERROR DISTRIBUTION
C            TO FIXED DISTRIBUTION. THIS IS PRIMARILY OF USE IN
C            APPROXIMATION OF FUNCTIONS WITH SINGULARITIES. ONE SHOULD
C            USE NORM = 1. OR SO IN SUCH CASES
C              = 0  PROPORTIONAL DISTRIBUTION
C              = 1  APPROXIMATE FIXED ERROR DISTRIBUTION
C                   ATTEMPTS TO ACHIEVE SPECIFIED ACCURACY VALUE ACCUR
C              = 2  TRUE FIXED ERROR DISTRIBUTION
C
C  ********** OUTPUT **********
C     THE OUTPUT OF THE COMPUTATION CONSISTS OF 4 PARTS, EACH RETURNED
C     TO THE USER IN A DIFFERENT WAY. THEY ARE
C
C   XKNOTS,COEFS - ARRAYS DEFINING THE PIECEWISE POLYNOMIAL RESULT.
C            XKNOTS(K)  = KNOTS OF THE APPROXIMATION ( K = 1 TO KNOTS)
C                         THE LAST ONE IS RIGHT END POINT OF INTERVAL
C            COEFS(K,N) = COEFFICIENT OF (X - XKNOT(K))**(N-1) IN THE
C                         INTERVAL XKNOT(K) TO XKNOT(K+1)
C                           K = 1 TO KNOTS-1  AND  N = 1 TO DEGREE+1
C            THESE ARRAYS ARE PASSED AS ARGUMENTS SO AS TO USE VARIABLE
C            DIMENSIONS. THE ARRAYS ARE OF DIMENSION XKNOTS(KDIMEN) AND
C            COEFS(KMAX,NDIMEN). IT IS ASSUMED THAT KDIMEN = KMAX+1.
C               ***** NOTE ***** SEVERAL SMALL ARRAYS HERE HAVE FIXED
C                        DIMENSIONS THAT LIMIT DEGREE AND THUS NDIMEN
C                        SHOULD NOT EXCEED THIS LIMIT (CURRENTLY = 20)
C
C   RESULZ - A LABELED COMMON BLOCK CONTAINING KNOTS AND ERROR
C              KNOTS - NUMBER OF KNOTS OF THE APPROXIMATION
C              ERROR - ESTIMATED ACCURACY OF THE APPROXIMATION
C
C   IERR - STATUS INDICATOR. IERR TAKES THE VALUES
C      0   THE APPROXIMATION WAS SUCCESSFULLY CONSTRUCTED.
C     -1   INPUT ERROR REPORTED BY ADSET.
C     -2   A AND B ARE TOO CLOSE.
C     -3   CHARF IS TOO SMALL.
C     -4   EITHER ALL THE BREAK POINTS ARE NOT BETWEEN A AND B, OR
C          XBREAK(I).GE.XBREAK(I+1) FOR SOME I.
C     -5   DBREAK(I).LT.0 .OR. DBREAK(I).GT.(DEGREE-1)/2 FOR SOME I.
C      1   THE KNOT LIMIT WAS EXCEEDED.
C      2   BREAK POINT ADJUSTMENT REQUIRES THAT A SUBINTERVAL BE
C          PARTITIONED. HOWEVER, THIS CANNOT BE DONE EITHER BECAUSE
C          THE INTERVAL STACK IS FULL, OR PARTITIONING WILL PRODUCE
C          TOO SMALL AN INTERVAL.
C      3   A SUBINTERVAL MUST BE PARTITIONED BECAUSE ITS LENGTH IS
C          GREATER THAN CHARF. HOWEVER, THIS CANNOT BE DONE SINCE THE
C          INTERVAL STACK IS FULL.
C      4   A SUBINTERVAL MUST BE PARTITIONED SO THAT THE ACCURACY
C          CRITERIA CAN BE SATISFIED. HOWEVER, THIS CANNOT BE DONE
C          EITHER BECAUSE THE INTERVAL STACK IS FULL, OR PARTITIONING
C          WILL PRODUCE TOO SMALL AN INTERVAL.
C
C  ********** DIMENSION CONSTRAINTS **********
C     MAXKNT - MAX NUMBER OF KNOTS TAKEN FROM USER VIA KDIMEN
C              ARRAYS WITH THIS DIMENSION (OR RELATED VALUES)
C                   COEFS   XKNOTS
C     MAXPAR - MAX NUMBER OF PARAMETERS PER INTERVAL (CURRENTLY = 20)
C                   USER PROVIDED NDIMEN MUST HAVE NDIMEN LE MAXPAR
C                   MUST HAVE  DEGREE + 1 LE MAXPAR
C              ARRAYS WITH THIS DIMENSION (OR RELATED VALUES)
C                D       DDTEMP  FDERVL  FDERVR  FDUMB   FACTOR
C                FINTRP  FLEFT   FRIGHT  POWERS  XTEMP   XINTRP  XDD
C              ***** NOTE ***** MAXPAR ALSO AFFECTS ARGUMENT FDERV
C              OF FUNCTION F.  FDERVL, FDERVR ARE ALSO INVOLVED.
C              SHOULD DECLARE FDERV OF SIZE 10 IN F TO BE SAFE.
C     MAXAUX - MAXIMUM NUMBER OF AUXILIARY INPUT ( = 20 NOW ). ARRAYS
C                 XBREAK  DBREAK  BLEFT   BRIGHT
C     MAXSTK - MAX SIZE OF ACTIVE INTERVAL STACK
C              MIN INTERVAL LENGTH IS 2**(-MAXSTK)*(B-A). ARRAYS
C                 XLEFT   XRIGHT
C
C  **********  PORTABILITY CONSIDERATIONS  **********
C
C     ALL THE ROUTINES IN THIS PACKAGE (EXCEPT ADAPT) ARE WRITTEN IN
C     ANSI STANDARD FORTRAN. IN ADDITION, THEY MEET ALL THE REQUIREMENTS
C     OF THE BELL LABS PORTABLE FORTRAN -PFORT-.  NEVERTHELESS, THE
C     ROUTINES ARE AFFECTED BY A CHANGE IN MACHINE WORD LENGTH AND
C     CHANGING TO SINGLE PRECISION.
C
C     ***** THE GAUSS WEIGHTS AND ABSCISSAE IN ADCOMP ARE GIVEN TO
C           30 DIGITS. THE PARAMETER EPS0 IN ADSET SPECIFIES THE
C           ACCURACY OF THESE CONSTANTS. IF THE ACCURACY IS CHANGED
C           TO K DECIMAL DIGITS THEN SET EPS0 = 10**(-K).
C
C     ***** THE INTERVAL STACK SIZE MAXSTK IS DEFINED IN ADSET TO
C           BE 50. IF MAXSTK IS MODIFIED THEN SET THE DIMENSIONS OF
C           XLEFT AND XRIGHT TO THE NEW VALUE FOR MAXSTK. NOTE THAT
C           THE MINIMUM INTERVAL LENGTH IS 2**(-MAXSTK)*(B-A).
C
C  SINGLE PRECISION CONVERSION -- REQUIRES FOUR STEPS
C     1. DECLARE ALL DOUBLE PRECISION VARIABLES TO BE REAL.
C
C     2. CHANGE ALL DOUBLE PRECISION NUMBERS IN THE DATA STATEMENTS.
C        (FLOATING POINT NUMBERS APPEAR ONLY IN DATA STATEMENTS.)
C
C     3. CHANGE DABS,DMAX1,DMIN1 AT MANY PLACES.
C
C     4. CHANGE DPMPAR TO SPMPAR IN ADSET.
C
      DOUBLE PRECISION A, ACCUR, B, BLEFT, BRIGHT, CHARF, DDTEMP,
     * DSCTOL, ERROR, ERRORI, FACTOR, FINTRP, FLEFT, FRIGHT, NORM,
     * XBREAK, XDD, XINTRP, XLEFT, XRIGHT, BUFFER
      DIMENSION XBREAK(20), DBREAK(20), BLEFT(20), BRIGHT(20)
      DIMENSION XLEFT(50), XRIGHT(50)
      DIMENSION DDTEMP(20,20), FACTOR(20), FINTRP(18), FLEFT(10),
     * FRIGHT(10), XDD(20), XINTRP(18)
      INTEGER BOTH, BREAK, DBREAK, DEGREE, EDIST, RIGHT, RIGHTX, SMOOTH
      LOGICAL DISCRD
      DOUBLE PRECISION XKNOTS(KDIMEN), COEFS(KMAX,NDIMEN)
      DOUBLE PRECISION F
      EXTERNAL F
C
      COMMON /INPUTZ/ A, B, ACCUR, NORM, CHARF, XBREAK, BLEFT, BRIGHT,
     * DBREAK, DEGREE, SMOOTH, LEVEL, EDIST, NBREAK, KNTDIM, NPARDM
C                      KNTDIM - KDIMEN, NAME CHANGED TO PUT IN COMMON
C                      NPARDM - NDIMEN, NAME CHANGED TO PUT IN COMMON
      COMMON /RESULZ/ ERROR, KNOTS
C                      KNOTS = FINAL NO. OF KNOTS, INCLUDES B AS ONE.
C                      ERROR = ESTIMATE OF ERROR ACTUALLY ACHIEVED.
      COMMON /KONTRL/ DSCTOL, ERRORI, XLEFT, XRIGHT, BREAK, BOTH,
     * FACTOR, IBREAK, INTERP, LEFT, MAXAUX, MAXKNT, MAXPAR, MAXSTK,
     * NPAR, NSTACK, RIGHT, DISCRD, BUFFER
C             KONTRL CONTAINS GENERALLY USEFUL VARIABLES
C                      MAXSTK - SEE COMMENTS ABOVE
C                      BUFFER - THE MACHINE DEPENDENT TOLERANCE USED
C                               BY THE ALGORITHM
C                      NSTACK - COUNTER FOR INTERVAL STACK, CONSISTS OF
C                               (XLEFT(J),XRIGHT(J))  J = 1 TO NSTACK
C                      ERRORI - ERROR ESTIMATE FOR TOP INTERVAL
C                      DSCTOL - TOLERANCE TO CHECK DISCARDING INTERVALS
C                      DISCRD - SWITCH TO SIGNAL DISCARD OF TOP INTERVAL
C                      FACTOR - ARRAY OF FACTORIALS
C                      NPAR   - NUMBER OF PAREMETERS = DEGREE + 1
C                      INTERP - NUMBER OF INTERIOR INTERPOLATION POINTS
C                               IN THE NORMAL INTERVAL
C                      IBREAK - COUNTER ON BREAK POINTS
C                      BREAK  - SWITCH FOR BREAK POINT IN TOP INTERVAL
C                               0     = NO BREAK PRESENT
C                               LEFT  = BREAK AT XLEFT(NSTACK)
C                               RIGHT = BREAK AT XRIGHT(NSTACK)
C                               BOTH  = BREAK AT BOTH ENDS
      COMMON /COMDIF/ DDTEMP, FINTRP, FLEFT, FRIGHT, XDD, XINTRP,
     * LEFTX, NINTRP, RIGHTX
C             COMDIF CONTAINS VARIABLES USED ONLY BY ADCOMP AND FRIENDS.
C                      NINTRP - NUMBER OF INTERIOR INTERPOLATION POINTS
C                               FOR THE CURRENT INTERVAL
C                      XINTRP - INTERIOR INTERPOLATION POINTS
C                      FINTRP - F VALUES AT XINTRP POINTS
C                      LEFTX  - MULTIPLICITY OF INTERPOLATION AT XLEFT
C                               = NO. OF DERIVATIVES MATCHED AT XLEFT
C                      FLEFT  - VALUES OF F AND ITS DERIVATIVES AT XLEFT
C                      RIGHTX - MULTIPLICITY OF INTERPOLATION AT XRIGHT
C                      FRIGHT - VALUES OF F AND DERIVATIVES AT XRIGHT
C                      DDTEMP - THE ARRAY OF DIVIDED DIFFERENCES
C                      XDD    - THE X VALUES FOR DDTEMP WITH PROPER
C                               MULTIPLICITIES OF XLEFT AND XRIGHT
C
C------------------------ MAIN CONTROL PROGRAM -------------------------
C
C            CHECK THE INPUT AND INITIALIZE ALL THE PARAMETERS
C
      CALL ADSET(XKNOTS, COEFS, KDIMEN, KMAX, NDIMEN, IERR)
      IF (IERR.NE.0) RETURN
C
C                  LOOP OVER PROCESSING OF INTERVALS
C
   10 CALL ADTAKE(IERR)
      IF (IERR.NE.0) RETURN
      CALL ADCOMP(F)
C
C                   CHECK FOR DISCARDING INTERVALS
C
      CALL ADCHK
C
C            PUT NEW INTERVALS ON STACK OR DISCARD, UPDATE STATUS
C
      CALL ADPUT(XKNOTS, COEFS, KDIMEN, KMAX, NDIMEN, IERR)
      IF (IERR.NE.0) RETURN
C
C                    TEST FOR NORMAL TERMINATION
C
      IF (NSTACK.EQ.0) RETURN
C
C                CHECK ON THE NUMBER OF KNOTS GENERATED
C
      IF (KNOTS.LT.MAXKNT) GO TO 10
      IERR = 1
      RETURN
      END
