180 SUBROUTINE dstedc( COMPZ, N, D, E, Z, LDZ, WORK, LWORK, IWORK,
189 INTEGER INFO, LDZ, LIWORK, LWORK, N
193 DOUBLE PRECISION D( * ), E( * ), WORK( * ), Z( LDZ, * )
199 DOUBLE PRECISION ZERO, ONE, TWO
200 parameter( zero = 0.0d0, one = 1.0d0, two = 2.0d0 )
204 INTEGER FINISH, I, ICOMPZ, II, J, K, LGN, LIWMIN,
205 $ lwmin, m, smlsiz, start, storez, strtrw
206 DOUBLE PRECISION EPS, ORGNRM, P, TINY
211 DOUBLE PRECISION DLAMCH, DLANST
212 EXTERNAL lsame, ilaenv, dlamch, dlanst
219 INTRINSIC abs, dble, int, log, max, mod, sqrt
226 lquery = ( lwork.EQ.-1 .OR. liwork.EQ.-1 )
228 IF( lsame( compz,
'N' ) )
THEN
230 ELSE IF( lsame( compz,
'V' ) )
THEN
232 ELSE IF( lsame( compz,
'I' ) )
THEN
237 IF( icompz.LT.0 )
THEN
239 ELSE IF( n.LT.0 )
THEN
241 ELSE IF( ( ldz.LT.1 ) .OR.
242 $ ( icompz.GT.0 .AND. ldz.LT.max( 1, n ) ) )
THEN
250 smlsiz = ilaenv( 9,
'DSTEDC',
' ', 0, 0, 0, 0 )
251 IF( n.LE.1 .OR. icompz.EQ.0 )
THEN
254 ELSE IF( n.LE.smlsiz )
THEN
258 lgn = int( log( dble( n ) )/log( two ) )
263 IF( icompz.EQ.1 )
THEN
264 lwmin = 1 + 3*n + 2*n*lgn + 4*n**2
265 liwmin = 6 + 6*n + 5*n*lgn
266 ELSE IF( icompz.EQ.2 )
THEN
267 lwmin = 1 + 4*n + n**2
274 IF( lwork.LT.lwmin .AND. .NOT. lquery )
THEN
276 ELSE IF( liwork.LT.liwmin .AND. .NOT. lquery )
THEN
282 CALL xerbla(
'DSTEDC', -info )
284 ELSE IF (lquery)
THEN
309 IF( icompz.EQ.0 )
THEN
310 CALL dsterf( n, d, e, info )
317 IF( n.LE.smlsiz )
THEN
319 CALL dsteqr( compz, n, d, e, z, ldz, work, info )
326 IF( icompz.EQ.1 )
THEN
332 IF( icompz.EQ.2 )
THEN
333 CALL dlaset(
'Full', n, n, zero, one, z, ldz )
338 orgnrm = dlanst(
'M', n, d, e )
342 eps = dlamch(
'Epsilon' )
349 IF( start.LE.n )
THEN
359 IF( finish.LT.n )
THEN
360 tiny = eps*sqrt( abs( d( finish ) ) )*
361 $ sqrt( abs( d( finish+1 ) ) )
362 IF( abs( e( finish ) ).GT.tiny )
THEN
370 m = finish - start + 1
375 IF( m.GT.smlsiz )
THEN
379 orgnrm = dlanst(
'M', m, d( start ), e( start ) )
380 CALL dlascl(
'G', 0, 0, orgnrm, one, m, 1, d( start ), m,
382 CALL dlascl(
'G', 0, 0, orgnrm, one, m-1, 1, e( start ),
385 IF( icompz.EQ.1 )
THEN
390 CALL dlaed0( icompz, n, m, d( start ), e( start ),
391 $ z( strtrw, start ), ldz, work( 1 ), n,
392 $ work( storez ), iwork, info )
394 info = ( info / ( m+1 )+start-1 )*( n+1 ) +
395 $ mod( info, ( m+1 ) ) + start - 1
401 CALL dlascl(
'G', 0, 0, one, orgnrm, m, 1, d( start ), m,
405 IF( icompz.EQ.1 )
THEN
411 CALL dsteqr(
'I', m, d( start ), e( start ), work, m,
412 $ work( m*m+1 ), info )
413 CALL dlacpy(
'A', n, m, z( 1, start ), ldz,
414 $ work( storez ), n )
415 CALL dgemm(
'N',
'N', n, m, m, one,
416 $ work( storez ), n, work, m, zero,
417 $ z( 1, start ), ldz )
418 ELSE IF( icompz.EQ.2 )
THEN
419 CALL dsteqr(
'I', m, d( start ), e( start ),
420 $ z( start, start ), ldz, work, info )
422 CALL dsterf( m, d( start ), e( start ), info )
425 info = start*( n+1 ) + finish
436 IF( icompz.EQ.0 )
THEN
440 CALL dlasrt(
'I', n, d, info )
451 IF( d( j ).LT.p )
THEN
459 CALL dswap( n, z( 1, i ), 1, z( 1, k ), 1 )
subroutine xerbla(srname, info)
subroutine dgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
DGEMM
subroutine dlacpy(uplo, m, n, a, lda, b, ldb)
DLACPY copies all or part of one two-dimensional array to another.
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 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 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 dsteqr(compz, n, d, e, z, ldz, work, info)
DSTEQR
subroutine dsterf(n, d, e, info)
DSTERF
subroutine dswap(n, dx, incx, dy, incy)
DSWAP