188 SUBROUTINE dstedc( COMPZ, N, D, E, Z, LDZ, WORK, LWORK, IWORK,
198 INTEGER INFO, LDZ, LIWORK, LWORK, N
202 DOUBLE PRECISION D( * ), E( * ), WORK( * ), Z( ldz, * )
208 DOUBLE PRECISION ZERO, ONE, TWO
209 parameter( zero = 0.0d0, one = 1.0d0, two = 2.0d0 )
213 INTEGER FINISH, I, ICOMPZ, II, J, K, LGN, LIWMIN,
214 $ lwmin, m, smlsiz, start, storez, strtrw
215 DOUBLE PRECISION EPS, ORGNRM, P, TINY
220 DOUBLE PRECISION DLAMCH, DLANST
221 EXTERNAL lsame, ilaenv, dlamch, dlanst
228 INTRINSIC abs, dble, int, log, max, mod, sqrt
235 lquery = ( lwork.EQ.-1 .OR. liwork.EQ.-1 )
237 IF( lsame( compz,
'N' ) )
THEN 239 ELSE IF( lsame( compz,
'V' ) )
THEN 241 ELSE IF( lsame( compz,
'I' ) )
THEN 246 IF( icompz.LT.0 )
THEN 248 ELSE IF( n.LT.0 )
THEN 250 ELSE IF( ( ldz.LT.1 ) .OR.
251 $ ( icompz.GT.0 .AND. ldz.LT.max( 1, n ) ) )
THEN 259 smlsiz = ilaenv( 9,
'DSTEDC',
' ', 0, 0, 0, 0 )
260 IF( n.LE.1 .OR. icompz.EQ.0 )
THEN 263 ELSE IF( n.LE.smlsiz )
THEN 267 lgn = int( log( dble( n ) )/log( two ) )
272 IF( icompz.EQ.1 )
THEN 273 lwmin = 1 + 3*n + 2*n*lgn + 4*n**2
274 liwmin = 6 + 6*n + 5*n*lgn
275 ELSE IF( icompz.EQ.2 )
THEN 276 lwmin = 1 + 4*n + n**2
283 IF( lwork.LT.lwmin .AND. .NOT. lquery )
THEN 285 ELSE IF( liwork.LT.liwmin .AND. .NOT. lquery )
THEN 291 CALL xerbla(
'DSTEDC', -info )
293 ELSE IF (lquery)
THEN 318 IF( icompz.EQ.0 )
THEN 319 CALL dsterf( n, d, e, info )
326 IF( n.LE.smlsiz )
THEN 328 CALL dsteqr( compz, n, d, e, z, ldz, work, info )
335 IF( icompz.EQ.1 )
THEN 341 IF( icompz.EQ.2 )
THEN 342 CALL dlaset(
'Full', n, n, zero, one, z, ldz )
347 orgnrm = dlanst(
'M', n, d, e )
351 eps = dlamch(
'Epsilon' )
358 IF( start.LE.n )
THEN 368 IF( finish.LT.n )
THEN 369 tiny = eps*sqrt( abs( d( finish ) ) )*
370 $ sqrt( abs( d( finish+1 ) ) )
371 IF( abs( e( finish ) ).GT.tiny )
THEN 379 m = finish - start + 1
384 IF( m.GT.smlsiz )
THEN 388 orgnrm = dlanst(
'M', m, d( start ), e( start ) )
389 CALL dlascl(
'G', 0, 0, orgnrm, one, m, 1, d( start ), m,
391 CALL dlascl(
'G', 0, 0, orgnrm, one, m-1, 1, e( start ),
394 IF( icompz.EQ.1 )
THEN 399 CALL dlaed0( icompz, n, m, d( start ), e( start ),
400 $ z( strtrw, start ), ldz, work( 1 ), n,
401 $ work( storez ), iwork, info )
403 info = ( info / ( m+1 )+start-1 )*( n+1 ) +
404 $ mod( info, ( m+1 ) ) + start - 1
410 CALL dlascl(
'G', 0, 0, one, orgnrm, m, 1, d( start ), m,
414 IF( icompz.EQ.1 )
THEN 420 CALL dsteqr(
'I', m, d( start ), e( start ), work, m,
421 $ work( m*m+1 ), info )
422 CALL dlacpy(
'A', n, m, z( 1, start ), ldz,
423 $ work( storez ), n )
424 CALL dgemm(
'N',
'N', n, m, m, one,
425 $ work( storez ), n, work, m, zero,
426 $ z( 1, start ), ldz )
427 ELSE IF( icompz.EQ.2 )
THEN 428 CALL dsteqr(
'I', m, d( start ), e( start ),
429 $ z( start, start ), ldz, work, info )
431 CALL dsterf( m, d( start ), e( start ), info )
434 info = start*( n+1 ) + finish
445 IF( icompz.EQ.0 )
THEN 449 CALL dlasrt(
'I', n, d, info )
460 IF( d( j ).LT.p )
THEN 468 CALL dswap( n, z( 1, i ), 1, z( 1, k ), 1 )
subroutine dlacpy(UPLO, M, N, A, LDA, B, LDB)
DLACPY copies all or part of one two-dimensional array to another.
subroutine dsteqr(COMPZ, N, D, E, Z, LDZ, WORK, INFO)
DSTEQR
subroutine dlascl(TYPE, KL, KU, CFROM, CTO, M, N, A, LDA, INFO)
DLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.
subroutine dsterf(N, D, E, INFO)
DSTERF
subroutine dlaset(UPLO, M, N, ALPHA, BETA, A, LDA)
DLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values...
subroutine dgemm(TRANSA, TRANSB, M, N, K, ALPHA, A, LDA, B, LDB, BETA, C, LDC)
DGEMM
subroutine dswap(N, DX, INCX, DY, INCY)
DSWAP
subroutine xerbla(SRNAME, INFO)
XERBLA
subroutine dlasrt(ID, N, D, INFO)
DLASRT sorts numbers in increasing or decreasing order.
subroutine dstedc(COMPZ, N, D, E, Z, LDZ, WORK, LWORK, IWORK, LIWORK, INFO)
DSTEDC
subroutine dlaed0(ICOMPQ, QSIZ, N, D, E, Q, LDQ, QSTORE, LDQS, WORK, IWORK, INFO)
DLAED0 used by sstedc. Computes all eigenvalues and corresponding eigenvectors of an unreduced symmet...