00001 SUBROUTINE CHGEQZ( JOB, COMPQ, COMPZ, N, ILO, IHI, H, LDH, T, LDT,
00002 $ ALPHA, BETA, Q, LDQ, Z, LDZ, WORK, LWORK,
00003 $ RWORK, INFO )
00004
00005
00006
00007
00008
00009
00010
00011 CHARACTER COMPQ, COMPZ, JOB
00012 INTEGER IHI, ILO, INFO, LDH, LDQ, LDT, LDZ, LWORK, N
00013
00014
00015 REAL RWORK( * )
00016 COMPLEX ALPHA( * ), BETA( * ), H( LDH, * ),
00017 $ Q( LDQ, * ), T( LDT, * ), WORK( * ),
00018 $ Z( LDZ, * )
00019
00020
00021
00022
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
00190 COMPLEX CZERO, CONE
00191 PARAMETER ( CZERO = ( 0.0E+0, 0.0E+0 ),
00192 $ CONE = ( 1.0E+0, 0.0E+0 ) )
00193 REAL ZERO, ONE
00194 PARAMETER ( ZERO = 0.0E+0, ONE = 1.0E+0 )
00195 REAL HALF
00196 PARAMETER ( HALF = 0.5E+0 )
00197
00198
00199 LOGICAL ILAZR2, ILAZRO, ILQ, ILSCHR, ILZ, LQUERY
00200 INTEGER ICOMPQ, ICOMPZ, IFIRST, IFRSTM, IITER, ILAST,
00201 $ ILASTM, IN, ISCHUR, ISTART, J, JC, JCH, JITER,
00202 $ JR, MAXIT
00203 REAL ABSB, ANORM, ASCALE, ATOL, BNORM, BSCALE, BTOL,
00204 $ C, SAFMIN, TEMP, TEMP2, TEMPR, ULP
00205 COMPLEX ABI22, AD11, AD12, AD21, AD22, CTEMP, CTEMP2,
00206 $ CTEMP3, ESHIFT, RTDISC, S, SHIFT, SIGNBC, T1,
00207 $ U12, X
00208
00209
00210 LOGICAL LSAME
00211 REAL CLANHS, SLAMCH
00212 EXTERNAL LSAME, CLANHS, SLAMCH
00213
00214
00215 EXTERNAL CLARTG, CLASET, CROT, CSCAL, XERBLA
00216
00217
00218 INTRINSIC ABS, AIMAG, CMPLX, CONJG, MAX, MIN, REAL, SQRT
00219
00220
00221 REAL ABS1
00222
00223
00224 ABS1( X ) = ABS( REAL( X ) ) + ABS( AIMAG( X ) )
00225
00226
00227
00228
00229
00230 IF( LSAME( JOB, 'E' ) ) THEN
00231 ILSCHR = .FALSE.
00232 ISCHUR = 1
00233 ELSE IF( LSAME( JOB, 'S' ) ) THEN
00234 ILSCHR = .TRUE.
00235 ISCHUR = 2
00236 ELSE
00237 ISCHUR = 0
00238 END IF
00239
00240 IF( LSAME( COMPQ, 'N' ) ) THEN
00241 ILQ = .FALSE.
00242 ICOMPQ = 1
00243 ELSE IF( LSAME( COMPQ, 'V' ) ) THEN
00244 ILQ = .TRUE.
00245 ICOMPQ = 2
00246 ELSE IF( LSAME( COMPQ, 'I' ) ) THEN
00247 ILQ = .TRUE.
00248 ICOMPQ = 3
00249 ELSE
00250 ICOMPQ = 0
00251 END IF
00252
00253 IF( LSAME( COMPZ, 'N' ) ) THEN
00254 ILZ = .FALSE.
00255 ICOMPZ = 1
00256 ELSE IF( LSAME( COMPZ, 'V' ) ) THEN
00257 ILZ = .TRUE.
00258 ICOMPZ = 2
00259 ELSE IF( LSAME( COMPZ, 'I' ) ) THEN
00260 ILZ = .TRUE.
00261 ICOMPZ = 3
00262 ELSE
00263 ICOMPZ = 0
00264 END IF
00265
00266
00267
00268 INFO = 0
00269 WORK( 1 ) = MAX( 1, N )
00270 LQUERY = ( LWORK.EQ.-1 )
00271 IF( ISCHUR.EQ.0 ) THEN
00272 INFO = -1
00273 ELSE IF( ICOMPQ.EQ.0 ) THEN
00274 INFO = -2
00275 ELSE IF( ICOMPZ.EQ.0 ) THEN
00276 INFO = -3
00277 ELSE IF( N.LT.0 ) THEN
00278 INFO = -4
00279 ELSE IF( ILO.LT.1 ) THEN
00280 INFO = -5
00281 ELSE IF( IHI.GT.N .OR. IHI.LT.ILO-1 ) THEN
00282 INFO = -6
00283 ELSE IF( LDH.LT.N ) THEN
00284 INFO = -8
00285 ELSE IF( LDT.LT.N ) THEN
00286 INFO = -10
00287 ELSE IF( LDQ.LT.1 .OR. ( ILQ .AND. LDQ.LT.N ) ) THEN
00288 INFO = -14
00289 ELSE IF( LDZ.LT.1 .OR. ( ILZ .AND. LDZ.LT.N ) ) THEN
00290 INFO = -16
00291 ELSE IF( LWORK.LT.MAX( 1, N ) .AND. .NOT.LQUERY ) THEN
00292 INFO = -18
00293 END IF
00294 IF( INFO.NE.0 ) THEN
00295 CALL XERBLA( 'CHGEQZ', -INFO )
00296 RETURN
00297 ELSE IF( LQUERY ) THEN
00298 RETURN
00299 END IF
00300
00301
00302
00303
00304 IF( N.LE.0 ) THEN
00305 WORK( 1 ) = CMPLX( 1 )
00306 RETURN
00307 END IF
00308
00309
00310
00311 IF( ICOMPQ.EQ.3 )
00312 $ CALL CLASET( 'Full', N, N, CZERO, CONE, Q, LDQ )
00313 IF( ICOMPZ.EQ.3 )
00314 $ CALL CLASET( 'Full', N, N, CZERO, CONE, Z, LDZ )
00315
00316
00317
00318 IN = IHI + 1 - ILO
00319 SAFMIN = SLAMCH( 'S' )
00320 ULP = SLAMCH( 'E' )*SLAMCH( 'B' )
00321 ANORM = CLANHS( 'F', IN, H( ILO, ILO ), LDH, RWORK )
00322 BNORM = CLANHS( 'F', IN, T( ILO, ILO ), LDT, RWORK )
00323 ATOL = MAX( SAFMIN, ULP*ANORM )
00324 BTOL = MAX( SAFMIN, ULP*BNORM )
00325 ASCALE = ONE / MAX( SAFMIN, ANORM )
00326 BSCALE = ONE / MAX( SAFMIN, BNORM )
00327
00328
00329
00330
00331 DO 10 J = IHI + 1, N
00332 ABSB = ABS( T( J, J ) )
00333 IF( ABSB.GT.SAFMIN ) THEN
00334 SIGNBC = CONJG( T( J, J ) / ABSB )
00335 T( J, J ) = ABSB
00336 IF( ILSCHR ) THEN
00337 CALL CSCAL( J-1, SIGNBC, T( 1, J ), 1 )
00338 CALL CSCAL( J, SIGNBC, H( 1, J ), 1 )
00339 ELSE
00340 H( J, J ) = H( J, J )*SIGNBC
00341 END IF
00342 IF( ILZ )
00343 $ CALL CSCAL( N, SIGNBC, Z( 1, J ), 1 )
00344 ELSE
00345 T( J, J ) = CZERO
00346 END IF
00347 ALPHA( J ) = H( J, J )
00348 BETA( J ) = T( J, J )
00349 10 CONTINUE
00350
00351
00352
00353 IF( IHI.LT.ILO )
00354 $ GO TO 190
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371 ILAST = IHI
00372 IF( ILSCHR ) THEN
00373 IFRSTM = 1
00374 ILASTM = N
00375 ELSE
00376 IFRSTM = ILO
00377 ILASTM = IHI
00378 END IF
00379 IITER = 0
00380 ESHIFT = CZERO
00381 MAXIT = 30*( IHI-ILO+1 )
00382
00383 DO 170 JITER = 1, MAXIT
00384
00385
00386
00387 IF( JITER.GT.MAXIT )
00388 $ GO TO 180
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398 IF( ILAST.EQ.ILO ) THEN
00399 GO TO 60
00400 ELSE
00401 IF( ABS1( H( ILAST, ILAST-1 ) ).LE.ATOL ) THEN
00402 H( ILAST, ILAST-1 ) = CZERO
00403 GO TO 60
00404 END IF
00405 END IF
00406
00407 IF( ABS( T( ILAST, ILAST ) ).LE.BTOL ) THEN
00408 T( ILAST, ILAST ) = CZERO
00409 GO TO 50
00410 END IF
00411
00412
00413
00414 DO 40 J = ILAST - 1, ILO, -1
00415
00416
00417
00418 IF( J.EQ.ILO ) THEN
00419 ILAZRO = .TRUE.
00420 ELSE
00421 IF( ABS1( H( J, J-1 ) ).LE.ATOL ) THEN
00422 H( J, J-1 ) = CZERO
00423 ILAZRO = .TRUE.
00424 ELSE
00425 ILAZRO = .FALSE.
00426 END IF
00427 END IF
00428
00429
00430
00431 IF( ABS( T( J, J ) ).LT.BTOL ) THEN
00432 T( J, J ) = CZERO
00433
00434
00435
00436 ILAZR2 = .FALSE.
00437 IF( .NOT.ILAZRO ) THEN
00438 IF( ABS1( H( J, J-1 ) )*( ASCALE*ABS1( H( J+1,
00439 $ J ) ) ).LE.ABS1( H( J, J ) )*( ASCALE*ATOL ) )
00440 $ ILAZR2 = .TRUE.
00441 END IF
00442
00443
00444
00445
00446
00447
00448
00449 IF( ILAZRO .OR. ILAZR2 ) THEN
00450 DO 20 JCH = J, ILAST - 1
00451 CTEMP = H( JCH, JCH )
00452 CALL CLARTG( CTEMP, H( JCH+1, JCH ), C, S,
00453 $ H( JCH, JCH ) )
00454 H( JCH+1, JCH ) = CZERO
00455 CALL CROT( ILASTM-JCH, H( JCH, JCH+1 ), LDH,
00456 $ H( JCH+1, JCH+1 ), LDH, C, S )
00457 CALL CROT( ILASTM-JCH, T( JCH, JCH+1 ), LDT,
00458 $ T( JCH+1, JCH+1 ), LDT, C, S )
00459 IF( ILQ )
00460 $ CALL CROT( N, Q( 1, JCH ), 1, Q( 1, JCH+1 ), 1,
00461 $ C, CONJG( S ) )
00462 IF( ILAZR2 )
00463 $ H( JCH, JCH-1 ) = H( JCH, JCH-1 )*C
00464 ILAZR2 = .FALSE.
00465 IF( ABS1( T( JCH+1, JCH+1 ) ).GE.BTOL ) THEN
00466 IF( JCH+1.GE.ILAST ) THEN
00467 GO TO 60
00468 ELSE
00469 IFIRST = JCH + 1
00470 GO TO 70
00471 END IF
00472 END IF
00473 T( JCH+1, JCH+1 ) = CZERO
00474 20 CONTINUE
00475 GO TO 50
00476 ELSE
00477
00478
00479
00480
00481 DO 30 JCH = J, ILAST - 1
00482 CTEMP = T( JCH, JCH+1 )
00483 CALL CLARTG( CTEMP, T( JCH+1, JCH+1 ), C, S,
00484 $ T( JCH, JCH+1 ) )
00485 T( JCH+1, JCH+1 ) = CZERO
00486 IF( JCH.LT.ILASTM-1 )
00487 $ CALL CROT( ILASTM-JCH-1, T( JCH, JCH+2 ), LDT,
00488 $ T( JCH+1, JCH+2 ), LDT, C, S )
00489 CALL CROT( ILASTM-JCH+2, H( JCH, JCH-1 ), LDH,
00490 $ H( JCH+1, JCH-1 ), LDH, C, S )
00491 IF( ILQ )
00492 $ CALL CROT( N, Q( 1, JCH ), 1, Q( 1, JCH+1 ), 1,
00493 $ C, CONJG( S ) )
00494 CTEMP = H( JCH+1, JCH )
00495 CALL CLARTG( CTEMP, H( JCH+1, JCH-1 ), C, S,
00496 $ H( JCH+1, JCH ) )
00497 H( JCH+1, JCH-1 ) = CZERO
00498 CALL CROT( JCH+1-IFRSTM, H( IFRSTM, JCH ), 1,
00499 $ H( IFRSTM, JCH-1 ), 1, C, S )
00500 CALL CROT( JCH-IFRSTM, T( IFRSTM, JCH ), 1,
00501 $ T( IFRSTM, JCH-1 ), 1, C, S )
00502 IF( ILZ )
00503 $ CALL CROT( N, Z( 1, JCH ), 1, Z( 1, JCH-1 ), 1,
00504 $ C, S )
00505 30 CONTINUE
00506 GO TO 50
00507 END IF
00508 ELSE IF( ILAZRO ) THEN
00509
00510
00511
00512 IFIRST = J
00513 GO TO 70
00514 END IF
00515
00516
00517
00518 40 CONTINUE
00519
00520
00521
00522 INFO = 2*N + 1
00523 GO TO 210
00524
00525
00526
00527
00528 50 CONTINUE
00529 CTEMP = H( ILAST, ILAST )
00530 CALL CLARTG( CTEMP, H( ILAST, ILAST-1 ), C, S,
00531 $ H( ILAST, ILAST ) )
00532 H( ILAST, ILAST-1 ) = CZERO
00533 CALL CROT( ILAST-IFRSTM, H( IFRSTM, ILAST ), 1,
00534 $ H( IFRSTM, ILAST-1 ), 1, C, S )
00535 CALL CROT( ILAST-IFRSTM, T( IFRSTM, ILAST ), 1,
00536 $ T( IFRSTM, ILAST-1 ), 1, C, S )
00537 IF( ILZ )
00538 $ CALL CROT( N, Z( 1, ILAST ), 1, Z( 1, ILAST-1 ), 1, C, S )
00539
00540
00541
00542 60 CONTINUE
00543 ABSB = ABS( T( ILAST, ILAST ) )
00544 IF( ABSB.GT.SAFMIN ) THEN
00545 SIGNBC = CONJG( T( ILAST, ILAST ) / ABSB )
00546 T( ILAST, ILAST ) = ABSB
00547 IF( ILSCHR ) THEN
00548 CALL CSCAL( ILAST-IFRSTM, SIGNBC, T( IFRSTM, ILAST ), 1 )
00549 CALL CSCAL( ILAST+1-IFRSTM, SIGNBC, H( IFRSTM, ILAST ),
00550 $ 1 )
00551 ELSE
00552 H( ILAST, ILAST ) = H( ILAST, ILAST )*SIGNBC
00553 END IF
00554 IF( ILZ )
00555 $ CALL CSCAL( N, SIGNBC, Z( 1, ILAST ), 1 )
00556 ELSE
00557 T( ILAST, ILAST ) = CZERO
00558 END IF
00559 ALPHA( ILAST ) = H( ILAST, ILAST )
00560 BETA( ILAST ) = T( ILAST, ILAST )
00561
00562
00563
00564 ILAST = ILAST - 1
00565 IF( ILAST.LT.ILO )
00566 $ GO TO 190
00567
00568
00569
00570 IITER = 0
00571 ESHIFT = CZERO
00572 IF( .NOT.ILSCHR ) THEN
00573 ILASTM = ILAST
00574 IF( IFRSTM.GT.ILAST )
00575 $ IFRSTM = ILO
00576 END IF
00577 GO TO 160
00578
00579
00580
00581
00582
00583
00584 70 CONTINUE
00585 IITER = IITER + 1
00586 IF( .NOT.ILSCHR ) THEN
00587 IFRSTM = IFIRST
00588 END IF
00589
00590
00591
00592
00593
00594
00595
00596 IF( ( IITER / 10 )*10.NE.IITER ) THEN
00597
00598
00599
00600
00601
00602
00603
00604
00605 U12 = ( BSCALE*T( ILAST-1, ILAST ) ) /
00606 $ ( BSCALE*T( ILAST, ILAST ) )
00607 AD11 = ( ASCALE*H( ILAST-1, ILAST-1 ) ) /
00608 $ ( BSCALE*T( ILAST-1, ILAST-1 ) )
00609 AD21 = ( ASCALE*H( ILAST, ILAST-1 ) ) /
00610 $ ( BSCALE*T( ILAST-1, ILAST-1 ) )
00611 AD12 = ( ASCALE*H( ILAST-1, ILAST ) ) /
00612 $ ( BSCALE*T( ILAST, ILAST ) )
00613 AD22 = ( ASCALE*H( ILAST, ILAST ) ) /
00614 $ ( BSCALE*T( ILAST, ILAST ) )
00615 ABI22 = AD22 - U12*AD21
00616
00617 T1 = HALF*( AD11+ABI22 )
00618 RTDISC = SQRT( T1**2+AD12*AD21-AD11*AD22 )
00619 TEMP = REAL( T1-ABI22 )*REAL( RTDISC ) +
00620 $ AIMAG( T1-ABI22 )*AIMAG( RTDISC )
00621 IF( TEMP.LE.ZERO ) THEN
00622 SHIFT = T1 + RTDISC
00623 ELSE
00624 SHIFT = T1 - RTDISC
00625 END IF
00626 ELSE
00627
00628
00629
00630 ESHIFT = ESHIFT + CONJG( ( ASCALE*H( ILAST-1, ILAST ) ) /
00631 $ ( BSCALE*T( ILAST-1, ILAST-1 ) ) )
00632 SHIFT = ESHIFT
00633 END IF
00634
00635
00636
00637 DO 80 J = ILAST - 1, IFIRST + 1, -1
00638 ISTART = J
00639 CTEMP = ASCALE*H( J, J ) - SHIFT*( BSCALE*T( J, J ) )
00640 TEMP = ABS1( CTEMP )
00641 TEMP2 = ASCALE*ABS1( H( J+1, J ) )
00642 TEMPR = MAX( TEMP, TEMP2 )
00643 IF( TEMPR.LT.ONE .AND. TEMPR.NE.ZERO ) THEN
00644 TEMP = TEMP / TEMPR
00645 TEMP2 = TEMP2 / TEMPR
00646 END IF
00647 IF( ABS1( H( J, J-1 ) )*TEMP2.LE.TEMP*ATOL )
00648 $ GO TO 90
00649 80 CONTINUE
00650
00651 ISTART = IFIRST
00652 CTEMP = ASCALE*H( IFIRST, IFIRST ) -
00653 $ SHIFT*( BSCALE*T( IFIRST, IFIRST ) )
00654 90 CONTINUE
00655
00656
00657
00658
00659
00660 CTEMP2 = ASCALE*H( ISTART+1, ISTART )
00661 CALL CLARTG( CTEMP, CTEMP2, C, S, CTEMP3 )
00662
00663
00664
00665 DO 150 J = ISTART, ILAST - 1
00666 IF( J.GT.ISTART ) THEN
00667 CTEMP = H( J, J-1 )
00668 CALL CLARTG( CTEMP, H( J+1, J-1 ), C, S, H( J, J-1 ) )
00669 H( J+1, J-1 ) = CZERO
00670 END IF
00671
00672 DO 100 JC = J, ILASTM
00673 CTEMP = C*H( J, JC ) + S*H( J+1, JC )
00674 H( J+1, JC ) = -CONJG( S )*H( J, JC ) + C*H( J+1, JC )
00675 H( J, JC ) = CTEMP
00676 CTEMP2 = C*T( J, JC ) + S*T( J+1, JC )
00677 T( J+1, JC ) = -CONJG( S )*T( J, JC ) + C*T( J+1, JC )
00678 T( J, JC ) = CTEMP2
00679 100 CONTINUE
00680 IF( ILQ ) THEN
00681 DO 110 JR = 1, N
00682 CTEMP = C*Q( JR, J ) + CONJG( S )*Q( JR, J+1 )
00683 Q( JR, J+1 ) = -S*Q( JR, J ) + C*Q( JR, J+1 )
00684 Q( JR, J ) = CTEMP
00685 110 CONTINUE
00686 END IF
00687
00688 CTEMP = T( J+1, J+1 )
00689 CALL CLARTG( CTEMP, T( J+1, J ), C, S, T( J+1, J+1 ) )
00690 T( J+1, J ) = CZERO
00691
00692 DO 120 JR = IFRSTM, MIN( J+2, ILAST )
00693 CTEMP = C*H( JR, J+1 ) + S*H( JR, J )
00694 H( JR, J ) = -CONJG( S )*H( JR, J+1 ) + C*H( JR, J )
00695 H( JR, J+1 ) = CTEMP
00696 120 CONTINUE
00697 DO 130 JR = IFRSTM, J
00698 CTEMP = C*T( JR, J+1 ) + S*T( JR, J )
00699 T( JR, J ) = -CONJG( S )*T( JR, J+1 ) + C*T( JR, J )
00700 T( JR, J+1 ) = CTEMP
00701 130 CONTINUE
00702 IF( ILZ ) THEN
00703 DO 140 JR = 1, N
00704 CTEMP = C*Z( JR, J+1 ) + S*Z( JR, J )
00705 Z( JR, J ) = -CONJG( S )*Z( JR, J+1 ) + C*Z( JR, J )
00706 Z( JR, J+1 ) = CTEMP
00707 140 CONTINUE
00708 END IF
00709 150 CONTINUE
00710
00711 160 CONTINUE
00712
00713 170 CONTINUE
00714
00715
00716
00717 180 CONTINUE
00718 INFO = ILAST
00719 GO TO 210
00720
00721
00722
00723 190 CONTINUE
00724
00725
00726
00727 DO 200 J = 1, ILO - 1
00728 ABSB = ABS( T( J, J ) )
00729 IF( ABSB.GT.SAFMIN ) THEN
00730 SIGNBC = CONJG( T( J, J ) / ABSB )
00731 T( J, J ) = ABSB
00732 IF( ILSCHR ) THEN
00733 CALL CSCAL( J-1, SIGNBC, T( 1, J ), 1 )
00734 CALL CSCAL( J, SIGNBC, H( 1, J ), 1 )
00735 ELSE
00736 H( J, J ) = H( J, J )*SIGNBC
00737 END IF
00738 IF( ILZ )
00739 $ CALL CSCAL( N, SIGNBC, Z( 1, J ), 1 )
00740 ELSE
00741 T( J, J ) = CZERO
00742 END IF
00743 ALPHA( J ) = H( J, J )
00744 BETA( J ) = T( J, J )
00745 200 CONTINUE
00746
00747
00748
00749 INFO = 0
00750
00751
00752
00753 210 CONTINUE
00754 WORK( 1 ) = CMPLX( N )
00755 RETURN
00756
00757
00758
00759 END