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 288 CALL xerbla(
'DSTEDC', -info )
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 )
subroutine xerbla(SRNAME, INFO)
XERBLA
subroutine dlacpy(UPLO, M, N, A, LDA, B, LDB)
DLACPY copies all or part of one two-dimensional array to another.
subroutine dgemm(TRANSA, TRANSB, M, N, K, ALPHA, A, LDA, B, LDB, BETA, C, LDC)
DGEMM
subroutine dsterf(N, D, E, INFO)
DSTERF
subroutine dstedc(COMPZ, N, D, E, Z, LDZ, WORK, LWORK, IWORK, LIWORK, INFO)
DSTEDC
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 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 dswap(N, DX, INCX, DY, INCY)
DSWAP
subroutine dlaed0(ICOMPQ, QSIZ, N, D, E, Q, LDQ, QSTORE, LDQS, WORK, IWORK, INFO)
DLAED0 used by DSTEDC. Computes all eigenvalues and corresponding eigenvectors of an unreduced symmet...
subroutine dsteqr(COMPZ, N, D, E, Z, LDZ, WORK, INFO)
DSTEQR
subroutine dlasrt(ID, N, D, INFO)
DLASRT sorts numbers in increasing or decreasing order.