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