250 SUBROUTINE dsyevx( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, IL, IU,
251 $ ABSTOL, M, W, Z, LDZ, WORK, LWORK, IWORK,
259 CHARACTER JOBZ, RANGE, UPLO
260 INTEGER IL, INFO, IU, LDA, LDZ, LWORK, M, N
261 DOUBLE PRECISION ABSTOL, VL, VU
264 INTEGER IFAIL( * ), IWORK( * )
265 DOUBLE PRECISION A( LDA, * ), W( * ), WORK( * ), Z( LDZ, * )
271 DOUBLE PRECISION ZERO, ONE
272 PARAMETER ( ZERO = 0.0d+0, one = 1.0d+0 )
275 LOGICAL ALLEIG, INDEIG, LOWER, LQUERY, TEST, VALEIG,
278 INTEGER I, IINFO, IMAX, INDD, INDE, INDEE, INDIBL,
279 $ indisp, indiwo, indtau, indwkn, indwrk, iscale,
280 $ itmp1, j, jj, llwork, llwrkn, lwkmin,
282 DOUBLE PRECISION ABSTLL, ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN,
283 $ SIGMA, SMLNUM, TMP1, VLL, VUU
288 DOUBLE PRECISION DLAMCH, DLANSY
289 EXTERNAL lsame, ilaenv, dlamch, dlansy
296 INTRINSIC max, min, sqrt
302 lower = lsame( uplo,
'L' )
303 wantz = lsame( jobz,
'V' )
304 alleig = lsame( range,
'A' )
305 valeig = lsame( range,
'V' )
306 indeig = lsame( range,
'I' )
307 lquery = ( lwork.EQ.-1 )
310 IF( .NOT.( wantz .OR. lsame( jobz,
'N' ) ) )
THEN
312 ELSE IF( .NOT.( alleig .OR. valeig .OR. indeig ) )
THEN
314 ELSE IF( .NOT.( lower .OR. lsame( uplo,
'U' ) ) )
THEN
316 ELSE IF( n.LT.0 )
THEN
318 ELSE IF( lda.LT.max( 1, n ) )
THEN
322 IF( n.GT.0 .AND. vu.LE.vl )
324 ELSE IF( indeig )
THEN
325 IF( il.LT.1 .OR. il.GT.max( 1, n ) )
THEN
327 ELSE IF( iu.LT.min( n, il ) .OR. iu.GT.n )
THEN
333 IF( ldz.LT.1 .OR. ( wantz .AND. ldz.LT.n ) )
THEN
344 nb = ilaenv( 1,
'DSYTRD', uplo, n, -1, -1, -1 )
345 nb = max( nb, ilaenv( 1,
'DORMTR', uplo, n, -1, -1, -1 ) )
346 lwkopt = max( lwkmin, ( nb + 3 )*n )
350 IF( lwork.LT.lwkmin .AND. .NOT.lquery )
355 CALL xerbla(
'DSYEVX', -info )
357 ELSE IF( lquery )
THEN
369 IF( alleig .OR. indeig )
THEN
373 IF( vl.LT.a( 1, 1 ) .AND. vu.GE.a( 1, 1 ) )
THEN
385 safmin = dlamch(
'Safe minimum' )
386 eps = dlamch(
'Precision' )
387 smlnum = safmin / eps
388 bignum = one / smlnum
389 rmin = sqrt( smlnum )
390 rmax = min( sqrt( bignum ), one / sqrt( sqrt( safmin ) ) )
400 anrm = dlansy(
'M', uplo, n, a, lda, work )
401 IF( anrm.GT.zero .AND. anrm.LT.rmin )
THEN
404 ELSE IF( anrm.GT.rmax )
THEN
408 IF( iscale.EQ.1 )
THEN
411 CALL dscal( n-j+1, sigma, a( j, j ), 1 )
415 CALL dscal( j, sigma, a( 1, j ), 1 )
419 $ abstll = abstol*sigma
432 llwork = lwork - indwrk + 1
433 CALL dsytrd( uplo, n, a, lda, work( indd ), work( inde ),
434 $ work( indtau ), work( indwrk ), llwork, iinfo )
442 IF( il.EQ.1 .AND. iu.EQ.n )
THEN
446 IF( ( alleig .OR. test ) .AND. ( abstol.LE.zero ) )
THEN
447 CALL dcopy( n, work( indd ), 1, w, 1 )
449 IF( .NOT.wantz )
THEN
450 CALL dcopy( n-1, work( inde ), 1, work( indee ), 1 )
451 CALL dsterf( n, w, work( indee ), info )
453 CALL dlacpy(
'A', n, n, a, lda, z, ldz )
454 CALL dorgtr( uplo, n, z, ldz, work( indtau ),
455 $ work( indwrk ), llwork, iinfo )
456 CALL dcopy( n-1, work( inde ), 1, work( indee ), 1 )
457 CALL dsteqr( jobz, n, w, work( indee ), z, ldz,
458 $ work( indwrk ), info )
482 CALL dstebz( range, order, n, vll, vuu, il, iu, abstll,
483 $ work( indd ), work( inde ), m, nsplit, w,
484 $ iwork( indibl ), iwork( indisp ), work( indwrk ),
485 $ iwork( indiwo ), info )
488 CALL dstein( n, work( indd ), work( inde ), m, w,
489 $ iwork( indibl ), iwork( indisp ), z, ldz,
490 $ work( indwrk ), iwork( indiwo ), ifail, info )
496 llwrkn = lwork - indwkn + 1
497 CALL dormtr(
'L', uplo,
'N', n, m, a, lda, work( indtau ), z,
498 $ ldz, work( indwkn ), llwrkn, iinfo )
504 IF( iscale.EQ.1 )
THEN
510 CALL dscal( imax, one / sigma, w, 1 )
521 IF( w( jj ).LT.tmp1 )
THEN
528 itmp1 = iwork( indibl+i-1 )
530 iwork( indibl+i-1 ) = iwork( indibl+j-1 )
532 iwork( indibl+j-1 ) = itmp1
533 CALL dswap( n, z( 1, i ), 1, z( 1, j ), 1 )
536 ifail( i ) = ifail( j )
subroutine xerbla(srname, info)
subroutine dcopy(n, dx, incx, dy, incy)
DCOPY
subroutine dsyevx(jobz, range, uplo, n, a, lda, vl, vu, il, iu, abstol, m, w, z, ldz, work, lwork, iwork, ifail, info)
DSYEVX computes the eigenvalues and, optionally, the left and/or right eigenvectors for SY matrices
subroutine dsytrd(uplo, n, a, lda, d, e, tau, work, lwork, info)
DSYTRD
subroutine dlacpy(uplo, m, n, a, lda, b, ldb)
DLACPY copies all or part of one two-dimensional array to another.
subroutine dscal(n, da, dx, incx)
DSCAL
subroutine dstebz(range, order, n, vl, vu, il, iu, abstol, d, e, m, nsplit, w, iblock, isplit, work, iwork, info)
DSTEBZ
subroutine dstein(n, d, e, m, w, iblock, isplit, z, ldz, work, iwork, ifail, info)
DSTEIN
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
subroutine dorgtr(uplo, n, a, lda, tau, work, lwork, info)
DORGTR
subroutine dormtr(side, uplo, trans, m, n, a, lda, tau, c, ldc, work, lwork, info)
DORMTR