*     F08VAF Example Program Text
*     Mark 21 Release. NAG Copyright 2004.
*     .. Parameters ..
      INTEGER          NIN, NOUT
      PARAMETER        (NIN=5,NOUT=6)
      INTEGER          MMAX, NMAX, PMAX
      PARAMETER        (MMAX=10,NMAX=10,PMAX=10)
      INTEGER          LDA, LDB, LDQ, LDU, LDV
      PARAMETER        (LDA=MMAX,LDB=PMAX,LDQ=NMAX,LDU=MMAX,LDV=PMAX)
*     .. Local Scalars ..
      DOUBLE PRECISION EPS, RCOND, SERRBD
      INTEGER          I, IFAIL, INFO, IRANK, J, K, L, M, N, P
*     .. Local Arrays ..
      DOUBLE PRECISION A(LDA,NMAX), ALPHA(NMAX), B(LDB,NMAX),
     +                 BETA(NMAX), Q(LDQ,NMAX), U(LDU,MMAX),
     +                 V(LDV,PMAX), WORK(MMAX+3*NMAX)
      INTEGER          IWORK(NMAX)
      CHARACTER        CLABS(1), RLABS(1)
*     .. External Functions ..
      DOUBLE PRECISION X02AJF
      EXTERNAL         X02AJF
*     .. External Subroutines ..
      EXTERNAL         DGGSVD, DTRCON, X04CBF
*     .. Executable Statements ..
      WRITE (NOUT,*) 'F08VAF Example Program Results'
      WRITE (NOUT,*)
*     Skip heading in data file
      READ (NIN,*)
      READ (NIN,*) M, N, P
      IF (M.LE.MMAX .AND. N.LE.NMAX .AND. P.LE.PMAX) THEN
*
*        Read the m by n matrix A and p by n matrix B from data file
*
         READ (NIN,*) ((A(I,J),J=1,N),I=1,M)
         READ (NIN,*) ((B(I,J),J=1,N),I=1,P)
*
*        Compute the generalized singular value decomposition of (A, B)
*        (A = U*D1*(0 R)*(Q**T), B = V*D2*(0 R)*(Q**T), m.ge.n)
*
         CALL DGGSVD('U','V','Q',M,N,P,K,L,A,LDA,B,LDB,ALPHA,BETA,U,LDU,
     +               V,LDV,Q,LDQ,WORK,IWORK,INFO)
*
         IF (INFO.EQ.0) THEN
*
*           Print solution
*
            IRANK = K + L
            WRITE (NOUT,*)
     +        'Number of infinite generalized singular values (K)'
            WRITE (NOUT,99999) K
            WRITE (NOUT,*)
     +        'Number of finite generalized singular values (L)'
            WRITE (NOUT,99999) L
            WRITE (NOUT,*) 'Numerical rank of (A**T B**T)**T (K+L)'
            WRITE (NOUT,99999) IRANK
            WRITE (NOUT,*)
            WRITE (NOUT,*) 'Finite generalized singular values'
            WRITE (NOUT,99998) (ALPHA(J)/BETA(J),J=K+1,IRANK)
*
            IFAIL = 0
            WRITE (NOUT,*)
            CALL X04CBF('General',' ',M,M,U,LDU,'1P,E12.4',
     +                  'Orthogonal matrix U','Integer',RLABS,'Integer',
     +                  CLABS,80,0,IFAIL)
            WRITE (NOUT,*)
            CALL X04CBF('General',' ',P,P,V,LDV,'1P,E12.4',
     +                  'Orthogonal matrix V','Integer',RLABS,'Integer',
     +                  CLABS,80,0,IFAIL)
            WRITE (NOUT,*)
            CALL X04CBF('General',' ',N,N,Q,LDQ,'1P,E12.4',
     +                  'Orthogonal matrix Q','Integer',RLABS,'Integer',
     +                  CLABS,80,0,IFAIL)
            WRITE (NOUT,*)
            CALL X04CBF('Upper triangular','Non-unit',IRANK,IRANK,
     +                  A(1,N-IRANK+1),LDA,'1P,E12.4',
     +                  'Non singular upper triangular matrix R',
     +                  'Integer',RLABS,'Integer',CLABS,80,0,IFAIL)
*
*           Call DTRCON (F07TGF) to estimate the reciprocal condition
*           number of R
*
            CALL DTRCON('Infinity-norm','Upper','Non-unit',IRANK,
     +                  A(1,N-IRANK+1),LDA,RCOND,WORK,IWORK,INFO)
*
            WRITE (NOUT,*)
            WRITE (NOUT,*)
     +        'Estimate of reciprocal condition number for R'
            WRITE (NOUT,99997) RCOND
            WRITE (NOUT,*)
*
*           So long as IRANK = N, get the machine precision, EPS, and
*           compute the approximate error bound for the computed
*           generalized singular values
*
            IF (IRANK.EQ.N) THEN
               EPS = X02AJF()
               SERRBD = EPS/RCOND
               WRITE (NOUT,*)
     +           'Error estimate for the generalized singular values'
               WRITE (NOUT,99997) SERRBD
            ELSE
               WRITE (NOUT,*) '(A**T B**T)**T is not of full rank'
            END IF
         ELSE
            WRITE (NOUT,99996) 'Failure in DGGSVD. INFO =', INFO
         END IF
      ELSE
         WRITE (NOUT,*) 'MMAX and/or NMAX too small'
      END IF
      STOP
*
99999 FORMAT (1X,I5)
99998 FORMAT (3X,8(1P,E12.4))
99997 FORMAT (1X,1P,E11.1)
99996 FORMAT (1X,A,I4)
      END
