178 SUBROUTINE dspevd( JOBZ, UPLO, N, AP, W, Z, LDZ, WORK, LWORK,
179 $ IWORK, LIWORK, INFO )
188 INTEGER INFO, LDZ, LIWORK, LWORK, N
192 DOUBLE PRECISION AP( * ), W( * ), WORK( * ), Z( LDZ, * )
198 DOUBLE PRECISION ZERO, ONE
199 parameter( zero = 0.0d+0, one = 1.0d+0 )
202 LOGICAL LQUERY, WANTZ
203 INTEGER IINFO, INDE, INDTAU, INDWRK, ISCALE, LIWMIN,
205 DOUBLE PRECISION ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN, SIGMA,
210 DOUBLE PRECISION DLAMCH, DLANSP
211 EXTERNAL lsame, dlamch, dlansp
223 wantz = lsame( jobz,
'V' )
224 lquery = ( lwork.EQ.-1 .OR. liwork.EQ.-1 )
227 IF( .NOT.( wantz .OR. lsame( jobz,
'N' ) ) )
THEN
229 ELSE IF( .NOT.( lsame( uplo,
'U' ) .OR. lsame( uplo,
'L' ) ) )
232 ELSE IF( n.LT.0 )
THEN
234 ELSE IF( ldz.LT.1 .OR. ( wantz .AND. ldz.LT.n ) )
THEN
245 lwmin = 1 + 6*n + n**2
254 IF( lwork.LT.lwmin .AND. .NOT.lquery )
THEN
256 ELSE IF( liwork.LT.liwmin .AND. .NOT.lquery )
THEN
262 CALL xerbla(
'DSPEVD', -info )
264 ELSE IF( lquery )
THEN
282 safmin = dlamch(
'Safe minimum' )
283 eps = dlamch(
'Precision' )
284 smlnum = safmin / eps
285 bignum = one / smlnum
286 rmin = sqrt( smlnum )
287 rmax = sqrt( bignum )
291 anrm = dlansp(
'M', uplo, n, ap, work )
293 IF( anrm.GT.zero .AND. anrm.LT.rmin )
THEN
296 ELSE IF( anrm.GT.rmax )
THEN
300 IF( iscale.EQ.1 )
THEN
301 CALL dscal( ( n*( n+1 ) ) / 2, sigma, ap, 1 )
308 CALL dsptrd( uplo, n, ap, w, work( inde ), work( indtau ), iinfo )
315 IF( .NOT.wantz )
THEN
316 CALL dsterf( n, w, work( inde ), info )
319 llwork = lwork - indwrk + 1
320 CALL dstedc(
'I', n, w, work( inde ), z, ldz, work( indwrk ),
321 $ llwork, iwork, liwork, info )
322 CALL dopmtr(
'L', uplo,
'N', n, n, ap, work( indtau ), z, ldz,
323 $ work( indwrk ), iinfo )
329 $
CALL dscal( n, one / sigma, w, 1 )