318 SUBROUTINE dstemr( JOBZ, RANGE, N, D, E, VL, VU, IL, IU,
319 $ M, W, Z, LDZ, NZC, ISUPPZ, TRYRAC, WORK, LWORK,
320 $ IWORK, LIWORK, INFO )
327 CHARACTER JOBZ, RANGE
329 INTEGER IL, INFO, IU, LDZ, NZC, LIWORK, LWORK, M, N
330 DOUBLE PRECISION VL, VU
333 INTEGER ISUPPZ( * ), IWORK( * )
334 DOUBLE PRECISION D( * ), E( * ), W( * ), WORK( * )
335 DOUBLE PRECISION Z( LDZ, * )
341 DOUBLE PRECISION ZERO, ONE, FOUR, MINRGP
342 PARAMETER ( ZERO = 0.0d0, one = 1.0d0,
347 LOGICAL ALLEIG, INDEIG, LQUERY, VALEIG, WANTZ, ZQUERY
348 INTEGER I, IBEGIN, IEND, IFIRST, IIL, IINDBL, IINDW,
349 $ iindwk, iinfo, iinspl, iiu, ilast, in, indd,
350 $ inde2, inderr, indgp, indgrs, indwrk, itmp,
351 $ itmp2, j, jblk, jj, liwmin, lwmin, nsplit,
352 $ nzcmin, offset, wbegin, wend
353 DOUBLE PRECISION BIGNUM, CS, EPS, PIVMIN, R1, R2, RMAX, RMIN,
354 $ RTOL1, RTOL2, SAFMIN, SCALE, SMLNUM, SN,
355 $ thresh, tmp, tnrm, wl, wu
360 DOUBLE PRECISION DLAMCH, DLANST
361 EXTERNAL lsame, dlamch, dlanst
368 INTRINSIC max, min, sqrt
376 wantz = lsame( jobz,
'V' )
377 alleig = lsame( range,
'A' )
378 valeig = lsame( range,
'V' )
379 indeig = lsame( range,
'I' )
381 lquery = ( ( lwork.EQ.-1 ).OR.( liwork.EQ.-1 ) )
382 zquery = ( nzc.EQ.-1 )
408 ELSEIF( indeig )
THEN
415 IF( .NOT.( wantz .OR. lsame( jobz,
'N' ) ) )
THEN
417 ELSE IF( .NOT.( alleig .OR. valeig .OR. indeig ) )
THEN
419 ELSE IF( n.LT.0 )
THEN
421 ELSE IF( valeig .AND. n.GT.0 .AND. wu.LE.wl )
THEN
423 ELSE IF( indeig .AND. ( iil.LT.1 .OR. iil.GT.n ) )
THEN
425 ELSE IF( indeig .AND. ( iiu.LT.iil .OR. iiu.GT.n ) )
THEN
427 ELSE IF( ldz.LT.1 .OR. ( wantz .AND. ldz.LT.n ) )
THEN
429 ELSE IF( lwork.LT.lwmin .AND. .NOT.lquery )
THEN
431 ELSE IF( liwork.LT.liwmin .AND. .NOT.lquery )
THEN
437 safmin = dlamch(
'Safe minimum' )
438 eps = dlamch(
'Precision' )
439 smlnum = safmin / eps
440 bignum = one / smlnum
441 rmin = sqrt( smlnum )
442 rmax = min( sqrt( bignum ), one / sqrt( sqrt( safmin ) ) )
448 IF( wantz .AND. alleig )
THEN
450 ELSE IF( wantz .AND. valeig )
THEN
451 CALL dlarrc(
'T', n, vl, vu, d, e, safmin,
452 $ nzcmin, itmp, itmp2, info )
453 ELSE IF( wantz .AND. indeig )
THEN
459 IF( zquery .AND. info.EQ.0 )
THEN
461 ELSE IF( nzc.LT.nzcmin .AND. .NOT.zquery )
THEN
468 CALL xerbla(
'DSTEMR', -info )
471 ELSE IF( lquery .OR. zquery )
THEN
482 IF( alleig .OR. indeig )
THEN
486 IF( wl.LT.d( 1 ) .AND. wu.GE.d( 1 ) )
THEN
491 IF( wantz.AND.(.NOT.zquery) )
THEN
500 IF( .NOT.wantz )
THEN
501 CALL dlae2( d(1), e(1), d(2), r1, r2 )
502 ELSE IF( wantz.AND.(.NOT.zquery) )
THEN
503 CALL dlaev2( d(1), e(1), d(2), r1, r2, cs, sn )
506 $ (valeig.AND.(r2.GT.wl).AND.
508 $ (indeig.AND.(iil.EQ.1)) )
THEN
511 IF( wantz.AND.(.NOT.zquery) )
THEN
530 $ (valeig.AND.(r1.GT.wl).AND.
532 $ (indeig.AND.(iiu.EQ.2)) )
THEN
535 IF( wantz.AND.(.NOT.zquery) )
THEN
577 tnrm = dlanst(
'M', n, d, e )
578 IF( tnrm.GT.zero .AND. tnrm.LT.rmin )
THEN
580 ELSE IF( tnrm.GT.rmax )
THEN
583 IF( scale.NE.one )
THEN
584 CALL dscal( n, scale, d, 1 )
585 CALL dscal( n-1, scale, e, 1 )
605 CALL dlarrr( n, d, e, iinfo )
621 CALL dcopy(n,d,1,work(indd),1)
625 work( inde2+j-1 ) = e(j)**2
629 IF( .NOT.wantz )
THEN
639 rtol2 = max( sqrt(eps)*5.0d-3, four * eps )
641 CALL dlarre( range, n, wl, wu, iil, iiu, d, e,
642 $ work(inde2), rtol1, rtol2, thresh, nsplit,
643 $ iwork( iinspl ), m, w, work( inderr ),
644 $ work( indgp ), iwork( iindbl ),
645 $ iwork( iindw ), work( indgrs ), pivmin,
646 $ work( indwrk ), iwork( iindwk ), iinfo )
647 IF( iinfo.NE.0 )
THEN
648 info = 10 + abs( iinfo )
661 CALL dlarrv( n, wl, wu, d, e,
662 $ pivmin, iwork( iinspl ), m,
663 $ 1, m, minrgp, rtol1, rtol2,
664 $ w, work( inderr ), work( indgp ), iwork( iindbl ),
665 $ iwork( iindw ), work( indgrs ), z, ldz,
666 $ isuppz, work( indwrk ), iwork( iindwk ), iinfo )
667 IF( iinfo.NE.0 )
THEN
668 info = 20 + abs( iinfo )
678 itmp = iwork( iindbl+j-1 )
679 w( j ) = w( j ) + e( iwork( iinspl+itmp-1 ) )
689 DO 39 jblk = 1, iwork( iindbl+m-1 )
690 iend = iwork( iinspl+jblk-1 )
691 in = iend - ibegin + 1
696 IF( iwork( iindbl+wend ).EQ.jblk )
THEN
701 IF( wend.LT.wbegin )
THEN
706 offset = iwork(iindw+wbegin-1)-1
707 ifirst = iwork(iindw+wbegin-1)
708 ilast = iwork(iindw+wend-1)
711 $ work(indd+ibegin-1), work(inde2+ibegin-1),
712 $ ifirst, ilast, rtol2, offset, w(wbegin),
713 $ work( inderr+wbegin-1 ),
714 $ work( indwrk ), iwork( iindwk ), pivmin,
723 IF( scale.NE.one )
THEN
724 CALL dscal( m, one / scale, w, 1 )
733 IF( nsplit.GT.1 .OR. n.EQ.2 )
THEN
734 IF( .NOT. wantz )
THEN
735 CALL dlasrt(
'I', m, w, iinfo )
736 IF( iinfo.NE.0 )
THEN
745 IF( w( jj ).LT.tmp )
THEN
754 CALL dswap( n, z( 1, i ), 1, z( 1, j ), 1 )
755 itmp = isuppz( 2*i-1 )
756 isuppz( 2*i-1 ) = isuppz( 2*j-1 )
757 isuppz( 2*j-1 ) = itmp
759 isuppz( 2*i ) = isuppz( 2*j )
subroutine dlaev2(A, B, C, RT1, RT2, CS1, SN1)
DLAEV2 computes the eigenvalues and eigenvectors of a 2-by-2 symmetric/Hermitian matrix.
subroutine dlarrj(N, D, E2, IFIRST, ILAST, RTOL, OFFSET, W, WERR, WORK, IWORK, PIVMIN, SPDIAM, INFO)
DLARRJ performs refinement of the initial estimates of the eigenvalues of the matrix T.
subroutine dlae2(A, B, C, RT1, RT2)
DLAE2 computes the eigenvalues of a 2-by-2 symmetric matrix.
subroutine dlarrc(JOBT, N, VL, VU, D, E, PIVMIN, EIGCNT, LCNT, RCNT, INFO)
DLARRC computes the number of eigenvalues of the symmetric tridiagonal matrix.
subroutine dlarre(RANGE, N, VL, VU, IL, IU, D, E, E2, RTOL1, RTOL2, SPLTOL, NSPLIT, ISPLIT, M, W, WERR, WGAP, IBLOCK, INDEXW, GERS, PIVMIN, WORK, IWORK, INFO)
DLARRE given the tridiagonal matrix T, sets small off-diagonal elements to zero and for each unreduce...
subroutine dlarrr(N, D, E, INFO)
DLARRR performs tests to decide whether the symmetric tridiagonal matrix T warrants expensive computa...
subroutine xerbla(SRNAME, INFO)
XERBLA
subroutine dlasrt(ID, N, D, INFO)
DLASRT sorts numbers in increasing or decreasing order.
subroutine dcopy(N, DX, INCX, DY, INCY)
DCOPY
subroutine dscal(N, DA, DX, INCX)
DSCAL
subroutine dswap(N, DX, INCX, DY, INCY)
DSWAP
subroutine dlarrv(N, VL, VU, D, L, PIVMIN, ISPLIT, M, DOL, DOU, MINRGP, RTOL1, RTOL2, W, WERR, WGAP, IBLOCK, INDEXW, GERS, Z, LDZ, ISUPPZ, WORK, IWORK, INFO)
DLARRV computes the eigenvectors of the tridiagonal matrix T = L D LT given L, D and the eigenvalues ...
subroutine dstemr(JOBZ, RANGE, N, D, E, VL, VU, IL, IU, M, W, Z, LDZ, NZC, ISUPPZ, TRYRAC, WORK, LWORK, IWORK, LIWORK, INFO)
DSTEMR