*     E04NKF Example Program Text
*     Mark 19 Revised. NAG Copyright 1999.
*     .. Parameters ..
      INTEGER          NIN, NOUT
      PARAMETER        (NIN=5,NOUT=6)
      INTEGER          IDUMMY
      PARAMETER        (IDUMMY=-11111)
      INTEGER          NMAX, MMAX, NNZMAX, LENIZ, LENZ
      PARAMETER        (NMAX=100,MMAX=100,NNZMAX=100,LENIZ=10000,
     +                 LENZ=10000)
*     .. Local Scalars ..
      DOUBLE PRECISION OBJ, SINF
      INTEGER          I, ICOL, IFAIL, IOBJ, J, JCOL, M, MINIZ, MINZ, N,
     +                 NCOLH, NINF, NNAME, NNZ, NS
      CHARACTER        START
*     .. Local Arrays ..
      DOUBLE PRECISION A(NNZMAX), BL(NMAX+MMAX), BU(NMAX+MMAX),
     +                 CLAMDA(NMAX+MMAX), XS(NMAX+MMAX), Z(LENZ)
      INTEGER          HA(NNZMAX), ISTATE(NMAX+MMAX), IZ(LENIZ),
     +                 KA(NMAX+1)
      CHARACTER*8      CRNAME(NMAX+MMAX), NAMES(5)
*     .. External Subroutines ..
      EXTERNAL         E04NKF, QPHX
*     .. Executable Statements ..
      WRITE (NOUT,*) 'E04NKF Example Program Results'
*     Skip heading in data file.
      READ (NIN,*)
      READ (NIN,*) N, M
      IF (N.LE.NMAX .AND. M.LE.MMAX) THEN
*
*        Read NNZ, IOBJ, NCOLH, START and NNAME from data file.
*
         READ (NIN,*) NNZ, IOBJ, NCOLH, START, NNAME
*
*        Read NAMES and CRNAME from data file.
*
         READ (NIN,*) (NAMES(I),I=1,5)
         READ (NIN,*) (CRNAME(I),I=1,NNAME)
*
*        Read the matrix A from data file. Set up KA.
*
         JCOL = 1
         KA(JCOL) = 1
         DO 40 I = 1, NNZ
*
*           Element ( HA( I ), ICOL ) is stored in A( I ).
*
            READ (NIN,*) A(I), HA(I), ICOL
*
            IF (ICOL.LT.JCOL) THEN
*
*              Elements not ordered by increasing column index.
*
               WRITE (NOUT,99999) 'Element in column', ICOL,
     +           ' found after element in column', JCOL, '. Problem',
     +           ' abandoned.'
               GO TO 80
            ELSE IF (ICOL.EQ.JCOL+1) THEN
*
*              Index in A of the start of the ICOL-th column equals I.
*
               KA(ICOL) = I
               JCOL = ICOL
            ELSE IF (ICOL.GT.JCOL+1) THEN
*
*              Index in A of the start of the ICOL-th column equals I,
*              but columns JCOL+1,JCOL+2,...,ICOL-1 are empty. Set the
*              corresponding elements of KA to I.
*
               DO 20 J = JCOL + 1, ICOL - 1
                  KA(J) = I
   20          CONTINUE
               KA(ICOL) = I
               JCOL = ICOL
            END IF
   40    CONTINUE
*
         KA(N+1) = NNZ + 1
*
         IF (N.GT.ICOL) THEN
*
*           Columns N,N-1,...,ICOL+1 are empty. Set the corresponding
*           elements of KA accordingly.
*
            DO 60 I = N, ICOL + 1, -1
               IF (KA(I).EQ.IDUMMY) KA(I) = KA(I+1)
   60       CONTINUE
         END IF
*
*        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)
*
*        Solve the QP problem.
*
         IFAIL = 1
*
         CALL E04NKF(N,M,NNZ,IOBJ,NCOLH,QPHX,A,HA,KA,BL,BU,START,NAMES,
     +               NNAME,CRNAME,NS,XS,ISTATE,MINIZ,MINZ,NINF,SINF,OBJ,
     +               CLAMDA,IZ,LENIZ,Z,LENZ,IFAIL)
*
         IF (IFAIL.NE.0) THEN
            WRITE (NOUT,99999) ' ** E04NKF returned with IFAIL = ',
     +        IFAIL
         END IF
      END IF
   80 CONTINUE
*
99999 FORMAT (/1X,A,I5,A,I5,A,A)
      END
*
      SUBROUTINE QPHX(NSTATE,NCOLH,X,HX)
*
*     Routine to compute H*x. (In this version of QPHX, the Hessian
*     matrix H is not referenced explicitly.)
*
*     .. Parameters ..
      DOUBLE PRECISION TWO
      PARAMETER        (TWO=2.0D+0)
*     .. Scalar Arguments ..
      INTEGER          NCOLH, NSTATE
*     .. Array Arguments ..
      DOUBLE PRECISION HX(NCOLH), X(NCOLH)
*     .. Executable Statements ..
      HX(1) = TWO*X(1)
      HX(2) = TWO*X(2)
      HX(3) = TWO*(X(3)+X(4))
      HX(4) = HX(3)
      HX(5) = TWO*X(5)
      HX(6) = TWO*(X(6)+X(7))
      HX(7) = HX(6)
*
      RETURN
      END
