00001 SUBROUTINE CGGESX( JOBVSL, JOBVSR, SORT, SELCTG, SENSE, N, A, LDA,
00002 $ B, LDB, SDIM, ALPHA, BETA, VSL, LDVSL, VSR,
00003 $ LDVSR, RCONDE, RCONDV, WORK, LWORK, RWORK,
00004 $ IWORK, LIWORK, BWORK, INFO )
00005
00006
00007
00008
00009
00010
00011
00012 CHARACTER JOBVSL, JOBVSR, SENSE, SORT
00013 INTEGER INFO, LDA, LDB, LDVSL, LDVSR, LIWORK, LWORK, N,
00014 $ SDIM
00015
00016
00017 LOGICAL BWORK( * )
00018 INTEGER IWORK( * )
00019 REAL RCONDE( 2 ), RCONDV( 2 ), RWORK( * )
00020 COMPLEX A( LDA, * ), ALPHA( * ), B( LDB, * ),
00021 $ BETA( * ), VSL( LDVSL, * ), VSR( LDVSR, * ),
00022 $ WORK( * )
00023
00024
00025 LOGICAL SELCTG
00026 EXTERNAL SELCTG
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
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220 REAL ZERO, ONE
00221 PARAMETER ( ZERO = 0.0E+0, ONE = 1.0E+0 )
00222 COMPLEX CZERO, CONE
00223 PARAMETER ( CZERO = ( 0.0E+0, 0.0E+0 ),
00224 $ CONE = ( 1.0E+0, 0.0E+0 ) )
00225
00226
00227 LOGICAL CURSL, ILASCL, ILBSCL, ILVSL, ILVSR, LASTSL,
00228 $ LQUERY, WANTSB, WANTSE, WANTSN, WANTST, WANTSV
00229 INTEGER I, ICOLS, IERR, IHI, IJOB, IJOBVL, IJOBVR,
00230 $ ILEFT, ILO, IRIGHT, IROWS, IRWRK, ITAU, IWRK,
00231 $ LIWMIN, LWRK, MAXWRK, MINWRK
00232 REAL ANRM, ANRMTO, BIGNUM, BNRM, BNRMTO, EPS, PL,
00233 $ PR, SMLNUM
00234
00235
00236 REAL DIF( 2 )
00237
00238
00239 EXTERNAL CGEQRF, CGGBAK, CGGBAL, CGGHRD, CHGEQZ, CLACPY,
00240 $ CLASCL, CLASET, CTGSEN, CUNGQR, CUNMQR, SLABAD,
00241 $ XERBLA
00242
00243
00244 LOGICAL LSAME
00245 INTEGER ILAENV
00246 REAL CLANGE, SLAMCH
00247 EXTERNAL LSAME, ILAENV, CLANGE, SLAMCH
00248
00249
00250 INTRINSIC MAX, SQRT
00251
00252
00253
00254
00255
00256 IF( LSAME( JOBVSL, 'N' ) ) THEN
00257 IJOBVL = 1
00258 ILVSL = .FALSE.
00259 ELSE IF( LSAME( JOBVSL, 'V' ) ) THEN
00260 IJOBVL = 2
00261 ILVSL = .TRUE.
00262 ELSE
00263 IJOBVL = -1
00264 ILVSL = .FALSE.
00265 END IF
00266
00267 IF( LSAME( JOBVSR, 'N' ) ) THEN
00268 IJOBVR = 1
00269 ILVSR = .FALSE.
00270 ELSE IF( LSAME( JOBVSR, 'V' ) ) THEN
00271 IJOBVR = 2
00272 ILVSR = .TRUE.
00273 ELSE
00274 IJOBVR = -1
00275 ILVSR = .FALSE.
00276 END IF
00277
00278 WANTST = LSAME( SORT, 'S' )
00279 WANTSN = LSAME( SENSE, 'N' )
00280 WANTSE = LSAME( SENSE, 'E' )
00281 WANTSV = LSAME( SENSE, 'V' )
00282 WANTSB = LSAME( SENSE, 'B' )
00283 LQUERY = ( LWORK.EQ.-1 .OR. LIWORK.EQ.-1 )
00284 IF( WANTSN ) THEN
00285 IJOB = 0
00286 ELSE IF( WANTSE ) THEN
00287 IJOB = 1
00288 ELSE IF( WANTSV ) THEN
00289 IJOB = 2
00290 ELSE IF( WANTSB ) THEN
00291 IJOB = 4
00292 END IF
00293
00294
00295
00296 INFO = 0
00297 IF( IJOBVL.LE.0 ) THEN
00298 INFO = -1
00299 ELSE IF( IJOBVR.LE.0 ) THEN
00300 INFO = -2
00301 ELSE IF( ( .NOT.WANTST ) .AND. ( .NOT.LSAME( SORT, 'N' ) ) ) THEN
00302 INFO = -3
00303 ELSE IF( .NOT.( WANTSN .OR. WANTSE .OR. WANTSV .OR. WANTSB ) .OR.
00304 $ ( .NOT.WANTST .AND. .NOT.WANTSN ) ) THEN
00305 INFO = -5
00306 ELSE IF( N.LT.0 ) THEN
00307 INFO = -6
00308 ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
00309 INFO = -8
00310 ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
00311 INFO = -10
00312 ELSE IF( LDVSL.LT.1 .OR. ( ILVSL .AND. LDVSL.LT.N ) ) THEN
00313 INFO = -15
00314 ELSE IF( LDVSR.LT.1 .OR. ( ILVSR .AND. LDVSR.LT.N ) ) THEN
00315 INFO = -17
00316 END IF
00317
00318
00319
00320
00321
00322
00323
00324
00325 IF( INFO.EQ.0 ) THEN
00326 IF( N.GT.0) THEN
00327 MINWRK = 2*N
00328 MAXWRK = N*(1 + ILAENV( 1, 'CGEQRF', ' ', N, 1, N, 0 ) )
00329 MAXWRK = MAX( MAXWRK, N*( 1 +
00330 $ ILAENV( 1, 'CUNMQR', ' ', N, 1, N, -1 ) ) )
00331 IF( ILVSL ) THEN
00332 MAXWRK = MAX( MAXWRK, N*( 1 +
00333 $ ILAENV( 1, 'CUNGQR', ' ', N, 1, N, -1 ) ) )
00334 END IF
00335 LWRK = MAXWRK
00336 IF( IJOB.GE.1 )
00337 $ LWRK = MAX( LWRK, N*N/2 )
00338 ELSE
00339 MINWRK = 1
00340 MAXWRK = 1
00341 LWRK = 1
00342 END IF
00343 WORK( 1 ) = LWRK
00344 IF( WANTSN .OR. N.EQ.0 ) THEN
00345 LIWMIN = 1
00346 ELSE
00347 LIWMIN = N + 2
00348 END IF
00349 IWORK( 1 ) = LIWMIN
00350
00351 IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY ) THEN
00352 INFO = -21
00353 ELSE IF( LIWORK.LT.LIWMIN .AND. .NOT.LQUERY) THEN
00354 INFO = -24
00355 END IF
00356 END IF
00357
00358 IF( INFO.NE.0 ) THEN
00359 CALL XERBLA( 'CGGESX', -INFO )
00360 RETURN
00361 ELSE IF (LQUERY) THEN
00362 RETURN
00363 END IF
00364
00365
00366
00367 IF( N.EQ.0 ) THEN
00368 SDIM = 0
00369 RETURN
00370 END IF
00371
00372
00373
00374 EPS = SLAMCH( 'P' )
00375 SMLNUM = SLAMCH( 'S' )
00376 BIGNUM = ONE / SMLNUM
00377 CALL SLABAD( SMLNUM, BIGNUM )
00378 SMLNUM = SQRT( SMLNUM ) / EPS
00379 BIGNUM = ONE / SMLNUM
00380
00381
00382
00383 ANRM = CLANGE( 'M', N, N, A, LDA, RWORK )
00384 ILASCL = .FALSE.
00385 IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
00386 ANRMTO = SMLNUM
00387 ILASCL = .TRUE.
00388 ELSE IF( ANRM.GT.BIGNUM ) THEN
00389 ANRMTO = BIGNUM
00390 ILASCL = .TRUE.
00391 END IF
00392 IF( ILASCL )
00393 $ CALL CLASCL( 'G', 0, 0, ANRM, ANRMTO, N, N, A, LDA, IERR )
00394
00395
00396
00397 BNRM = CLANGE( 'M', N, N, B, LDB, RWORK )
00398 ILBSCL = .FALSE.
00399 IF( BNRM.GT.ZERO .AND. BNRM.LT.SMLNUM ) THEN
00400 BNRMTO = SMLNUM
00401 ILBSCL = .TRUE.
00402 ELSE IF( BNRM.GT.BIGNUM ) THEN
00403 BNRMTO = BIGNUM
00404 ILBSCL = .TRUE.
00405 END IF
00406 IF( ILBSCL )
00407 $ CALL CLASCL( 'G', 0, 0, BNRM, BNRMTO, N, N, B, LDB, IERR )
00408
00409
00410
00411
00412 ILEFT = 1
00413 IRIGHT = N + 1
00414 IRWRK = IRIGHT + N
00415 CALL CGGBAL( 'P', N, A, LDA, B, LDB, ILO, IHI, RWORK( ILEFT ),
00416 $ RWORK( IRIGHT ), RWORK( IRWRK ), IERR )
00417
00418
00419
00420
00421 IROWS = IHI + 1 - ILO
00422 ICOLS = N + 1 - ILO
00423 ITAU = 1
00424 IWRK = ITAU + IROWS
00425 CALL CGEQRF( IROWS, ICOLS, B( ILO, ILO ), LDB, WORK( ITAU ),
00426 $ WORK( IWRK ), LWORK+1-IWRK, IERR )
00427
00428
00429
00430
00431 CALL CUNMQR( 'L', 'C', IROWS, ICOLS, IROWS, B( ILO, ILO ), LDB,
00432 $ WORK( ITAU ), A( ILO, ILO ), LDA, WORK( IWRK ),
00433 $ LWORK+1-IWRK, IERR )
00434
00435
00436
00437
00438 IF( ILVSL ) THEN
00439 CALL CLASET( 'Full', N, N, CZERO, CONE, VSL, LDVSL )
00440 IF( IROWS.GT.1 ) THEN
00441 CALL CLACPY( 'L', IROWS-1, IROWS-1, B( ILO+1, ILO ), LDB,
00442 $ VSL( ILO+1, ILO ), LDVSL )
00443 END IF
00444 CALL CUNGQR( IROWS, IROWS, IROWS, VSL( ILO, ILO ), LDVSL,
00445 $ WORK( ITAU ), WORK( IWRK ), LWORK+1-IWRK, IERR )
00446 END IF
00447
00448
00449
00450 IF( ILVSR )
00451 $ CALL CLASET( 'Full', N, N, CZERO, CONE, VSR, LDVSR )
00452
00453
00454
00455
00456 CALL CGGHRD( JOBVSL, JOBVSR, N, ILO, IHI, A, LDA, B, LDB, VSL,
00457 $ LDVSL, VSR, LDVSR, IERR )
00458
00459 SDIM = 0
00460
00461
00462
00463
00464
00465 IWRK = ITAU
00466 CALL CHGEQZ( 'S', JOBVSL, JOBVSR, N, ILO, IHI, A, LDA, B, LDB,
00467 $ ALPHA, BETA, VSL, LDVSL, VSR, LDVSR, WORK( IWRK ),
00468 $ LWORK+1-IWRK, RWORK( IRWRK ), IERR )
00469 IF( IERR.NE.0 ) THEN
00470 IF( IERR.GT.0 .AND. IERR.LE.N ) THEN
00471 INFO = IERR
00472 ELSE IF( IERR.GT.N .AND. IERR.LE.2*N ) THEN
00473 INFO = IERR - N
00474 ELSE
00475 INFO = N + 1
00476 END IF
00477 GO TO 40
00478 END IF
00479
00480
00481
00482
00483 IF( WANTST ) THEN
00484
00485
00486
00487 IF( ILASCL )
00488 $ CALL CLASCL( 'G', 0, 0, ANRMTO, ANRM, N, 1, ALPHA, N, IERR )
00489 IF( ILBSCL )
00490 $ CALL CLASCL( 'G', 0, 0, BNRMTO, BNRM, N, 1, BETA, N, IERR )
00491
00492
00493
00494 DO 10 I = 1, N
00495 BWORK( I ) = SELCTG( ALPHA( I ), BETA( I ) )
00496 10 CONTINUE
00497
00498
00499
00500
00501
00502
00503 CALL CTGSEN( IJOB, ILVSL, ILVSR, BWORK, N, A, LDA, B, LDB,
00504 $ ALPHA, BETA, VSL, LDVSL, VSR, LDVSR, SDIM, PL, PR,
00505 $ DIF, WORK( IWRK ), LWORK-IWRK+1, IWORK, LIWORK,
00506 $ IERR )
00507
00508 IF( IJOB.GE.1 )
00509 $ MAXWRK = MAX( MAXWRK, 2*SDIM*( N-SDIM ) )
00510 IF( IERR.EQ.-21 ) THEN
00511
00512
00513
00514 INFO = -21
00515 ELSE
00516 IF( IJOB.EQ.1 .OR. IJOB.EQ.4 ) THEN
00517 RCONDE( 1 ) = PL
00518 RCONDE( 2 ) = PR
00519 END IF
00520 IF( IJOB.EQ.2 .OR. IJOB.EQ.4 ) THEN
00521 RCONDV( 1 ) = DIF( 1 )
00522 RCONDV( 2 ) = DIF( 2 )
00523 END IF
00524 IF( IERR.EQ.1 )
00525 $ INFO = N + 3
00526 END IF
00527
00528 END IF
00529
00530
00531
00532
00533 IF( ILVSL )
00534 $ CALL CGGBAK( 'P', 'L', N, ILO, IHI, RWORK( ILEFT ),
00535 $ RWORK( IRIGHT ), N, VSL, LDVSL, IERR )
00536
00537 IF( ILVSR )
00538 $ CALL CGGBAK( 'P', 'R', N, ILO, IHI, RWORK( ILEFT ),
00539 $ RWORK( IRIGHT ), N, VSR, LDVSR, IERR )
00540
00541
00542
00543 IF( ILASCL ) THEN
00544 CALL CLASCL( 'U', 0, 0, ANRMTO, ANRM, N, N, A, LDA, IERR )
00545 CALL CLASCL( 'G', 0, 0, ANRMTO, ANRM, N, 1, ALPHA, N, IERR )
00546 END IF
00547
00548 IF( ILBSCL ) THEN
00549 CALL CLASCL( 'U', 0, 0, BNRMTO, BNRM, N, N, B, LDB, IERR )
00550 CALL CLASCL( 'G', 0, 0, BNRMTO, BNRM, N, 1, BETA, N, IERR )
00551 END IF
00552
00553 IF( WANTST ) THEN
00554
00555
00556
00557 LASTSL = .TRUE.
00558 SDIM = 0
00559 DO 30 I = 1, N
00560 CURSL = SELCTG( ALPHA( I ), BETA( I ) )
00561 IF( CURSL )
00562 $ SDIM = SDIM + 1
00563 IF( CURSL .AND. .NOT.LASTSL )
00564 $ INFO = N + 2
00565 LASTSL = CURSL
00566 30 CONTINUE
00567
00568 END IF
00569
00570 40 CONTINUE
00571
00572 WORK( 1 ) = MAXWRK
00573 IWORK( 1 ) = LIWMIN
00574
00575 RETURN
00576
00577
00578
00579 END