00001 SUBROUTINE ZSTEQR( COMPZ, N, D, E, Z, LDZ, WORK, INFO )
00002
00003
00004
00005
00006
00007
00008
00009 CHARACTER COMPZ
00010 INTEGER INFO, LDZ, N
00011
00012
00013 DOUBLE PRECISION D( * ), E( * ), WORK( * )
00014 COMPLEX*16 Z( LDZ, * )
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 DOUBLE PRECISION ZERO, ONE, TWO, THREE
00081 PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0, TWO = 2.0D0,
00082 $ THREE = 3.0D0 )
00083 COMPLEX*16 CZERO, CONE
00084 PARAMETER ( CZERO = ( 0.0D0, 0.0D0 ),
00085 $ CONE = ( 1.0D0, 0.0D0 ) )
00086 INTEGER MAXIT
00087 PARAMETER ( MAXIT = 30 )
00088
00089
00090 INTEGER I, ICOMPZ, II, ISCALE, J, JTOT, K, L, L1, LEND,
00091 $ LENDM1, LENDP1, LENDSV, LM1, LSV, M, MM, MM1,
00092 $ NM1, NMAXIT
00093 DOUBLE PRECISION ANORM, B, C, EPS, EPS2, F, G, P, R, RT1, RT2,
00094 $ S, SAFMAX, SAFMIN, SSFMAX, SSFMIN, TST
00095
00096
00097 LOGICAL LSAME
00098 DOUBLE PRECISION DLAMCH, DLANST, DLAPY2
00099 EXTERNAL LSAME, DLAMCH, DLANST, DLAPY2
00100
00101
00102 EXTERNAL DLAE2, DLAEV2, DLARTG, DLASCL, DLASRT, XERBLA,
00103 $ ZLASET, ZLASR, ZSWAP
00104
00105
00106 INTRINSIC ABS, MAX, SIGN, SQRT
00107
00108
00109
00110
00111
00112 INFO = 0
00113
00114 IF( LSAME( COMPZ, 'N' ) ) THEN
00115 ICOMPZ = 0
00116 ELSE IF( LSAME( COMPZ, 'V' ) ) THEN
00117 ICOMPZ = 1
00118 ELSE IF( LSAME( COMPZ, 'I' ) ) THEN
00119 ICOMPZ = 2
00120 ELSE
00121 ICOMPZ = -1
00122 END IF
00123 IF( ICOMPZ.LT.0 ) THEN
00124 INFO = -1
00125 ELSE IF( N.LT.0 ) THEN
00126 INFO = -2
00127 ELSE IF( ( LDZ.LT.1 ) .OR. ( ICOMPZ.GT.0 .AND. LDZ.LT.MAX( 1,
00128 $ N ) ) ) THEN
00129 INFO = -6
00130 END IF
00131 IF( INFO.NE.0 ) THEN
00132 CALL XERBLA( 'ZSTEQR', -INFO )
00133 RETURN
00134 END IF
00135
00136
00137
00138 IF( N.EQ.0 )
00139 $ RETURN
00140
00141 IF( N.EQ.1 ) THEN
00142 IF( ICOMPZ.EQ.2 )
00143 $ Z( 1, 1 ) = CONE
00144 RETURN
00145 END IF
00146
00147
00148
00149 EPS = DLAMCH( 'E' )
00150 EPS2 = EPS**2
00151 SAFMIN = DLAMCH( 'S' )
00152 SAFMAX = ONE / SAFMIN
00153 SSFMAX = SQRT( SAFMAX ) / THREE
00154 SSFMIN = SQRT( SAFMIN ) / EPS2
00155
00156
00157
00158
00159 IF( ICOMPZ.EQ.2 )
00160 $ CALL ZLASET( 'Full', N, N, CZERO, CONE, Z, LDZ )
00161
00162 NMAXIT = N*MAXIT
00163 JTOT = 0
00164
00165
00166
00167
00168
00169 L1 = 1
00170 NM1 = N - 1
00171
00172 10 CONTINUE
00173 IF( L1.GT.N )
00174 $ GO TO 160
00175 IF( L1.GT.1 )
00176 $ E( L1-1 ) = ZERO
00177 IF( L1.LE.NM1 ) THEN
00178 DO 20 M = L1, NM1
00179 TST = ABS( E( M ) )
00180 IF( TST.EQ.ZERO )
00181 $ GO TO 30
00182 IF( TST.LE.( SQRT( ABS( D( M ) ) )*SQRT( ABS( D( M+
00183 $ 1 ) ) ) )*EPS ) THEN
00184 E( M ) = ZERO
00185 GO TO 30
00186 END IF
00187 20 CONTINUE
00188 END IF
00189 M = N
00190
00191 30 CONTINUE
00192 L = L1
00193 LSV = L
00194 LEND = M
00195 LENDSV = LEND
00196 L1 = M + 1
00197 IF( LEND.EQ.L )
00198 $ GO TO 10
00199
00200
00201
00202 ANORM = DLANST( 'I', LEND-L+1, D( L ), E( L ) )
00203 ISCALE = 0
00204 IF( ANORM.EQ.ZERO )
00205 $ GO TO 10
00206 IF( ANORM.GT.SSFMAX ) THEN
00207 ISCALE = 1
00208 CALL DLASCL( 'G', 0, 0, ANORM, SSFMAX, LEND-L+1, 1, D( L ), N,
00209 $ INFO )
00210 CALL DLASCL( 'G', 0, 0, ANORM, SSFMAX, LEND-L, 1, E( L ), N,
00211 $ INFO )
00212 ELSE IF( ANORM.LT.SSFMIN ) THEN
00213 ISCALE = 2
00214 CALL DLASCL( 'G', 0, 0, ANORM, SSFMIN, LEND-L+1, 1, D( L ), N,
00215 $ INFO )
00216 CALL DLASCL( 'G', 0, 0, ANORM, SSFMIN, LEND-L, 1, E( L ), N,
00217 $ INFO )
00218 END IF
00219
00220
00221
00222 IF( ABS( D( LEND ) ).LT.ABS( D( L ) ) ) THEN
00223 LEND = LSV
00224 L = LENDSV
00225 END IF
00226
00227 IF( LEND.GT.L ) THEN
00228
00229
00230
00231
00232
00233 40 CONTINUE
00234 IF( L.NE.LEND ) THEN
00235 LENDM1 = LEND - 1
00236 DO 50 M = L, LENDM1
00237 TST = ABS( E( M ) )**2
00238 IF( TST.LE.( EPS2*ABS( D( M ) ) )*ABS( D( M+1 ) )+
00239 $ SAFMIN )GO TO 60
00240 50 CONTINUE
00241 END IF
00242
00243 M = LEND
00244
00245 60 CONTINUE
00246 IF( M.LT.LEND )
00247 $ E( M ) = ZERO
00248 P = D( L )
00249 IF( M.EQ.L )
00250 $ GO TO 80
00251
00252
00253
00254
00255 IF( M.EQ.L+1 ) THEN
00256 IF( ICOMPZ.GT.0 ) THEN
00257 CALL DLAEV2( D( L ), E( L ), D( L+1 ), RT1, RT2, C, S )
00258 WORK( L ) = C
00259 WORK( N-1+L ) = S
00260 CALL ZLASR( 'R', 'V', 'B', N, 2, WORK( L ),
00261 $ WORK( N-1+L ), Z( 1, L ), LDZ )
00262 ELSE
00263 CALL DLAE2( D( L ), E( L ), D( L+1 ), RT1, RT2 )
00264 END IF
00265 D( L ) = RT1
00266 D( L+1 ) = RT2
00267 E( L ) = ZERO
00268 L = L + 2
00269 IF( L.LE.LEND )
00270 $ GO TO 40
00271 GO TO 140
00272 END IF
00273
00274 IF( JTOT.EQ.NMAXIT )
00275 $ GO TO 140
00276 JTOT = JTOT + 1
00277
00278
00279
00280 G = ( D( L+1 )-P ) / ( TWO*E( L ) )
00281 R = DLAPY2( G, ONE )
00282 G = D( M ) - P + ( E( L ) / ( G+SIGN( R, G ) ) )
00283
00284 S = ONE
00285 C = ONE
00286 P = ZERO
00287
00288
00289
00290 MM1 = M - 1
00291 DO 70 I = MM1, L, -1
00292 F = S*E( I )
00293 B = C*E( I )
00294 CALL DLARTG( G, F, C, S, R )
00295 IF( I.NE.M-1 )
00296 $ E( I+1 ) = R
00297 G = D( I+1 ) - P
00298 R = ( D( I )-G )*S + TWO*C*B
00299 P = S*R
00300 D( I+1 ) = G + P
00301 G = C*R - B
00302
00303
00304
00305 IF( ICOMPZ.GT.0 ) THEN
00306 WORK( I ) = C
00307 WORK( N-1+I ) = -S
00308 END IF
00309
00310 70 CONTINUE
00311
00312
00313
00314 IF( ICOMPZ.GT.0 ) THEN
00315 MM = M - L + 1
00316 CALL ZLASR( 'R', 'V', 'B', N, MM, WORK( L ), WORK( N-1+L ),
00317 $ Z( 1, L ), LDZ )
00318 END IF
00319
00320 D( L ) = D( L ) - P
00321 E( L ) = G
00322 GO TO 40
00323
00324
00325
00326 80 CONTINUE
00327 D( L ) = P
00328
00329 L = L + 1
00330 IF( L.LE.LEND )
00331 $ GO TO 40
00332 GO TO 140
00333
00334 ELSE
00335
00336
00337
00338
00339
00340 90 CONTINUE
00341 IF( L.NE.LEND ) THEN
00342 LENDP1 = LEND + 1
00343 DO 100 M = L, LENDP1, -1
00344 TST = ABS( E( M-1 ) )**2
00345 IF( TST.LE.( EPS2*ABS( D( M ) ) )*ABS( D( M-1 ) )+
00346 $ SAFMIN )GO TO 110
00347 100 CONTINUE
00348 END IF
00349
00350 M = LEND
00351
00352 110 CONTINUE
00353 IF( M.GT.LEND )
00354 $ E( M-1 ) = ZERO
00355 P = D( L )
00356 IF( M.EQ.L )
00357 $ GO TO 130
00358
00359
00360
00361
00362 IF( M.EQ.L-1 ) THEN
00363 IF( ICOMPZ.GT.0 ) THEN
00364 CALL DLAEV2( D( L-1 ), E( L-1 ), D( L ), RT1, RT2, C, S )
00365 WORK( M ) = C
00366 WORK( N-1+M ) = S
00367 CALL ZLASR( 'R', 'V', 'F', N, 2, WORK( M ),
00368 $ WORK( N-1+M ), Z( 1, L-1 ), LDZ )
00369 ELSE
00370 CALL DLAE2( D( L-1 ), E( L-1 ), D( L ), RT1, RT2 )
00371 END IF
00372 D( L-1 ) = RT1
00373 D( L ) = RT2
00374 E( L-1 ) = ZERO
00375 L = L - 2
00376 IF( L.GE.LEND )
00377 $ GO TO 90
00378 GO TO 140
00379 END IF
00380
00381 IF( JTOT.EQ.NMAXIT )
00382 $ GO TO 140
00383 JTOT = JTOT + 1
00384
00385
00386
00387 G = ( D( L-1 )-P ) / ( TWO*E( L-1 ) )
00388 R = DLAPY2( G, ONE )
00389 G = D( M ) - P + ( E( L-1 ) / ( G+SIGN( R, G ) ) )
00390
00391 S = ONE
00392 C = ONE
00393 P = ZERO
00394
00395
00396
00397 LM1 = L - 1
00398 DO 120 I = M, LM1
00399 F = S*E( I )
00400 B = C*E( I )
00401 CALL DLARTG( G, F, C, S, R )
00402 IF( I.NE.M )
00403 $ E( I-1 ) = R
00404 G = D( I ) - P
00405 R = ( D( I+1 )-G )*S + TWO*C*B
00406 P = S*R
00407 D( I ) = G + P
00408 G = C*R - B
00409
00410
00411
00412 IF( ICOMPZ.GT.0 ) THEN
00413 WORK( I ) = C
00414 WORK( N-1+I ) = S
00415 END IF
00416
00417 120 CONTINUE
00418
00419
00420
00421 IF( ICOMPZ.GT.0 ) THEN
00422 MM = L - M + 1
00423 CALL ZLASR( 'R', 'V', 'F', N, MM, WORK( M ), WORK( N-1+M ),
00424 $ Z( 1, M ), LDZ )
00425 END IF
00426
00427 D( L ) = D( L ) - P
00428 E( LM1 ) = G
00429 GO TO 90
00430
00431
00432
00433 130 CONTINUE
00434 D( L ) = P
00435
00436 L = L - 1
00437 IF( L.GE.LEND )
00438 $ GO TO 90
00439 GO TO 140
00440
00441 END IF
00442
00443
00444
00445 140 CONTINUE
00446 IF( ISCALE.EQ.1 ) THEN
00447 CALL DLASCL( 'G', 0, 0, SSFMAX, ANORM, LENDSV-LSV+1, 1,
00448 $ D( LSV ), N, INFO )
00449 CALL DLASCL( 'G', 0, 0, SSFMAX, ANORM, LENDSV-LSV, 1, E( LSV ),
00450 $ N, INFO )
00451 ELSE IF( ISCALE.EQ.2 ) THEN
00452 CALL DLASCL( 'G', 0, 0, SSFMIN, ANORM, LENDSV-LSV+1, 1,
00453 $ D( LSV ), N, INFO )
00454 CALL DLASCL( 'G', 0, 0, SSFMIN, ANORM, LENDSV-LSV, 1, E( LSV ),
00455 $ N, INFO )
00456 END IF
00457
00458
00459
00460
00461 IF( JTOT.EQ.NMAXIT ) THEN
00462 DO 150 I = 1, N - 1
00463 IF( E( I ).NE.ZERO )
00464 $ INFO = INFO + 1
00465 150 CONTINUE
00466 RETURN
00467 END IF
00468 GO TO 10
00469
00470
00471
00472 160 CONTINUE
00473 IF( ICOMPZ.EQ.0 ) THEN
00474
00475
00476
00477 CALL DLASRT( 'I', N, D, INFO )
00478
00479 ELSE
00480
00481
00482
00483 DO 180 II = 2, N
00484 I = II - 1
00485 K = I
00486 P = D( I )
00487 DO 170 J = II, N
00488 IF( D( J ).LT.P ) THEN
00489 K = J
00490 P = D( J )
00491 END IF
00492 170 CONTINUE
00493 IF( K.NE.I ) THEN
00494 D( K ) = D( I )
00495 D( I ) = P
00496 CALL ZSWAP( N, Z( 1, I ), 1, Z( 1, K ), 1 )
00497 END IF
00498 180 CONTINUE
00499 END IF
00500 RETURN
00501
00502
00503
00504 END