00001 SUBROUTINE SGGES( JOBVSL, JOBVSR, SORT, SELCTG, N, A, LDA, B, LDB,
00002 $ SDIM, ALPHAR, ALPHAI, BETA, VSL, LDVSL, VSR,
00003 $ LDVSR, WORK, LWORK, BWORK, INFO )
00004
00005
00006
00007
00008
00009
00010
00011 CHARACTER JOBVSL, JOBVSR, SORT
00012 INTEGER INFO, LDA, LDB, LDVSL, LDVSR, LWORK, N, SDIM
00013
00014
00015 LOGICAL BWORK( * )
00016 REAL A( LDA, * ), ALPHAI( * ), ALPHAR( * ),
00017 $ B( LDB, * ), BETA( * ), VSL( LDVSL, * ),
00018 $ VSR( LDVSR, * ), WORK( * )
00019
00020
00021 LOGICAL SELCTG
00022 EXTERNAL SELCTG
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189 REAL ZERO, ONE
00190 PARAMETER ( ZERO = 0.0E+0, ONE = 1.0E+0 )
00191
00192
00193 LOGICAL CURSL, ILASCL, ILBSCL, ILVSL, ILVSR, LASTSL,
00194 $ LQUERY, LST2SL, WANTST
00195 INTEGER I, ICOLS, IERR, IHI, IJOBVL, IJOBVR, ILEFT,
00196 $ ILO, IP, IRIGHT, IROWS, ITAU, IWRK, MAXWRK,
00197 $ MINWRK
00198 REAL ANRM, ANRMTO, BIGNUM, BNRM, BNRMTO, EPS, PVSL,
00199 $ PVSR, SAFMAX, SAFMIN, SMLNUM
00200
00201
00202 INTEGER IDUM( 1 )
00203 REAL DIF( 2 )
00204
00205
00206 EXTERNAL SGEQRF, SGGBAK, SGGBAL, SGGHRD, SHGEQZ, SLABAD,
00207 $ SLACPY, SLASCL, SLASET, SORGQR, SORMQR, STGSEN,
00208 $ XERBLA
00209
00210
00211 LOGICAL LSAME
00212 INTEGER ILAENV
00213 REAL SLAMCH, SLANGE
00214 EXTERNAL LSAME, ILAENV, SLAMCH, SLANGE
00215
00216
00217 INTRINSIC ABS, MAX, SQRT
00218
00219
00220
00221
00222
00223 IF( LSAME( JOBVSL, 'N' ) ) THEN
00224 IJOBVL = 1
00225 ILVSL = .FALSE.
00226 ELSE IF( LSAME( JOBVSL, 'V' ) ) THEN
00227 IJOBVL = 2
00228 ILVSL = .TRUE.
00229 ELSE
00230 IJOBVL = -1
00231 ILVSL = .FALSE.
00232 END IF
00233
00234 IF( LSAME( JOBVSR, 'N' ) ) THEN
00235 IJOBVR = 1
00236 ILVSR = .FALSE.
00237 ELSE IF( LSAME( JOBVSR, 'V' ) ) THEN
00238 IJOBVR = 2
00239 ILVSR = .TRUE.
00240 ELSE
00241 IJOBVR = -1
00242 ILVSR = .FALSE.
00243 END IF
00244
00245 WANTST = LSAME( SORT, 'S' )
00246
00247
00248
00249 INFO = 0
00250 LQUERY = ( LWORK.EQ.-1 )
00251 IF( IJOBVL.LE.0 ) THEN
00252 INFO = -1
00253 ELSE IF( IJOBVR.LE.0 ) THEN
00254 INFO = -2
00255 ELSE IF( ( .NOT.WANTST ) .AND. ( .NOT.LSAME( SORT, 'N' ) ) ) THEN
00256 INFO = -3
00257 ELSE IF( N.LT.0 ) THEN
00258 INFO = -5
00259 ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
00260 INFO = -7
00261 ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
00262 INFO = -9
00263 ELSE IF( LDVSL.LT.1 .OR. ( ILVSL .AND. LDVSL.LT.N ) ) THEN
00264 INFO = -15
00265 ELSE IF( LDVSR.LT.1 .OR. ( ILVSR .AND. LDVSR.LT.N ) ) THEN
00266 INFO = -17
00267 END IF
00268
00269
00270
00271
00272
00273
00274
00275
00276 IF( INFO.EQ.0 ) THEN
00277 IF( N.GT.0 )THEN
00278 MINWRK = MAX( 8*N, 6*N + 16 )
00279 MAXWRK = MINWRK - N +
00280 $ N*ILAENV( 1, 'SGEQRF', ' ', N, 1, N, 0 )
00281 MAXWRK = MAX( MAXWRK, MINWRK - N +
00282 $ N*ILAENV( 1, 'SORMQR', ' ', N, 1, N, -1 ) )
00283 IF( ILVSL ) THEN
00284 MAXWRK = MAX( MAXWRK, MINWRK - N +
00285 $ N*ILAENV( 1, 'SORGQR', ' ', N, 1, N, -1 ) )
00286 END IF
00287 ELSE
00288 MINWRK = 1
00289 MAXWRK = 1
00290 END IF
00291 WORK( 1 ) = MAXWRK
00292
00293 IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY )
00294 $ INFO = -19
00295 END IF
00296
00297 IF( INFO.NE.0 ) THEN
00298 CALL XERBLA( 'SGGES ', -INFO )
00299 RETURN
00300 ELSE IF( LQUERY ) THEN
00301 RETURN
00302 END IF
00303
00304
00305
00306 IF( N.EQ.0 ) THEN
00307 SDIM = 0
00308 RETURN
00309 END IF
00310
00311
00312
00313 EPS = SLAMCH( 'P' )
00314 SAFMIN = SLAMCH( 'S' )
00315 SAFMAX = ONE / SAFMIN
00316 CALL SLABAD( SAFMIN, SAFMAX )
00317 SMLNUM = SQRT( SAFMIN ) / EPS
00318 BIGNUM = ONE / SMLNUM
00319
00320
00321
00322 ANRM = SLANGE( 'M', N, N, A, LDA, WORK )
00323 ILASCL = .FALSE.
00324 IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
00325 ANRMTO = SMLNUM
00326 ILASCL = .TRUE.
00327 ELSE IF( ANRM.GT.BIGNUM ) THEN
00328 ANRMTO = BIGNUM
00329 ILASCL = .TRUE.
00330 END IF
00331 IF( ILASCL )
00332 $ CALL SLASCL( 'G', 0, 0, ANRM, ANRMTO, N, N, A, LDA, IERR )
00333
00334
00335
00336 BNRM = SLANGE( 'M', N, N, B, LDB, WORK )
00337 ILBSCL = .FALSE.
00338 IF( BNRM.GT.ZERO .AND. BNRM.LT.SMLNUM ) THEN
00339 BNRMTO = SMLNUM
00340 ILBSCL = .TRUE.
00341 ELSE IF( BNRM.GT.BIGNUM ) THEN
00342 BNRMTO = BIGNUM
00343 ILBSCL = .TRUE.
00344 END IF
00345 IF( ILBSCL )
00346 $ CALL SLASCL( 'G', 0, 0, BNRM, BNRMTO, N, N, B, LDB, IERR )
00347
00348
00349
00350
00351 ILEFT = 1
00352 IRIGHT = N + 1
00353 IWRK = IRIGHT + N
00354 CALL SGGBAL( 'P', N, A, LDA, B, LDB, ILO, IHI, WORK( ILEFT ),
00355 $ WORK( IRIGHT ), WORK( IWRK ), IERR )
00356
00357
00358
00359
00360 IROWS = IHI + 1 - ILO
00361 ICOLS = N + 1 - ILO
00362 ITAU = IWRK
00363 IWRK = ITAU + IROWS
00364 CALL SGEQRF( IROWS, ICOLS, B( ILO, ILO ), LDB, WORK( ITAU ),
00365 $ WORK( IWRK ), LWORK+1-IWRK, IERR )
00366
00367
00368
00369
00370 CALL SORMQR( 'L', 'T', IROWS, ICOLS, IROWS, B( ILO, ILO ), LDB,
00371 $ WORK( ITAU ), A( ILO, ILO ), LDA, WORK( IWRK ),
00372 $ LWORK+1-IWRK, IERR )
00373
00374
00375
00376
00377 IF( ILVSL ) THEN
00378 CALL SLASET( 'Full', N, N, ZERO, ONE, VSL, LDVSL )
00379 IF( IROWS.GT.1 ) THEN
00380 CALL SLACPY( 'L', IROWS-1, IROWS-1, B( ILO+1, ILO ), LDB,
00381 $ VSL( ILO+1, ILO ), LDVSL )
00382 END IF
00383 CALL SORGQR( IROWS, IROWS, IROWS, VSL( ILO, ILO ), LDVSL,
00384 $ WORK( ITAU ), WORK( IWRK ), LWORK+1-IWRK, IERR )
00385 END IF
00386
00387
00388
00389 IF( ILVSR )
00390 $ CALL SLASET( 'Full', N, N, ZERO, ONE, VSR, LDVSR )
00391
00392
00393
00394
00395 CALL SGGHRD( JOBVSL, JOBVSR, N, ILO, IHI, A, LDA, B, LDB, VSL,
00396 $ LDVSL, VSR, LDVSR, IERR )
00397
00398
00399
00400
00401 IWRK = ITAU
00402 CALL SHGEQZ( 'S', JOBVSL, JOBVSR, N, ILO, IHI, A, LDA, B, LDB,
00403 $ ALPHAR, ALPHAI, BETA, VSL, LDVSL, VSR, LDVSR,
00404 $ WORK( IWRK ), LWORK+1-IWRK, IERR )
00405 IF( IERR.NE.0 ) THEN
00406 IF( IERR.GT.0 .AND. IERR.LE.N ) THEN
00407 INFO = IERR
00408 ELSE IF( IERR.GT.N .AND. IERR.LE.2*N ) THEN
00409 INFO = IERR - N
00410 ELSE
00411 INFO = N + 1
00412 END IF
00413 GO TO 40
00414 END IF
00415
00416
00417
00418
00419 SDIM = 0
00420 IF( WANTST ) THEN
00421
00422
00423
00424 IF( ILASCL ) THEN
00425 CALL SLASCL( 'G', 0, 0, ANRMTO, ANRM, N, 1, ALPHAR, N,
00426 $ IERR )
00427 CALL SLASCL( 'G', 0, 0, ANRMTO, ANRM, N, 1, ALPHAI, N,
00428 $ IERR )
00429 END IF
00430 IF( ILBSCL )
00431 $ CALL SLASCL( 'G', 0, 0, BNRMTO, BNRM, N, 1, BETA, N, IERR )
00432
00433
00434
00435 DO 10 I = 1, N
00436 BWORK( I ) = SELCTG( ALPHAR( I ), ALPHAI( I ), BETA( I ) )
00437 10 CONTINUE
00438
00439 CALL STGSEN( 0, ILVSL, ILVSR, BWORK, N, A, LDA, B, LDB, ALPHAR,
00440 $ ALPHAI, BETA, VSL, LDVSL, VSR, LDVSR, SDIM, PVSL,
00441 $ PVSR, DIF, WORK( IWRK ), LWORK-IWRK+1, IDUM, 1,
00442 $ IERR )
00443 IF( IERR.EQ.1 )
00444 $ INFO = N + 3
00445
00446 END IF
00447
00448
00449
00450
00451 IF( ILVSL )
00452 $ CALL SGGBAK( 'P', 'L', N, ILO, IHI, WORK( ILEFT ),
00453 $ WORK( IRIGHT ), N, VSL, LDVSL, IERR )
00454
00455 IF( ILVSR )
00456 $ CALL SGGBAK( 'P', 'R', N, ILO, IHI, WORK( ILEFT ),
00457 $ WORK( IRIGHT ), N, VSR, LDVSR, IERR )
00458
00459
00460
00461
00462
00463 IF( ILASCL )THEN
00464 DO 50 I = 1, N
00465 IF( ALPHAI( I ).NE.ZERO ) THEN
00466 IF( ( ALPHAR( I )/SAFMAX ).GT.( ANRMTO/ANRM ) .OR.
00467 $ ( SAFMIN/ALPHAR( I ) ).GT.( ANRM/ANRMTO ) ) THEN
00468 WORK( 1 ) = ABS( A( I, I )/ALPHAR( I ) )
00469 BETA( I ) = BETA( I )*WORK( 1 )
00470 ALPHAR( I ) = ALPHAR( I )*WORK( 1 )
00471 ALPHAI( I ) = ALPHAI( I )*WORK( 1 )
00472 ELSE IF( ( ALPHAI( I )/SAFMAX ).GT.( ANRMTO/ANRM ) .OR.
00473 $ ( SAFMIN/ALPHAI( I ) ).GT.( ANRM/ANRMTO ) ) THEN
00474 WORK( 1 ) = ABS( A( I, I+1 )/ALPHAI( I ) )
00475 BETA( I ) = BETA( I )*WORK( 1 )
00476 ALPHAR( I ) = ALPHAR( I )*WORK( 1 )
00477 ALPHAI( I ) = ALPHAI( I )*WORK( 1 )
00478 END IF
00479 END IF
00480 50 CONTINUE
00481 END IF
00482
00483 IF( ILBSCL )THEN
00484 DO 60 I = 1, N
00485 IF( ALPHAI( I ).NE.ZERO ) THEN
00486 IF( ( BETA( I )/SAFMAX ).GT.( BNRMTO/BNRM ) .OR.
00487 $ ( SAFMIN/BETA( I ) ).GT.( BNRM/BNRMTO ) ) THEN
00488 WORK( 1 ) = ABS(B( I, I )/BETA( I ))
00489 BETA( I ) = BETA( I )*WORK( 1 )
00490 ALPHAR( I ) = ALPHAR( I )*WORK( 1 )
00491 ALPHAI( I ) = ALPHAI( I )*WORK( 1 )
00492 END IF
00493 END IF
00494 60 CONTINUE
00495 END IF
00496
00497
00498
00499 IF( ILASCL ) THEN
00500 CALL SLASCL( 'H', 0, 0, ANRMTO, ANRM, N, N, A, LDA, IERR )
00501 CALL SLASCL( 'G', 0, 0, ANRMTO, ANRM, N, 1, ALPHAR, N, IERR )
00502 CALL SLASCL( 'G', 0, 0, ANRMTO, ANRM, N, 1, ALPHAI, N, IERR )
00503 END IF
00504
00505 IF( ILBSCL ) THEN
00506 CALL SLASCL( 'U', 0, 0, BNRMTO, BNRM, N, N, B, LDB, IERR )
00507 CALL SLASCL( 'G', 0, 0, BNRMTO, BNRM, N, 1, BETA, N, IERR )
00508 END IF
00509
00510 IF( WANTST ) THEN
00511
00512
00513
00514 LASTSL = .TRUE.
00515 LST2SL = .TRUE.
00516 SDIM = 0
00517 IP = 0
00518 DO 30 I = 1, N
00519 CURSL = SELCTG( ALPHAR( I ), ALPHAI( I ), BETA( I ) )
00520 IF( ALPHAI( I ).EQ.ZERO ) THEN
00521 IF( CURSL )
00522 $ SDIM = SDIM + 1
00523 IP = 0
00524 IF( CURSL .AND. .NOT.LASTSL )
00525 $ INFO = N + 2
00526 ELSE
00527 IF( IP.EQ.1 ) THEN
00528
00529
00530
00531 CURSL = CURSL .OR. LASTSL
00532 LASTSL = CURSL
00533 IF( CURSL )
00534 $ SDIM = SDIM + 2
00535 IP = -1
00536 IF( CURSL .AND. .NOT.LST2SL )
00537 $ INFO = N + 2
00538 ELSE
00539
00540
00541
00542 IP = 1
00543 END IF
00544 END IF
00545 LST2SL = LASTSL
00546 LASTSL = CURSL
00547 30 CONTINUE
00548
00549 END IF
00550
00551 40 CONTINUE
00552
00553 WORK( 1 ) = MAXWRK
00554
00555 RETURN
00556
00557
00558
00559 END