*     F04YCF Example Program Text
*     Mark 20 Revised. NAG Copyright 2001.
*     .. Parameters ..
      INTEGER          NOUT
      PARAMETER        (NOUT=6)
*     .. External Subroutines ..
      EXTERNAL         EX1, EX2
*     .. Executable Statements ..
      WRITE (NOUT,*) 'F04YCF Example Program Results'
      CALL EX1
      CALL EX2
      STOP
      END
*
      SUBROUTINE EX1
*     .. Parameters ..
      INTEGER          NIN, NOUT
      PARAMETER        (NIN=5,NOUT=6)
      INTEGER          NMAX, LDA
      PARAMETER        (NMAX=20,LDA=NMAX)
      DOUBLE PRECISION ZERO
      PARAMETER        (ZERO=0.0D+0)
*     .. Local Scalars ..
      DOUBLE PRECISION ANORM, COND, D1, EPS, ESTNRM
      INTEGER          I, ICASE, ID, IFAIL, J, N
*     .. Local Arrays ..
      DOUBLE PRECISION A(LDA,NMAX), P(NMAX), WORK(NMAX), X(NMAX)
      INTEGER          IWORK(NMAX)
*     .. External Functions ..
      DOUBLE PRECISION DASUM, X02AJF
      EXTERNAL         DASUM, X02AJF
*     .. External Subroutines ..
      EXTERNAL         DTRSV, F03AFF, F04YCF
*     .. Intrinsic Functions ..
      INTRINSIC        MAX
*     .. Executable Statements ..
      WRITE (NOUT,*)
      WRITE (NOUT,*)
      WRITE (NOUT,*) 'Example 1'
*     Skip heading in data file
      READ (NIN,*)
      READ (NIN,*)
      READ (NIN,*)
      READ (NIN,*) N
      WRITE (NOUT,*)
      IF (N.GT.NMAX) THEN
         WRITE (NOUT,99999) 'N is out of range: N =', N, '.'
      ELSE
         READ (NIN,*) ((A(I,J),J=1,N),I=1,N)
*        First compute the norm of A. DASUM returns the sum of the
*        absolute values of a column of A.
         ANORM = ZERO
         DO 20 J = 1, N
            ANORM = MAX(ANORM,DASUM(N,A(1,J),1))
   20    CONTINUE
         WRITE (NOUT,99998) 'Computed norm of A =', ANORM
*        Next estimate the norm of inverse(A). We do not form the
*        inverse explicitly.
         EPS = X02AJF()
         IFAIL = 0
*
*        Factorise A as P*A = L*U using F03AFF.
         CALL F03AFF(N,EPS,A,LDA,D1,ID,P,IFAIL)
         ICASE = 0
*
   40    CALL F04YCF(ICASE,N,X,ESTNRM,WORK,IWORK,IFAIL)
*
         IF (ICASE.NE.0) THEN
            IF (ICASE.EQ.1) THEN
*              Return the vector inv(P*A)*X by solving the equations
*              L*U*Y = X, overwriting Y on X. First solve L*Z = X for Z.
               CALL DTRSV('Lower','No Transpose','Non-Unit',N,A,LDA,X,1)
*              Then solve U*Y = Z for Y.
               CALL DTRSV('Upper','No Transpose','Unit',N,A,LDA,X,1)
            ELSE IF (ICASE.EQ.2) THEN
*              Return the vector inv(P*A)'*X by solving U'*L'*Y = X,
*              overwriting Y on X. First solve U'*Z = X for Z.
               CALL DTRSV('Upper','Transpose','Unit',N,A,LDA,X,1)
*              Then solve L'*Y = Z for Y.
               CALL DTRSV('Lower','Transpose','Non-Unit',N,A,LDA,X,1)
            END IF
*           Continue until ICASE is returned as 0.
            GO TO 40
         ELSE
            WRITE (NOUT,99998) 'Estimated norm of inverse(A) =', ESTNRM
         END IF
         COND = ANORM*ESTNRM
         WRITE (NOUT,99997) 'Estimated condition number of A =', COND
         WRITE (NOUT,*)
      END IF
