LAPACK 3.3.1
Linear Algebra PACKage

sggesx.f

Go to the documentation of this file.
00001       SUBROUTINE SGGESX( JOBVSL, JOBVSR, SORT, SELCTG, SENSE, N, A, LDA,
00002      $                   B, LDB, SDIM, ALPHAR, ALPHAI, BETA, VSL, LDVSL,
00003      $                   VSR, LDVSR, RCONDE, RCONDV, WORK, LWORK, IWORK,
00004      $                   LIWORK, BWORK, INFO )
00005 *
00006 *  -- LAPACK driver routine (version 3.2.1)                                  --
00007 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
00008 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
00009 *  -- April 2009                                                      --
00010 *
00011 *     .. Scalar Arguments ..
00012       CHARACTER          JOBVSL, JOBVSR, SENSE, SORT
00013       INTEGER            INFO, LDA, LDB, LDVSL, LDVSR, LIWORK, LWORK, N,
00014      $                   SDIM
00015 *     ..
00016 *     .. Array Arguments ..
00017       LOGICAL            BWORK( * )
00018       INTEGER            IWORK( * )
00019       REAL               A( LDA, * ), ALPHAI( * ), ALPHAR( * ),
00020      $                   B( LDB, * ), BETA( * ), RCONDE( 2 ),
00021      $                   RCONDV( 2 ), VSL( LDVSL, * ), VSR( LDVSR, * ),
00022      $                   WORK( * )
00023 *     ..
00024 *     .. Function Arguments ..
00025       LOGICAL            SELCTG
00026       EXTERNAL           SELCTG
00027 *     ..
00028 *
00029 *  Purpose
00030 *  =======
00031 *
00032 *  SGGESX computes for a pair of N-by-N real nonsymmetric matrices
00033 *  (A,B), the generalized eigenvalues, the real Schur form (S,T), and,
00034 *  optionally, the left and/or right matrices of Schur vectors (VSL and
00035 *  VSR).  This gives the generalized Schur factorization
00036 *
00037 *       (A,B) = ( (VSL) S (VSR)**T, (VSL) T (VSR)**T )
00038 *
00039 *  Optionally, it also orders the eigenvalues so that a selected cluster
00040 *  of eigenvalues appears in the leading diagonal blocks of the upper
00041 *  quasi-triangular matrix S and the upper triangular matrix T; computes
00042 *  a reciprocal condition number for the average of the selected
00043 *  eigenvalues (RCONDE); and computes a reciprocal condition number for
00044 *  the right and left deflating subspaces corresponding to the selected
00045 *  eigenvalues (RCONDV). The leading columns of VSL and VSR then form
00046 *  an orthonormal basis for the corresponding left and right eigenspaces
00047 *  (deflating subspaces).
00048 *
00049 *  A generalized eigenvalue for a pair of matrices (A,B) is a scalar w
00050 *  or a ratio alpha/beta = w, such that  A - w*B is singular.  It is
00051 *  usually represented as the pair (alpha,beta), as there is a
00052 *  reasonable interpretation for beta=0 or for both being zero.
00053 *
00054 *  A pair of matrices (S,T) is in generalized real Schur form if T is
00055 *  upper triangular with non-negative diagonal and S is block upper
00056 *  triangular with 1-by-1 and 2-by-2 blocks.  1-by-1 blocks correspond
00057 *  to real generalized eigenvalues, while 2-by-2 blocks of S will be
00058 *  "standardized" by making the corresponding elements of T have the
00059 *  form:
00060 *          [  a  0  ]
00061 *          [  0  b  ]
00062 *
00063 *  and the pair of corresponding 2-by-2 blocks in S and T will have a
00064 *  complex conjugate pair of generalized eigenvalues.
00065 *
00066 *
00067 *  Arguments
00068 *  =========
00069 *
00070 *  JOBVSL  (input) CHARACTER*1
00071 *          = 'N':  do not compute the left Schur vectors;
00072 *          = 'V':  compute the left Schur vectors.
00073 *
00074 *  JOBVSR  (input) CHARACTER*1
00075 *          = 'N':  do not compute the right Schur vectors;
00076 *          = 'V':  compute the right Schur vectors.
00077 *
00078 *  SORT    (input) CHARACTER*1
00079 *          Specifies whether or not to order the eigenvalues on the
00080 *          diagonal of the generalized Schur form.
00081 *          = 'N':  Eigenvalues are not ordered;
00082 *          = 'S':  Eigenvalues are ordered (see SELCTG).
00083 *
00084 *  SELCTG  (external procedure) LOGICAL FUNCTION of three REAL arguments
00085 *          SELCTG must be declared EXTERNAL in the calling subroutine.
00086 *          If SORT = 'N', SELCTG is not referenced.
00087 *          If SORT = 'S', SELCTG is used to select eigenvalues to sort
00088 *          to the top left of the Schur form.
00089 *          An eigenvalue (ALPHAR(j)+ALPHAI(j))/BETA(j) is selected if
00090 *          SELCTG(ALPHAR(j),ALPHAI(j),BETA(j)) is true; i.e. if either
00091 *          one of a complex conjugate pair of eigenvalues is selected,
00092 *          then both complex eigenvalues are selected.
00093 *          Note that a selected complex eigenvalue may no longer satisfy
00094 *          SELCTG(ALPHAR(j),ALPHAI(j),BETA(j)) = .TRUE. after ordering,
00095 *          since ordering may change the value of complex eigenvalues
00096 *          (especially if the eigenvalue is ill-conditioned), in this
00097 *          case INFO is set to N+3.
00098 *
00099 *  SENSE   (input) CHARACTER*1
00100 *          Determines which reciprocal condition numbers are computed.
00101 *          = 'N' : None are computed;
00102 *          = 'E' : Computed for average of selected eigenvalues only;
00103 *          = 'V' : Computed for selected deflating subspaces only;
00104 *          = 'B' : Computed for both.
00105 *          If SENSE = 'E', 'V', or 'B', SORT must equal 'S'.
00106 *
00107 *  N       (input) INTEGER
00108 *          The order of the matrices A, B, VSL, and VSR.  N >= 0.
00109 *
00110 *  A       (input/output) REAL array, dimension (LDA, N)
00111 *          On entry, the first of the pair of matrices.
00112 *          On exit, A has been overwritten by its generalized Schur
00113 *          form S.
00114 *
00115 *  LDA     (input) INTEGER
00116 *          The leading dimension of A.  LDA >= max(1,N).
00117 *
00118 *  B       (input/output) REAL array, dimension (LDB, N)
00119 *          On entry, the second of the pair of matrices.
00120 *          On exit, B has been overwritten by its generalized Schur
00121 *          form T.
00122 *
00123 *  LDB     (input) INTEGER
00124 *          The leading dimension of B.  LDB >= max(1,N).
00125 *
00126 *  SDIM    (output) INTEGER
00127 *          If SORT = 'N', SDIM = 0.
00128 *          If SORT = 'S', SDIM = number of eigenvalues (after sorting)
00129 *          for which SELCTG is true.  (Complex conjugate pairs for which
00130 *          SELCTG is true for either eigenvalue count as 2.)
00131 *
00132 *  ALPHAR  (output) REAL array, dimension (N)
00133 *  ALPHAI  (output) REAL array, dimension (N)
00134 *  BETA    (output) REAL array, dimension (N)
00135 *          On exit, (ALPHAR(j) + ALPHAI(j)*i)/BETA(j), j=1,...,N, will
00136 *          be the generalized eigenvalues.  ALPHAR(j) + ALPHAI(j)*i
00137 *          and BETA(j),j=1,...,N  are the diagonals of the complex Schur
00138 *          form (S,T) that would result if the 2-by-2 diagonal blocks of
00139 *          the real Schur form of (A,B) were further reduced to
00140 *          triangular form using 2-by-2 complex unitary transformations.
00141 *          If ALPHAI(j) is zero, then the j-th eigenvalue is real; if
00142 *          positive, then the j-th and (j+1)-st eigenvalues are a
00143 *          complex conjugate pair, with ALPHAI(j+1) negative.
00144 *
00145 *          Note: the quotients ALPHAR(j)/BETA(j) and ALPHAI(j)/BETA(j)
00146 *          may easily over- or underflow, and BETA(j) may even be zero.
00147 *          Thus, the user should avoid naively computing the ratio.
00148 *          However, ALPHAR and ALPHAI will be always less than and
00149 *          usually comparable with norm(A) in magnitude, and BETA always
00150 *          less than and usually comparable with norm(B).
00151 *
00152 *  VSL     (output) REAL array, dimension (LDVSL,N)
00153 *          If JOBVSL = 'V', VSL will contain the left Schur vectors.
00154 *          Not referenced if JOBVSL = 'N'.
00155 *
00156 *  LDVSL   (input) INTEGER
00157 *          The leading dimension of the matrix VSL. LDVSL >=1, and
00158 *          if JOBVSL = 'V', LDVSL >= N.
00159 *
00160 *  VSR     (output) REAL array, dimension (LDVSR,N)
00161 *          If JOBVSR = 'V', VSR will contain the right Schur vectors.
00162 *          Not referenced if JOBVSR = 'N'.
00163 *
00164 *  LDVSR   (input) INTEGER
00165 *          The leading dimension of the matrix VSR. LDVSR >= 1, and
00166 *          if JOBVSR = 'V', LDVSR >= N.
00167 *
00168 *  RCONDE  (output) REAL array, dimension ( 2 )
00169 *          If SENSE = 'E' or 'B', RCONDE(1) and RCONDE(2) contain the
00170 *          reciprocal condition numbers for the average of the selected
00171 *          eigenvalues.
00172 *          Not referenced if SENSE = 'N' or 'V'.
00173 *
00174 *  RCONDV  (output) REAL array, dimension ( 2 )
00175 *          If SENSE = 'V' or 'B', RCONDV(1) and RCONDV(2) contain the
00176 *          reciprocal condition numbers for the selected deflating
00177 *          subspaces.
00178 *          Not referenced if SENSE = 'N' or 'E'.
00179 *
00180 *  WORK    (workspace/output) REAL array, dimension (MAX(1,LWORK))
00181 *          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
00182 *
00183 *  LWORK   (input) INTEGER
00184 *          The dimension of the array WORK.
00185 *          If N = 0, LWORK >= 1, else if SENSE = 'E', 'V', or 'B',
00186 *          LWORK >= max( 8*N, 6*N+16, 2*SDIM*(N-SDIM) ), else
00187 *          LWORK >= max( 8*N, 6*N+16 ).
00188 *          Note that 2*SDIM*(N-SDIM) <= N*N/2.
00189 *          Note also that an error is only returned if
00190 *          LWORK < max( 8*N, 6*N+16), but if SENSE = 'E' or 'V' or 'B'
00191 *          this may not be large enough.
00192 *
00193 *          If LWORK = -1, then a workspace query is assumed; the routine
00194 *          only calculates the bound on the optimal size of the WORK
00195 *          array and the minimum size of the IWORK array, returns these
00196 *          values as the first entries of the WORK and IWORK arrays, and
00197 *          no error message related to LWORK or LIWORK is issued by
00198 *          XERBLA.
00199 *
00200 *  IWORK   (workspace) INTEGER array, dimension (MAX(1,LIWORK))
00201 *          On exit, if INFO = 0, IWORK(1) returns the minimum LIWORK.
00202 *
00203 *  LIWORK  (input) INTEGER
00204 *          The dimension of the array IWORK.
00205 *          If SENSE = 'N' or N = 0, LIWORK >= 1, otherwise
00206 *          LIWORK >= N+6.
00207 *
00208 *          If LIWORK = -1, then a workspace query is assumed; the
00209 *          routine only calculates the bound on the optimal size of the
00210 *          WORK array and the minimum size of the IWORK array, returns
00211 *          these values as the first entries of the WORK and IWORK
00212 *          arrays, and no error message related to LWORK or LIWORK is
00213 *          issued by XERBLA.
00214 *
00215 *  BWORK   (workspace) LOGICAL array, dimension (N)
00216 *          Not referenced if SORT = 'N'.
00217 *
00218 *  INFO    (output) INTEGER
00219 *          = 0:  successful exit
00220 *          < 0:  if INFO = -i, the i-th argument had an illegal value.
00221 *          = 1,...,N:
00222 *                The QZ iteration failed.  (A,B) are not in Schur
00223 *                form, but ALPHAR(j), ALPHAI(j), and BETA(j) should
00224 *                be correct for j=INFO+1,...,N.
00225 *          > N:  =N+1: other than QZ iteration failed in SHGEQZ
00226 *                =N+2: after reordering, roundoff changed values of
00227 *                      some complex eigenvalues so that leading
00228 *                      eigenvalues in the Generalized Schur form no
00229 *                      longer satisfy SELCTG=.TRUE.  This could also
00230 *                      be caused due to scaling.
00231 *                =N+3: reordering failed in STGSEN.
00232 *
00233 *  Further Details
00234 *  ===============
00235 *
00236 *  An approximate (asymptotic) bound on the average absolute error of
00237 *  the selected eigenvalues is
00238 *
00239 *       EPS * norm((A, B)) / RCONDE( 1 ).
00240 *
00241 *  An approximate (asymptotic) bound on the maximum angular error in
00242 *  the computed deflating subspaces is
00243 *
00244 *       EPS * norm((A, B)) / RCONDV( 2 ).
00245 *
00246 *  See LAPACK User's Guide, section 4.11 for more information.
00247 *
00248 *  =====================================================================
00249 *
00250 *     .. Parameters ..
00251       REAL               ZERO, ONE
00252       PARAMETER          ( ZERO = 0.0E+0, ONE = 1.0E+0 )
00253 *     ..
00254 *     .. Local Scalars ..
00255       LOGICAL            CURSL, ILASCL, ILBSCL, ILVSL, ILVSR, LASTSL,
00256      $                   LQUERY, LST2SL, WANTSB, WANTSE, WANTSN, WANTST,
00257      $                   WANTSV
00258       INTEGER            I, ICOLS, IERR, IHI, IJOB, IJOBVL, IJOBVR,
00259      $                   ILEFT, ILO, IP, IRIGHT, IROWS, ITAU, IWRK,
00260      $                   LIWMIN, LWRK, MAXWRK, MINWRK
00261       REAL               ANRM, ANRMTO, BIGNUM, BNRM, BNRMTO, EPS, PL,
00262      $                   PR, SAFMAX, SAFMIN, SMLNUM
00263 *     ..
00264 *     .. Local Arrays ..
00265       REAL               DIF( 2 )
00266 *     ..
00267 *     .. External Subroutines ..
00268       EXTERNAL           SGEQRF, SGGBAK, SGGBAL, SGGHRD, SHGEQZ, SLABAD,
00269      $                   SLACPY, SLASCL, SLASET, SORGQR, SORMQR, STGSEN,
00270      $                   XERBLA
00271 *     ..
00272 *     .. External Functions ..
00273       LOGICAL            LSAME
00274       INTEGER            ILAENV
00275       REAL               SLAMCH, SLANGE
00276       EXTERNAL           LSAME, ILAENV, SLAMCH, SLANGE
00277 *     ..
00278 *     .. Intrinsic Functions ..
00279       INTRINSIC          ABS, MAX, SQRT
00280 *     ..
00281 *     .. Executable Statements ..
00282 *
00283 *     Decode the input arguments
00284 *
00285       IF( LSAME( JOBVSL, 'N' ) ) THEN
00286          IJOBVL = 1
00287          ILVSL = .FALSE.
00288       ELSE IF( LSAME( JOBVSL, 'V' ) ) THEN
00289          IJOBVL = 2
00290          ILVSL = .TRUE.
00291       ELSE
00292          IJOBVL = -1
00293          ILVSL = .FALSE.
00294       END IF
00295 *
00296       IF( LSAME( JOBVSR, 'N' ) ) THEN
00297          IJOBVR = 1
00298          ILVSR = .FALSE.
00299       ELSE IF( LSAME( JOBVSR, 'V' ) ) THEN
00300          IJOBVR = 2
00301          ILVSR = .TRUE.
00302       ELSE
00303          IJOBVR = -1
00304          ILVSR = .FALSE.
00305       END IF
00306 *
00307       WANTST = LSAME( SORT, 'S' )
00308       WANTSN = LSAME( SENSE, 'N' )
00309       WANTSE = LSAME( SENSE, 'E' )
00310       WANTSV = LSAME( SENSE, 'V' )
00311       WANTSB = LSAME( SENSE, 'B' )
00312       LQUERY = ( LWORK.EQ.-1 .OR. LIWORK.EQ.-1 )
00313       IF( WANTSN ) THEN
00314          IJOB = 0
00315       ELSE IF( WANTSE ) THEN
00316          IJOB = 1
00317       ELSE IF( WANTSV ) THEN
00318          IJOB = 2
00319       ELSE IF( WANTSB ) THEN
00320          IJOB = 4
00321       END IF
00322 *
00323 *     Test the input arguments
00324 *
00325       INFO = 0
00326       IF( IJOBVL.LE.0 ) THEN
00327          INFO = -1
00328       ELSE IF( IJOBVR.LE.0 ) THEN
00329          INFO = -2
00330       ELSE IF( ( .NOT.WANTST ) .AND. ( .NOT.LSAME( SORT, 'N' ) ) ) THEN
00331          INFO = -3
00332       ELSE IF( .NOT.( WANTSN .OR. WANTSE .OR. WANTSV .OR. WANTSB ) .OR.
00333      $         ( .NOT.WANTST .AND. .NOT.WANTSN ) ) THEN
00334          INFO = -5
00335       ELSE IF( N.LT.0 ) THEN
00336          INFO = -6
00337       ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
00338          INFO = -8
00339       ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
00340          INFO = -10
00341       ELSE IF( LDVSL.LT.1 .OR. ( ILVSL .AND. LDVSL.LT.N ) ) THEN
00342          INFO = -16
00343       ELSE IF( LDVSR.LT.1 .OR. ( ILVSR .AND. LDVSR.LT.N ) ) THEN
00344          INFO = -18
00345       END IF
00346 *
00347 *     Compute workspace
00348 *      (Note: Comments in the code beginning "Workspace:" describe the
00349 *       minimal amount of workspace needed at that point in the code,
00350 *       as well as the preferred amount for good performance.
00351 *       NB refers to the optimal block size for the immediately
00352 *       following subroutine, as returned by ILAENV.)
00353 *
00354       IF( INFO.EQ.0 ) THEN
00355          IF( N.GT.0) THEN
00356             MINWRK = MAX( 8*N, 6*N + 16 )
00357             MAXWRK = MINWRK - N +
00358      $               N*ILAENV( 1, 'SGEQRF', ' ', N, 1, N, 0 )
00359             MAXWRK = MAX( MAXWRK, MINWRK - N +
00360      $               N*ILAENV( 1, 'SORMQR', ' ', N, 1, N, -1 ) )
00361             IF( ILVSL ) THEN
00362                MAXWRK = MAX( MAXWRK, MINWRK - N +
00363      $                  N*ILAENV( 1, 'SORGQR', ' ', N, 1, N, -1 ) )
00364             END IF
00365             LWRK = MAXWRK
00366             IF( IJOB.GE.1 )
00367      $         LWRK = MAX( LWRK, N*N/2 )
00368          ELSE
00369             MINWRK = 1
00370             MAXWRK = 1
00371             LWRK   = 1
00372          END IF
00373          WORK( 1 ) = LWRK
00374          IF( WANTSN .OR. N.EQ.0 ) THEN
00375             LIWMIN = 1
00376          ELSE
00377             LIWMIN = N + 6
00378          END IF
00379          IWORK( 1 ) = LIWMIN
00380 *
00381          IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY ) THEN
00382             INFO = -22
00383          ELSE IF( LIWORK.LT.LIWMIN  .AND. .NOT.LQUERY ) THEN
00384             INFO = -24
00385          END IF
00386       END IF
00387 *
00388       IF( INFO.NE.0 ) THEN
00389          CALL XERBLA( 'SGGESX', -INFO )
00390          RETURN
00391       ELSE IF (LQUERY) THEN
00392          RETURN
00393       END IF
00394 *
00395 *     Quick return if possible
00396 *
00397       IF( N.EQ.0 ) THEN
00398          SDIM = 0
00399          RETURN
00400       END IF
00401 *
00402 *     Get machine constants
00403 *
00404       EPS = SLAMCH( 'P' )
00405       SAFMIN = SLAMCH( 'S' )
00406       SAFMAX = ONE / SAFMIN
00407       CALL SLABAD( SAFMIN, SAFMAX )
00408       SMLNUM = SQRT( SAFMIN ) / EPS
00409       BIGNUM = ONE / SMLNUM
00410 *
00411 *     Scale A if max element outside range [SMLNUM,BIGNUM]
00412 *
00413       ANRM = SLANGE( 'M', N, N, A, LDA, WORK )
00414       ILASCL = .FALSE.
00415       IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
00416          ANRMTO = SMLNUM
00417          ILASCL = .TRUE.
00418       ELSE IF( ANRM.GT.BIGNUM ) THEN
00419          ANRMTO = BIGNUM
00420          ILASCL = .TRUE.
00421       END IF
00422       IF( ILASCL )
00423      $   CALL SLASCL( 'G', 0, 0, ANRM, ANRMTO, N, N, A, LDA, IERR )
00424 *
00425 *     Scale B if max element outside range [SMLNUM,BIGNUM]
00426 *
00427       BNRM = SLANGE( 'M', N, N, B, LDB, WORK )
00428       ILBSCL = .FALSE.
00429       IF( BNRM.GT.ZERO .AND. BNRM.LT.SMLNUM ) THEN
00430          BNRMTO = SMLNUM
00431          ILBSCL = .TRUE.
00432       ELSE IF( BNRM.GT.BIGNUM ) THEN
00433          BNRMTO = BIGNUM
00434          ILBSCL = .TRUE.
00435       END IF
00436       IF( ILBSCL )
00437      $   CALL SLASCL( 'G', 0, 0, BNRM, BNRMTO, N, N, B, LDB, IERR )
00438 *
00439 *     Permute the matrix to make it more nearly triangular
00440 *     (Workspace: need 6*N + 2*N for permutation parameters)
00441 *
00442       ILEFT = 1
00443       IRIGHT = N + 1
00444       IWRK = IRIGHT + N
00445       CALL SGGBAL( 'P', N, A, LDA, B, LDB, ILO, IHI, WORK( ILEFT ),
00446      $             WORK( IRIGHT ), WORK( IWRK ), IERR )
00447 *
00448 *     Reduce B to triangular form (QR decomposition of B)
00449 *     (Workspace: need N, prefer N*NB)
00450 *
00451       IROWS = IHI + 1 - ILO
00452       ICOLS = N + 1 - ILO
00453       ITAU = IWRK
00454       IWRK = ITAU + IROWS
00455       CALL SGEQRF( IROWS, ICOLS, B( ILO, ILO ), LDB, WORK( ITAU ),
00456      $             WORK( IWRK ), LWORK+1-IWRK, IERR )
00457 *
00458 *     Apply the orthogonal transformation to matrix A
00459 *     (Workspace: need N, prefer N*NB)
00460 *
00461       CALL SORMQR( 'L', 'T', IROWS, ICOLS, IROWS, B( ILO, ILO ), LDB,
00462      $             WORK( ITAU ), A( ILO, ILO ), LDA, WORK( IWRK ),
00463      $             LWORK+1-IWRK, IERR )
00464 *
00465 *     Initialize VSL
00466 *     (Workspace: need N, prefer N*NB)
00467 *
00468       IF( ILVSL ) THEN
00469          CALL SLASET( 'Full', N, N, ZERO, ONE, VSL, LDVSL )
00470          IF( IROWS.GT.1 ) THEN
00471             CALL SLACPY( 'L', IROWS-1, IROWS-1, B( ILO+1, ILO ), LDB,
00472      $                   VSL( ILO+1, ILO ), LDVSL )
00473          END IF
00474          CALL SORGQR( IROWS, IROWS, IROWS, VSL( ILO, ILO ), LDVSL,
00475      $                WORK( ITAU ), WORK( IWRK ), LWORK+1-IWRK, IERR )
00476       END IF
00477 *
00478 *     Initialize VSR
00479 *
00480       IF( ILVSR )
00481      $   CALL SLASET( 'Full', N, N, ZERO, ONE, VSR, LDVSR )
00482 *
00483 *     Reduce to generalized Hessenberg form
00484 *     (Workspace: none needed)
00485 *
00486       CALL SGGHRD( JOBVSL, JOBVSR, N, ILO, IHI, A, LDA, B, LDB, VSL,
00487      $             LDVSL, VSR, LDVSR, IERR )
00488 *
00489       SDIM = 0
00490 *
00491 *     Perform QZ algorithm, computing Schur vectors if desired
00492 *     (Workspace: need N)
00493 *
00494       IWRK = ITAU
00495       CALL SHGEQZ( 'S', JOBVSL, JOBVSR, N, ILO, IHI, A, LDA, B, LDB,
00496      $             ALPHAR, ALPHAI, BETA, VSL, LDVSL, VSR, LDVSR,
00497      $             WORK( IWRK ), LWORK+1-IWRK, IERR )
00498       IF( IERR.NE.0 ) THEN
00499          IF( IERR.GT.0 .AND. IERR.LE.N ) THEN
00500             INFO = IERR
00501          ELSE IF( IERR.GT.N .AND. IERR.LE.2*N ) THEN
00502             INFO = IERR - N
00503          ELSE
00504             INFO = N + 1
00505          END IF
00506          GO TO 50
00507       END IF
00508 *
00509 *     Sort eigenvalues ALPHA/BETA and compute the reciprocal of
00510 *     condition number(s)
00511 *     (Workspace: If IJOB >= 1, need MAX( 8*(N+1), 2*SDIM*(N-SDIM) )
00512 *                 otherwise, need 8*(N+1) )
00513 *
00514       IF( WANTST ) THEN
00515 *
00516 *        Undo scaling on eigenvalues before SELCTGing
00517 *
00518          IF( ILASCL ) THEN
00519             CALL SLASCL( 'G', 0, 0, ANRMTO, ANRM, N, 1, ALPHAR, N,
00520      $                   IERR )
00521             CALL SLASCL( 'G', 0, 0, ANRMTO, ANRM, N, 1, ALPHAI, N,
00522      $                   IERR )
00523          END IF
00524          IF( ILBSCL )
00525      $      CALL SLASCL( 'G', 0, 0, BNRMTO, BNRM, N, 1, BETA, N, IERR )
00526 *
00527 *        Select eigenvalues
00528 *
00529          DO 10 I = 1, N
00530             BWORK( I ) = SELCTG( ALPHAR( I ), ALPHAI( I ), BETA( I ) )
00531    10    CONTINUE
00532 *
00533 *        Reorder eigenvalues, transform Generalized Schur vectors, and
00534 *        compute reciprocal condition numbers
00535 *
00536          CALL STGSEN( IJOB, ILVSL, ILVSR, BWORK, N, A, LDA, B, LDB,
00537      $                ALPHAR, ALPHAI, BETA, VSL, LDVSL, VSR, LDVSR,
00538      $                SDIM, PL, PR, DIF, WORK( IWRK ), LWORK-IWRK+1,
00539      $                IWORK, LIWORK, IERR )
00540 *
00541          IF( IJOB.GE.1 )
00542      $      MAXWRK = MAX( MAXWRK, 2*SDIM*( N-SDIM ) )
00543          IF( IERR.EQ.-22 ) THEN
00544 *
00545 *            not enough real workspace
00546 *
00547             INFO = -22
00548          ELSE
00549             IF( IJOB.EQ.1 .OR. IJOB.EQ.4 ) THEN
00550                RCONDE( 1 ) = PL
00551                RCONDE( 2 ) = PR
00552             END IF
00553             IF( IJOB.EQ.2 .OR. IJOB.EQ.4 ) THEN
00554                RCONDV( 1 ) = DIF( 1 )
00555                RCONDV( 2 ) = DIF( 2 )
00556             END IF
00557             IF( IERR.EQ.1 )
00558      $         INFO = N + 3
00559          END IF
00560 *
00561       END IF
00562 *
00563 *     Apply permutation to VSL and VSR
00564 *     (Workspace: none needed)
00565 *
00566       IF( ILVSL )
00567      $   CALL SGGBAK( 'P', 'L', N, ILO, IHI, WORK( ILEFT ),
00568      $                WORK( IRIGHT ), N, VSL, LDVSL, IERR )
00569 *
00570       IF( ILVSR )
00571      $   CALL SGGBAK( 'P', 'R', N, ILO, IHI, WORK( ILEFT ),
00572      $                WORK( IRIGHT ), N, VSR, LDVSR, IERR )
00573 *
00574 *     Check if unscaling would cause over/underflow, if so, rescale
00575 *     (ALPHAR(I),ALPHAI(I),BETA(I)) so BETA(I) is on the order of
00576 *     B(I,I) and ALPHAR(I) and ALPHAI(I) are on the order of A(I,I)
00577 *
00578       IF( ILASCL ) THEN  
00579          DO 20 I = 1, N  
00580             IF( ALPHAI( I ).NE.ZERO ) THEN
00581                IF( ( ALPHAR( I ) / SAFMAX ).GT.( ANRMTO / ANRM ) .OR.
00582      $             ( SAFMIN / ALPHAR( I ) ).GT.( ANRM / ANRMTO ) )        
00583      $            THEN
00584                   WORK( 1 ) = ABS( A( I, I ) / ALPHAR( I ) )
00585                   BETA( I ) = BETA( I )*WORK( 1 )
00586                   ALPHAR( I ) = ALPHAR( I )*WORK( 1 )
00587                   ALPHAI( I ) = ALPHAI( I )*WORK( 1 )
00588                ELSE IF( ( ALPHAI( I ) / SAFMAX ).GT.( ANRMTO / ANRM ) 
00589      $            .OR. ( SAFMIN / ALPHAI( I ) ).GT.( ANRM / ANRMTO ) )
00590      $            THEN
00591                   WORK( 1 ) = ABS( A( I, I+1 ) / ALPHAI( I ) )
00592                   BETA( I ) = BETA( I )*WORK( 1 )
00593                   ALPHAR( I ) = ALPHAR( I )*WORK( 1 )
00594                   ALPHAI( I ) = ALPHAI( I )*WORK( 1 )
00595                END IF
00596             END IF
00597    20    CONTINUE
00598       END IF 
00599 *
00600       IF( ILBSCL ) THEN 
00601          DO 25 I = 1, N
00602             IF( ALPHAI( I ).NE.ZERO ) THEN
00603                IF( ( BETA( I ) / SAFMAX ).GT.( BNRMTO / BNRM ) .OR.
00604      $             ( SAFMIN / BETA( I ) ).GT.( BNRM / BNRMTO ) ) THEN
00605                   WORK( 1 ) = ABS( B( I, I ) / BETA( I ) )
00606                   BETA( I ) = BETA( I )*WORK( 1 )
00607                   ALPHAR( I ) = ALPHAR( I )*WORK( 1 )
00608                   ALPHAI( I ) = ALPHAI( I )*WORK( 1 )
00609                END IF 
00610             END IF 
00611    25    CONTINUE
00612       END IF 
00613 *
00614 *     Undo scaling
00615 *
00616       IF( ILASCL ) THEN
00617          CALL SLASCL( 'H', 0, 0, ANRMTO, ANRM, N, N, A, LDA, IERR )
00618          CALL SLASCL( 'G', 0, 0, ANRMTO, ANRM, N, 1, ALPHAR, N, IERR )
00619          CALL SLASCL( 'G', 0, 0, ANRMTO, ANRM, N, 1, ALPHAI, N, IERR )
00620       END IF
00621 *
00622       IF( ILBSCL ) THEN
00623          CALL SLASCL( 'U', 0, 0, BNRMTO, BNRM, N, N, B, LDB, IERR )
00624          CALL SLASCL( 'G', 0, 0, BNRMTO, BNRM, N, 1, BETA, N, IERR )
00625       END IF
00626 *
00627       IF( WANTST ) THEN
00628 *
00629 *        Check if reordering is correct
00630 *
00631          LASTSL = .TRUE.
00632          LST2SL = .TRUE.
00633          SDIM = 0
00634          IP = 0
00635          DO 40 I = 1, N
00636             CURSL = SELCTG( ALPHAR( I ), ALPHAI( I ), BETA( I ) )
00637             IF( ALPHAI( I ).EQ.ZERO ) THEN
00638                IF( CURSL )
00639      $            SDIM = SDIM + 1
00640                IP = 0
00641                IF( CURSL .AND. .NOT.LASTSL )
00642      $            INFO = N + 2
00643             ELSE
00644                IF( IP.EQ.1 ) THEN
00645 *
00646 *                 Last eigenvalue of conjugate pair
00647 *
00648                   CURSL = CURSL .OR. LASTSL
00649                   LASTSL = CURSL
00650                   IF( CURSL )
00651      $               SDIM = SDIM + 2
00652                   IP = -1
00653                   IF( CURSL .AND. .NOT.LST2SL )
00654      $               INFO = N + 2
00655                ELSE
00656 *
00657 *                 First eigenvalue of conjugate pair
00658 *
00659                   IP = 1
00660                END IF
00661             END IF
00662             LST2SL = LASTSL
00663             LASTSL = CURSL
00664    40    CONTINUE
00665 *
00666       END IF
00667 *
00668    50 CONTINUE
00669 *
00670       WORK( 1 ) = MAXWRK
00671       IWORK( 1 ) = LIWMIN
00672 *
00673       RETURN
00674 *
00675 *     End of SGGESX
00676 *
00677       END
 All Files Functions