00001 SUBROUTINE DSTEDC( COMPZ, N, D, E, Z, LDZ, WORK, LWORK, IWORK,
00002 $ LIWORK, INFO )
00003
00004
00005
00006
00007
00008
00009
00010 CHARACTER COMPZ
00011 INTEGER INFO, LDZ, LIWORK, LWORK, N
00012
00013
00014 INTEGER IWORK( * )
00015 DOUBLE PRECISION D( * ), E( * ), WORK( * ), Z( LDZ, * )
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 DOUBLE PRECISION ZERO, ONE, TWO
00129 PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0, TWO = 2.0D0 )
00130
00131
00132 LOGICAL LQUERY
00133 INTEGER FINISH, I, ICOMPZ, II, J, K, LGN, LIWMIN,
00134 $ LWMIN, M, SMLSIZ, START, STOREZ, STRTRW
00135 DOUBLE PRECISION EPS, ORGNRM, P, TINY
00136
00137
00138 LOGICAL LSAME
00139 INTEGER ILAENV
00140 DOUBLE PRECISION DLAMCH, DLANST
00141 EXTERNAL LSAME, ILAENV, DLAMCH, DLANST
00142
00143
00144 EXTERNAL DGEMM, DLACPY, DLAED0, DLASCL, DLASET, DLASRT,
00145 $ DSTEQR, DSTERF, DSWAP, XERBLA
00146
00147
00148 INTRINSIC ABS, DBLE, INT, LOG, MAX, MOD, SQRT
00149
00150
00151
00152
00153
00154 INFO = 0
00155 LQUERY = ( LWORK.EQ.-1 .OR. LIWORK.EQ.-1 )
00156
00157 IF( LSAME( COMPZ, 'N' ) ) THEN
00158 ICOMPZ = 0
00159 ELSE IF( LSAME( COMPZ, 'V' ) ) THEN
00160 ICOMPZ = 1
00161 ELSE IF( LSAME( COMPZ, 'I' ) ) THEN
00162 ICOMPZ = 2
00163 ELSE
00164 ICOMPZ = -1
00165 END IF
00166 IF( ICOMPZ.LT.0 ) THEN
00167 INFO = -1
00168 ELSE IF( N.LT.0 ) THEN
00169 INFO = -2
00170 ELSE IF( ( LDZ.LT.1 ) .OR.
00171 $ ( ICOMPZ.GT.0 .AND. LDZ.LT.MAX( 1, N ) ) ) THEN
00172 INFO = -6
00173 END IF
00174
00175 IF( INFO.EQ.0 ) THEN
00176
00177
00178
00179 SMLSIZ = ILAENV( 9, 'DSTEDC', ' ', 0, 0, 0, 0 )
00180 IF( N.LE.1 .OR. ICOMPZ.EQ.0 ) THEN
00181 LIWMIN = 1
00182 LWMIN = 1
00183 ELSE IF( N.LE.SMLSIZ ) THEN
00184 LIWMIN = 1
00185 LWMIN = 2*( N - 1 )
00186 ELSE
00187 LGN = INT( LOG( DBLE( N ) )/LOG( TWO ) )
00188 IF( 2**LGN.LT.N )
00189 $ LGN = LGN + 1
00190 IF( 2**LGN.LT.N )
00191 $ LGN = LGN + 1
00192 IF( ICOMPZ.EQ.1 ) THEN
00193 LWMIN = 1 + 3*N + 2*N*LGN + 3*N**2
00194 LIWMIN = 6 + 6*N + 5*N*LGN
00195 ELSE IF( ICOMPZ.EQ.2 ) THEN
00196 LWMIN = 1 + 4*N + N**2
00197 LIWMIN = 3 + 5*N
00198 END IF
00199 END IF
00200 WORK( 1 ) = LWMIN
00201 IWORK( 1 ) = LIWMIN
00202
00203 IF( LWORK.LT.LWMIN .AND. .NOT. LQUERY ) THEN
00204 INFO = -8
00205 ELSE IF( LIWORK.LT.LIWMIN .AND. .NOT. LQUERY ) THEN
00206 INFO = -10
00207 END IF
00208 END IF
00209
00210 IF( INFO.NE.0 ) THEN
00211 CALL XERBLA( 'DSTEDC', -INFO )
00212 RETURN
00213 ELSE IF (LQUERY) THEN
00214 RETURN
00215 END IF
00216
00217
00218
00219 IF( N.EQ.0 )
00220 $ RETURN
00221 IF( N.EQ.1 ) THEN
00222 IF( ICOMPZ.NE.0 )
00223 $ Z( 1, 1 ) = ONE
00224 RETURN
00225 END IF
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238 IF( ICOMPZ.EQ.0 ) THEN
00239 CALL DSTERF( N, D, E, INFO )
00240 GO TO 50
00241 END IF
00242
00243
00244
00245
00246 IF( N.LE.SMLSIZ ) THEN
00247
00248 CALL DSTEQR( COMPZ, N, D, E, Z, LDZ, WORK, INFO )
00249
00250 ELSE
00251
00252
00253
00254
00255 IF( ICOMPZ.EQ.1 ) THEN
00256 STOREZ = 1 + N*N
00257 ELSE
00258 STOREZ = 1
00259 END IF
00260
00261 IF( ICOMPZ.EQ.2 ) THEN
00262 CALL DLASET( 'Full', N, N, ZERO, ONE, Z, LDZ )
00263 END IF
00264
00265
00266
00267 ORGNRM = DLANST( 'M', N, D, E )
00268 IF( ORGNRM.EQ.ZERO )
00269 $ GO TO 50
00270
00271 EPS = DLAMCH( 'Epsilon' )
00272
00273 START = 1
00274
00275
00276
00277 10 CONTINUE
00278 IF( START.LE.N ) THEN
00279
00280
00281
00282
00283
00284
00285
00286 FINISH = START
00287 20 CONTINUE
00288 IF( FINISH.LT.N ) THEN
00289 TINY = EPS*SQRT( ABS( D( FINISH ) ) )*
00290 $ SQRT( ABS( D( FINISH+1 ) ) )
00291 IF( ABS( E( FINISH ) ).GT.TINY ) THEN
00292 FINISH = FINISH + 1
00293 GO TO 20
00294 END IF
00295 END IF
00296
00297
00298
00299 M = FINISH - START + 1
00300 IF( M.EQ.1 ) THEN
00301 START = FINISH + 1
00302 GO TO 10
00303 END IF
00304 IF( M.GT.SMLSIZ ) THEN
00305
00306
00307
00308 ORGNRM = DLANST( 'M', M, D( START ), E( START ) )
00309 CALL DLASCL( 'G', 0, 0, ORGNRM, ONE, M, 1, D( START ), M,
00310 $ INFO )
00311 CALL DLASCL( 'G', 0, 0, ORGNRM, ONE, M-1, 1, E( START ),
00312 $ M-1, INFO )
00313
00314 IF( ICOMPZ.EQ.1 ) THEN
00315 STRTRW = 1
00316 ELSE
00317 STRTRW = START
00318 END IF
00319 CALL DLAED0( ICOMPZ, N, M, D( START ), E( START ),
00320 $ Z( STRTRW, START ), LDZ, WORK( 1 ), N,
00321 $ WORK( STOREZ ), IWORK, INFO )
00322 IF( INFO.NE.0 ) THEN
00323 INFO = ( INFO / ( M+1 )+START-1 )*( N+1 ) +
00324 $ MOD( INFO, ( M+1 ) ) + START - 1
00325 GO TO 50
00326 END IF
00327
00328
00329
00330 CALL DLASCL( 'G', 0, 0, ONE, ORGNRM, M, 1, D( START ), M,
00331 $ INFO )
00332
00333 ELSE
00334 IF( ICOMPZ.EQ.1 ) THEN
00335
00336
00337
00338
00339
00340 CALL DSTEQR( 'I', M, D( START ), E( START ), WORK, M,
00341 $ WORK( M*M+1 ), INFO )
00342 CALL DLACPY( 'A', N, M, Z( 1, START ), LDZ,
00343 $ WORK( STOREZ ), N )
00344 CALL DGEMM( 'N', 'N', N, M, M, ONE,
00345 $ WORK( STOREZ ), N, WORK, M, ZERO,
00346 $ Z( 1, START ), LDZ )
00347 ELSE IF( ICOMPZ.EQ.2 ) THEN
00348 CALL DSTEQR( 'I', M, D( START ), E( START ),
00349 $ Z( START, START ), LDZ, WORK, INFO )
00350 ELSE
00351 CALL DSTERF( M, D( START ), E( START ), INFO )
00352 END IF
00353 IF( INFO.NE.0 ) THEN
00354 INFO = START*( N+1 ) + FINISH
00355 GO TO 50
00356 END IF
00357 END IF
00358
00359 START = FINISH + 1
00360 GO TO 10
00361 END IF
00362
00363
00364
00365
00366
00367
00368
00369 IF( M.NE.N ) THEN
00370 IF( ICOMPZ.EQ.0 ) THEN
00371
00372
00373
00374 CALL DLASRT( 'I', N, D, INFO )
00375
00376 ELSE
00377
00378
00379
00380 DO 40 II = 2, N
00381 I = II - 1
00382 K = I
00383 P = D( I )
00384 DO 30 J = II, N
00385 IF( D( J ).LT.P ) THEN
00386 K = J
00387 P = D( J )
00388 END IF
00389 30 CONTINUE
00390 IF( K.NE.I ) THEN
00391 D( K ) = D( I )
00392 D( I ) = P
00393 CALL DSWAP( N, Z( 1, I ), 1, Z( 1, K ), 1 )
00394 END IF
00395 40 CONTINUE
00396 END IF
00397 END IF
00398 END IF
00399
00400 50 CONTINUE
00401 WORK( 1 ) = LWMIN
00402 IWORK( 1 ) = LIWMIN
00403
00404 RETURN
00405
00406
00407
00408 END