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 dsterf(N, D, E, INFO)
DSTERF
subroutine dstebz(RANGE, ORDER, N, VL, VU, IL, IU, ABSTOL, D, E, M, NSPLIT, W, IBLOCK, ISPLIT, WORK, IWORK, INFO)
DSTEBZ
subroutine dcopy(N, DX, INCX, DY, INCY)
DCOPY
subroutine dorgtr(UPLO, N, A, LDA, TAU, WORK, LWORK, INFO)
DORGTR
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 dsteqr(COMPZ, N, D, E, Z, LDZ, WORK, INFO)
DSTEQR
subroutine xerbla(SRNAME, INFO)
XERBLA
subroutine dswap(N, DX, INCX, DY, INCY)
DSWAP
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 dormtr(SIDE, UPLO, TRANS, M, N, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)
DORMTR
subroutine dscal(N, DA, DX, INCX)
DSCAL
subroutine dstein(N, D, E, M, W, IBLOCK, ISPLIT, Z, LDZ, WORK, IWORK, IFAIL, INFO)
DSTEIN