252 SUBROUTINE dsyevx( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, IL, IU,
253 $ ABSTOL, M, W, Z, LDZ, WORK, LWORK, IWORK,
262 CHARACTER JOBZ, RANGE, UPLO
263 INTEGER IL, INFO, IU, LDA, LDZ, LWORK, M, N
264 DOUBLE PRECISION ABSTOL, VL, VU
267 INTEGER IFAIL( * ), IWORK( * )
268 DOUBLE PRECISION A( lda, * ), W( * ), WORK( * ), Z( ldz, * )
274 DOUBLE PRECISION ZERO, ONE
275 parameter( zero = 0.0d+0, one = 1.0d+0 )
278 LOGICAL ALLEIG, INDEIG, LOWER, LQUERY, TEST, VALEIG,
281 INTEGER I, IINFO, IMAX, INDD, INDE, INDEE, INDIBL,
282 $ indisp, indiwo, indtau, indwkn, indwrk, iscale,
283 $ itmp1, j, jj, llwork, llwrkn, lwkmin,
285 DOUBLE PRECISION ABSTLL, ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN,
286 $ sigma, smlnum, tmp1, vll, vuu
291 DOUBLE PRECISION DLAMCH, DLANSY
292 EXTERNAL lsame, ilaenv, dlamch, dlansy
299 INTRINSIC max, min, sqrt
305 lower = lsame( uplo,
'L' )
306 wantz = lsame( jobz,
'V' )
307 alleig = lsame( range,
'A' )
308 valeig = lsame( range,
'V' )
309 indeig = lsame( range,
'I' )
310 lquery = ( lwork.EQ.-1 )
313 IF( .NOT.( wantz .OR. lsame( jobz,
'N' ) ) )
THEN 315 ELSE IF( .NOT.( alleig .OR. valeig .OR. indeig ) )
THEN 317 ELSE IF( .NOT.( lower .OR. lsame( uplo,
'U' ) ) )
THEN 319 ELSE IF( n.LT.0 )
THEN 321 ELSE IF( lda.LT.max( 1, n ) )
THEN 325 IF( n.GT.0 .AND. vu.LE.vl )
327 ELSE IF( indeig )
THEN 328 IF( il.LT.1 .OR. il.GT.max( 1, n ) )
THEN 330 ELSE IF( iu.LT.min( n, il ) .OR. iu.GT.n )
THEN 336 IF( ldz.LT.1 .OR. ( wantz .AND. ldz.LT.n ) )
THEN 347 nb = ilaenv( 1,
'DSYTRD', uplo, n, -1, -1, -1 )
348 nb = max( nb, ilaenv( 1,
'DORMTR', uplo, n, -1, -1, -1 ) )
349 lwkopt = max( lwkmin, ( nb + 3 )*n )
353 IF( lwork.LT.lwkmin .AND. .NOT.lquery )
358 CALL xerbla(
'DSYEVX', -info )
360 ELSE IF( lquery )
THEN 372 IF( alleig .OR. indeig )
THEN 376 IF( vl.LT.a( 1, 1 ) .AND. vu.GE.a( 1, 1 ) )
THEN 388 safmin = dlamch(
'Safe minimum' )
389 eps = dlamch(
'Precision' )
390 smlnum = safmin / eps
391 bignum = one / smlnum
392 rmin = sqrt( smlnum )
393 rmax = min( sqrt( bignum ), one / sqrt( sqrt( safmin ) ) )
403 anrm = dlansy(
'M', uplo, n, a, lda, work )
404 IF( anrm.GT.zero .AND. anrm.LT.rmin )
THEN 407 ELSE IF( anrm.GT.rmax )
THEN 411 IF( iscale.EQ.1 )
THEN 414 CALL dscal( n-j+1, sigma, a( j, j ), 1 )
418 CALL dscal( j, sigma, a( 1, j ), 1 )
422 $ abstll = abstol*sigma
435 llwork = lwork - indwrk + 1
436 CALL dsytrd( uplo, n, a, lda, work( indd ), work( inde ),
437 $ work( indtau ), work( indwrk ), llwork, iinfo )
445 IF( il.EQ.1 .AND. iu.EQ.n )
THEN 449 IF( ( alleig .OR. test ) .AND. ( abstol.LE.zero ) )
THEN 450 CALL dcopy( n, work( indd ), 1, w, 1 )
452 IF( .NOT.wantz )
THEN 453 CALL dcopy( n-1, work( inde ), 1, work( indee ), 1 )
454 CALL dsterf( n, w, work( indee ), info )
456 CALL dlacpy(
'A', n, n, a, lda, z, ldz )
457 CALL dorgtr( uplo, n, z, ldz, work( indtau ),
458 $ work( indwrk ), llwork, iinfo )
459 CALL dcopy( n-1, work( inde ), 1, work( indee ), 1 )
460 CALL dsteqr( jobz, n, w, work( indee ), z, ldz,
461 $ work( indwrk ), info )
485 CALL dstebz( range, order, n, vll, vuu, il, iu, abstll,
486 $ work( indd ), work( inde ), m, nsplit, w,
487 $ iwork( indibl ), iwork( indisp ), work( indwrk ),
488 $ iwork( indiwo ), info )
491 CALL dstein( n, work( indd ), work( inde ), m, w,
492 $ iwork( indibl ), iwork( indisp ), z, ldz,
493 $ work( indwrk ), iwork( indiwo ), ifail, info )
499 llwrkn = lwork - indwkn + 1
500 CALL dormtr(
'L', uplo,
'N', n, m, a, lda, work( indtau ), z,
501 $ ldz, work( indwkn ), llwrkn, iinfo )
507 IF( iscale.EQ.1 )
THEN 513 CALL dscal( imax, one / sigma, w, 1 )
524 IF( w( jj ).LT.tmp1 )
THEN 531 itmp1 = iwork( indibl+i-1 )
533 iwork( indibl+i-1 ) = iwork( indibl+j-1 )
535 iwork( indibl+j-1 ) = itmp1
536 CALL dswap( n, z( 1, i ), 1, z( 1, j ), 1 )
539 ifail( i ) = ifail( j )
subroutine dlacpy(UPLO, M, N, A, LDA, B, LDB)
DLACPY copies all or part of one two-dimensional array to another.
subroutine dsteqr(COMPZ, N, D, E, Z, LDZ, WORK, INFO)
DSTEQR
subroutine dstein(N, D, E, M, W, IBLOCK, ISPLIT, Z, LDZ, WORK, IWORK, IFAIL, INFO)
DSTEIN
subroutine dcopy(N, DX, INCX, DY, INCY)
DCOPY
subroutine dsytrd(UPLO, N, A, LDA, D, E, TAU, WORK, LWORK, INFO)
DSYTRD
subroutine dormtr(SIDE, UPLO, TRANS, M, N, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)
DORMTR
subroutine dsterf(N, D, E, INFO)
DSTERF
subroutine dswap(N, DX, INCX, DY, INCY)
DSWAP
subroutine xerbla(SRNAME, INFO)
XERBLA
subroutine dscal(N, DA, DX, INCX)
DSCAL
subroutine dorgtr(UPLO, N, A, LDA, TAU, WORK, LWORK, INFO)
DORGTR
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 dstebz(RANGE, ORDER, N, VL, VU, IL, IU, ABSTOL, D, E, M, NSPLIT, W, IBLOCK, ISPLIT, WORK, IWORK, INFO)
DSTEBZ