      SUBROUTINE C05ZAF(M,N,X,FVEC,FJAC,LDFJAC,XP,FVECP,MODE,ERR)
C     MARK 9 RELEASE.  NAG COPYRIGHT 1981
C     MARK 11.5(F77) REVISED. (SEPT 1985.)
C     MARK 13 REVISED. USE OF MARK 12 X02 FUNCTIONS (APR 1988).
C     **********
C
C     SUBROUTINE C05ZAF(BASED ON MINPACK ROUTINE CHKDER)
C
C     THIS SUBROUTINE CHECKS THE GRADIENTS OF M NONLINEAR FUNCTIONS
C     IN N VARIABLES, EVALUATED AT A POINT X, FOR CONSISTENCY WITH
C     THE FUNCTIONS THEMSELVES. THE USER MUST CALL C05ZAF TWICE,
C     FIRST WITH MODE = 1 AND THEN WITH MODE = 2.
C
C     MODE = 1. ON INPUT, X MUST CONTAIN THE POINT OF EVALUATION.
C     ON OUTPUT, XP IS SET TO A NEIGHBORING POINT.
C
C     MODE = 2. ON INPUT, FVEC MUST CONTAIN THE FUNCTIONS AND THE
C     ROWS OF FJAC MUST CONTAIN THE GRADIENTS
C     OF THE RESPECTIVE FUNCTIONS EACH EVALUATED
C     AT X, AND FVECP MUST CONTAIN THE FUNCTIONS
C     EVALUATED AT XP.
C     ON OUTPUT, ERR CONTAINS MEASURES OF CORRECTNESS OF
C     THE RESPECTIVE GRADIENTS.
C
C     THE SUBROUTINE DOES NOT PERFORM RELIABLY IF CANCELLATION OR
C     ROUNDING ERRORS CAUSE A SEVERE LOSS OF SIGNIFICANCE IN THE
C     EVALUATION OF A FUNCTION. THEREFORE, NONE OF THE COMPONENTS
C     OF X SHOULD BE UNUSUALLY SMALL (IN PARTICULAR, ZERO) OR ANY
C     OTHER VALUE WHICH MAY CAUSE LOSS OF SIGNIFICANCE.
C
C     **********
C
C     EPSMCH IS THE MACHINE PRECISION.
C
C     .. Scalar Arguments ..
      INTEGER           LDFJAC, M, MODE, N
C     .. Array Arguments ..
      DOUBLE PRECISION  ERR(M), FJAC(LDFJAC,N), FVEC(M), FVECP(M), X(N),
     *                  XP(N)
C     .. Local Scalars ..
      DOUBLE PRECISION  EPS, EPSF, EPSLOG, EPSMCH, FACTOR, ONE, TEMP,
     *                  ZERO
      INTEGER           I, J
C     .. External Functions ..
      DOUBLE PRECISION  X02AJF
      EXTERNAL          X02AJF
C     .. Intrinsic Functions ..
      INTRINSIC         ABS, LOG10, SQRT
C     .. Data statements ..
      DATA              FACTOR, ONE, ZERO/1.0D2, 1.0D0, 0.0D0/
C     .. Executable Statements ..
      EPSMCH = X02AJF()
C
      EPS = SQRT(EPSMCH)
C
      IF (MODE.EQ.2) GO TO 40
C
C     MODE = 1.
C
      DO 20 J = 1, N
         TEMP = EPS*ABS(X(J))
         IF (TEMP.EQ.ZERO) TEMP = EPS
         XP(J) = X(J) + TEMP
   20 CONTINUE
      GO TO 140
   40 CONTINUE
C
C     MODE = 2.
C
      EPSF = FACTOR*EPSMCH
      EPSLOG = LOG10(EPS)
      DO 60 I = 1, M
         ERR(I) = ZERO
   60 CONTINUE
      DO 100 J = 1, N
         TEMP = ABS(X(J))
         IF (TEMP.EQ.ZERO) TEMP = ONE
         DO 80 I = 1, M
            ERR(I) = ERR(I) + TEMP*FJAC(I,J)
   80    CONTINUE
  100 CONTINUE
      DO 120 I = 1, M
         TEMP = ONE
         IF (FVEC(I).NE.ZERO .AND. FVECP(I).NE.ZERO .AND. ABS(FVECP(I)
     *       -FVEC(I)).GE.EPSF*ABS(FVEC(I))) TEMP = EPS*ABS((FVECP(I)
     *       -FVEC(I))/EPS-ERR(I))/(ABS(FVEC(I))+ABS(FVECP(I)))
         ERR(I) = ONE
         IF (TEMP.GT.EPSMCH .AND. TEMP.LT.EPS) ERR(I) = (LOG10(TEMP)
     *       -EPSLOG)/EPSLOG
         IF (TEMP.GE.EPS) ERR(I) = ZERO
  120 CONTINUE
  140 CONTINUE
      RETURN
      END
