*     E04DGA Example Program Text
*     Mark 20 Release. NAG Copyright 2001.
*     .. Parameters ..
      INTEGER          NMAX
      PARAMETER        (NMAX=10)
      INTEGER          NIN, NOUT
      PARAMETER        (NIN=5,NOUT=6)
      INTEGER          LCWSAV, LIWSAV, LLWSAV, LRWSAV
      PARAMETER        (LCWSAV=1,LIWSAV=610,LLWSAV=120,LRWSAV=475)
*     .. Local Scalars ..
      DOUBLE PRECISION OBJF
      INTEGER          I, IFAIL, ITER, N
*     .. Local Arrays ..
      DOUBLE PRECISION OBJGRD(NMAX), RWSAV(LRWSAV), USER(1),
     +                 WORK(13*NMAX), X(NMAX)
      INTEGER          IUSER(1), IWORK(NMAX+1), IWSAV(LIWSAV)
      LOGICAL          LWSAV(LLWSAV)
      CHARACTER*80     CWSAV(LCWSAV)
*     .. External Subroutines ..
      EXTERNAL         E04DGA, E04WBF, OBJFUN
*     .. Executable Statements ..
      WRITE (NOUT,*) 'E04DGA Example Program Results'
*     Skip heading in data file
      READ (NIN,*)
      READ (NIN,*) N
      IF (N.LE.NMAX) THEN
*
*        Read X from data file
*
         READ (NIN,*) (X(I),I=1,N)
*
*        Initialise E04DGA and check for error exits
*
         IFAIL = 1
         CALL E04WBF('E04DGA',CWSAV,LCWSAV,LWSAV,LLWSAV,IWSAV,LIWSAV,
     +               RWSAV,LRWSAV,IFAIL)
         IF (IFAIL.NE.0) THEN
            WRITE (NOUT,99999) IFAIL
         ELSE
*
*           Solve the problem
*
            IFAIL = 1
            CALL E04DGA(N,OBJFUN,ITER,OBJF,OBJGRD,X,IWORK,WORK,IUSER,
     +                  USER,LWSAV,IWSAV,RWSAV,IFAIL)
*
*           Check for error exits
*
            WRITE (NOUT,*)
            IF (IFAIL.GE.9) THEN
               WRITE (NOUT,99998)
            ELSE IF (IFAIL.LT.0) THEN
               WRITE (NOUT,99997)
            ELSE
               WRITE (NOUT,99996) IFAIL
               WRITE (NOUT,*)
               WRITE (NOUT,99995)
               WRITE (NOUT,*)
               DO 20 I = 1, N
                  WRITE (NOUT,99994) I, X(I), OBJGRD(I)
   20          CONTINUE
               WRITE (NOUT,*)
               WRITE (NOUT,*)
               WRITE (NOUT,99993) OBJF
            END IF
         END IF
*
      END IF
      STOP
*
99999 FORMAT (1X,'E04WBF returned with IFAIL = ',I4)
99998 FORMAT (1X,'An input parameter is invalid')
99997 FORMAT (1X,'MODE < 0 on exit from OBJFUN. Problem abandoned.')
99996 FORMAT (1X,'E04DGA returned with IFAIL = ',I4)
99995 FORMAT (1X,'Variable',10X,'Value',8X,'Gradient value')
99994 FORMAT (1X,'Varbl',1X,I3,4X,1P,G15.7,4X,1P,G9.1)
99993 FORMAT (1X,'Final objective value = ',G15.7)
      END
*
      SUBROUTINE OBJFUN(MODE,N,X,OBJF,OBJGRD,NSTATE,IUSER,USER)
*     Routine to evaluate F(x) and its 1st derivatives.
*     .. Parameters ..
      DOUBLE PRECISION  ONE, TWO, FOUR
      PARAMETER         (ONE=1.0D0,TWO=2.0D0,FOUR=4.0D0)
*     .. Scalar Arguments ..
      DOUBLE PRECISION  OBJF
      INTEGER           MODE, N, NSTATE
*     .. Array Arguments ..
      DOUBLE PRECISION  OBJGRD(N), USER(*), X(N)
      INTEGER           IUSER(*)
*     .. Local Scalars ..
      DOUBLE PRECISION  EXPX1, X1, X2
*     .. Intrinsic Functions ..
      INTRINSIC         EXP
*     .. Executable Statements ..
      X1 = X(1)
      X2 = X(2)
*
      EXPX1 = EXP(X1)
      OBJF = EXPX1*(FOUR*X1**2+TWO*X2**2+FOUR*X1*X2+TWO*X2+ONE)
*
      IF (MODE.EQ.2) THEN
         OBJGRD(1) = FOUR*EXPX1*(TWO*X1+X2) + OBJF
         OBJGRD(2) = TWO*EXPX1*(TWO*X2+TWO*X1+ONE)
      END IF
*
      RETURN
      END
