LAPACK 3.3.1
Linear Algebra PACKage

sggevx.f

Go to the documentation of this file.
00001       SUBROUTINE SGGEVX( BALANC, JOBVL, JOBVR, SENSE, N, A, LDA, B, LDB,
00002      $                   ALPHAR, ALPHAI, BETA, VL, LDVL, VR, LDVR, ILO,
00003      $                   IHI, LSCALE, RSCALE, ABNRM, BBNRM, RCONDE,
00004      $                   RCONDV, WORK, LWORK, IWORK, BWORK, INFO )
00005 *
00006 *  -- LAPACK driver routine (version 3.2) --
00007 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
00008 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
00009 *     November 2006
00010 *
00011 *     .. Scalar Arguments ..
00012       CHARACTER          BALANC, JOBVL, JOBVR, SENSE
00013       INTEGER            IHI, ILO, INFO, LDA, LDB, LDVL, LDVR, LWORK, N
00014       REAL               ABNRM, BBNRM
00015 *     ..
00016 *     .. Array Arguments ..
00017       LOGICAL            BWORK( * )
00018       INTEGER            IWORK( * )
00019       REAL               A( LDA, * ), ALPHAI( * ), ALPHAR( * ),
00020      $                   B( LDB, * ), BETA( * ), LSCALE( * ),
00021      $                   RCONDE( * ), RCONDV( * ), RSCALE( * ),
00022      $                   VL( LDVL, * ), VR( LDVR, * ), WORK( * )
00023 *     ..
00024 *
00025 *  Purpose
00026 *  =======
00027 *
00028 *  SGGEVX computes for a pair of N-by-N real nonsymmetric matrices (A,B)
00029 *  the generalized eigenvalues, and optionally, the left and/or right
00030 *  generalized eigenvectors.
00031 *
00032 *  Optionally also, it computes a balancing transformation to improve
00033 *  the conditioning of the eigenvalues and eigenvectors (ILO, IHI,
00034 *  LSCALE, RSCALE, ABNRM, and BBNRM), reciprocal condition numbers for
00035 *  the eigenvalues (RCONDE), and reciprocal condition numbers for the
00036 *  right eigenvectors (RCONDV).
00037 *
00038 *  A generalized eigenvalue for a pair of matrices (A,B) is a scalar
00039 *  lambda or a ratio alpha/beta = lambda, such that A - lambda*B is
00040 *  singular. It is usually represented as the pair (alpha,beta), as
00041 *  there is a reasonable interpretation for beta=0, and even for both
00042 *  being zero.
00043 *
00044 *  The right eigenvector v(j) corresponding to the eigenvalue lambda(j)
00045 *  of (A,B) satisfies
00046 *
00047 *                   A * v(j) = lambda(j) * B * v(j) .
00048 *
00049 *  The left eigenvector u(j) corresponding to the eigenvalue lambda(j)
00050 *  of (A,B) satisfies
00051 *
00052 *                   u(j)**H * A  = lambda(j) * u(j)**H * B.
00053 *
00054 *  where u(j)**H is the conjugate-transpose of u(j).
00055 *
00056 *
00057 *  Arguments
00058 *  =========
00059 *
00060 *  BALANC  (input) CHARACTER*1
00061 *          Specifies the balance option to be performed.
00062 *          = 'N':  do not diagonally scale or permute;
00063 *          = 'P':  permute only;
00064 *          = 'S':  scale only;
00065 *          = 'B':  both permute and scale.
00066 *          Computed reciprocal condition numbers will be for the
00067 *          matrices after permuting and/or balancing. Permuting does
00068 *          not change condition numbers (in exact arithmetic), but
00069 *          balancing does.
00070 *
00071 *  JOBVL   (input) CHARACTER*1
00072 *          = 'N':  do not compute the left generalized eigenvectors;
00073 *          = 'V':  compute the left generalized eigenvectors.
00074 *
00075 *  JOBVR   (input) CHARACTER*1
00076 *          = 'N':  do not compute the right generalized eigenvectors;
00077 *          = 'V':  compute the right generalized eigenvectors.
00078 *
00079 *  SENSE   (input) CHARACTER*1
00080 *          Determines which reciprocal condition numbers are computed.
00081 *          = 'N': none are computed;
00082 *          = 'E': computed for eigenvalues only;
00083 *          = 'V': computed for eigenvectors only;
00084 *          = 'B': computed for eigenvalues and eigenvectors.
00085 *
00086 *  N       (input) INTEGER
00087 *          The order of the matrices A, B, VL, and VR.  N >= 0.
00088 *
00089 *  A       (input/output) REAL array, dimension (LDA, N)
00090 *          On entry, the matrix A in the pair (A,B).
00091 *          On exit, A has been overwritten. If JOBVL='V' or JOBVR='V'
00092 *          or both, then A contains the first part of the real Schur
00093 *          form of the "balanced" versions of the input A and B.
00094 *
00095 *  LDA     (input) INTEGER
00096 *          The leading dimension of A.  LDA >= max(1,N).
00097 *
00098 *  B       (input/output) REAL array, dimension (LDB, N)
00099 *          On entry, the matrix B in the pair (A,B).
00100 *          On exit, B has been overwritten. If JOBVL='V' or JOBVR='V'
00101 *          or both, then B contains the second part of the real Schur
00102 *          form of the "balanced" versions of the input A and B.
00103 *
00104 *  LDB     (input) INTEGER
00105 *          The leading dimension of B.  LDB >= max(1,N).
00106 *
00107 *  ALPHAR  (output) REAL array, dimension (N)
00108 *  ALPHAI  (output) REAL array, dimension (N)
00109 *  BETA    (output) REAL array, dimension (N)
00110 *          On exit, (ALPHAR(j) + ALPHAI(j)*i)/BETA(j), j=1,...,N, will
00111 *          be the generalized eigenvalues.  If ALPHAI(j) is zero, then
00112 *          the j-th eigenvalue is real; if positive, then the j-th and
00113 *          (j+1)-st eigenvalues are a complex conjugate pair, with
00114 *          ALPHAI(j+1) negative.
00115 *
00116 *          Note: the quotients ALPHAR(j)/BETA(j) and ALPHAI(j)/BETA(j)
00117 *          may easily over- or underflow, and BETA(j) may even be zero.
00118 *          Thus, the user should avoid naively computing the ratio
00119 *          ALPHA/BETA. However, ALPHAR and ALPHAI will be always less
00120 *          than and usually comparable with norm(A) in magnitude, and
00121 *          BETA always less than and usually comparable with norm(B).
00122 *
00123 *  VL      (output) REAL array, dimension (LDVL,N)
00124 *          If JOBVL = 'V', the left eigenvectors u(j) are stored one
00125 *          after another in the columns of VL, in the same order as
00126 *          their eigenvalues. If the j-th eigenvalue is real, then
00127 *          u(j) = VL(:,j), the j-th column of VL. If the j-th and
00128 *          (j+1)-th eigenvalues form a complex conjugate pair, then
00129 *          u(j) = VL(:,j)+i*VL(:,j+1) and u(j+1) = VL(:,j)-i*VL(:,j+1).
00130 *          Each eigenvector will be scaled so the largest component have
00131 *          abs(real part) + abs(imag. part) = 1.
00132 *          Not referenced if JOBVL = 'N'.
00133 *
00134 *  LDVL    (input) INTEGER
00135 *          The leading dimension of the matrix VL. LDVL >= 1, and
00136 *          if JOBVL = 'V', LDVL >= N.
00137 *
00138 *  VR      (output) REAL array, dimension (LDVR,N)
00139 *          If JOBVR = 'V', the right eigenvectors v(j) are stored one
00140 *          after another in the columns of VR, in the same order as
00141 *          their eigenvalues. If the j-th eigenvalue is real, then
00142 *          v(j) = VR(:,j), the j-th column of VR. If the j-th and
00143 *          (j+1)-th eigenvalues form a complex conjugate pair, then
00144 *          v(j) = VR(:,j)+i*VR(:,j+1) and v(j+1) = VR(:,j)-i*VR(:,j+1).
00145 *          Each eigenvector will be scaled so the largest component have
00146 *          abs(real part) + abs(imag. part) = 1.
00147 *          Not referenced if JOBVR = 'N'.
00148 *
00149 *  LDVR    (input) INTEGER
00150 *          The leading dimension of the matrix VR. LDVR >= 1, and
00151 *          if JOBVR = 'V', LDVR >= N.
00152 *
00153 *  ILO     (output) INTEGER
00154 *  IHI     (output) INTEGER
00155 *          ILO and IHI are integer values such that on exit
00156 *          A(i,j) = 0 and B(i,j) = 0 if i > j and
00157 *          j = 1,...,ILO-1 or i = IHI+1,...,N.
00158 *          If BALANC = 'N' or 'S', ILO = 1 and IHI = N.
00159 *
00160 *  LSCALE  (output) REAL array, dimension (N)
00161 *          Details of the permutations and scaling factors applied
00162 *          to the left side of A and B.  If PL(j) is the index of the
00163 *          row interchanged with row j, and DL(j) is the scaling
00164 *          factor applied to row j, then
00165 *            LSCALE(j) = PL(j)  for j = 1,...,ILO-1
00166 *                      = DL(j)  for j = ILO,...,IHI
00167 *                      = PL(j)  for j = IHI+1,...,N.
00168 *          The order in which the interchanges are made is N to IHI+1,
00169 *          then 1 to ILO-1.
00170 *
00171 *  RSCALE  (output) REAL array, dimension (N)
00172 *          Details of the permutations and scaling factors applied
00173 *          to the right side of A and B.  If PR(j) is the index of the
00174 *          column interchanged with column j, and DR(j) is the scaling
00175 *          factor applied to column j, then
00176 *            RSCALE(j) = PR(j)  for j = 1,...,ILO-1
00177 *                      = DR(j)  for j = ILO,...,IHI
00178 *                      = PR(j)  for j = IHI+1,...,N
00179 *          The order in which the interchanges are made is N to IHI+1,
00180 *          then 1 to ILO-1.
00181 *
00182 *  ABNRM   (output) REAL
00183 *          The one-norm of the balanced matrix A.
00184 *
00185 *  BBNRM   (output) REAL
00186 *          The one-norm of the balanced matrix B.
00187 *
00188 *  RCONDE  (output) REAL array, dimension (N)
00189 *          If SENSE = 'E' or 'B', the reciprocal condition numbers of
00190 *          the eigenvalues, stored in consecutive elements of the array.
00191 *          For a complex conjugate pair of eigenvalues two consecutive
00192 *          elements of RCONDE are set to the same value. Thus RCONDE(j),
00193 *          RCONDV(j), and the j-th columns of VL and VR all correspond
00194 *          to the j-th eigenpair.
00195 *          If SENSE = 'N' or 'V', RCONDE is not referenced.
00196 *
00197 *  RCONDV  (output) REAL array, dimension (N)
00198 *          If SENSE = 'V' or 'B', the estimated reciprocal condition
00199 *          numbers of the eigenvectors, stored in consecutive elements
00200 *          of the array. For a complex eigenvector two consecutive
00201 *          elements of RCONDV are set to the same value. If the
00202 *          eigenvalues cannot be reordered to compute RCONDV(j),
00203 *          RCONDV(j) is set to 0; this can only occur when the true
00204 *          value would be very small anyway.
00205 *          If SENSE = 'N' or 'E', RCONDV is not referenced.
00206 *
00207 *  WORK    (workspace/output) REAL array, dimension (MAX(1,LWORK))
00208 *          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
00209 *
00210 *  LWORK   (input) INTEGER
00211 *          The dimension of the array WORK. LWORK >= max(1,2*N).
00212 *          If BALANC = 'S' or 'B', or JOBVL = 'V', or JOBVR = 'V',
00213 *          LWORK >= max(1,6*N).
00214 *          If SENSE = 'E', LWORK >= max(1,10*N).
00215 *          If SENSE = 'V' or 'B', LWORK >= 2*N*N+8*N+16.
00216 *
00217 *          If LWORK = -1, then a workspace query is assumed; the routine
00218 *          only calculates the optimal size of the WORK array, returns
00219 *          this value as the first entry of the WORK array, and no error
00220 *          message related to LWORK is issued by XERBLA.
00221 *
00222 *  IWORK   (workspace) INTEGER array, dimension (N+6)
00223 *          If SENSE = 'E', IWORK is not referenced.
00224 *
00225 *  BWORK   (workspace) LOGICAL array, dimension (N)
00226 *          If SENSE = 'N', BWORK is not referenced.
00227 *
00228 *  INFO    (output) INTEGER
00229 *          = 0:  successful exit
00230 *          < 0:  if INFO = -i, the i-th argument had an illegal value.
00231 *          = 1,...,N:
00232 *                The QZ iteration failed.  No eigenvectors have been
00233 *                calculated, but ALPHAR(j), ALPHAI(j), and BETA(j)
00234 *                should be correct for j=INFO+1,...,N.
00235 *          > N:  =N+1: other than QZ iteration failed in SHGEQZ.
00236 *                =N+2: error return from STGEVC.
00237 *
00238 *  Further Details
00239 *  ===============
00240 *
00241 *  Balancing a matrix pair (A,B) includes, first, permuting rows and
00242 *  columns to isolate eigenvalues, second, applying diagonal similarity
00243 *  transformation to the rows and columns to make the rows and columns
00244 *  as close in norm as possible. The computed reciprocal condition
00245 *  numbers correspond to the balanced matrix. Permuting rows and columns
00246 *  will not change the condition numbers (in exact arithmetic) but
00247 *  diagonal scaling will.  For further explanation of balancing, see
00248 *  section 4.11.1.2 of LAPACK Users' Guide.
00249 *
00250 *  An approximate error bound on the chordal distance between the i-th
00251 *  computed generalized eigenvalue w and the corresponding exact
00252 *  eigenvalue lambda is
00253 *
00254 *       chord(w, lambda) <= EPS * norm(ABNRM, BBNRM) / RCONDE(I)
00255 *
00256 *  An approximate error bound for the angle between the i-th computed
00257 *  eigenvector VL(i) or VR(i) is given by
00258 *
00259 *       EPS * norm(ABNRM, BBNRM) / DIF(i).
00260 *
00261 *  For further explanation of the reciprocal condition numbers RCONDE
00262 *  and RCONDV, see section 4.11 of LAPACK User's Guide.
00263 *
00264 *  =====================================================================
00265 *
00266 *     .. Parameters ..
00267       REAL               ZERO, ONE
00268       PARAMETER          ( ZERO = 0.0E+0, ONE = 1.0E+0 )
00269 *     ..
00270 *     .. Local Scalars ..
00271       LOGICAL            ILASCL, ILBSCL, ILV, ILVL, ILVR, LQUERY, NOSCL,
00272      $                   PAIR, WANTSB, WANTSE, WANTSN, WANTSV
00273       CHARACTER          CHTEMP
00274       INTEGER            I, ICOLS, IERR, IJOBVL, IJOBVR, IN, IROWS,
00275      $                   ITAU, IWRK, IWRK1, J, JC, JR, M, MAXWRK,
00276      $                   MINWRK, MM
00277       REAL               ANRM, ANRMTO, BIGNUM, BNRM, BNRMTO, EPS,
00278      $                   SMLNUM, TEMP
00279 *     ..
00280 *     .. Local Arrays ..
00281       LOGICAL            LDUMMA( 1 )
00282 *     ..
00283 *     .. External Subroutines ..
00284       EXTERNAL           SGEQRF, SGGBAK, SGGBAL, SGGHRD, SHGEQZ, SLABAD,
00285      $                   SLACPY, SLASCL, SLASET, SORGQR, SORMQR, STGEVC,
00286      $                   STGSNA, XERBLA
00287 *     ..
00288 *     .. External Functions ..
00289       LOGICAL            LSAME
00290       INTEGER            ILAENV
00291       REAL               SLAMCH, SLANGE
00292       EXTERNAL           LSAME, ILAENV, SLAMCH, SLANGE
00293 *     ..
00294 *     .. Intrinsic Functions ..
00295       INTRINSIC          ABS, MAX, SQRT
00296 *     ..
00297 *     .. Executable Statements ..
00298 *
00299 *     Decode the input arguments
00300 *
00301       IF( LSAME( JOBVL, 'N' ) ) THEN
00302          IJOBVL = 1
00303          ILVL = .FALSE.
00304       ELSE IF( LSAME( JOBVL, 'V' ) ) THEN
00305          IJOBVL = 2
00306          ILVL = .TRUE.
00307       ELSE
00308          IJOBVL = -1
00309          ILVL = .FALSE.
00310       END IF
00311 *
00312       IF( LSAME( JOBVR, 'N' ) ) THEN
00313          IJOBVR = 1
00314          ILVR = .FALSE.
00315       ELSE IF( LSAME( JOBVR, 'V' ) ) THEN
00316          IJOBVR = 2
00317          ILVR = .TRUE.
00318       ELSE
00319          IJOBVR = -1
00320          ILVR = .FALSE.
00321       END IF
00322       ILV = ILVL .OR. ILVR
00323 *
00324       NOSCL  = LSAME( BALANC, 'N' ) .OR. LSAME( BALANC, 'P' )
00325       WANTSN = LSAME( SENSE, 'N' )
00326       WANTSE = LSAME( SENSE, 'E' )
00327       WANTSV = LSAME( SENSE, 'V' )
00328       WANTSB = LSAME( SENSE, 'B' )
00329 *
00330 *     Test the input arguments
00331 *
00332       INFO = 0
00333       LQUERY = ( LWORK.EQ.-1 )
00334       IF( .NOT.( NOSCL .OR. LSAME( BALANC, 'S' ) .OR.
00335      $    LSAME( BALANC, 'B' ) ) ) THEN
00336          INFO = -1
00337       ELSE IF( IJOBVL.LE.0 ) THEN
00338          INFO = -2
00339       ELSE IF( IJOBVR.LE.0 ) THEN
00340          INFO = -3
00341       ELSE IF( .NOT.( WANTSN .OR. WANTSE .OR. WANTSB .OR. WANTSV ) )
00342      $          THEN
00343          INFO = -4
00344       ELSE IF( N.LT.0 ) THEN
00345          INFO = -5
00346       ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
00347          INFO = -7
00348       ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
00349          INFO = -9
00350       ELSE IF( LDVL.LT.1 .OR. ( ILVL .AND. LDVL.LT.N ) ) THEN
00351          INFO = -14
00352       ELSE IF( LDVR.LT.1 .OR. ( ILVR .AND. LDVR.LT.N ) ) THEN
00353          INFO = -16
00354       END IF
00355 *
00356 *     Compute workspace
00357 *      (Note: Comments in the code beginning "Workspace:" describe the
00358 *       minimal amount of workspace needed at that point in the code,
00359 *       as well as the preferred amount for good performance.
00360 *       NB refers to the optimal block size for the immediately
00361 *       following subroutine, as returned by ILAENV. The workspace is
00362 *       computed assuming ILO = 1 and IHI = N, the worst case.)
00363 *
00364       IF( INFO.EQ.0 ) THEN
00365          IF( N.EQ.0 ) THEN
00366             MINWRK = 1
00367             MAXWRK = 1
00368          ELSE
00369             IF( NOSCL .AND. .NOT.ILV ) THEN
00370                MINWRK = 2*N
00371             ELSE
00372                MINWRK = 6*N
00373             END IF
00374             IF( WANTSE ) THEN
00375                MINWRK = 10*N
00376             ELSE IF( WANTSV .OR. WANTSB ) THEN
00377                MINWRK = 2*N*( N + 4 ) + 16
00378             END IF
00379             MAXWRK = MINWRK
00380             MAXWRK = MAX( MAXWRK,
00381      $                    N + N*ILAENV( 1, 'SGEQRF', ' ', N, 1, N, 0 ) )
00382             MAXWRK = MAX( MAXWRK,
00383      $                    N + N*ILAENV( 1, 'SORMQR', ' ', N, 1, N, 0 ) )
00384             IF( ILVL ) THEN
00385                MAXWRK = MAX( MAXWRK, N +
00386      $                       N*ILAENV( 1, 'SORGQR', ' ', N, 1, N, 0 ) )
00387             END IF
00388          END IF
00389          WORK( 1 ) = MAXWRK
00390 *
00391          IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY ) THEN
00392             INFO = -26
00393          END IF
00394       END IF
00395 *
00396       IF( INFO.NE.0 ) THEN
00397          CALL XERBLA( 'SGGEVX', -INFO )
00398          RETURN
00399       ELSE IF( LQUERY ) THEN
00400          RETURN
00401       END IF
00402 *
00403 *     Quick return if possible
00404 *
00405       IF( N.EQ.0 )
00406      $   RETURN
00407 *
00408 *
00409 *     Get machine constants
00410 *
00411       EPS = SLAMCH( 'P' )
00412       SMLNUM = SLAMCH( 'S' )
00413       BIGNUM = ONE / SMLNUM
00414       CALL SLABAD( SMLNUM, BIGNUM )
00415       SMLNUM = SQRT( SMLNUM ) / EPS
00416       BIGNUM = ONE / SMLNUM
00417 *
00418 *     Scale A if max element outside range [SMLNUM,BIGNUM]
00419 *
00420       ANRM = SLANGE( 'M', N, N, A, LDA, WORK )
00421       ILASCL = .FALSE.
00422       IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
00423          ANRMTO = SMLNUM
00424          ILASCL = .TRUE.
00425       ELSE IF( ANRM.GT.BIGNUM ) THEN
00426          ANRMTO = BIGNUM
00427          ILASCL = .TRUE.
00428       END IF
00429       IF( ILASCL )
00430      $   CALL SLASCL( 'G', 0, 0, ANRM, ANRMTO, N, N, A, LDA, IERR )
00431 *
00432 *     Scale B if max element outside range [SMLNUM,BIGNUM]
00433 *
00434       BNRM = SLANGE( 'M', N, N, B, LDB, WORK )
00435       ILBSCL = .FALSE.
00436       IF( BNRM.GT.ZERO .AND. BNRM.LT.SMLNUM ) THEN
00437          BNRMTO = SMLNUM
00438          ILBSCL = .TRUE.
00439       ELSE IF( BNRM.GT.BIGNUM ) THEN
00440          BNRMTO = BIGNUM
00441          ILBSCL = .TRUE.
00442       END IF
00443       IF( ILBSCL )
00444      $   CALL SLASCL( 'G', 0, 0, BNRM, BNRMTO, N, N, B, LDB, IERR )
00445 *
00446 *     Permute and/or balance the matrix pair (A,B)
00447 *     (Workspace: need 6*N if BALANC = 'S' or 'B', 1 otherwise)
00448 *
00449       CALL SGGBAL( BALANC, N, A, LDA, B, LDB, ILO, IHI, LSCALE, RSCALE,
00450      $             WORK, IERR )
00451 *
00452 *     Compute ABNRM and BBNRM
00453 *
00454       ABNRM = SLANGE( '1', N, N, A, LDA, WORK( 1 ) )
00455       IF( ILASCL ) THEN
00456          WORK( 1 ) = ABNRM
00457          CALL SLASCL( 'G', 0, 0, ANRMTO, ANRM, 1, 1, WORK( 1 ), 1,
00458      $                IERR )
00459          ABNRM = WORK( 1 )
00460       END IF
00461 *
00462       BBNRM = SLANGE( '1', N, N, B, LDB, WORK( 1 ) )
00463       IF( ILBSCL ) THEN
00464          WORK( 1 ) = BBNRM
00465          CALL SLASCL( 'G', 0, 0, BNRMTO, BNRM, 1, 1, WORK( 1 ), 1,
00466      $                IERR )
00467          BBNRM = WORK( 1 )
00468       END IF
00469 *
00470 *     Reduce B to triangular form (QR decomposition of B)
00471 *     (Workspace: need N, prefer N*NB )
00472 *
00473       IROWS = IHI + 1 - ILO
00474       IF( ILV .OR. .NOT.WANTSN ) THEN
00475          ICOLS = N + 1 - ILO
00476       ELSE
00477          ICOLS = IROWS
00478       END IF
00479       ITAU = 1
00480       IWRK = ITAU + IROWS
00481       CALL SGEQRF( IROWS, ICOLS, B( ILO, ILO ), LDB, WORK( ITAU ),
00482      $             WORK( IWRK ), LWORK+1-IWRK, IERR )
00483 *
00484 *     Apply the orthogonal transformation to A
00485 *     (Workspace: need N, prefer N*NB)
00486 *
00487       CALL SORMQR( 'L', 'T', IROWS, ICOLS, IROWS, B( ILO, ILO ), LDB,
00488      $             WORK( ITAU ), A( ILO, ILO ), LDA, WORK( IWRK ),
00489      $             LWORK+1-IWRK, IERR )
00490 *
00491 *     Initialize VL and/or VR
00492 *     (Workspace: need N, prefer N*NB)
00493 *
00494       IF( ILVL ) THEN
00495          CALL SLASET( 'Full', N, N, ZERO, ONE, VL, LDVL )
00496          IF( IROWS.GT.1 ) THEN
00497             CALL SLACPY( 'L', IROWS-1, IROWS-1, B( ILO+1, ILO ), LDB,
00498      $                   VL( ILO+1, ILO ), LDVL )
00499          END IF
00500          CALL SORGQR( IROWS, IROWS, IROWS, VL( ILO, ILO ), LDVL,
00501      $                WORK( ITAU ), WORK( IWRK ), LWORK+1-IWRK, IERR )
00502       END IF
00503 *
00504       IF( ILVR )
00505      $   CALL SLASET( 'Full', N, N, ZERO, ONE, VR, LDVR )
00506 *
00507 *     Reduce to generalized Hessenberg form
00508 *     (Workspace: none needed)
00509 *
00510       IF( ILV .OR. .NOT.WANTSN ) THEN
00511 *
00512 *        Eigenvectors requested -- work on whole matrix.
00513 *
00514          CALL SGGHRD( JOBVL, JOBVR, N, ILO, IHI, A, LDA, B, LDB, VL,
00515      $                LDVL, VR, LDVR, IERR )
00516       ELSE
00517          CALL SGGHRD( 'N', 'N', IROWS, 1, IROWS, A( ILO, ILO ), LDA,
00518      $                B( ILO, ILO ), LDB, VL, LDVL, VR, LDVR, IERR )
00519       END IF
00520 *
00521 *     Perform QZ algorithm (Compute eigenvalues, and optionally, the
00522 *     Schur forms and Schur vectors)
00523 *     (Workspace: need N)
00524 *
00525       IF( ILV .OR. .NOT.WANTSN ) THEN
00526          CHTEMP = 'S'
00527       ELSE
00528          CHTEMP = 'E'
00529       END IF
00530 *
00531       CALL SHGEQZ( CHTEMP, JOBVL, JOBVR, N, ILO, IHI, A, LDA, B, LDB,
00532      $             ALPHAR, ALPHAI, BETA, VL, LDVL, VR, LDVR, WORK,
00533      $             LWORK, IERR )
00534       IF( IERR.NE.0 ) THEN
00535          IF( IERR.GT.0 .AND. IERR.LE.N ) THEN
00536             INFO = IERR
00537          ELSE IF( IERR.GT.N .AND. IERR.LE.2*N ) THEN
00538             INFO = IERR - N
00539          ELSE
00540             INFO = N + 1
00541          END IF
00542          GO TO 130
00543       END IF
00544 *
00545 *     Compute Eigenvectors and estimate condition numbers if desired
00546 *     (Workspace: STGEVC: need 6*N
00547 *                 STGSNA: need 2*N*(N+2)+16 if SENSE = 'V' or 'B',
00548 *                         need N otherwise )
00549 *
00550       IF( ILV .OR. .NOT.WANTSN ) THEN
00551          IF( ILV ) THEN
00552             IF( ILVL ) THEN
00553                IF( ILVR ) THEN
00554                   CHTEMP = 'B'
00555                ELSE
00556                   CHTEMP = 'L'
00557                END IF
00558             ELSE
00559                CHTEMP = 'R'
00560             END IF
00561 *
00562             CALL STGEVC( CHTEMP, 'B', LDUMMA, N, A, LDA, B, LDB, VL,
00563      $                   LDVL, VR, LDVR, N, IN, WORK, IERR )
00564             IF( IERR.NE.0 ) THEN
00565                INFO = N + 2
00566                GO TO 130
00567             END IF
00568          END IF
00569 *
00570          IF( .NOT.WANTSN ) THEN
00571 *
00572 *           compute eigenvectors (STGEVC) and estimate condition
00573 *           numbers (STGSNA). Note that the definition of the condition
00574 *           number is not invariant under transformation (u,v) to
00575 *           (Q*u, Z*v), where (u,v) are eigenvectors of the generalized
00576 *           Schur form (S,T), Q and Z are orthogonal matrices. In order
00577 *           to avoid using extra 2*N*N workspace, we have to recalculate
00578 *           eigenvectors and estimate one condition numbers at a time.
00579 *
00580             PAIR = .FALSE.
00581             DO 20 I = 1, N
00582 *
00583                IF( PAIR ) THEN
00584                   PAIR = .FALSE.
00585                   GO TO 20
00586                END IF
00587                MM = 1
00588                IF( I.LT.N ) THEN
00589                   IF( A( I+1, I ).NE.ZERO ) THEN
00590                      PAIR = .TRUE.
00591                      MM = 2
00592                   END IF
00593                END IF
00594 *
00595                DO 10 J = 1, N
00596                   BWORK( J ) = .FALSE.
00597    10          CONTINUE
00598                IF( MM.EQ.1 ) THEN
00599                   BWORK( I ) = .TRUE.
00600                ELSE IF( MM.EQ.2 ) THEN
00601                   BWORK( I ) = .TRUE.
00602                   BWORK( I+1 ) = .TRUE.
00603                END IF
00604 *
00605                IWRK = MM*N + 1
00606                IWRK1 = IWRK + MM*N
00607 *
00608 *              Compute a pair of left and right eigenvectors.
00609 *              (compute workspace: need up to 4*N + 6*N)
00610 *
00611                IF( WANTSE .OR. WANTSB ) THEN
00612                   CALL STGEVC( 'B', 'S', BWORK, N, A, LDA, B, LDB,
00613      $                         WORK( 1 ), N, WORK( IWRK ), N, MM, M,
00614      $                         WORK( IWRK1 ), IERR )
00615                   IF( IERR.NE.0 ) THEN
00616                      INFO = N + 2
00617                      GO TO 130
00618                   END IF
00619                END IF
00620 *
00621                CALL STGSNA( SENSE, 'S', BWORK, N, A, LDA, B, LDB,
00622      $                      WORK( 1 ), N, WORK( IWRK ), N, RCONDE( I ),
00623      $                      RCONDV( I ), MM, M, WORK( IWRK1 ),
00624      $                      LWORK-IWRK1+1, IWORK, IERR )
00625 *
00626    20       CONTINUE
00627          END IF
00628       END IF
00629 *
00630 *     Undo balancing on VL and VR and normalization
00631 *     (Workspace: none needed)
00632 *
00633       IF( ILVL ) THEN
00634          CALL SGGBAK( BALANC, 'L', N, ILO, IHI, LSCALE, RSCALE, N, VL,
00635      $                LDVL, IERR )
00636 *
00637          DO 70 JC = 1, N
00638             IF( ALPHAI( JC ).LT.ZERO )
00639      $         GO TO 70
00640             TEMP = ZERO
00641             IF( ALPHAI( JC ).EQ.ZERO ) THEN
00642                DO 30 JR = 1, N
00643                   TEMP = MAX( TEMP, ABS( VL( JR, JC ) ) )
00644    30          CONTINUE
00645             ELSE
00646                DO 40 JR = 1, N
00647                   TEMP = MAX( TEMP, ABS( VL( JR, JC ) )+
00648      $                   ABS( VL( JR, JC+1 ) ) )
00649    40          CONTINUE
00650             END IF
00651             IF( TEMP.LT.SMLNUM )
00652      $         GO TO 70
00653             TEMP = ONE / TEMP
00654             IF( ALPHAI( JC ).EQ.ZERO ) THEN
00655                DO 50 JR = 1, N
00656                   VL( JR, JC ) = VL( JR, JC )*TEMP
00657    50          CONTINUE
00658             ELSE
00659                DO 60 JR = 1, N
00660                   VL( JR, JC ) = VL( JR, JC )*TEMP
00661                   VL( JR, JC+1 ) = VL( JR, JC+1 )*TEMP
00662    60          CONTINUE
00663             END IF
00664    70    CONTINUE
00665       END IF
00666       IF( ILVR ) THEN
00667          CALL SGGBAK( BALANC, 'R', N, ILO, IHI, LSCALE, RSCALE, N, VR,
00668      $                LDVR, IERR )
00669          DO 120 JC = 1, N
00670             IF( ALPHAI( JC ).LT.ZERO )
00671      $         GO TO 120
00672             TEMP = ZERO
00673             IF( ALPHAI( JC ).EQ.ZERO ) THEN
00674                DO 80 JR = 1, N
00675                   TEMP = MAX( TEMP, ABS( VR( JR, JC ) ) )
00676    80          CONTINUE
00677             ELSE
00678                DO 90 JR = 1, N
00679                   TEMP = MAX( TEMP, ABS( VR( JR, JC ) )+
00680      $                   ABS( VR( JR, JC+1 ) ) )
00681    90          CONTINUE
00682             END IF
00683             IF( TEMP.LT.SMLNUM )
00684      $         GO TO 120
00685             TEMP = ONE / TEMP
00686             IF( ALPHAI( JC ).EQ.ZERO ) THEN
00687                DO 100 JR = 1, N
00688                   VR( JR, JC ) = VR( JR, JC )*TEMP
00689   100          CONTINUE
00690             ELSE
00691                DO 110 JR = 1, N
00692                   VR( JR, JC ) = VR( JR, JC )*TEMP
00693                   VR( JR, JC+1 ) = VR( JR, JC+1 )*TEMP
00694   110          CONTINUE
00695             END IF
00696   120    CONTINUE
00697       END IF
00698 *
00699 *     Undo scaling if necessary
00700 *
00701       IF( ILASCL ) THEN
00702          CALL SLASCL( 'G', 0, 0, ANRMTO, ANRM, N, 1, ALPHAR, N, IERR )
00703          CALL SLASCL( 'G', 0, 0, ANRMTO, ANRM, N, 1, ALPHAI, N, IERR )
00704       END IF
00705 *
00706       IF( ILBSCL ) THEN
00707          CALL SLASCL( 'G', 0, 0, BNRMTO, BNRM, N, 1, BETA, N, IERR )
00708       END IF
00709 *
00710   130 CONTINUE
00711       WORK( 1 ) = MAXWRK
00712 *
00713       RETURN
00714 *
00715 *     End of SGGEVX
00716 *
00717       END
 All Files Functions