319 SUBROUTINE sstemr( 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
334 INTEGER ISUPPZ( * ), IWORK( * )
335 REAL D( * ), E( * ), W( * ), WORK( * )
342 REAL ZERO, ONE, FOUR, MINRGP
343 PARAMETER ( ZERO = 0.0e0, one = 1.0e0,
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 REAL BIGNUM, CS, EPS, PIVMIN, R1, R2, RMAX, RMIN,
356 $ RTOL1, RTOL2, SAFMIN, SCALE, SMLNUM, SN,
357 $ thresh, tmp, tnrm, wl, wu
362 REAL SLAMCH, SLANST, SROUNDUP_LWORK
363 EXTERNAL lsame, slamch, slanst, sroundup_lwork
370 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 )
409 ELSEIF( indeig )
THEN
416 IF( .NOT.( wantz .OR. lsame( jobz,
'N' ) ) )
THEN
418 ELSE IF( .NOT.( alleig .OR. valeig .OR. indeig ) )
THEN
420 ELSE IF( n.LT.0 )
THEN
422 ELSE IF( valeig .AND. n.GT.0 .AND. wu.LE.wl )
THEN
424 ELSE IF( indeig .AND. ( iil.LT.1 .OR. iil.GT.n ) )
THEN
426 ELSE IF( indeig .AND. ( iiu.LT.iil .OR. iiu.GT.n ) )
THEN
428 ELSE IF( ldz.LT.1 .OR. ( wantz .AND. ldz.LT.n ) )
THEN
430 ELSE IF( lwork.LT.lwmin .AND. .NOT.lquery )
THEN
432 ELSE IF( liwork.LT.liwmin .AND. .NOT.lquery )
THEN
438 safmin = slamch(
'Safe minimum' )
439 eps = slamch(
'Precision' )
440 smlnum = safmin / eps
441 bignum = one / smlnum
442 rmin = sqrt( smlnum )
443 rmax = min( sqrt( bignum ), one / sqrt( sqrt( safmin ) ) )
446 work( 1 ) = sroundup_lwork(lwmin)
449 IF( wantz .AND. alleig )
THEN
451 ELSE IF( wantz .AND. valeig )
THEN
452 CALL slarrc(
'T', n, vl, vu, d, e, safmin,
453 $ nzcmin, itmp, itmp2, info )
454 ELSE IF( wantz .AND. indeig )
THEN
460 IF( zquery .AND. info.EQ.0 )
THEN
462 ELSE IF( nzc.LT.nzcmin .AND. .NOT.zquery )
THEN
469 CALL xerbla(
'SSTEMR', -info )
472 ELSE IF( lquery .OR. zquery )
THEN
483 IF( alleig .OR. indeig )
THEN
487 IF( wl.LT.d( 1 ) .AND. wu.GE.d( 1 ) )
THEN
492 IF( wantz.AND.(.NOT.zquery) )
THEN
501 IF( .NOT.wantz )
THEN
502 CALL slae2( d(1), e(1), d(2), r1, r2 )
503 ELSE IF( wantz.AND.(.NOT.zquery) )
THEN
504 CALL slaev2( d(1), e(1), d(2), r1, r2, cs, sn )
516 $ (valeig.AND.(r2.GT.wl).AND.
518 $ (indeig.AND.(iil.EQ.1)) )
THEN
521 IF( wantz.AND.(.NOT.zquery) )
THEN
545 $ (valeig.AND.(r1.GT.wl).AND.
547 $ (indeig.AND.(iiu.EQ.2)) )
THEN
550 IF( wantz.AND.(.NOT.zquery) )
THEN
596 tnrm = slanst(
'M', n, d, e )
597 IF( tnrm.GT.zero .AND. tnrm.LT.rmin )
THEN
599 ELSE IF( tnrm.GT.rmax )
THEN
602 IF( scale.NE.one )
THEN
603 CALL sscal( n, scale, d, 1 )
604 CALL sscal( n-1, scale, e, 1 )
624 CALL slarrr( n, d, e, iinfo )
640 CALL scopy(n,d,1,work(indd),1)
644 work( inde2+j-1 ) = e(j)**2
648 IF( .NOT.wantz )
THEN
657 rtol1 = max( sqrt(eps)*5.0e-2, four * eps )
658 rtol2 = max( sqrt(eps)*5.0e-3, four * eps )
660 CALL slarre( range, n, wl, wu, iil, iiu, d, e,
661 $ work(inde2), rtol1, rtol2, thresh, nsplit,
662 $ iwork( iinspl ), m, w, work( inderr ),
663 $ work( indgp ), iwork( iindbl ),
664 $ iwork( iindw ), work( indgrs ), pivmin,
665 $ work( indwrk ), iwork( iindwk ), iinfo )
666 IF( iinfo.NE.0 )
THEN
667 info = 10 + abs( iinfo )
680 CALL slarrv( n, wl, wu, d, e,
681 $ pivmin, iwork( iinspl ), m,
682 $ 1, m, minrgp, rtol1, rtol2,
683 $ w, work( inderr ), work( indgp ), iwork( iindbl ),
684 $ iwork( iindw ), work( indgrs ), z, ldz,
685 $ isuppz, work( indwrk ), iwork( iindwk ), iinfo )
686 IF( iinfo.NE.0 )
THEN
687 info = 20 + abs( iinfo )
697 itmp = iwork( iindbl+j-1 )
698 w( j ) = w( j ) + e( iwork( iinspl+itmp-1 ) )
708 DO 39 jblk = 1, iwork( iindbl+m-1 )
709 iend = iwork( iinspl+jblk-1 )
710 in = iend - ibegin + 1
715 IF( iwork( iindbl+wend ).EQ.jblk )
THEN
720 IF( wend.LT.wbegin )
THEN
725 offset = iwork(iindw+wbegin-1)-1
726 ifirst = iwork(iindw+wbegin-1)
727 ilast = iwork(iindw+wend-1)
730 $ work(indd+ibegin-1), work(inde2+ibegin-1),
731 $ ifirst, ilast, rtol2, offset, w(wbegin),
732 $ work( inderr+wbegin-1 ),
733 $ work( indwrk ), iwork( iindwk ), pivmin,
742 IF( scale.NE.one )
THEN
743 CALL sscal( m, one / scale, w, 1 )
750 IF( nsplit.GT.1 .OR. n.EQ.2 )
THEN
751 IF( .NOT. wantz )
THEN
752 CALL slasrt(
'I', m, w, iinfo )
753 IF( iinfo.NE.0 )
THEN
762 IF( w( jj ).LT.tmp )
THEN
771 CALL sswap( n, z( 1, i ), 1, z( 1, j ), 1 )
772 itmp = isuppz( 2*i-1 )
773 isuppz( 2*i-1 ) = isuppz( 2*j-1 )
774 isuppz( 2*j-1 ) = itmp
776 isuppz( 2*i ) = isuppz( 2*j )
785 work( 1 ) = sroundup_lwork(lwmin)
subroutine xerbla(srname, info)
subroutine scopy(n, sx, incx, sy, incy)
SCOPY
subroutine slae2(a, b, c, rt1, rt2)
SLAE2 computes the eigenvalues of a 2-by-2 symmetric matrix.
subroutine slaev2(a, b, c, rt1, rt2, cs1, sn1)
SLAEV2 computes the eigenvalues and eigenvectors of a 2-by-2 symmetric/Hermitian matrix.
subroutine slarrc(jobt, n, vl, vu, d, e, pivmin, eigcnt, lcnt, rcnt, info)
SLARRC computes the number of eigenvalues of the symmetric tridiagonal matrix.
subroutine slarre(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)
SLARRE given the tridiagonal matrix T, sets small off-diagonal elements to zero and for each unreduce...
subroutine slarrj(n, d, e2, ifirst, ilast, rtol, offset, w, werr, work, iwork, pivmin, spdiam, info)
SLARRJ performs refinement of the initial estimates of the eigenvalues of the matrix T.
subroutine slarrr(n, d, e, info)
SLARRR performs tests to decide whether the symmetric tridiagonal matrix T warrants expensive computa...
subroutine slarrv(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)
SLARRV computes the eigenvectors of the tridiagonal matrix T = L D LT given L, D and the eigenvalues ...
subroutine slasrt(id, n, d, info)
SLASRT sorts numbers in increasing or decreasing order.
subroutine sscal(n, sa, sx, incx)
SSCAL
subroutine sstemr(jobz, range, n, d, e, vl, vu, il, iu, m, w, z, ldz, nzc, isuppz, tryrac, work, lwork, iwork, liwork, info)
SSTEMR
subroutine sswap(n, sx, incx, sy, incy)
SSWAP