*     C02AGF Example Program Text
*     Mark 20 Revised. NAG Copyright 2001.
*     .. Parameters ..
      INTEGER          NOUT
      PARAMETER        (NOUT=6)
*     .. External Subroutines ..
      EXTERNAL         EX1, EX2
*     .. Executable Statements ..
      WRITE (NOUT,*) 'C02AGF Example Program Results'
      CALL EX1
      CALL EX2
      STOP
      END
*
      SUBROUTINE EX1
*     .. Parameters ..
      INTEGER          NIN, NOUT
      PARAMETER        (NIN=5,NOUT=6)
      DOUBLE PRECISION ZERO
      PARAMETER        (ZERO=0.0D0)
      INTEGER          MAXDEG
      PARAMETER        (MAXDEG=100)
      LOGICAL          SCALE
      PARAMETER        (SCALE=.TRUE.)
*     .. Local Scalars ..
      INTEGER          I, IFAIL, N, NROOT
*     .. Local Arrays ..
      DOUBLE PRECISION A(0:MAXDEG), W(2*MAXDEG+2), Z(2,MAXDEG)
*     .. External Subroutines ..
      EXTERNAL         C02AGF
*     .. Intrinsic Functions ..
      INTRINSIC        ABS
*     .. Executable Statements ..
      WRITE (NOUT,*)
      WRITE (NOUT,*)
      WRITE (NOUT,*) 'Example 1'
*     Skip heading in data file
      READ (NIN,*)
      READ (NIN,*)
      READ (NIN,*)
      READ (NIN,*) N
      IF (N.GT.0 .AND. N.LE.MAXDEG) THEN
         READ (NIN,*) (A(I),I=0,N)
         WRITE (NOUT,*)
         WRITE (NOUT,99999) 'Degree of polynomial = ', N
*
         IFAIL = 0
*
         CALL C02AGF(A,N,SCALE,Z,W,IFAIL)
*
         WRITE (NOUT,*)
         WRITE (NOUT,*) 'Computed roots of polynomial'
         WRITE (NOUT,*)
         NROOT = 1
   20    IF (NROOT.LE.N) THEN
            IF (Z(2,NROOT).EQ.ZERO) THEN
               WRITE (NOUT,99998) 'z = ', Z(1,NROOT)
               NROOT = NROOT + 1
            ELSE
               WRITE (NOUT,99998) 'z = ', Z(1,NROOT), ' +/- ',
     +           ABS(Z(2,NROOT)), '*i'
               NROOT = NROOT + 2
            END IF
            GO TO 20
         END IF
      ELSE
         WRITE (NOUT,*) 'N is out of range'
      END IF
*
99999 FORMAT (1X,A,I4)
99998 FORMAT (1X,A,1P,E12.4,A,E12.4,A)
      END
*
      SUBROUTINE EX2
*     .. Parameters ..
      INTEGER          NIN, NOUT
      PARAMETER        (NIN=5,NOUT=6)
      DOUBLE PRECISION ZERO, ONE, THREE
      PARAMETER        (ZERO=0.0D0,ONE=1.0D0,THREE=3.0D0)
      INTEGER          MAXDEG
      PARAMETER        (MAXDEG=100)
      LOGICAL          SCALE
      PARAMETER        (SCALE=.TRUE.)
*     .. Local Scalars ..
      DOUBLE PRECISION DELTAC, DELTAI, DI, EPS, EPSBAR, F, R1, R2, R3,
     +                 RMAX
      INTEGER          I, IFAIL, J, JMIN, N
*     .. Local Arrays ..
      DOUBLE PRECISION A(0:MAXDEG), ABAR(0:MAXDEG), R(MAXDEG),
     +                 W(2*MAXDEG+2), Z(2,MAXDEG), ZBAR(2,MAXDEG)
      INTEGER          M(MAXDEG)
*     .. External Functions ..
      DOUBLE PRECISION A02ABF, X02AJF, X02ALF
      EXTERNAL         A02ABF, X02AJF, X02ALF
*     .. External Subroutines ..
      EXTERNAL         C02AGF
*     .. Intrinsic Functions ..
      INTRINSIC        ABS, MAX, MIN
*     .. Executable Statements ..
      WRITE (NOUT,*)
      WRITE (NOUT,*)
      WRITE (NOUT,*) 'Example 2'
*     Skip heading in data file
      READ (NIN,*)
      READ (NIN,*)
      READ (NIN,*) N
      IF (N.GT.0 .AND. N.LE.MAXDEG) THEN
*
*        Read in the coefficients of the original polynomial.
*
         READ (NIN,*) (A(I),I=0,N)
*
*        Compute the roots of the original polynomial.
*
         IFAIL = 0
*
         CALL C02AGF(A,N,SCALE,Z,W,IFAIL)
*
*        Form the coefficients of the perturbed polynomial.
*
         EPS = X02AJF()
         EPSBAR = THREE*EPS
         DO 20 I = 0, N
            IF (A(I).NE.ZERO) THEN
               F = ONE + EPSBAR
               EPSBAR = -EPSBAR
               ABAR(I) = F*A(I)
            ELSE
               ABAR(I) = ZERO
            END IF
   20    CONTINUE
*
*        Compute the roots of the perturbed polynomial.
*
         IFAIL = 0
*
         CALL C02AGF(ABAR,N,SCALE,ZBAR,W,IFAIL)
*
*        Perform error analysis.
*
         DO 40 I = 1, N
*           Initialize markers to 0 (unmarked).
            M(I) = 0
   40    CONTINUE
         RMAX = X02ALF()
*        Loop over all unperturbed roots (stored in Z).
         DO 80 I = 1, N
            DELTAI = RMAX
            R1 = A02ABF(Z(1,I),Z(2,I))
*           Loop over all perturbed roots (stored in ZBAR).
            DO 60 J = 1, N
*              Compare the current unperturbed root to all unmarked
*              perturbed roots.
               IF (M(J).EQ.0) THEN
                  R2 = A02ABF(ZBAR(1,J),ZBAR(2,J))
                  DELTAC = ABS(R1-R2)
                  IF (DELTAC.LT.DELTAI) THEN
                     DELTAI = DELTAC
                     JMIN = J
                  END IF
               END IF
   60       CONTINUE
*           Mark the selected perturbed root.
            M(JMIN) = 1
*           Compute the relative error.
            IF (R1.NE.ZERO) THEN
               R3 = A02ABF(ZBAR(1,JMIN),ZBAR(2,JMIN))
               DI = MIN(R1,R3)
               R(I) = MAX(DELTAI/MAX(DI,DELTAI/RMAX),EPS)
            ELSE
               R(I) = ZERO
            END IF
   80    CONTINUE
*
         WRITE (NOUT,*)
         WRITE (NOUT,99999) 'Degree of polynomial = ', N
         WRITE (NOUT,*)
         WRITE (NOUT,*) 'Computed roots of polynomial   ',
     +     '  Error estimates'
         WRITE (NOUT,*) '                            ',
     +     '   (machine-dependent)'
         WRITE (NOUT,*)
         DO 100 I = 1, N
            WRITE (NOUT,99998) 'z = ', Z(1,I), Z(2,I), '*i', R(I)
  100    CONTINUE
      ELSE
         WRITE (NOUT,*) 'N is out of range'
      END IF
*
99999 FORMAT (1X,A,I4)
99998 FORMAT (1X,A,1P,E12.4,SP,E12.4,A,5X,SS,E9.1)
      END
