*     F08YKF Example Program Text
*     Mark 20 Release. NAG Copyright 2001.
*     .. Parameters ..
      INTEGER          NIN, NOUT
      PARAMETER        (NIN=5,NOUT=6)
      INTEGER          NMAX, LDA, LDB, LWORK
      PARAMETER        (NMAX=10,LDA=NMAX,LDB=NMAX,LWORK=6*NMAX)
      INTEGER          LDQ, LDZ
      PARAMETER        (LDQ=NMAX,LDZ=NMAX)
      DOUBLE PRECISION ONE, ZERO
      PARAMETER        (ONE=1.0D0,ZERO=0.0D0)
*     .. Local Scalars ..
      INTEGER          I, ICOLS, IFAIL, IHI, ILO, INFO, IROWS, J, JWORK,
     +                 M, N
      LOGICAL          ILEFT, IRIGHT
      CHARACTER        COMPQ, COMPZ, HOWMNY, JOB, SIDE
*     .. Local Arrays ..
      DOUBLE PRECISION A(LDA,NMAX), ALPHAI(NMAX), ALPHAR(NMAX),
     +                 B(LDB,NMAX), BETA(NMAX), LSCALE(NMAX),
     +                 Q(LDQ,LDQ), RSCALE(NMAX), TAU(NMAX), WORK(LWORK),
     +                 Z(LDZ,LDZ)
      LOGICAL          SELECT(NMAX)
*     .. External Subroutines ..
      EXTERNAL         DGEQRF, DGGBAK, DGGBAL, DGGHRD, DHGEQZ, DORGQR,
     +                 DORMQR, DTGEVC, F06QFF, F06QHF, X04CAF
*     .. Intrinsic Functions ..
      INTRINSIC        NINT
*     .. Executable Statements ..
      WRITE (NOUT,*) 'F08YKF Example Program Results'
*
*     ILEFT  is TRUE if left  eigenvectors are required
*     IRIGHT is TRUE if right eigenvectors are required
*
      ILEFT = .TRUE.
      IRIGHT = .TRUE.
*
*     Skip heading in data file
*
      READ (NIN,*)
      READ (NIN,*) N
      IF (N.LE.NMAX) THEN
*
*        READ matrix A from data file
*
         READ (NIN,*) ((A(I,J),J=1,N),I=1,N)
*
*        READ matrix B from data file
*
         READ (NIN,*) ((B(I,J),J=1,N),I=1,N)
*
*        Balance matrix pair (A,B)
*
         JOB = 'B'
         CALL DGGBAL(JOB,N,A,LDA,B,LDB,ILO,IHI,LSCALE,RSCALE,WORK,INFO)
*
*        Matrix A after balancing
*
         IFAIL = 0
         CALL X04CAF('General',' ',N,N,A,LDA,'Matrix A after balancing',
     +               IFAIL)
         WRITE (NOUT,*)
*
*        Matrix B after balancing
*
         IFAIL = 0
         CALL X04CAF('General',' ',N,N,B,LDB,'Matrix B after balancing',
     +               IFAIL)
         WRITE (NOUT,*)
*
*        Reduce B to triangular form using QR
*
         IROWS = IHI + 1 - ILO
         ICOLS = N + 1 - ILO
         CALL DGEQRF(IROWS,ICOLS,B(ILO,ILO),LDB,TAU,WORK,LWORK,INFO)
*
*        Apply the orthogonal transformation to matrix A
*
         CALL DORMQR('L','T',IROWS,ICOLS,IROWS,B(ILO,ILO),LDB,TAU,
     +               A(ILO,ILO),LDA,WORK,LWORK,INFO)
*
*        Initialize Q (if left eigenvectors are required)
*
         IF (ILEFT) THEN
            CALL F06QHF('General',N,N,ZERO,ONE,Q,LDQ)
            CALL F06QFF('Lower',IROWS-1,IROWS-1,B(ILO+1,ILO),LDB,
     +                  Q(ILO+1,ILO),LDQ)
*
            CALL DORGQR(IROWS,IROWS,IROWS,Q(ILO,ILO),LDQ,TAU,WORK,LWORK,
     +                  INFO)
         END IF
*
*        Initialize Z (if right eigenvectors are required)
*
         IF (IRIGHT) CALL F06QHF('General',N,N,ZERO,ONE,Z,LDZ)
