*     E04UHA Example Program Text
*     Mark 20 Release. NAG Copyright 2001.
*     .. Parameters ..
      INTEGER          NIN, NOUT
      PARAMETER        (NIN=5,NOUT=6)
      INTEGER          MMAX, NMAX, LENIZ, LENZ
      PARAMETER        (MMAX=100,NMAX=100,LENIZ=1000,LENZ=1000)
      INTEGER          LCWSAV, LIWSAV, LLWSAV, LRWSAV
      PARAMETER        (LCWSAV=1,LIWSAV=550,LLWSAV=20,LRWSAV=550)
*     .. Local Scalars ..
      DOUBLE PRECISION OBJ, SINF
      INTEGER          I, IFAIL, INFORM, IOBJ, J, M, MINIZ, MINZ, N,
     +                 NCNLN, NINF, NJNLN, NNAME, NNZ, NONLN, NS
      CHARACTER        START
*     .. Local Arrays ..
      DOUBLE PRECISION A(1), BL(NMAX+MMAX), BU(NMAX+MMAX),
     +                 CLAMDA(NMAX+MMAX), RWSAV(LRWSAV), USER(1),
     +                 XS(NMAX+MMAX), Z(LENZ)
      INTEGER          HA(1), ISTATE(NMAX+MMAX), IUSER(1),
     +                 IWSAV(LIWSAV), IZ(LENIZ), KA(NMAX+1)
      LOGICAL          LWSAV(LLWSAV)
      CHARACTER*8      NAMES(NMAX+MMAX)
      CHARACTER*80     CWSAV(LCWSAV)
*     .. External Subroutines ..
      EXTERNAL         E04UGA, E04UGM, E04UHA, E04UJA, E04WBF, OBJFUN,
     +                 X04ABF
*     .. Executable Statements ..
      WRITE (NOUT,*) 'E04UHA Example Program Results'
*     Skip heading in data file.
      READ (NIN,*)
      READ (NIN,*) N, M
      IF (N.LE.NMAX .AND. M.LE.MMAX) THEN
*
*        Read NCNLN, NONLN and NJNLN from data file.
*
         READ (NIN,*) NCNLN, NONLN, NJNLN
*
*        Read START, NNAME and NAMES from data file.
*
         READ (NIN,*) START, NNAME
         IF (NNAME.EQ.N+M) READ (NIN,*) (NAMES(I),I=1,N+M)
*
*        Define the matrix A to contain a dummy `free' row that consists
*        of a single (zero) element subject to `infinite' upper and
*        lower bounds. Set up KA.
*
         NNZ = 1
         IOBJ = -1
*
         KA(1) = 1
*
         A(1) = 0.0D+0
         HA(1) = 1
*
*        Columns 2,3,...,N of A are empty. Set the corresponding element
*        of KA to 2.
*
         DO 20 J = 2, N
            KA(J) = 2
   20    CONTINUE
*
         KA(N+1) = NNZ + 1
*
*        Read BL, BU, ISTATE and XS from data file.
*
         READ (NIN,*) (BL(I),I=1,N+M)
         READ (NIN,*) (BU(I),I=1,N+M)
         IF (START.EQ.'C') THEN
            READ (NIN,*) (ISTATE(I),I=1,N)
         ELSE IF (START.EQ.'W') THEN
            READ (NIN,*) (ISTATE(I),I=1,N+M)
         END IF
         READ (NIN,*) (XS(I),I=1,N)
*
*        Set the unit number for advisory messages to NOUT.
*
         CALL X04ABF(1,NOUT)
*
*        Initialise using E04WBF and check for error exits
*
         IFAIL = 1
         CALL E04WBF('E04UGA',CWSAV,LCWSAV,LWSAV,LLWSAV,IWSAV,LIWSAV,
     +               RWSAV,LRWSAV,IFAIL)
         IF (IFAIL.NE.0) THEN
            WRITE (NOUT,99999) 'E04WBF terminated with IFAIL = ', IFAIL
         ELSE
*
*           Set three options using E04UJA.
*
            CALL E04UJA(' Verify Level = -1 ',LWSAV,IWSAV,RWSAV,INFORM)
*
            IF (INFORM.EQ.0) THEN
               CALL E04UJA(' Major Iteration Limit = 25 ',LWSAV,IWSAV,
     +                     RWSAV,INFORM)
*
               IF (INFORM.EQ.0) THEN
                  CALL E04UJA(' Infinite Bound Size = 1.0D+25 ',LWSAV,
     +                        IWSAV,RWSAV,INFORM)
               END IF
            END IF
            IF (INFORM.NE.0) THEN
               WRITE (NOUT,99999) 'E04UJA terminated with INFORM = ',
     +           INFORM
            ELSE
*
*              Read the options file for the remaining options.
*
               CALL E04UHA(NIN,LWSAV,IWSAV,RWSAV,INFORM)
