186 SUBROUTINE dstedc( COMPZ, N, D, E, Z, LDZ, WORK, LWORK, IWORK,
195 INTEGER INFO, LDZ, LIWORK, LWORK, N
199 DOUBLE PRECISION D( * ), E( * ), WORK( * ), Z( LDZ, * )
205 DOUBLE PRECISION ZERO, ONE, TWO
206 parameter( zero = 0.0d0, one = 1.0d0, two = 2.0d0 )
210 INTEGER FINISH, I, ICOMPZ, II, J, K, LGN, LIWMIN,
211 $ lwmin, m, smlsiz, start, storez, strtrw
212 DOUBLE PRECISION EPS, ORGNRM, P, TINY
217 DOUBLE PRECISION DLAMCH, DLANST
218 EXTERNAL lsame, ilaenv, dlamch, dlanst
225 INTRINSIC abs, dble, int, log,
max, mod, sqrt
232 lquery = ( lwork.EQ.-1 .OR. liwork.EQ.-1 )
234 IF( lsame( compz,
'N' ) )
THEN
236 ELSE IF( lsame( compz,
'V' ) )
THEN
238 ELSE IF( lsame( compz,
'I' ) )
THEN
243 IF( icompz.LT.0 )
THEN
245 ELSE IF( n.LT.0 )
THEN
247 ELSE IF( ( ldz.LT.1 ) .OR.
248 $ ( icompz.GT.0 .AND. ldz.LT.
max( 1, n ) ) )
THEN
256 smlsiz = ilaenv( 9,
'DSTEDC',
' ', 0, 0, 0, 0 )
257 IF( n.LE.1 .OR. icompz.EQ.0 )
THEN
260 ELSE IF( n.LE.smlsiz )
THEN
264 lgn = int( log( dble( n ) )/log( two ) )
269 IF( icompz.EQ.1 )
THEN
270 lwmin = 1 + 3*n + 2*n*lgn + 4*n**2
271 liwmin = 6 + 6*n + 5*n*lgn
272 ELSE IF( icompz.EQ.2 )
THEN
273 lwmin = 1 + 4*n + n**2
280 IF( lwork.LT.lwmin .AND. .NOT. lquery )
THEN
282 ELSE IF( liwork.LT.liwmin .AND. .NOT. lquery )
THEN
290 ELSE IF (lquery)
THEN
315 IF( icompz.EQ.0 )
THEN
316 CALL dsterf( n, d, e, info )
323 IF( n.LE.smlsiz )
THEN
325 CALL dsteqr( compz, n, d, e, z, ldz, work, info )
332 IF( icompz.EQ.1 )
THEN
338 IF( icompz.EQ.2 )
THEN
339 CALL dlaset(
'Full', n, n, zero, one, z, ldz )
344 orgnrm = dlanst(
'M', n, d, e )
348 eps = dlamch(
'Epsilon' )
355 IF( start.LE.n )
THEN
365 IF( finish.LT.n )
THEN
366 tiny = eps*sqrt( abs( d( finish ) ) )*
367 $ sqrt( abs( d( finish+1 ) ) )
368 IF( abs( e( finish ) ).GT.tiny )
THEN
376 m = finish - start + 1
381 IF( m.GT.smlsiz )
THEN
385 orgnrm = dlanst(
'M', m, d( start ), e( start ) )
386 CALL dlascl(
'G', 0, 0, orgnrm, one, m, 1, d( start ), m,
388 CALL dlascl(
'G', 0, 0, orgnrm, one, m-1, 1, e( start ),
391 IF( icompz.EQ.1 )
THEN
396 CALL dlaed0( icompz, n, m, d( start ), e( start ),
397 $ z( strtrw, start ), ldz, work( 1 ), n,
398 $ work( storez ), iwork, info )
400 info = ( info / ( m+1 )+start-1 )*( n+1 ) +
401 $ mod( info, ( m+1 ) ) + start - 1
407 CALL dlascl(
'G', 0, 0, one, orgnrm, m, 1, d( start ), m,
411 IF( icompz.EQ.1 )
THEN
417 CALL dsteqr(
'I', m, d( start ), e( start ), work, m,
418 $ work( m*m+1 ), info )
419 CALL dlacpy(
'A', n, m, z( 1, start ), ldz,
420 $ work( storez ), n )
421 CALL dgemm(
'N',
'N', n, m, m, one,
422 $ work( storez ), n, work, m, zero,
423 $ z( 1, start ), ldz )
424 ELSE IF( icompz.EQ.2 )
THEN
425 CALL dsteqr(
'I', m, d( start ), e( start ),
426 $ z( start, start ), ldz, work, info )
428 CALL dsterf( m, d( start ), e( start ), info )
431 info = start*( n+1 ) + finish
442 IF( icompz.EQ.0 )
THEN
446 CALL dlasrt(
'I', n, d, info )
457 IF( d( j ).LT.p )
THEN
465 CALL dswap( n, z( 1, i ), 1, z( 1, k ), 1 )