180 SUBROUTINE sstedc( COMPZ, N, D, E, Z, LDZ, WORK, LWORK, IWORK,
189 INTEGER INFO, LDZ, LIWORK, LWORK, N
193 REAL D( * ), E( * ), WORK( * ), Z( LDZ, * )
200 parameter( zero = 0.0e0, one = 1.0e0, two = 2.0e0 )
204 INTEGER FINISH, I, ICOMPZ, II, J, K, LGN, LIWMIN,
205 $ lwmin, m, smlsiz, start, storez, strtrw
206 REAL EPS, ORGNRM, P, TINY
211 REAL SLAMCH, SLANST, SROUNDUP_LWORK
212 EXTERNAL ilaenv, lsame, slamch, slanst, sroundup_lwork
219 INTRINSIC abs, int, log, max, mod, real, 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,
'SSTEDC',
' ', 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( real( 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
271 work( 1 ) = sroundup_lwork(lwmin)
274 IF( lwork.LT.lwmin .AND. .NOT. lquery )
THEN
276 ELSE IF( liwork.LT.liwmin .AND. .NOT. lquery )
THEN
282 CALL xerbla(
'SSTEDC', -info )
284 ELSE IF (lquery)
THEN
309 IF( icompz.EQ.0 )
THEN
310 CALL ssterf( n, d, e, info )
317 IF( n.LE.smlsiz )
THEN
319 CALL ssteqr( compz, n, d, e, z, ldz, work, info )
326 IF( icompz.EQ.1 )
THEN
332 IF( icompz.EQ.2 )
THEN
333 CALL slaset(
'Full', n, n, zero, one, z, ldz )
338 orgnrm = slanst(
'M', n, d, e )
342 eps = slamch(
'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 = slanst(
'M', m, d( start ), e( start ) )
380 CALL slascl(
'G', 0, 0, orgnrm, one, m, 1, d( start ), m,
382 CALL slascl(
'G', 0, 0, orgnrm, one, m-1, 1, e( start ),
385 IF( icompz.EQ.1 )
THEN
390 CALL slaed0( 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 slascl(
'G', 0, 0, one, orgnrm, m, 1, d( start ), m,
405 IF( icompz.EQ.1 )
THEN
411 CALL ssteqr(
'I', m, d( start ), e( start ), work, m,
412 $ work( m*m+1 ), info )
413 CALL slacpy(
'A', n, m, z( 1, start ), ldz,
414 $ work( storez ), n )
415 CALL sgemm(
'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 ssteqr(
'I', m, d( start ), e( start ),
420 $ z( start, start ), ldz, work, info )
422 CALL ssterf( m, d( start ), e( start ), info )
425 info = start*( n+1 ) + finish
436 IF( icompz.EQ.0 )
THEN
440 CALL slasrt(
'I', n, d, info )
451 IF( d( j ).LT.p )
THEN
459 CALL sswap( n, z( 1, i ), 1, z( 1, k ), 1 )
466 work( 1 ) = sroundup_lwork(lwmin)
subroutine xerbla(srname, info)
subroutine sgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
SGEMM
subroutine slacpy(uplo, m, n, a, lda, b, ldb)
SLACPY copies all or part of one two-dimensional array to another.
subroutine slaed0(icompq, qsiz, n, d, e, q, ldq, qstore, ldqs, work, iwork, info)
SLAED0 used by SSTEDC. Computes all eigenvalues and corresponding eigenvectors of an unreduced symmet...
subroutine slascl(type, kl, ku, cfrom, cto, m, n, a, lda, info)
SLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.
subroutine slaset(uplo, m, n, alpha, beta, a, lda)
SLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
subroutine slasrt(id, n, d, info)
SLASRT sorts numbers in increasing or decreasing order.
subroutine sstedc(compz, n, d, e, z, ldz, work, lwork, iwork, liwork, info)
SSTEDC
subroutine ssteqr(compz, n, d, e, z, ldz, work, info)
SSTEQR
subroutine ssterf(n, d, e, info)
SSTERF
subroutine sswap(n, sx, incx, sy, incy)
SSWAP