*
*        Compute the generalized Hessenberg form of (A,B)
*
         COMPQ = 'V'
         COMPZ = 'V'
         CALL DGGHRD(COMPQ,COMPZ,N,ILO,IHI,A,LDA,B,LDB,Q,LDQ,Z,LDZ,INFO)
*
*        Matrix A in generalized Hessenberg form
*
         IFAIL = 0
         CALL X04CAF('General',' ',N,N,A,LDA,
     +               'Matrix A in Hessenberg form',IFAIL)
         WRITE (NOUT,*)
*
*        Matrix B in generalized Hessenberg form
*
         IFAIL = 0
         CALL X04CAF('General',' ',N,N,B,LDB,
     +               'Matrix B in Hessenberg form',IFAIL)
*
*        Routine DHGEQZ
*        Workspace query: JWORK = -1
*
         JWORK = -1
         JOB = 'S'
         CALL DHGEQZ(JOB,COMPQ,COMPZ,N,ILO,IHI,A,LDA,B,LDB,ALPHAR,
     +               ALPHAI,BETA,Q,LDQ,Z,LDZ,WORK,JWORK,INFO)
         WRITE (NOUT,*)
         WRITE (NOUT,99999) NINT(WORK(1))
         WRITE (NOUT,99998) LWORK
         WRITE (NOUT,*)
         WRITE (NOUT,99997)
         WRITE (NOUT,99996)
*
*        Compute the generalized Schur form
*        if the workspace LWORK is adequate
*        The Schur form also gives parameters
*        required to compute generalized eigenvalues
*
         IF (NINT(WORK(1)).LE.LWORK) THEN
            CALL DHGEQZ(JOB,COMPQ,COMPZ,N,ILO,IHI,A,LDA,B,LDB,ALPHAR,
     +                  ALPHAI,BETA,Q,LDQ,Z,LDZ,WORK,LWORK,INFO)
*
*        Print the generalized eigenvalues
*
            DO 20 I = 1, N
               IF (BETA(I).NE.0.0D0) THEN
                  WRITE (NOUT,99995) I, '(', ALPHAR(I)/BETA(I), ',',
     +              ALPHAI(I)/BETA(I), ')'
               ELSE
                  WRITE (NOUT,99996) I
               END IF
   20       CONTINUE
            WRITE (NOUT,*)
*
*        Compute left and right generalized eigenvectors
*        of the balanced matrix
*
            HOWMNY = 'B'
            IF (ILEFT .AND. IRIGHT) THEN
               SIDE = 'B'
            ELSE IF (ILEFT) THEN
               SIDE = 'L'
            ELSE IF (IRIGHT) THEN
               SIDE = 'R'
            END IF
            CALL DTGEVC(SIDE,HOWMNY,SELECT,N,A,LDA,B,LDB,Q,LDQ,Z,LDZ,N,
     +                  M,WORK,INFO)
            IF (IRIGHT) THEN
*
*        Compute right eigenvectors of the original matrix
*
               JOB = 'B'
               SIDE = 'R'
*
               CALL DGGBAK(JOB,SIDE,N,ILO,IHI,LSCALE,RSCALE,N,Z,LDZ,
     +                     INFO)
*
*        Print the right eigenvectors
*
               IFAIL = 0
               CALL X04CAF('General',' ',N,N,Z,LDZ,'Right eigenvectors',
     +                     IFAIL)
               WRITE (NOUT,*)
            END IF
*
*        Compute left eigenvectors of the original matrix
*
            IF (ILEFT) THEN
               JOB = 'B'
               SIDE = 'L'
*
               CALL DGGBAK(JOB,SIDE,N,ILO,IHI,LSCALE,RSCALE,N,Q,LDQ,
     +                     INFO)
*
*        Print the left eigenvectors
*
               IFAIL = 0
               CALL X04CAF('General',' ',N,N,Q,LDQ,'Left eigenvectors',
     +                     IFAIL)
            END IF
         ELSE
            WRITE (NOUT,99994)
         END IF
      END IF
      STOP
*
99999 FORMAT (1X,'Minimal required LWORK = ',I6)
99998 FORMAT (1X,'Actual value of  LWORK = ',I6)
99997 FORMAT (1X,'Generalized eigenvalues')
99996 FORMAT (1X,I4,5X,'Infinite eigenvalue')
99995 FORMAT (1X,I4,5X,A,F7.3,A,F7.3,A)
99994 FORMAT (1X,'Insufficient workspace for array WORK',/' in F08XEF/',
     +       'DHGEQZ')
      END
