00001 SUBROUTINE SLAHQR( WANTT, WANTZ, N, ILO, IHI, H, LDH, WR, WI,
00002 $ ILOZ, IHIZ, Z, LDZ, INFO )
00003
00004
00005
00006
00007
00008
00009 INTEGER IHI, IHIZ, ILO, ILOZ, INFO, LDH, LDZ, N
00010 LOGICAL WANTT, WANTZ
00011
00012
00013 REAL H( LDH, * ), WI( * ), WR( * ), Z( LDZ, * )
00014
00015
00016
00017
00018
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 INTEGER ITMAX
00130 PARAMETER ( ITMAX = 30 )
00131 REAL ZERO, ONE, TWO
00132 PARAMETER ( ZERO = 0.0e0, ONE = 1.0e0, TWO = 2.0e0 )
00133 REAL DAT1, DAT2
00134 PARAMETER ( DAT1 = 3.0e0 / 4.0e0, DAT2 = -0.4375e0 )
00135
00136
00137 REAL AA, AB, BA, BB, CS, DET, H11, H12, H21, H21S,
00138 $ H22, RT1I, RT1R, RT2I, RT2R, RTDISC, S, SAFMAX,
00139 $ SAFMIN, SMLNUM, SN, SUM, T1, T2, T3, TR, TST,
00140 $ ULP, V2, V3
00141 INTEGER I, I1, I2, ITS, J, K, L, M, NH, NR, NZ
00142
00143
00144 REAL V( 3 )
00145
00146
00147 REAL SLAMCH
00148 EXTERNAL SLAMCH
00149
00150
00151 EXTERNAL SCOPY, SLABAD, SLANV2, SLARFG, SROT
00152
00153
00154 INTRINSIC ABS, MAX, MIN, REAL, SQRT
00155
00156
00157
00158 INFO = 0
00159
00160
00161
00162 IF( N.EQ.0 )
00163 $ RETURN
00164 IF( ILO.EQ.IHI ) THEN
00165 WR( ILO ) = H( ILO, ILO )
00166 WI( ILO ) = ZERO
00167 RETURN
00168 END IF
00169
00170
00171 DO 10 J = ILO, IHI - 3
00172 H( J+2, J ) = ZERO
00173 H( J+3, J ) = ZERO
00174 10 CONTINUE
00175 IF( ILO.LE.IHI-2 )
00176 $ H( IHI, IHI-2 ) = ZERO
00177
00178 NH = IHI - ILO + 1
00179 NZ = IHIZ - ILOZ + 1
00180
00181
00182
00183 SAFMIN = SLAMCH( 'SAFE MINIMUM' )
00184 SAFMAX = ONE / SAFMIN
00185 CALL SLABAD( SAFMIN, SAFMAX )
00186 ULP = SLAMCH( 'PRECISION' )
00187 SMLNUM = SAFMIN*( REAL( NH ) / ULP )
00188
00189
00190
00191
00192
00193 IF( WANTT ) THEN
00194 I1 = 1
00195 I2 = N
00196 END IF
00197
00198
00199
00200
00201
00202
00203
00204 I = IHI
00205 20 CONTINUE
00206 L = ILO
00207 IF( I.LT.ILO )
00208 $ GO TO 160
00209
00210
00211
00212
00213
00214 DO 140 ITS = 0, ITMAX
00215
00216
00217
00218 DO 30 K = I, L + 1, -1
00219 IF( ABS( H( K, K-1 ) ).LE.SMLNUM )
00220 $ GO TO 40
00221 TST = ABS( H( K-1, K-1 ) ) + ABS( H( K, K ) )
00222 IF( TST.EQ.ZERO ) THEN
00223 IF( K-2.GE.ILO )
00224 $ TST = TST + ABS( H( K-1, K-2 ) )
00225 IF( K+1.LE.IHI )
00226 $ TST = TST + ABS( H( K+1, K ) )
00227 END IF
00228
00229
00230
00231
00232 IF( ABS( H( K, K-1 ) ).LE.ULP*TST ) THEN
00233 AB = MAX( ABS( H( K, K-1 ) ), ABS( H( K-1, K ) ) )
00234 BA = MIN( ABS( H( K, K-1 ) ), ABS( H( K-1, K ) ) )
00235 AA = MAX( ABS( H( K, K ) ),
00236 $ ABS( H( K-1, K-1 )-H( K, K ) ) )
00237 BB = MIN( ABS( H( K, K ) ),
00238 $ ABS( H( K-1, K-1 )-H( K, K ) ) )
00239 S = AA + AB
00240 IF( BA*( AB / S ).LE.MAX( SMLNUM,
00241 $ ULP*( BB*( AA / S ) ) ) )GO TO 40
00242 END IF
00243 30 CONTINUE
00244 40 CONTINUE
00245 L = K
00246 IF( L.GT.ILO ) THEN
00247
00248
00249
00250 H( L, L-1 ) = ZERO
00251 END IF
00252
00253
00254
00255 IF( L.GE.I-1 )
00256 $ GO TO 150
00257
00258
00259
00260
00261
00262 IF( .NOT.WANTT ) THEN
00263 I1 = L
00264 I2 = I
00265 END IF
00266
00267 IF( ITS.EQ.10 ) THEN
00268
00269
00270
00271 S = ABS( H( L+1, L ) ) + ABS( H( L+2, L+1 ) )
00272 H11 = DAT1*S + H( L, L )
00273 H12 = DAT2*S
00274 H21 = S
00275 H22 = H11
00276 ELSE IF( ITS.EQ.20 ) THEN
00277
00278
00279
00280 S = ABS( H( I, I-1 ) ) + ABS( H( I-1, I-2 ) )
00281 H11 = DAT1*S + H( I, I )
00282 H12 = DAT2*S
00283 H21 = S
00284 H22 = H11
00285 ELSE
00286
00287
00288
00289
00290 H11 = H( I-1, I-1 )
00291 H21 = H( I, I-1 )
00292 H12 = H( I-1, I )
00293 H22 = H( I, I )
00294 END IF
00295 S = ABS( H11 ) + ABS( H12 ) + ABS( H21 ) + ABS( H22 )
00296 IF( S.EQ.ZERO ) THEN
00297 RT1R = ZERO
00298 RT1I = ZERO
00299 RT2R = ZERO
00300 RT2I = ZERO
00301 ELSE
00302 H11 = H11 / S
00303 H21 = H21 / S
00304 H12 = H12 / S
00305 H22 = H22 / S
00306 TR = ( H11+H22 ) / TWO
00307 DET = ( H11-TR )*( H22-TR ) - H12*H21
00308 RTDISC = SQRT( ABS( DET ) )
00309 IF( DET.GE.ZERO ) THEN
00310
00311
00312
00313 RT1R = TR*S
00314 RT2R = RT1R
00315 RT1I = RTDISC*S
00316 RT2I = -RT1I
00317 ELSE
00318
00319
00320
00321 RT1R = TR + RTDISC
00322 RT2R = TR - RTDISC
00323 IF( ABS( RT1R-H22 ).LE.ABS( RT2R-H22 ) ) THEN
00324 RT1R = RT1R*S
00325 RT2R = RT1R
00326 ELSE
00327 RT2R = RT2R*S
00328 RT1R = RT2R
00329 END IF
00330 RT1I = ZERO
00331 RT2I = ZERO
00332 END IF
00333 END IF
00334
00335
00336
00337 DO 50 M = I - 2, L, -1
00338
00339
00340
00341
00342
00343 H21S = H( M+1, M )
00344 S = ABS( H( M, M )-RT2R ) + ABS( RT2I ) + ABS( H21S )
00345 H21S = H( M+1, M ) / S
00346 V( 1 ) = H21S*H( M, M+1 ) + ( H( M, M )-RT1R )*
00347 $ ( ( H( M, M )-RT2R ) / S ) - RT1I*( RT2I / S )
00348 V( 2 ) = H21S*( H( M, M )+H( M+1, M+1 )-RT1R-RT2R )
00349 V( 3 ) = H21S*H( M+2, M+1 )
00350 S = ABS( V( 1 ) ) + ABS( V( 2 ) ) + ABS( V( 3 ) )
00351 V( 1 ) = V( 1 ) / S
00352 V( 2 ) = V( 2 ) / S
00353 V( 3 ) = V( 3 ) / S
00354 IF( M.EQ.L )
00355 $ GO TO 60
00356 IF( ABS( H( M, M-1 ) )*( ABS( V( 2 ) )+ABS( V( 3 ) ) ).LE.
00357 $ ULP*ABS( V( 1 ) )*( ABS( H( M-1, M-1 ) )+ABS( H( M,
00358 $ M ) )+ABS( H( M+1, M+1 ) ) ) )GO TO 60
00359 50 CONTINUE
00360 60 CONTINUE
00361
00362
00363
00364 DO 130 K = M, I - 1
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375 NR = MIN( 3, I-K+1 )
00376 IF( K.GT.M )
00377 $ CALL SCOPY( NR, H( K, K-1 ), 1, V, 1 )
00378 CALL SLARFG( NR, V( 1 ), V( 2 ), 1, T1 )
00379 IF( K.GT.M ) THEN
00380 H( K, K-1 ) = V( 1 )
00381 H( K+1, K-1 ) = ZERO
00382 IF( K.LT.I-1 )
00383 $ H( K+2, K-1 ) = ZERO
00384 ELSE IF( M.GT.L ) THEN
00385
00386
00387
00388
00389 H( K, K-1 ) = H( K, K-1 )*( ONE-T1 )
00390 END IF
00391 V2 = V( 2 )
00392 T2 = T1*V2
00393 IF( NR.EQ.3 ) THEN
00394 V3 = V( 3 )
00395 T3 = T1*V3
00396
00397
00398
00399
00400 DO 70 J = K, I2
00401 SUM = H( K, J ) + V2*H( K+1, J ) + V3*H( K+2, J )
00402 H( K, J ) = H( K, J ) - SUM*T1
00403 H( K+1, J ) = H( K+1, J ) - SUM*T2
00404 H( K+2, J ) = H( K+2, J ) - SUM*T3
00405 70 CONTINUE
00406
00407
00408
00409
00410 DO 80 J = I1, MIN( K+3, I )
00411 SUM = H( J, K ) + V2*H( J, K+1 ) + V3*H( J, K+2 )
00412 H( J, K ) = H( J, K ) - SUM*T1
00413 H( J, K+1 ) = H( J, K+1 ) - SUM*T2
00414 H( J, K+2 ) = H( J, K+2 ) - SUM*T3
00415 80 CONTINUE
00416
00417 IF( WANTZ ) THEN
00418
00419
00420
00421 DO 90 J = ILOZ, IHIZ
00422 SUM = Z( J, K ) + V2*Z( J, K+1 ) + V3*Z( J, K+2 )
00423 Z( J, K ) = Z( J, K ) - SUM*T1
00424 Z( J, K+1 ) = Z( J, K+1 ) - SUM*T2
00425 Z( J, K+2 ) = Z( J, K+2 ) - SUM*T3
00426 90 CONTINUE
00427 END IF
00428 ELSE IF( NR.EQ.2 ) THEN
00429
00430
00431
00432
00433 DO 100 J = K, I2
00434 SUM = H( K, J ) + V2*H( K+1, J )
00435 H( K, J ) = H( K, J ) - SUM*T1
00436 H( K+1, J ) = H( K+1, J ) - SUM*T2
00437 100 CONTINUE
00438
00439
00440
00441
00442 DO 110 J = I1, I
00443 SUM = H( J, K ) + V2*H( J, K+1 )
00444 H( J, K ) = H( J, K ) - SUM*T1
00445 H( J, K+1 ) = H( J, K+1 ) - SUM*T2
00446 110 CONTINUE
00447
00448 IF( WANTZ ) THEN
00449
00450
00451
00452 DO 120 J = ILOZ, IHIZ
00453 SUM = Z( J, K ) + V2*Z( J, K+1 )
00454 Z( J, K ) = Z( J, K ) - SUM*T1
00455 Z( J, K+1 ) = Z( J, K+1 ) - SUM*T2
00456 120 CONTINUE
00457 END IF
00458 END IF
00459 130 CONTINUE
00460
00461 140 CONTINUE
00462
00463
00464
00465 INFO = I
00466 RETURN
00467
00468 150 CONTINUE
00469
00470 IF( L.EQ.I ) THEN
00471
00472
00473
00474 WR( I ) = H( I, I )
00475 WI( I ) = ZERO
00476 ELSE IF( L.EQ.I-1 ) THEN
00477
00478
00479
00480
00481
00482
00483 CALL SLANV2( H( I-1, I-1 ), H( I-1, I ), H( I, I-1 ),
00484 $ H( I, I ), WR( I-1 ), WI( I-1 ), WR( I ), WI( I ),
00485 $ CS, SN )
00486
00487 IF( WANTT ) THEN
00488
00489
00490
00491 IF( I2.GT.I )
00492 $ CALL SROT( I2-I, H( I-1, I+1 ), LDH, H( I, I+1 ), LDH,
00493 $ CS, SN )
00494 CALL SROT( I-I1-1, H( I1, I-1 ), 1, H( I1, I ), 1, CS, SN )
00495 END IF
00496 IF( WANTZ ) THEN
00497
00498
00499
00500 CALL SROT( NZ, Z( ILOZ, I-1 ), 1, Z( ILOZ, I ), 1, CS, SN )
00501 END IF
00502 END IF
00503
00504
00505
00506 I = L - 1
00507 GO TO 20
00508
00509 160 CONTINUE
00510 RETURN
00511
00512
00513
00514 END