1*> \brief <b> SGGESX computes the eigenvalues, the Schur form, and, optionally, the matrix of Schur vectors for GE matrices</b> 2* 3* =========== DOCUMENTATION =========== 4* 5* Online html documentation available at 6* http://www.netlib.org/lapack/explore-html/ 7* 8*> \htmlonly 9*> Download SGGESX + dependencies 10*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/sggesx.f"> 11*> [TGZ]</a> 12*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/sggesx.f"> 13*> [ZIP]</a> 14*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/sggesx.f"> 15*> [TXT]</a> 16*> \endhtmlonly 17* 18* Definition: 19* =========== 20* 21* SUBROUTINE SGGESX( JOBVSL, JOBVSR, SORT, SELCTG, SENSE, N, A, LDA, 22* B, LDB, SDIM, ALPHAR, ALPHAI, BETA, VSL, LDVSL, 23* VSR, LDVSR, RCONDE, RCONDV, WORK, LWORK, IWORK, 24* LIWORK, BWORK, INFO ) 25* 26* .. Scalar Arguments .. 27* CHARACTER JOBVSL, JOBVSR, SENSE, SORT 28* INTEGER INFO, LDA, LDB, LDVSL, LDVSR, LIWORK, LWORK, N, 29* $ SDIM 30* .. 31* .. Array Arguments .. 32* LOGICAL BWORK( * ) 33* INTEGER IWORK( * ) 34* REAL A( LDA, * ), ALPHAI( * ), ALPHAR( * ), 35* $ B( LDB, * ), BETA( * ), RCONDE( 2 ), 36* $ RCONDV( 2 ), VSL( LDVSL, * ), VSR( LDVSR, * ), 37* $ WORK( * ) 38* .. 39* .. Function Arguments .. 40* LOGICAL SELCTG 41* EXTERNAL SELCTG 42* .. 43* 44* 45*> \par Purpose: 46* ============= 47*> 48*> \verbatim 49*> 50*> SGGESX computes for a pair of N-by-N real nonsymmetric matrices 51*> (A,B), the generalized eigenvalues, the real Schur form (S,T), and, 52*> optionally, the left and/or right matrices of Schur vectors (VSL and 53*> VSR). This gives the generalized Schur factorization 54*> 55*> (A,B) = ( (VSL) S (VSR)**T, (VSL) T (VSR)**T ) 56*> 57*> Optionally, it also orders the eigenvalues so that a selected cluster 58*> of eigenvalues appears in the leading diagonal blocks of the upper 59*> quasi-triangular matrix S and the upper triangular matrix T; computes 60*> a reciprocal condition number for the average of the selected 61*> eigenvalues (RCONDE); and computes a reciprocal condition number for 62*> the right and left deflating subspaces corresponding to the selected 63*> eigenvalues (RCONDV). The leading columns of VSL and VSR then form 64*> an orthonormal basis for the corresponding left and right eigenspaces 65*> (deflating subspaces). 66*> 67*> A generalized eigenvalue for a pair of matrices (A,B) is a scalar w 68*> or a ratio alpha/beta = w, such that A - w*B is singular. It is 69*> usually represented as the pair (alpha,beta), as there is a 70*> reasonable interpretation for beta=0 or for both being zero. 71*> 72*> A pair of matrices (S,T) is in generalized real Schur form if T is 73*> upper triangular with non-negative diagonal and S is block upper 74*> triangular with 1-by-1 and 2-by-2 blocks. 1-by-1 blocks correspond 75*> to real generalized eigenvalues, while 2-by-2 blocks of S will be 76*> "standardized" by making the corresponding elements of T have the 77*> form: 78*> [ a 0 ] 79*> [ 0 b ] 80*> 81*> and the pair of corresponding 2-by-2 blocks in S and T will have a 82*> complex conjugate pair of generalized eigenvalues. 83*> 84*> \endverbatim 85* 86* Arguments: 87* ========== 88* 89*> \param[in] JOBVSL 90*> \verbatim 91*> JOBVSL is CHARACTER*1 92*> = 'N': do not compute the left Schur vectors; 93*> = 'V': compute the left Schur vectors. 94*> \endverbatim 95*> 96*> \param[in] JOBVSR 97*> \verbatim 98*> JOBVSR is CHARACTER*1 99*> = 'N': do not compute the right Schur vectors; 100*> = 'V': compute the right Schur vectors. 101*> \endverbatim 102*> 103*> \param[in] SORT 104*> \verbatim 105*> SORT is CHARACTER*1 106*> Specifies whether or not to order the eigenvalues on the 107*> diagonal of the generalized Schur form. 108*> = 'N': Eigenvalues are not ordered; 109*> = 'S': Eigenvalues are ordered (see SELCTG). 110*> \endverbatim 111*> 112*> \param[in] SELCTG 113*> \verbatim 114*> SELCTG is procedure) LOGICAL FUNCTION of three REAL arguments 115*> SELCTG must be declared EXTERNAL in the calling subroutine. 116*> If SORT = 'N', SELCTG is not referenced. 117*> If SORT = 'S', SELCTG is used to select eigenvalues to sort 118*> to the top left of the Schur form. 119*> An eigenvalue (ALPHAR(j)+ALPHAI(j))/BETA(j) is selected if 120*> SELCTG(ALPHAR(j),ALPHAI(j),BETA(j)) is true; i.e. if either 121*> one of a complex conjugate pair of eigenvalues is selected, 122*> then both complex eigenvalues are selected. 123*> Note that a selected complex eigenvalue may no longer satisfy 124*> SELCTG(ALPHAR(j),ALPHAI(j),BETA(j)) = .TRUE. after ordering, 125*> since ordering may change the value of complex eigenvalues 126*> (especially if the eigenvalue is ill-conditioned), in this 127*> case INFO is set to N+3. 128*> \endverbatim 129*> 130*> \param[in] SENSE 131*> \verbatim 132*> SENSE is CHARACTER*1 133*> Determines which reciprocal condition numbers are computed. 134*> = 'N' : None are computed; 135*> = 'E' : Computed for average of selected eigenvalues only; 136*> = 'V' : Computed for selected deflating subspaces only; 137*> = 'B' : Computed for both. 138*> If SENSE = 'E', 'V', or 'B', SORT must equal 'S'. 139*> \endverbatim 140*> 141*> \param[in] N 142*> \verbatim 143*> N is INTEGER 144*> The order of the matrices A, B, VSL, and VSR. N >= 0. 145*> \endverbatim 146*> 147*> \param[in,out] A 148*> \verbatim 149*> A is REAL array, dimension (LDA, N) 150*> On entry, the first of the pair of matrices. 151*> On exit, A has been overwritten by its generalized Schur 152*> form S. 153*> \endverbatim 154*> 155*> \param[in] LDA 156*> \verbatim 157*> LDA is INTEGER 158*> The leading dimension of A. LDA >= max(1,N). 159*> \endverbatim 160*> 161*> \param[in,out] B 162*> \verbatim 163*> B is REAL array, dimension (LDB, N) 164*> On entry, the second of the pair of matrices. 165*> On exit, B has been overwritten by its generalized Schur 166*> form T. 167*> \endverbatim 168*> 169*> \param[in] LDB 170*> \verbatim 171*> LDB is INTEGER 172*> The leading dimension of B. LDB >= max(1,N). 173*> \endverbatim 174*> 175*> \param[out] SDIM 176*> \verbatim 177*> SDIM is INTEGER 178*> If SORT = 'N', SDIM = 0. 179*> If SORT = 'S', SDIM = number of eigenvalues (after sorting) 180*> for which SELCTG is true. (Complex conjugate pairs for which 181*> SELCTG is true for either eigenvalue count as 2.) 182*> \endverbatim 183*> 184*> \param[out] ALPHAR 185*> \verbatim 186*> ALPHAR is REAL array, dimension (N) 187*> \endverbatim 188*> 189*> \param[out] ALPHAI 190*> \verbatim 191*> ALPHAI is REAL array, dimension (N) 192*> \endverbatim 193*> 194*> \param[out] BETA 195*> \verbatim 196*> BETA is REAL array, dimension (N) 197*> On exit, (ALPHAR(j) + ALPHAI(j)*i)/BETA(j), j=1,...,N, will 198*> be the generalized eigenvalues. ALPHAR(j) + ALPHAI(j)*i 199*> and BETA(j),j=1,...,N are the diagonals of the complex Schur 200*> form (S,T) that would result if the 2-by-2 diagonal blocks of 201*> the real Schur form of (A,B) were further reduced to 202*> triangular form using 2-by-2 complex unitary transformations. 203*> If ALPHAI(j) is zero, then the j-th eigenvalue is real; if 204*> positive, then the j-th and (j+1)-st eigenvalues are a 205*> complex conjugate pair, with ALPHAI(j+1) negative. 206*> 207*> Note: the quotients ALPHAR(j)/BETA(j) and ALPHAI(j)/BETA(j) 208*> may easily over- or underflow, and BETA(j) may even be zero. 209*> Thus, the user should avoid naively computing the ratio. 210*> However, ALPHAR and ALPHAI will be always less than and 211*> usually comparable with norm(A) in magnitude, and BETA always 212*> less than and usually comparable with norm(B). 213*> \endverbatim 214*> 215*> \param[out] VSL 216*> \verbatim 217*> VSL is REAL array, dimension (LDVSL,N) 218*> If JOBVSL = 'V', VSL will contain the left Schur vectors. 219*> Not referenced if JOBVSL = 'N'. 220*> \endverbatim 221*> 222*> \param[in] LDVSL 223*> \verbatim 224*> LDVSL is INTEGER 225*> The leading dimension of the matrix VSL. LDVSL >=1, and 226*> if JOBVSL = 'V', LDVSL >= N. 227*> \endverbatim 228*> 229*> \param[out] VSR 230*> \verbatim 231*> VSR is REAL array, dimension (LDVSR,N) 232*> If JOBVSR = 'V', VSR will contain the right Schur vectors. 233*> Not referenced if JOBVSR = 'N'. 234*> \endverbatim 235*> 236*> \param[in] LDVSR 237*> \verbatim 238*> LDVSR is INTEGER 239*> The leading dimension of the matrix VSR. LDVSR >= 1, and 240*> if JOBVSR = 'V', LDVSR >= N. 241*> \endverbatim 242*> 243*> \param[out] RCONDE 244*> \verbatim 245*> RCONDE is REAL array, dimension ( 2 ) 246*> If SENSE = 'E' or 'B', RCONDE(1) and RCONDE(2) contain the 247*> reciprocal condition numbers for the average of the selected 248*> eigenvalues. 249*> Not referenced if SENSE = 'N' or 'V'. 250*> \endverbatim 251*> 252*> \param[out] RCONDV 253*> \verbatim 254*> RCONDV is REAL array, dimension ( 2 ) 255*> If SENSE = 'V' or 'B', RCONDV(1) and RCONDV(2) contain the 256*> reciprocal condition numbers for the selected deflating 257*> subspaces. 258*> Not referenced if SENSE = 'N' or 'E'. 259*> \endverbatim 260*> 261*> \param[out] WORK 262*> \verbatim 263*> WORK is REAL array, dimension (MAX(1,LWORK)) 264*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK. 265*> \endverbatim 266*> 267*> \param[in] LWORK 268*> \verbatim 269*> LWORK is INTEGER 270*> The dimension of the array WORK. 271*> If N = 0, LWORK >= 1, else if SENSE = 'E', 'V', or 'B', 272*> LWORK >= max( 8*N, 6*N+16, 2*SDIM*(N-SDIM) ), else 273*> LWORK >= max( 8*N, 6*N+16 ). 274*> Note that 2*SDIM*(N-SDIM) <= N*N/2. 275*> Note also that an error is only returned if 276*> LWORK < max( 8*N, 6*N+16), but if SENSE = 'E' or 'V' or 'B' 277*> this may not be large enough. 278*> 279*> If LWORK = -1, then a workspace query is assumed; the routine 280*> only calculates the bound on the optimal size of the WORK 281*> array and the minimum size of the IWORK array, returns these 282*> values as the first entries of the WORK and IWORK arrays, and 283*> no error message related to LWORK or LIWORK is issued by 284*> XERBLA. 285*> \endverbatim 286*> 287*> \param[out] IWORK 288*> \verbatim 289*> IWORK is INTEGER array, dimension (MAX(1,LIWORK)) 290*> On exit, if INFO = 0, IWORK(1) returns the minimum LIWORK. 291*> \endverbatim 292*> 293*> \param[in] LIWORK 294*> \verbatim 295*> LIWORK is INTEGER 296*> The dimension of the array IWORK. 297*> If SENSE = 'N' or N = 0, LIWORK >= 1, otherwise 298*> LIWORK >= N+6. 299*> 300*> If LIWORK = -1, then a workspace query is assumed; the 301*> routine only calculates the bound on the optimal size of the 302*> WORK array and the minimum size of the IWORK array, returns 303*> these values as the first entries of the WORK and IWORK 304*> arrays, and no error message related to LWORK or LIWORK is 305*> issued by XERBLA. 306*> \endverbatim 307*> 308*> \param[out] BWORK 309*> \verbatim 310*> BWORK is LOGICAL array, dimension (N) 311*> Not referenced if SORT = 'N'. 312*> \endverbatim 313*> 314*> \param[out] INFO 315*> \verbatim 316*> INFO is INTEGER 317*> = 0: successful exit 318*> < 0: if INFO = -i, the i-th argument had an illegal value. 319*> = 1,...,N: 320*> The QZ iteration failed. (A,B) are not in Schur 321*> form, but ALPHAR(j), ALPHAI(j), and BETA(j) should 322*> be correct for j=INFO+1,...,N. 323*> > N: =N+1: other than QZ iteration failed in SHGEQZ 324*> =N+2: after reordering, roundoff changed values of 325*> some complex eigenvalues so that leading 326*> eigenvalues in the Generalized Schur form no 327*> longer satisfy SELCTG=.TRUE. This could also 328*> be caused due to scaling. 329*> =N+3: reordering failed in STGSEN. 330*> \endverbatim 331* 332* Authors: 333* ======== 334* 335*> \author Univ. of Tennessee 336*> \author Univ. of California Berkeley 337*> \author Univ. of Colorado Denver 338*> \author NAG Ltd. 339* 340*> \date November 2011 341* 342*> \ingroup realGEeigen 343* 344*> \par Further Details: 345* ===================== 346*> 347*> \verbatim 348*> 349*> An approximate (asymptotic) bound on the average absolute error of 350*> the selected eigenvalues is 351*> 352*> EPS * norm((A, B)) / RCONDE( 1 ). 353*> 354*> An approximate (asymptotic) bound on the maximum angular error in 355*> the computed deflating subspaces is 356*> 357*> EPS * norm((A, B)) / RCONDV( 2 ). 358*> 359*> See LAPACK User's Guide, section 4.11 for more information. 360*> \endverbatim 361*> 362* ===================================================================== 363 SUBROUTINE SGGESX( JOBVSL, JOBVSR, SORT, SELCTG, SENSE, N, A, LDA, 364 $ B, LDB, SDIM, ALPHAR, ALPHAI, BETA, VSL, LDVSL, 365 $ VSR, LDVSR, RCONDE, RCONDV, WORK, LWORK, IWORK, 366 $ LIWORK, BWORK, INFO ) 367* 368* -- LAPACK driver routine (version 3.4.0) -- 369* -- LAPACK is a software package provided by Univ. of Tennessee, -- 370* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- 371* November 2011 372* 373* .. Scalar Arguments .. 374 CHARACTER JOBVSL, JOBVSR, SENSE, SORT 375 INTEGER INFO, LDA, LDB, LDVSL, LDVSR, LIWORK, LWORK, N, 376 $ SDIM 377* .. 378* .. Array Arguments .. 379 LOGICAL BWORK( * ) 380 INTEGER IWORK( * ) 381 REAL A( LDA, * ), ALPHAI( * ), ALPHAR( * ), 382 $ B( LDB, * ), BETA( * ), RCONDE( 2 ), 383 $ RCONDV( 2 ), VSL( LDVSL, * ), VSR( LDVSR, * ), 384 $ WORK( * ) 385* .. 386* .. Function Arguments .. 387 LOGICAL SELCTG 388 EXTERNAL SELCTG 389* .. 390* 391* ===================================================================== 392* 393* .. Parameters .. 394 REAL ZERO, ONE 395 PARAMETER ( ZERO = 0.0E+0, ONE = 1.0E+0 ) 396* .. 397* .. Local Scalars .. 398 LOGICAL CURSL, ILASCL, ILBSCL, ILVSL, ILVSR, LASTSL, 399 $ LQUERY, LST2SL, WANTSB, WANTSE, WANTSN, WANTST, 400 $ WANTSV 401 INTEGER I, ICOLS, IERR, IHI, IJOB, IJOBVL, IJOBVR, 402 $ ILEFT, ILO, IP, IRIGHT, IROWS, ITAU, IWRK, 403 $ LIWMIN, LWRK, MAXWRK, MINWRK 404 REAL ANRM, ANRMTO, BIGNUM, BNRM, BNRMTO, EPS, PL, 405 $ PR, SAFMAX, SAFMIN, SMLNUM 406* .. 407* .. Local Arrays .. 408 REAL DIF( 2 ) 409* .. 410* .. External Subroutines .. 411 EXTERNAL SGEQRF, SGGBAK, SGGBAL, SGGHRD, SHGEQZ, SLABAD, 412 $ SLACPY, SLASCL, SLASET, SORGQR, SORMQR, STGSEN, 413 $ XERBLA 414* .. 415* .. External Functions .. 416 LOGICAL LSAME 417 INTEGER ILAENV 418 REAL SLAMCH, SLANGE 419 EXTERNAL LSAME, ILAENV, SLAMCH, SLANGE 420* .. 421* .. Intrinsic Functions .. 422 INTRINSIC ABS, MAX, SQRT 423* .. 424* .. Executable Statements .. 425* 426* Decode the input arguments 427* 428 IF( LSAME( JOBVSL, 'N' ) ) THEN 429 IJOBVL = 1 430 ILVSL = .FALSE. 431 ELSE IF( LSAME( JOBVSL, 'V' ) ) THEN 432 IJOBVL = 2 433 ILVSL = .TRUE. 434 ELSE 435 IJOBVL = -1 436 ILVSL = .FALSE. 437 END IF 438* 439 IF( LSAME( JOBVSR, 'N' ) ) THEN 440 IJOBVR = 1 441 ILVSR = .FALSE. 442 ELSE IF( LSAME( JOBVSR, 'V' ) ) THEN 443 IJOBVR = 2 444 ILVSR = .TRUE. 445 ELSE 446 IJOBVR = -1 447 ILVSR = .FALSE. 448 END IF 449* 450 WANTST = LSAME( SORT, 'S' ) 451 WANTSN = LSAME( SENSE, 'N' ) 452 WANTSE = LSAME( SENSE, 'E' ) 453 WANTSV = LSAME( SENSE, 'V' ) 454 WANTSB = LSAME( SENSE, 'B' ) 455 LQUERY = ( LWORK.EQ.-1 .OR. LIWORK.EQ.-1 ) 456 IF( WANTSN ) THEN 457 IJOB = 0 458 ELSE IF( WANTSE ) THEN 459 IJOB = 1 460 ELSE IF( WANTSV ) THEN 461 IJOB = 2 462 ELSE IF( WANTSB ) THEN 463 IJOB = 4 464 END IF 465* 466* Test the input arguments 467* 468 INFO = 0 469 IF( IJOBVL.LE.0 ) THEN 470 INFO = -1 471 ELSE IF( IJOBVR.LE.0 ) THEN 472 INFO = -2 473 ELSE IF( ( .NOT.WANTST ) .AND. ( .NOT.LSAME( SORT, 'N' ) ) ) THEN 474 INFO = -3 475 ELSE IF( .NOT.( WANTSN .OR. WANTSE .OR. WANTSV .OR. WANTSB ) .OR. 476 $ ( .NOT.WANTST .AND. .NOT.WANTSN ) ) THEN 477 INFO = -5 478 ELSE IF( N.LT.0 ) THEN 479 INFO = -6 480 ELSE IF( LDA.LT.MAX( 1, N ) ) THEN 481 INFO = -8 482 ELSE IF( LDB.LT.MAX( 1, N ) ) THEN 483 INFO = -10 484 ELSE IF( LDVSL.LT.1 .OR. ( ILVSL .AND. LDVSL.LT.N ) ) THEN 485 INFO = -16 486 ELSE IF( LDVSR.LT.1 .OR. ( ILVSR .AND. LDVSR.LT.N ) ) THEN 487 INFO = -18 488 END IF 489* 490* Compute workspace 491* (Note: Comments in the code beginning "Workspace:" describe the 492* minimal amount of workspace needed at that point in the code, 493* as well as the preferred amount for good performance. 494* NB refers to the optimal block size for the immediately 495* following subroutine, as returned by ILAENV.) 496* 497 IF( INFO.EQ.0 ) THEN 498 IF( N.GT.0) THEN 499 MINWRK = MAX( 8*N, 6*N + 16 ) 500 MAXWRK = MINWRK - N + 501 $ N*ILAENV( 1, 'SGEQRF', ' ', N, 1, N, 0 ) 502 MAXWRK = MAX( MAXWRK, MINWRK - N + 503 $ N*ILAENV( 1, 'SORMQR', ' ', N, 1, N, -1 ) ) 504 IF( ILVSL ) THEN 505 MAXWRK = MAX( MAXWRK, MINWRK - N + 506 $ N*ILAENV( 1, 'SORGQR', ' ', N, 1, N, -1 ) ) 507 END IF 508 LWRK = MAXWRK 509 IF( IJOB.GE.1 ) 510 $ LWRK = MAX( LWRK, N*N/2 ) 511 ELSE 512 MINWRK = 1 513 MAXWRK = 1 514 LWRK = 1 515 END IF 516 WORK( 1 ) = LWRK 517 IF( WANTSN .OR. N.EQ.0 ) THEN 518 LIWMIN = 1 519 ELSE 520 LIWMIN = N + 6 521 END IF 522 IWORK( 1 ) = LIWMIN 523* 524 IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY ) THEN 525 INFO = -22 526 ELSE IF( LIWORK.LT.LIWMIN .AND. .NOT.LQUERY ) THEN 527 INFO = -24 528 END IF 529 END IF 530* 531 IF( INFO.NE.0 ) THEN 532 CALL XERBLA( 'SGGESX', -INFO ) 533 RETURN 534 ELSE IF (LQUERY) THEN 535 RETURN 536 END IF 537* 538* Quick return if possible 539* 540 IF( N.EQ.0 ) THEN 541 SDIM = 0 542 RETURN 543 END IF 544* 545* Get machine constants 546* 547 EPS = SLAMCH( 'P' ) 548 SAFMIN = SLAMCH( 'S' ) 549 SAFMAX = ONE / SAFMIN 550 CALL SLABAD( SAFMIN, SAFMAX ) 551 SMLNUM = SQRT( SAFMIN ) / EPS 552 BIGNUM = ONE / SMLNUM 553* 554* Scale A if max element outside range [SMLNUM,BIGNUM] 555* 556 ANRM = SLANGE( 'M', N, N, A, LDA, WORK ) 557 ILASCL = .FALSE. 558 IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN 559 ANRMTO = SMLNUM 560 ILASCL = .TRUE. 561 ELSE IF( ANRM.GT.BIGNUM ) THEN 562 ANRMTO = BIGNUM 563 ILASCL = .TRUE. 564 END IF 565 IF( ILASCL ) 566 $ CALL SLASCL( 'G', 0, 0, ANRM, ANRMTO, N, N, A, LDA, IERR ) 567* 568* Scale B if max element outside range [SMLNUM,BIGNUM] 569* 570 BNRM = SLANGE( 'M', N, N, B, LDB, WORK ) 571 ILBSCL = .FALSE. 572 IF( BNRM.GT.ZERO .AND. BNRM.LT.SMLNUM ) THEN 573 BNRMTO = SMLNUM 574 ILBSCL = .TRUE. 575 ELSE IF( BNRM.GT.BIGNUM ) THEN 576 BNRMTO = BIGNUM 577 ILBSCL = .TRUE. 578 END IF 579 IF( ILBSCL ) 580 $ CALL SLASCL( 'G', 0, 0, BNRM, BNRMTO, N, N, B, LDB, IERR ) 581* 582* Permute the matrix to make it more nearly triangular 583* (Workspace: need 6*N + 2*N for permutation parameters) 584* 585 ILEFT = 1 586 IRIGHT = N + 1 587 IWRK = IRIGHT + N 588 CALL SGGBAL( 'P', N, A, LDA, B, LDB, ILO, IHI, WORK( ILEFT ), 589 $ WORK( IRIGHT ), WORK( IWRK ), IERR ) 590* 591* Reduce B to triangular form (QR decomposition of B) 592* (Workspace: need N, prefer N*NB) 593* 594 IROWS = IHI + 1 - ILO 595 ICOLS = N + 1 - ILO 596 ITAU = IWRK 597 IWRK = ITAU + IROWS 598 CALL SGEQRF( IROWS, ICOLS, B( ILO, ILO ), LDB, WORK( ITAU ), 599 $ WORK( IWRK ), LWORK+1-IWRK, IERR ) 600* 601* Apply the orthogonal transformation to matrix A 602* (Workspace: need N, prefer N*NB) 603* 604 CALL SORMQR( 'L', 'T', IROWS, ICOLS, IROWS, B( ILO, ILO ), LDB, 605 $ WORK( ITAU ), A( ILO, ILO ), LDA, WORK( IWRK ), 606 $ LWORK+1-IWRK, IERR ) 607* 608* Initialize VSL 609* (Workspace: need N, prefer N*NB) 610* 611 IF( ILVSL ) THEN 612 CALL SLASET( 'Full', N, N, ZERO, ONE, VSL, LDVSL ) 613 IF( IROWS.GT.1 ) THEN 614 CALL SLACPY( 'L', IROWS-1, IROWS-1, B( ILO+1, ILO ), LDB, 615 $ VSL( ILO+1, ILO ), LDVSL ) 616 END IF 617 CALL SORGQR( IROWS, IROWS, IROWS, VSL( ILO, ILO ), LDVSL, 618 $ WORK( ITAU ), WORK( IWRK ), LWORK+1-IWRK, IERR ) 619 END IF 620* 621* Initialize VSR 622* 623 IF( ILVSR ) 624 $ CALL SLASET( 'Full', N, N, ZERO, ONE, VSR, LDVSR ) 625* 626* Reduce to generalized Hessenberg form 627* (Workspace: none needed) 628* 629 CALL SGGHRD( JOBVSL, JOBVSR, N, ILO, IHI, A, LDA, B, LDB, VSL, 630 $ LDVSL, VSR, LDVSR, IERR ) 631* 632 SDIM = 0 633* 634* Perform QZ algorithm, computing Schur vectors if desired 635* (Workspace: need N) 636* 637 IWRK = ITAU 638 CALL SHGEQZ( 'S', JOBVSL, JOBVSR, N, ILO, IHI, A, LDA, B, LDB, 639 $ ALPHAR, ALPHAI, BETA, VSL, LDVSL, VSR, LDVSR, 640 $ WORK( IWRK ), LWORK+1-IWRK, IERR ) 641 IF( IERR.NE.0 ) THEN 642 IF( IERR.GT.0 .AND. IERR.LE.N ) THEN 643 INFO = IERR 644 ELSE IF( IERR.GT.N .AND. IERR.LE.2*N ) THEN 645 INFO = IERR - N 646 ELSE 647 INFO = N + 1 648 END IF 649 GO TO 50 650 END IF 651* 652* Sort eigenvalues ALPHA/BETA and compute the reciprocal of 653* condition number(s) 654* (Workspace: If IJOB >= 1, need MAX( 8*(N+1), 2*SDIM*(N-SDIM) ) 655* otherwise, need 8*(N+1) ) 656* 657 IF( WANTST ) THEN 658* 659* Undo scaling on eigenvalues before SELCTGing 660* 661 IF( ILASCL ) THEN 662 CALL SLASCL( 'G', 0, 0, ANRMTO, ANRM, N, 1, ALPHAR, N, 663 $ IERR ) 664 CALL SLASCL( 'G', 0, 0, ANRMTO, ANRM, N, 1, ALPHAI, N, 665 $ IERR ) 666 END IF 667 IF( ILBSCL ) 668 $ CALL SLASCL( 'G', 0, 0, BNRMTO, BNRM, N, 1, BETA, N, IERR ) 669* 670* Select eigenvalues 671* 672 DO 10 I = 1, N 673 BWORK( I ) = SELCTG( ALPHAR( I ), ALPHAI( I ), BETA( I ) ) 674 10 CONTINUE 675* 676* Reorder eigenvalues, transform Generalized Schur vectors, and 677* compute reciprocal condition numbers 678* 679 CALL STGSEN( IJOB, ILVSL, ILVSR, BWORK, N, A, LDA, B, LDB, 680 $ ALPHAR, ALPHAI, BETA, VSL, LDVSL, VSR, LDVSR, 681 $ SDIM, PL, PR, DIF, WORK( IWRK ), LWORK-IWRK+1, 682 $ IWORK, LIWORK, IERR ) 683* 684 IF( IJOB.GE.1 ) 685 $ MAXWRK = MAX( MAXWRK, 2*SDIM*( N-SDIM ) ) 686 IF( IERR.EQ.-22 ) THEN 687* 688* not enough real workspace 689* 690 INFO = -22 691 ELSE 692 IF( IJOB.EQ.1 .OR. IJOB.EQ.4 ) THEN 693 RCONDE( 1 ) = PL 694 RCONDE( 2 ) = PR 695 END IF 696 IF( IJOB.EQ.2 .OR. IJOB.EQ.4 ) THEN 697 RCONDV( 1 ) = DIF( 1 ) 698 RCONDV( 2 ) = DIF( 2 ) 699 END IF 700 IF( IERR.EQ.1 ) 701 $ INFO = N + 3 702 END IF 703* 704 END IF 705* 706* Apply permutation to VSL and VSR 707* (Workspace: none needed) 708* 709 IF( ILVSL ) 710 $ CALL SGGBAK( 'P', 'L', N, ILO, IHI, WORK( ILEFT ), 711 $ WORK( IRIGHT ), N, VSL, LDVSL, IERR ) 712* 713 IF( ILVSR ) 714 $ CALL SGGBAK( 'P', 'R', N, ILO, IHI, WORK( ILEFT ), 715 $ WORK( IRIGHT ), N, VSR, LDVSR, IERR ) 716* 717* Check if unscaling would cause over/underflow, if so, rescale 718* (ALPHAR(I),ALPHAI(I),BETA(I)) so BETA(I) is on the order of 719* B(I,I) and ALPHAR(I) and ALPHAI(I) are on the order of A(I,I) 720* 721 IF( ILASCL ) THEN 722 DO 20 I = 1, N 723 IF( ALPHAI( I ).NE.ZERO ) THEN 724 IF( ( ALPHAR( I ) / SAFMAX ).GT.( ANRMTO / ANRM ) .OR. 725 $ ( SAFMIN / ALPHAR( I ) ).GT.( ANRM / ANRMTO ) ) 726 $ THEN 727 WORK( 1 ) = ABS( A( I, I ) / ALPHAR( I ) ) 728 BETA( I ) = BETA( I )*WORK( 1 ) 729 ALPHAR( I ) = ALPHAR( I )*WORK( 1 ) 730 ALPHAI( I ) = ALPHAI( I )*WORK( 1 ) 731 ELSE IF( ( ALPHAI( I ) / SAFMAX ).GT.( ANRMTO / ANRM ) 732 $ .OR. ( SAFMIN / ALPHAI( I ) ).GT.( ANRM / ANRMTO ) ) 733 $ THEN 734 WORK( 1 ) = ABS( A( I, I+1 ) / ALPHAI( I ) ) 735 BETA( I ) = BETA( I )*WORK( 1 ) 736 ALPHAR( I ) = ALPHAR( I )*WORK( 1 ) 737 ALPHAI( I ) = ALPHAI( I )*WORK( 1 ) 738 END IF 739 END IF 740 20 CONTINUE 741 END IF 742* 743 IF( ILBSCL ) THEN 744 DO 25 I = 1, N 745 IF( ALPHAI( I ).NE.ZERO ) THEN 746 IF( ( BETA( I ) / SAFMAX ).GT.( BNRMTO / BNRM ) .OR. 747 $ ( SAFMIN / BETA( I ) ).GT.( BNRM / BNRMTO ) ) THEN 748 WORK( 1 ) = ABS( B( I, I ) / BETA( I ) ) 749 BETA( I ) = BETA( I )*WORK( 1 ) 750 ALPHAR( I ) = ALPHAR( I )*WORK( 1 ) 751 ALPHAI( I ) = ALPHAI( I )*WORK( 1 ) 752 END IF 753 END IF 754 25 CONTINUE 755 END IF 756* 757* Undo scaling 758* 759 IF( ILASCL ) THEN 760 CALL SLASCL( 'H', 0, 0, ANRMTO, ANRM, N, N, A, LDA, IERR ) 761 CALL SLASCL( 'G', 0, 0, ANRMTO, ANRM, N, 1, ALPHAR, N, IERR ) 762 CALL SLASCL( 'G', 0, 0, ANRMTO, ANRM, N, 1, ALPHAI, N, IERR ) 763 END IF 764* 765 IF( ILBSCL ) THEN 766 CALL SLASCL( 'U', 0, 0, BNRMTO, BNRM, N, N, B, LDB, IERR ) 767 CALL SLASCL( 'G', 0, 0, BNRMTO, BNRM, N, 1, BETA, N, IERR ) 768 END IF 769* 770 IF( WANTST ) THEN 771* 772* Check if reordering is correct 773* 774 LASTSL = .TRUE. 775 LST2SL = .TRUE. 776 SDIM = 0 777 IP = 0 778 DO 40 I = 1, N 779 CURSL = SELCTG( ALPHAR( I ), ALPHAI( I ), BETA( I ) ) 780 IF( ALPHAI( I ).EQ.ZERO ) THEN 781 IF( CURSL ) 782 $ SDIM = SDIM + 1 783 IP = 0 784 IF( CURSL .AND. .NOT.LASTSL ) 785 $ INFO = N + 2 786 ELSE 787 IF( IP.EQ.1 ) THEN 788* 789* Last eigenvalue of conjugate pair 790* 791 CURSL = CURSL .OR. LASTSL 792 LASTSL = CURSL 793 IF( CURSL ) 794 $ SDIM = SDIM + 2 795 IP = -1 796 IF( CURSL .AND. .NOT.LST2SL ) 797 $ INFO = N + 2 798 ELSE 799* 800* First eigenvalue of conjugate pair 801* 802 IP = 1 803 END IF 804 END IF 805 LST2SL = LASTSL 806 LASTSL = CURSL 807 40 CONTINUE 808* 809 END IF 810* 811 50 CONTINUE 812* 813 WORK( 1 ) = MAXWRK 814 IWORK( 1 ) = LIWMIN 815* 816 RETURN 817* 818* End of SGGESX 819* 820 END 821