178 SUBROUTINE dstedc( COMPZ, N, D, E, Z, LDZ, WORK, LWORK, IWORK,
187 INTEGER INFO, LDZ, LIWORK, LWORK, N
191 DOUBLE PRECISION D( * ), E( * ), WORK( * ), Z( LDZ, * )
197 DOUBLE PRECISION ZERO, ONE, TWO
198 parameter( zero = 0.0d0, one = 1.0d0, two = 2.0d0 )
202 INTEGER FINISH, I, ICOMPZ, II, J, K, LGN, LIWMIN,
203 $ lwmin, m, smlsiz, start, storez, strtrw
204 DOUBLE PRECISION EPS, ORGNRM, P, TINY
209 DOUBLE PRECISION DLAMCH, DLANST
210 EXTERNAL lsame, ilaenv, dlamch, dlanst
218 INTRINSIC abs, dble, int, log, max, mod, sqrt
225 lquery = ( lwork.EQ.-1 .OR. liwork.EQ.-1 )
227 IF( lsame( compz,
'N' ) )
THEN
229 ELSE IF( lsame( compz,
'V' ) )
THEN
231 ELSE IF( lsame( compz,
'I' ) )
THEN
236 IF( icompz.LT.0 )
THEN
238 ELSE IF( n.LT.0 )
THEN
240 ELSE IF( ( ldz.LT.1 ) .OR.
241 $ ( icompz.GT.0 .AND. ldz.LT.max( 1, n ) ) )
THEN
249 smlsiz = ilaenv( 9,
'DSTEDC',
' ', 0, 0, 0, 0 )
250 IF( n.LE.1 .OR. icompz.EQ.0 )
THEN
253 ELSE IF( n.LE.smlsiz )
THEN
257 lgn = int( log( dble( n ) )/log( two ) )
262 IF( icompz.EQ.1 )
THEN
263 lwmin = 1 + 3*n + 2*n*lgn + 4*n**2
264 liwmin = 6 + 6*n + 5*n*lgn
265 ELSE IF( icompz.EQ.2 )
THEN
266 lwmin = 1 + 4*n + n**2
273 IF( lwork.LT.lwmin .AND. .NOT. lquery )
THEN
275 ELSE IF( liwork.LT.liwmin .AND. .NOT. lquery )
THEN
281 CALL xerbla(
'DSTEDC', -info )
283 ELSE IF (lquery)
THEN
308 IF( icompz.EQ.0 )
THEN
309 CALL dsterf( n, d, e, info )
316 IF( n.LE.smlsiz )
THEN
318 CALL dsteqr( compz, n, d, e, z, ldz, work, info )
325 IF( icompz.EQ.1 )
THEN
331 IF( icompz.EQ.2 )
THEN
332 CALL dlaset(
'Full', n, n, zero, one, z, ldz )
337 orgnrm = dlanst(
'M', n, d, e )
341 eps = dlamch(
'Epsilon' )
348 IF( start.LE.n )
THEN
358 IF( finish.LT.n )
THEN
359 tiny = eps*sqrt( abs( d( finish ) ) )*
360 $ sqrt( abs( d( finish+1 ) ) )
361 IF( abs( e( finish ) ).GT.tiny )
THEN
369 m = finish - start + 1
374 IF( m.GT.smlsiz )
THEN
378 orgnrm = dlanst(
'M', m, d( start ), e( start ) )
379 CALL dlascl(
'G', 0, 0, orgnrm, one, m, 1, d( start ),
382 CALL dlascl(
'G', 0, 0, orgnrm, one, m-1, 1,
386 IF( icompz.EQ.1 )
THEN
391 CALL dlaed0( icompz, n, m, d( start ), e( start ),
392 $ z( strtrw, start ), ldz, work( 1 ), n,
393 $ work( storez ), iwork, info )
395 info = ( info / ( m+1 )+start-1 )*( n+1 ) +
396 $ mod( info, ( m+1 ) ) + start - 1
402 CALL dlascl(
'G', 0, 0, one, orgnrm, m, 1, d( start ),
407 IF( icompz.EQ.1 )
THEN
413 CALL dsteqr(
'I', m, d( start ), e( start ), work,
415 $ work( m*m+1 ), info )
416 CALL dlacpy(
'A', n, m, z( 1, start ), ldz,
417 $ work( storez ), n )
418 CALL dgemm(
'N',
'N', n, m, m, one,
419 $ work( storez ), n, work, m, zero,
420 $ z( 1, start ), ldz )
421 ELSE IF( icompz.EQ.2 )
THEN
422 CALL dsteqr(
'I', m, d( start ), e( start ),
423 $ z( start, start ), ldz, work, info )
425 CALL dsterf( m, d( start ), e( start ), info )
428 info = start*( n+1 ) + finish
439 IF( icompz.EQ.0 )
THEN
443 CALL dlasrt(
'I', n, d, info )
454 IF( d( j ).LT.p )
THEN
462 CALL dswap( n, z( 1, i ), 1, z( 1, k ), 1 )