319 SUBROUTINE dstemr( JOBZ, RANGE, N, D, E, VL, VU, IL, IU,
320 $ M, W, Z, LDZ, NZC, ISUPPZ, TRYRAC, WORK, LWORK,
321 $ IWORK, LIWORK, INFO )
328 CHARACTER JOBZ, RANGE
330 INTEGER IL, INFO, IU, LDZ, NZC, LIWORK, LWORK, M, N
331 DOUBLE PRECISION VL, VU
334 INTEGER ISUPPZ( * ), IWORK( * )
335 DOUBLE PRECISION D( * ), E( * ), W( * ), WORK( * )
336 DOUBLE PRECISION Z( LDZ, * )
342 DOUBLE PRECISION ZERO, ONE, FOUR, MINRGP
343 PARAMETER ( ZERO = 0.0d0, one = 1.0d0,
348 LOGICAL ALLEIG, INDEIG, LQUERY, VALEIG, WANTZ, ZQUERY,
350 INTEGER I, IBEGIN, IEND, IFIRST, IIL, IINDBL, IINDW,
351 $ IINDWK, IINFO, IINSPL, IIU, ILAST, IN, INDD,
352 $ inde2, inderr, indgp, indgrs, indwrk, itmp,
353 $ itmp2, j, jblk, jj, liwmin, lwmin, nsplit,
354 $ nzcmin, offset, wbegin, wend
355 DOUBLE PRECISION BIGNUM, CS, EPS, PIVMIN, R1, R2, RMAX, RMIN,
356 $ RTOL1, RTOL2, SAFMIN, SCALE, SMLNUM, SN,
357 $ thresh, tmp, tnrm, wl, wu
362 DOUBLE PRECISION DLAMCH, DLANST
363 EXTERNAL lsame, dlamch, dlanst
370 INTRINSIC max, min, sqrt
378 wantz = lsame( jobz,
'V' )
379 alleig = lsame( range,
'A' )
380 valeig = lsame( range,
'V' )
381 indeig = lsame( range,
'I' )
383 lquery = ( ( lwork.EQ.-1 ).OR.( liwork.EQ.-1 ) )
384 zquery = ( nzc.EQ.-1 )
411 ELSEIF( indeig )
THEN
418 IF( .NOT.( wantz .OR. lsame( jobz,
'N' ) ) )
THEN
420 ELSE IF( .NOT.( alleig .OR. valeig .OR. indeig ) )
THEN
422 ELSE IF( n.LT.0 )
THEN
424 ELSE IF( valeig .AND. n.GT.0 .AND. wu.LE.wl )
THEN
426 ELSE IF( indeig .AND. ( iil.LT.1 .OR. iil.GT.n ) )
THEN
428 ELSE IF( indeig .AND. ( iiu.LT.iil .OR. iiu.GT.n ) )
THEN
430 ELSE IF( ldz.LT.1 .OR. ( wantz .AND. ldz.LT.n ) )
THEN
432 ELSE IF( lwork.LT.lwmin .AND. .NOT.lquery )
THEN
434 ELSE IF( liwork.LT.liwmin .AND. .NOT.lquery )
THEN
440 safmin = dlamch(
'Safe minimum' )
441 eps = dlamch(
'Precision' )
442 smlnum = safmin / eps
443 bignum = one / smlnum
444 rmin = sqrt( smlnum )
445 rmax = min( sqrt( bignum ), one / sqrt( sqrt( safmin ) ) )
451 IF( wantz .AND. alleig )
THEN
453 ELSE IF( wantz .AND. valeig )
THEN
454 CALL dlarrc(
'T', n, vl, vu, d, e, safmin,
455 $ nzcmin, itmp, itmp2, info )
456 ELSE IF( wantz .AND. indeig )
THEN
462 IF( zquery .AND. info.EQ.0 )
THEN
464 ELSE IF( nzc.LT.nzcmin .AND. .NOT.zquery )
THEN
471 CALL xerbla(
'DSTEMR', -info )
474 ELSE IF( lquery .OR. zquery )
THEN
485 IF( alleig .OR. indeig )
THEN
489 IF( wl.LT.d( 1 ) .AND. wu.GE.d( 1 ) )
THEN
494 IF( wantz.AND.(.NOT.zquery) )
THEN
503 IF( .NOT.wantz )
THEN
504 CALL dlae2( d(1), e(1), d(2), r1, r2 )
505 ELSE IF( wantz.AND.(.NOT.zquery) )
THEN
506 CALL dlaev2( d(1), e(1), d(2), r1, r2, cs, sn )
518 $ (valeig.AND.(r2.GT.wl).AND.
520 $ (indeig.AND.(iil.EQ.1)) )
THEN
523 IF( wantz.AND.(.NOT.zquery) )
THEN
547 $ (valeig.AND.(r1.GT.wl).AND.
549 $ (indeig.AND.(iiu.EQ.2)) )
THEN
552 IF( wantz.AND.(.NOT.zquery) )
THEN
599 tnrm = dlanst(
'M', n, d, e )
600 IF( tnrm.GT.zero .AND. tnrm.LT.rmin )
THEN
602 ELSE IF( tnrm.GT.rmax )
THEN
605 IF( scale.NE.one )
THEN
606 CALL dscal( n, scale, d, 1 )
607 CALL dscal( n-1, scale, e, 1 )
627 CALL dlarrr( n, d, e, iinfo )
643 CALL dcopy(n,d,1,work(indd),1)
647 work( inde2+j-1 ) = e(j)**2
651 IF( .NOT.wantz )
THEN
661 rtol2 = max( sqrt(eps)*5.0d-3, four * eps )
663 CALL dlarre( range, n, wl, wu, iil, iiu, d, e,
664 $ work(inde2), rtol1, rtol2, thresh, nsplit,
665 $ iwork( iinspl ), m, w, work( inderr ),
666 $ work( indgp ), iwork( iindbl ),
667 $ iwork( iindw ), work( indgrs ), pivmin,
668 $ work( indwrk ), iwork( iindwk ), iinfo )
669 IF( iinfo.NE.0 )
THEN
670 info = 10 + abs( iinfo )
683 CALL dlarrv( n, wl, wu, d, e,
684 $ pivmin, iwork( iinspl ), m,
685 $ 1, m, minrgp, rtol1, rtol2,
686 $ w, work( inderr ), work( indgp ), iwork( iindbl ),
687 $ iwork( iindw ), work( indgrs ), z, ldz,
688 $ isuppz, work( indwrk ), iwork( iindwk ), iinfo )
689 IF( iinfo.NE.0 )
THEN
690 info = 20 + abs( iinfo )
700 itmp = iwork( iindbl+j-1 )
701 w( j ) = w( j ) + e( iwork( iinspl+itmp-1 ) )
711 DO 39 jblk = 1, iwork( iindbl+m-1 )
712 iend = iwork( iinspl+jblk-1 )
713 in = iend - ibegin + 1
718 IF( iwork( iindbl+wend ).EQ.jblk )
THEN
723 IF( wend.LT.wbegin )
THEN
728 offset = iwork(iindw+wbegin-1)-1
729 ifirst = iwork(iindw+wbegin-1)
730 ilast = iwork(iindw+wend-1)
733 $ work(indd+ibegin-1), work(inde2+ibegin-1),
734 $ ifirst, ilast, rtol2, offset, w(wbegin),
735 $ work( inderr+wbegin-1 ),
736 $ work( indwrk ), iwork( iindwk ), pivmin,
745 IF( scale.NE.one )
THEN
746 CALL dscal( m, one / scale, w, 1 )
755 IF( nsplit.GT.1 .OR. n.EQ.2 )
THEN
756 IF( .NOT. wantz )
THEN
757 CALL dlasrt(
'I', m, w, iinfo )
758 IF( iinfo.NE.0 )
THEN
767 IF( w( jj ).LT.tmp )
THEN
776 CALL dswap( n, z( 1, i ), 1, z( 1, j ), 1 )
777 itmp = isuppz( 2*i-1 )
778 isuppz( 2*i-1 ) = isuppz( 2*j-1 )
779 isuppz( 2*j-1 ) = itmp
781 isuppz( 2*i ) = isuppz( 2*j )
subroutine xerbla(srname, info)
subroutine dcopy(n, dx, incx, dy, incy)
DCOPY
subroutine dlae2(a, b, c, rt1, rt2)
DLAE2 computes the eigenvalues of a 2-by-2 symmetric matrix.
subroutine dlaev2(a, b, c, rt1, rt2, cs1, sn1)
DLAEV2 computes the eigenvalues and eigenvectors of a 2-by-2 symmetric/Hermitian 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 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 dlarrr(n, d, e, info)
DLARRR performs tests to decide whether the symmetric tridiagonal matrix T warrants expensive computa...
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 dlasrt(id, n, d, info)
DLASRT sorts numbers in increasing or decreasing order.
subroutine dscal(n, da, dx, incx)
DSCAL
subroutine dstemr(jobz, range, n, d, e, vl, vu, il, iu, m, w, z, ldz, nzc, isuppz, tryrac, work, lwork, iwork, liwork, info)
DSTEMR
subroutine dswap(n, dx, incx, dy, incy)
DSWAP