336 SUBROUTINE zstemr( JOBZ, RANGE, N, D, E, VL, VU, IL, IU,
337 $ M, W, Z, LDZ, NZC, ISUPPZ, TRYRAC, WORK, LWORK,
338 $ IWORK, LIWORK, INFO )
345 CHARACTER JOBZ, RANGE
347 INTEGER IL, INFO, IU, LDZ, NZC, LIWORK, LWORK, M, N
348 DOUBLE PRECISION VL, VU
351 INTEGER ISUPPZ( * ), IWORK( * )
352 DOUBLE PRECISION D( * ), E( * ), W( * ), WORK( * )
353 COMPLEX*16 Z( LDZ, * )
359 DOUBLE PRECISION ZERO, ONE, FOUR, MINRGP
360 PARAMETER ( ZERO = 0.0d0, one = 1.0d0,
365 LOGICAL ALLEIG, INDEIG, LQUERY, VALEIG, WANTZ, ZQUERY,
367 INTEGER I, IBEGIN, IEND, IFIRST, IIL, IINDBL, IINDW,
368 $ IINDWK, IINFO, IINSPL, IIU, ILAST, IN, INDD,
369 $ inde2, inderr, indgp, indgrs, indwrk, itmp,
370 $ itmp2, j, jblk, jj, liwmin, lwmin, nsplit,
371 $ nzcmin, offset, wbegin, wend
372 DOUBLE PRECISION BIGNUM, CS, EPS, PIVMIN, R1, R2, RMAX, RMIN,
373 $ RTOL1, RTOL2, SAFMIN, SCALE, SMLNUM, SN,
374 $ thresh, tmp, tnrm, wl, wu
379 DOUBLE PRECISION DLAMCH, DLANST
380 EXTERNAL lsame, dlamch, dlanst
387 INTRINSIC max, min, sqrt
395 wantz = lsame( jobz,
'V' )
396 alleig = lsame( range,
'A' )
397 valeig = lsame( range,
'V' )
398 indeig = lsame( range,
'I' )
400 lquery = ( ( lwork.EQ.-1 ).OR.( liwork.EQ.-1 ) )
401 zquery = ( nzc.EQ.-1 )
428 ELSEIF( indeig )
THEN
435 IF( .NOT.( wantz .OR. lsame( jobz,
'N' ) ) )
THEN
437 ELSE IF( .NOT.( alleig .OR. valeig .OR. indeig ) )
THEN
439 ELSE IF( n.LT.0 )
THEN
441 ELSE IF( valeig .AND. n.GT.0 .AND. wu.LE.wl )
THEN
443 ELSE IF( indeig .AND. ( iil.LT.1 .OR. iil.GT.n ) )
THEN
445 ELSE IF( indeig .AND. ( iiu.LT.iil .OR. iiu.GT.n ) )
THEN
447 ELSE IF( ldz.LT.1 .OR. ( wantz .AND. ldz.LT.n ) )
THEN
449 ELSE IF( lwork.LT.lwmin .AND. .NOT.lquery )
THEN
451 ELSE IF( liwork.LT.liwmin .AND. .NOT.lquery )
THEN
457 safmin = dlamch(
'Safe minimum' )
458 eps = dlamch(
'Precision' )
459 smlnum = safmin / eps
460 bignum = one / smlnum
461 rmin = sqrt( smlnum )
462 rmax = min( sqrt( bignum ), one / sqrt( sqrt( safmin ) ) )
468 IF( wantz .AND. alleig )
THEN
470 ELSE IF( wantz .AND. valeig )
THEN
471 CALL dlarrc(
'T', n, vl, vu, d, e, safmin,
472 $ nzcmin, itmp, itmp2, info )
473 ELSE IF( wantz .AND. indeig )
THEN
479 IF( zquery .AND. info.EQ.0 )
THEN
481 ELSE IF( nzc.LT.nzcmin .AND. .NOT.zquery )
THEN
488 CALL xerbla(
'ZSTEMR', -info )
491 ELSE IF( lquery .OR. zquery )
THEN
502 IF( alleig .OR. indeig )
THEN
506 IF( wl.LT.d( 1 ) .AND. wu.GE.d( 1 ) )
THEN
511 IF( wantz.AND.(.NOT.zquery) )
THEN
520 IF( .NOT.wantz )
THEN
521 CALL dlae2( d(1), e(1), d(2), r1, r2 )
522 ELSE IF( wantz.AND.(.NOT.zquery) )
THEN
523 CALL dlaev2( d(1), e(1), d(2), r1, r2, cs, sn )
535 $ (valeig.AND.(r2.GT.wl).AND.
537 $ (indeig.AND.(iil.EQ.1)) )
THEN
540 IF( wantz.AND.(.NOT.zquery) )
THEN
564 $ (valeig.AND.(r1.GT.wl).AND.
566 $ (indeig.AND.(iiu.EQ.2)) )
THEN
569 IF( wantz.AND.(.NOT.zquery) )
THEN
615 tnrm = dlanst(
'M', n, d, e )
616 IF( tnrm.GT.zero .AND. tnrm.LT.rmin )
THEN
618 ELSE IF( tnrm.GT.rmax )
THEN
621 IF( scale.NE.one )
THEN
622 CALL dscal( n, scale, d, 1 )
623 CALL dscal( n-1, scale, e, 1 )
643 CALL dlarrr( n, d, e, iinfo )
659 CALL dcopy(n,d,1,work(indd),1)
663 work( inde2+j-1 ) = e(j)**2
667 IF( .NOT.wantz )
THEN
677 rtol2 = max( sqrt(eps)*5.0d-3, four * eps )
679 CALL dlarre( range, n, wl, wu, iil, iiu, d, e,
680 $ work(inde2), rtol1, rtol2, thresh, nsplit,
681 $ iwork( iinspl ), m, w, work( inderr ),
682 $ work( indgp ), iwork( iindbl ),
683 $ iwork( iindw ), work( indgrs ), pivmin,
684 $ work( indwrk ), iwork( iindwk ), iinfo )
685 IF( iinfo.NE.0 )
THEN
686 info = 10 + abs( iinfo )
699 CALL zlarrv( n, wl, wu, d, e,
700 $ pivmin, iwork( iinspl ), m,
701 $ 1, m, minrgp, rtol1, rtol2,
702 $ w, work( inderr ), work( indgp ), iwork( iindbl ),
703 $ iwork( iindw ), work( indgrs ), z, ldz,
704 $ isuppz, work( indwrk ), iwork( iindwk ), iinfo )
705 IF( iinfo.NE.0 )
THEN
706 info = 20 + abs( iinfo )
716 itmp = iwork( iindbl+j-1 )
717 w( j ) = w( j ) + e( iwork( iinspl+itmp-1 ) )
727 DO 39 jblk = 1, iwork( iindbl+m-1 )
728 iend = iwork( iinspl+jblk-1 )
729 in = iend - ibegin + 1
734 IF( iwork( iindbl+wend ).EQ.jblk )
THEN
739 IF( wend.LT.wbegin )
THEN
744 offset = iwork(iindw+wbegin-1)-1
745 ifirst = iwork(iindw+wbegin-1)
746 ilast = iwork(iindw+wend-1)
749 $ work(indd+ibegin-1), work(inde2+ibegin-1),
750 $ ifirst, ilast, rtol2, offset, w(wbegin),
751 $ work( inderr+wbegin-1 ),
752 $ work( indwrk ), iwork( iindwk ), pivmin,
761 IF( scale.NE.one )
THEN
762 CALL dscal( m, one / scale, w, 1 )
769 IF( nsplit.GT.1 .OR. n.EQ.2 )
THEN
770 IF( .NOT. wantz )
THEN
771 CALL dlasrt(
'I', m, w, iinfo )
772 IF( iinfo.NE.0 )
THEN
781 IF( w( jj ).LT.tmp )
THEN
790 CALL zswap( n, z( 1, i ), 1, z( 1, j ), 1 )
791 itmp = isuppz( 2*i-1 )
792 isuppz( 2*i-1 ) = isuppz( 2*j-1 )
793 isuppz( 2*j-1 ) = itmp
795 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 zlarrv(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)
ZLARRV 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 zstemr(jobz, range, n, d, e, vl, vu, il, iu, m, w, z, ldz, nzc, isuppz, tryrac, work, lwork, iwork, liwork, info)
ZSTEMR
subroutine zswap(n, zx, incx, zy, incy)
ZSWAP