178 SUBROUTINE sspevd( JOBZ, UPLO, N, AP, W, Z, LDZ, WORK, LWORK,
179 $ IWORK, LIWORK, INFO )
188 INTEGER INFO, LDZ, LIWORK, LWORK, N
192 REAL AP( * ), W( * ), WORK( * ), Z( LDZ, * )
199 parameter( zero = 0.0e+0, one = 1.0e+0 )
202 LOGICAL LQUERY, WANTZ
203 INTEGER IINFO, INDE, INDTAU, INDWRK, ISCALE, LIWMIN,
205 REAL ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN, SIGMA,
211 EXTERNAL lsame, slamch, slansp
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(
'SSPEVD', -info )
264 ELSE IF( lquery )
THEN
282 safmin = slamch(
'Safe minimum' )
283 eps = slamch(
'Precision' )
284 smlnum = safmin / eps
285 bignum = one / smlnum
286 rmin = sqrt( smlnum )
287 rmax = sqrt( bignum )
291 anrm = slansp(
'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 sscal( ( n*( n+1 ) ) / 2, sigma, ap, 1 )
308 CALL ssptrd( uplo, n, ap, w, work( inde ), work( indtau ), iinfo )
315 IF( .NOT.wantz )
THEN
316 CALL ssterf( n, w, work( inde ), info )
319 llwork = lwork - indwrk + 1
320 CALL sstedc(
'I', n, w, work( inde ), z, ldz, work( indwrk ),
321 $ llwork, iwork, liwork, info )
322 CALL sopmtr(
'L', uplo,
'N', n, n, ap, work( indtau ), z, ldz,
323 $ work( indwrk ), iinfo )
329 $
CALL sscal( n, one / sigma, w, 1 )