
 
 Purpose
 =======
 
      LA_GGEVX computes for a pair of n-by-n real or complex matrices
 (A, B) the generalized eigenvalues in the form of scalar pairs 
 (alpha; beta) and, optionally, the left and/or right generalized 
 eigenvectors.
      A generalized eigenvalue of the pair (A; B) is, roughly speaking, 
 a scalar of the form lambda = alpha / beta such that the matrix 
 A - lambda * B is singular. It is usually represented as the pair
 (alpha, beta), as there is a reasonable interpretation of the case 
 beta = 0 (even if alpha = 0).
      A right generalized eigenvector corresponding to a generalized 
 eigenvalue lambda is a vector  v  such that ( A - lambda*B)* v = 0. 
 A left generalized eigenvector is a vector u such that 
 u^H*(A-lambda*B) = 0, where u^H is the conjugate-transpose of u.
      The computation is based on the (generalized) real or complex 
 Schur form of (A, B). (See LA_GGES for details of this form.)
      Optionally, LA_GGEVX also computes a balancing transformation 
 (to improve the conditioning of the eigenvalues and eigenvectors), 
 reciprocal condition numbers for the eigenvalues, and reciprocal 
 condition numbers for the right eigenvectors. The balancing 
 transformation consists of a permutation of rows and columns and/or a
 scaling of rows and columns.
 
 ==========
 
    SUBROUTINE LA_GGEVX( A, B, <alpha>, BETA, VL=vl, &
          VR=vr, BALANC=balanc, ILO=ilo, IHI=ihi, &
          LSCALE=lscale, RSCALE=rscale, ABNRM=abnrm, &
          BBNRM=bbnrm, RCONDE=rconde, RCONDV=rcondv, &
          INFO=info )
        <type>(<wp>), INTENT(INOUT) :: A(:,:), B(:,:)
        <type>(<wp>), INTENT(OUT) :: <alpha(:)>, BETA(:)
        <type>(<wp>), INTENT(OUT), OPTIONAL :: VL(:,:), VR(:,:)
        CHARACTER(LEN=1), INTENT(IN), OPTIONAL :: BALANC
        INTEGER, INTENT(OUT), OPTIONAL :: ILO, IHI
        REAL(<wp>), INTENT(OUT), OPTIONAL :: LSCALE(:),
             RSCALE(:), RCONDE(:), RCONDV(:)
        REAL(<wp>), INTENT(OUT), OPTIONAL :: ABNRM, BBNRM
        INTEGER, INTENT(OUT), OPTIONAL :: INFO
     where
        <type>     ::= REAL | COMPLEX
        <wp>       ::= KIND(1.0) | KIND(1.0D0)
        <alpha>    ::= ALPHAR, ALPHAI | ALPHA
        <alpha(:)> ::= ALPHAR(:), ALPHAI(:) | ALPHA(:)
 
 
 Arguments
 =========
 
 A       (input/output) REAL or COMPLEX square array, shape (:, :).
         On entry, the matrix A.
         On exit, A has been overwritten. If the left, the right or 
         both generalized eigenvectors are computed, then A contains 
 	 the first part of the real/complex Schur form of the
         "balanced" versions of the matrix pair (A, B).
 B       (input/output) REAL or COMPLEX square array, shape (:, :) 
         with size(B, 1) = size(A, 1).
         On entry, the matrix B.
         On exit, B has been overwritten. If the left, the right or 
 	 both generalized eigenvectors are computed, then B contains 
 	 the second part of the real/complex Schur form of the "bal-
         anced" versions of the matrix pair (A, B).
 <alpha> (output) REAL or COMPLEX array, shape (:) with 
         size(<alpha>) = size(A, 1).
         The values of alpha.
         <alpha(:)> ::= ALPHAR(:), ALPHAI(:) |  ALPHA(:),
         where
         ALPHAR(:), ALPHAI(:) are of REAL type (for the real and 
 	 imaginary parts) and ALPHA(:) is of COMPLEX type.
 BETA    (output) REAL or COMPLEX array, shape (:) with 
         size(BETA) = size(A,1).
         The values of beta.
         Note: The generalized eigenvalues of the pair (A, B) are the
 	 scalars lambda(j) = alpha(j) / beta(j) . These quotients
         may easily over- or underflow, and beta(j) may even be zero. 
 	 Thus, the user should avoid computing them naively.
         Note: If A and B are real then complex eigenvalues occur in 
 	 complex conjugate pairs. Each pair is stored consecutively. 
 	 Thus a complex conjugate pair is given by
                 lambda(j) = (ALPHAR(j) + i*ALPHAI(j))/BETA(j)
                 lambda(j+1) = (ALPHAR(j+1) + i*ALPHAI(j+1))/BETA(j+1)
         where
              ALPHAI(j)/BETA(j)= - (ALPHAI(j+1)/BETA(j+1))
 VL      Optional (output) REAL or COMPLEX square array, shape (:, :)
         with  size(VL, 1) = size(A, 1).
         The left generalized eigenvectors u(j) are stored in the
         columns of VL in the order of their eigenvalues. Each
         eigenvector is scaled so the largest component has
             |realpart| + |imag.part| = 1,
         except that for eigenvalues with alpha = beta = 0, a zero
         vector is returned as the corresponding eigenvector.
         Note: If A and B are real then complex eigenvectors, like
         their eigenvalues, occur in complex conjugate pairs. The real
         and imaginary parts of the first eigenvector of the pair are
         stored in VL(:,j) and VL(:,j+1) . Thus a complex conjugate
         pair is given by
         u(j) = VL(:,j) + i*VL(:,j+1), u(j+1) = VL(:,j) - i*VL(:,j+1)
 VR      Optional (output) REAL or COMPLEX square array, shape (:,:)
         with size(VR,1) = size(A,1).
         The right generalized eigenvectors v(j) are stored in the 
         columns of VR in the order of their eigenvalues. Each 
 	 eigenvector is scaled so the largest component has 
 	 | realpart | + | imag.part | = 1,except that for eigenvalues
 	 with alpha = beta = 0, a zero vector is returned as the 
 	 corresponding eigenvector.
         Note: If A and B are real then complex eigenvectors, like 
 	 their eigenvalues, occur in complex conjugate pairs. The real
 	 and imaginary parts of the first eigenvector of the pair are
 	 stored in VR(:,j) and VR(:,j+1) . Thus a complex conjugate 
 	 pair is given by
         v(j) = VR(:,j) + i*VR(:,j+1), v(j+1) = VR(:,j) - i*VR(:,j+1)
 BALANC  Optional (input) CHARACTER(LEN=1).
         Specifies the balance option to be performed.
            = 'N': do not permute or scale;
            = 'P': permute only;
            = 'S': scale only;
            = 'B': both permute and scale.
         Default value: 'N".
         Note: Computed reciprocal condition numbers will be for the
 	 matrices after balancing. Permuting does not change condition
 	 numbers (in exact arithmetic), but scaling does.
 ILO,IHI Optional (output) INTEGER.
         ILO and IHI are integer values such that on exit A(i,j) = 0
 	 and B(i,j) = 0 if i > j and j =1,...,ILO-1 or 
 	 i = IHI+1,...,n.
 	 If BALANC = 'N' or 'S', then ILO = 1 and IHI = n.
 LSCALE  Optional (output) REAL array, shape (:) with size(LSCALE) = 
         size(A, 1).
         Details of the permutations and scaling factors applied to 
 	 the left side of A and B. If PL(j) is the index of the row 
 	 interchanged with row j, and DL(j) is the scaling factor
         applied to row j, then
                 PL(j) = LSCALE(j),  j = 1,...,ILO-1 and IHI+1,..., n
 	 and
 	        DL(j) = LSCALE(j),  j = ILO, ..., IHI
 RSCALE  Optional (output) REAL array, shape (:), size(RSCALE) = 
         size(A, 1).
         Details of the permutations and scaling factors applied to the
 	 right side of A and B. If PR(j) is the index of the column 
 	 interchanged with column j, and DR(j) is the scaling factor 
 	 applied to column j, then
                PR(j) = RSCALE(j),  j = 1,...,ILO-1 and IHI+1,..., n
         and
                DR(j) = RSCALE(j),  j = ILO, ..., IHI
 ABNRM   Optional (output) REAL.
         The l1 norm of A after balancing.
 BBNRM   Optional (output) REAL.
         The l 1 norm of B after balancing.
 RCONDE  Optional (output) REAL array, shape (:) with size(RCONDE) = 
         size(A, 1).
         The reciprocal condition numbers of the eigenvalues.
 RCONDV  Optional (output) REAL array, shape (:) with size(RCONDE) = 
         size(A, 1).
         The estimated reciprocal condition numbers of the right 
 	 eigenvectors. If the eigenvalues cannot be reordered to 
 	 compute RCONDV(j) then RCONDV(j) is set to 0. This can only
         occur when the true value would be very small.
 INFO    Optional (output) INTEGER.
         = 0: successful exit.
         < 0: if INFO = -i, the i-th argument had an illegal value.
         > 0: if INFO = i, and i is 
 	    <= n: The QZ iteration failed. No eigenvectors have been
 	          calculated, but (alpha(j) , BETA(j) ) should be 
 	   correct for j = INFO + 1,..., n.
             = n+1: another part of the algorithm failed.
             = n+2: a failure occurred during the computation of the
 	          generalized eigenvectors.
         If INFO is not present and an error occurs, then the program 
 	 is terminated with an error message.