*
               IF (INFORM.NE.0) THEN
                  WRITE (NOUT,99999) 'E04UHA terminated with INFORM = ',
     +              INFORM
               END IF
            END IF
            IF (INFORM.EQ.0) THEN
*
*              Solve the problem.
*
               IFAIL = 1
*
               CALL E04UGA(E04UGM,OBJFUN,N,M,NCNLN,NONLN,NJNLN,IOBJ,NNZ,
     +                     A,HA,KA,BL,BU,START,NNAME,NAMES,NS,XS,ISTATE,
     +                     CLAMDA,MINIZ,MINZ,NINF,SINF,OBJ,IZ,LENIZ,Z,
     +                     LENZ,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 40 I = 1, N
                     WRITE (NOUT,99994) I, ISTATE(I), XS(I), CLAMDA(I)
   40             CONTINUE
                  WRITE (NOUT,*)
                  WRITE (NOUT,*)
                  WRITE (NOUT,99992)
                  WRITE (NOUT,*)
                  IF (NCNLN.GT.0) THEN
                     DO 60 I = N + 1, N + NCNLN
                        J = I - N
                        WRITE (NOUT,99991) J, ISTATE(I), XS(I),
     +                    CLAMDA(I)
   60                CONTINUE
                  END IF
                  IF (NCNLN.EQ.0 .AND. M.EQ.1 .AND. A(1).EQ.0.0D0) THEN
                     WRITE (NOUT,99989) ISTATE(N+1), XS(N+1),
     +                 CLAMDA(N+1)
                  ELSE IF (M.GT.NCNLN) THEN
                     DO 80 I = N + NCNLN + 1, N + M
                        J = I - N - NCNLN
                        IF (I-N.EQ.IOBJ) THEN
                           WRITE (NOUT,99990) ISTATE(I), XS(I),
     +                       CLAMDA(I)
                        ELSE
                           WRITE (NOUT,99993) J, ISTATE(I), XS(I),
     +                       CLAMDA(I)
                        END IF
   80                CONTINUE
                  END IF
               END IF
               WRITE (NOUT,*)
               WRITE (NOUT,*)
               WRITE (NOUT,99988) OBJ
            END IF
         END IF
      END IF
*
      STOP
*
99999 FORMAT (1X,A,I3)
99998 FORMAT (1X,'An input parameter is invalid')
99997 FORMAT (1X,'MODE < 0 on exit from OBJFUN or CONFUN.',//' Problem',
     +       ' abandoned.')
99996 FORMAT (1X,'E04UGA returned with IFAIL = ',I4)
99995 FORMAT (1X,'Variable',2X,'Istate',5X,'Value',9X,'Lagr Mult')
99994 FORMAT (1X,'Varble',1X,I2,1X,I3,4X,1P,G14.6,2X,1P,G12.4)
99993 FORMAT (1X,'LinCon',1X,I2,1X,I3,4X,1P,G14.6,2X,1P,G12.4)
99992 FORMAT (1X,'Constrnt',2X,'Istate',5X,'Value',9X,'Lagr Mult')
99991 FORMAT (1X,'NlnCon',1X,I2,1X,I3,4X,1P,G14.6,2X,1P,G12.4)
99990 FORMAT (1X,'Free Row',2X,I3,4X,1P,G14.6,2X,1P,G12.4)
99989 FORMAT (1X,'DummyRow',2X,I3,4X,1P,G14.6,2X,1P,G12.4)
99988 FORMAT (1X,'Final objective value = ',1P,G15.7)
      END
*
      SUBROUTINE OBJFUN(MODE,NONLN,X,OBJF,OBJGRD,NSTATE,IUSER,USER)
*     Computes the nonlinear part of the objective function and its
*     gradient
*     .. Scalar Arguments ..
      DOUBLE PRECISION  OBJF
      INTEGER           MODE, NONLN, NSTATE
*     .. Array Arguments ..
*
      DOUBLE PRECISION  OBJGRD(NONLN), USER(*), X(NONLN)
      INTEGER           IUSER(*)
*     .. Executable Statements ..
      IF (MODE.EQ.0 .OR. MODE.EQ.2) OBJF = 2.0D+0 - X(1)*X(2)*X(3)*X(4)
     +    *X(5)/120.0D+0
*
      IF (MODE.EQ.1 .OR. MODE.EQ.2) THEN
         OBJGRD(1) = -X(2)*X(3)*X(4)*X(5)/120.0D+0
         OBJGRD(2) = -X(1)*X(3)*X(4)*X(5)/120.0D+0
         OBJGRD(3) = -X(1)*X(2)*X(4)*X(5)/120.0D+0
         OBJGRD(4) = -X(1)*X(2)*X(3)*X(5)/120.0D+0
         OBJGRD(5) = -X(1)*X(2)*X(3)*X(4)/120.0D+0
      END IF
*
      END
