183 SUBROUTINE dsyevd( JOBZ, UPLO, N, A, LDA, W, WORK, LWORK, IWORK,
192 INTEGER INFO, LDA, LIWORK, LWORK, N
196 DOUBLE PRECISION A( LDA, * ), W( * ), WORK( * )
202 DOUBLE PRECISION ZERO, ONE
203 parameter( zero = 0.0d+0, one = 1.0d+0 )
207 LOGICAL LOWER, LQUERY, WANTZ
208 INTEGER IINFO, INDE, INDTAU, INDWK2, , ISCALE,
209 $ liopt, liwmin, llwork, llwrk2, lopt, lwmin
210 DOUBLE PRECISION ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN, SIGMA,
216 DOUBLE PRECISION DLAMCH, DLANSY
217 EXTERNAL lsame, dlamch, dlansy, ilaenv
230 wantz = lsame( jobz,
'V' )
231 lower = lsame( uplo,
'L' )
232 lquery = ( lwork.EQ.-1 .OR. liwork.EQ.-1 )
235 IF( .NOT.( wantz .OR. lsame( jobz,
'N' ) ) )
THEN
237 ELSE IF( .NOT.( lower .OR. lsame( uplo,
'U' ) ) )
THEN
239 ELSE IF( n.LT.0 )
THEN
241 ELSE IF( lda.LT.
max( 1, n ) )
THEN
254 lwmin = 1 + 6*n + 2*n**2
259 lopt =
max( lwmin, 2*n +
260 $ ilaenv( 1,
'DSYTRD', uplo, n, -1, -1, -1 ) )
266 IF( lwork.LT.lwmin .AND. .NOT.lquery )
THEN
268 ELSE IF( liwork.LT.liwmin .AND. .NOT.lquery )
THEN
274 CALL xerbla(
'DSYEVD', -info )
276 ELSE IF( lquery )
THEN
294 safmin = dlamch(
'Safe minimum' )
295 eps = dlamch(
'Precision' )
296 smlnum = safmin / eps
297 bignum = one / smlnum
298 rmin = sqrt( smlnum )
299 rmax = sqrt( bignum )
303 anrm = dlansy(
'M', uplo, n, a, lda, work )
305 IF( anrm.GT.zero .AND. anrm.LT.rmin )
THEN
308 ELSE IF( anrm.GT.rmax )
THEN
313 $
CALL dlascl( uplo, 0, 0, one, sigma, n, n, a, lda, info )
320 llwork = lwork - indwrk + 1
321 indwk2 = indwrk + n*n
322 llwrk2 = lwork - indwk2 + 1
324 CALL dsytrd( uplo, n, a, lda, w, work( inde ), work( indtau ),
325 $ work( indwrk ), llwork, iinfo )
332 IF( .NOT.wantz )
THEN
333 CALL dsterf( n, w, work( inde ), info )
335 CALL dstedc(
'I', n, w, work( inde ), work( indwrk ), n,
336 $ work( indwk2 ), llwrk2, iwork, liwork, info )
337 CALL dormtr(
'L', uplo,
'N', n, n, a, lda, work( indtau ),
338 $ work( indwrk ), n, work( indwk2 ), llwrk2, iinfo )
339 CALL dlacpy(
'A', n, n, work( indwrk ), n, a, lda )
345 $
CALL dscal( n, one / sigma, w, 1 )
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 dormtr(side, uplo, trans, m, n, a, lda, tau, c, ldc, work, lwork, info)
DORMTR
subroutine dsyevd(jobz, uplo, n, a, lda, w, work, lwork, iwork, liwork, info)
DSYEVD computes the eigenvalues and, optionally, the left and/or right eigenvectors for SY matrices