*
99999 FORMAT (1X,A,I5,A)
99998 FORMAT (1X,A,F8.4)
99997 FORMAT (1X,A,F5.1)
      END
*
      SUBROUTINE EX2
*     .. Parameters ..
      INTEGER          NIN, NOUT
      PARAMETER        (NIN=5,NOUT=6)
      INTEGER          NMAX, NZMAX, LICN, LIRN
      PARAMETER        (NMAX=20,NZMAX=25,LICN=4*NZMAX,LIRN=2*NZMAX)
      DOUBLE PRECISION TENTH, ZERO
      PARAMETER        (TENTH=0.1D+0,ZERO=0.0D+0)
*     .. Local Scalars ..
      DOUBLE PRECISION ANORM, COND, ESTNRM, RESID, SUM, U
      INTEGER          I, ICASE, IFAIL, J, N, NZ
      LOGICAL          GROW, LBLOCK
*     .. Local Arrays ..
      DOUBLE PRECISION A(LICN), W(NMAX), WORK1(NMAX), X(NMAX)
      INTEGER          ICN(LICN), IDISP(10), IKEEP(5*NMAX), IRN(LIRN),
     +                 IW(8*NMAX), IWORK(NMAX)
      LOGICAL          ABORT(4)
*     .. External Subroutines ..
      EXTERNAL         F01BRF, F04AXF, F04YCF
*     .. Intrinsic Functions ..
      INTRINSIC        ABS, MAX
*     .. Executable Statements ..
      WRITE (NOUT,*)
      WRITE (NOUT,*)
      WRITE (NOUT,*) 'Example 2'
*     Skip heading in data file
      READ (NIN,*)
      READ (NIN,*)
*     Input N, the order of matrix A, and NZ, the number of non-zero
*     elements of A.
      READ (NIN,*) N, NZ
      WRITE (NOUT,*)
      IF (N.GT.NMAX .OR. NZ.GT.NZMAX) THEN
         WRITE (NOUT,99999) 'N or NZ is out of range: N =', N,
     +     ',   NZ =', NZ, '.'
      ELSE
*        Input the elements of A, along with row and column information.
         READ (NIN,*) (A(I),IRN(I),ICN(I),I=1,NZ)
*        First compute the norm of A.
         ANORM = 0
         DO 40 I = 1, N
            SUM = ZERO
            DO 20 J = 1, NZ
               IF (ICN(J).EQ.I) SUM = SUM + ABS(A(J))
   20       CONTINUE
            ANORM = MAX(ANORM,SUM)
   40    CONTINUE
         WRITE (NOUT,99998) 'Computed norm of A =', ANORM
*        Next estimate the norm of inverse(A). We do not form the
*        inverse explicitly.
*        Factorise A into L*U using F01BRF.
         U = TENTH
         LBLOCK = .TRUE.
         GROW = .TRUE.
         ABORT(1) = .TRUE.
         ABORT(2) = .TRUE.
         ABORT(3) = .FALSE.
         ABORT(4) = .TRUE.
         IFAIL = 110
*
         CALL F01BRF(N,NZ,A,LICN,IRN,LIRN,ICN,U,IKEEP,IW,W,LBLOCK,GROW,
     +               ABORT,IDISP,IFAIL)
         ICASE = 0
*
   60    CALL F04YCF(ICASE,N,X,ESTNRM,WORK1,IWORK,IFAIL)
*
         IF (ICASE.NE.0) THEN
*           Return X := inv(A)*X or X = inv(A)'*X, depending on the
*           value of ICASE, by solving A*Y = X or A'*Y = X,
*           overwriting Y on X.
            CALL F04AXF(N,A,LICN,ICN,IKEEP,X,W,ICASE,IDISP,RESID)
*           Continue until ICASE is returned as 0.
            GO TO 60
         ELSE
            WRITE (NOUT,99998) 'Estimated norm of inverse(A) =', ESTNRM
         END IF
         COND = ANORM*ESTNRM
         WRITE (NOUT,99997) 'Estimated condition number of A =', COND
      END IF
*
99999 FORMAT (1X,A,I5,A,I5,A)
99998 FORMAT (1X,A,F8.4)
99997 FORMAT (1X,A,F5.1)
      END
