317 SUBROUTINE dstemr( JOBZ, RANGE, N, D, E, VL, VU, IL, IU,
318 $ M, W, Z, LDZ, NZC, ISUPPZ, TRYRAC, WORK, LWORK,
319 $ IWORK, LIWORK, INFO )
326 CHARACTER JOBZ, RANGE
328 INTEGER IL, INFO, IU, LDZ, NZC, LIWORK, LWORK, M, N
329 DOUBLE PRECISION VL, VU
332 INTEGER ISUPPZ( * ), IWORK( * )
333 DOUBLE PRECISION D( * ), E( * ), W( * ), WORK( * )
334 DOUBLE PRECISION Z( LDZ, * )
340 DOUBLE PRECISION ZERO, ONE, FOUR, MINRGP
341 PARAMETER ( ZERO = 0.0d0, one = 1.0d0,
346 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
369 INTRINSIC max, min, sqrt
377 wantz = lsame( jobz,
'V' )
378 alleig = lsame( range,
'A' )
379 valeig = lsame( range,
'V' )
380 indeig = lsame( range,
'I' )
382 lquery = ( ( lwork.EQ.-1 ).OR.( liwork.EQ.-1 ) )
383 zquery = ( nzc.EQ.-1 )
410 ELSEIF( indeig )
THEN
417 IF( .NOT.( wantz .OR. lsame( jobz,
'N' ) ) )
THEN
419 ELSE IF( .NOT.( alleig .OR. valeig .OR. indeig ) )
THEN
421 ELSE IF( n.LT.0 )
THEN
423 ELSE IF( valeig .AND. n.GT.0 .AND. wu.LE.wl )
THEN
425 ELSE IF( indeig .AND. ( iil.LT.1 .OR. iil.GT.n ) )
THEN
427 ELSE IF( indeig .AND. ( iiu.LT.iil .OR. iiu.GT.n ) )
THEN
429 ELSE IF( ldz.LT.1 .OR. ( wantz .AND. ldz.LT.n ) )
THEN
431 ELSE IF( lwork.LT.lwmin .AND. .NOT.lquery )
THEN
433 ELSE IF( liwork.LT.liwmin .AND. .NOT.lquery )
THEN
439 safmin = dlamch(
'Safe minimum' )
440 eps = dlamch(
'Precision' )
441 smlnum = safmin / eps
442 bignum = one / smlnum
443 rmin = sqrt( smlnum )
444 rmax = min( sqrt( bignum ), one / sqrt( sqrt( safmin ) ) )
450 IF( wantz .AND. alleig )
THEN
452 ELSE IF( wantz .AND. valeig )
THEN
453 CALL dlarrc(
'T', n, vl, vu, d, e, safmin,
454 $ nzcmin, itmp, itmp2, info )
455 ELSE IF( wantz .AND. indeig )
THEN
461 IF( zquery .AND. info.EQ.0 )
THEN
463 ELSE IF( nzc.LT.nzcmin .AND. .NOT.zquery )
THEN
470 CALL xerbla(
'DSTEMR', -info )
473 ELSE IF( lquery .OR. zquery )
THEN
484 IF( alleig .OR. indeig )
THEN
488 IF( wl.LT.d( 1 ) .AND. wu.GE.d( 1 ) )
THEN
493 IF( wantz.AND.(.NOT.zquery) )
THEN
502 IF( .NOT.wantz )
THEN
503 CALL dlae2( d(1), e(1), d(2), r1, r2 )
504 ELSE IF( wantz.AND.(.NOT.zquery) )
THEN
505 CALL dlaev2( d(1), e(1), d(2), r1, r2, cs, sn )
517 $ (valeig.AND.(r2.GT.wl).AND.
519 $ (indeig.AND.(iil.EQ.1)) )
THEN
522 IF( wantz.AND.(.NOT.zquery) )
THEN
546 $ (valeig.AND.(r1.GT.wl).AND.
548 $ (indeig.AND.(iiu.EQ.2)) )
THEN
551 IF( wantz.AND.(.NOT.zquery) )
THEN
598 tnrm = dlanst(
'M', n, d, e )
599 IF( tnrm.GT.zero .AND. tnrm.LT.rmin )
THEN
601 ELSE IF( tnrm.GT.rmax )
THEN
604 IF( scale.NE.one )
THEN
605 CALL dscal( n, scale, d, 1 )
606 CALL dscal( n-1, scale, e, 1 )
626 CALL dlarrr( n, d, e, iinfo )
642 CALL dcopy(n,d,1,work(indd),1)
646 work( inde2+j-1 ) = e(j)**2
650 IF( .NOT.wantz )
THEN
660 rtol2 = max( sqrt(eps)*5.0d-3, four * eps )
662 CALL dlarre( range, n, wl, wu, iil, iiu, d, e,
663 $ work(inde2), rtol1, rtol2, thresh, nsplit,
664 $ iwork( iinspl ), m, w, work( inderr ),
665 $ work( indgp ), iwork( iindbl ),
666 $ iwork( iindw ), work( indgrs ), pivmin,
667 $ work( indwrk ), iwork( iindwk ), iinfo )
668 IF( iinfo.NE.0 )
THEN
669 info = 10 + abs( iinfo )
682 CALL dlarrv( n, wl, wu, d, e,
683 $ pivmin, iwork( iinspl ), m,
684 $ 1, m, minrgp, rtol1, rtol2,
685 $ w, work( inderr ), work( indgp ), iwork( iindbl ),
686 $ iwork( iindw ), work( indgrs ), z, ldz,
687 $ isuppz, work( indwrk ), iwork( iindwk ), iinfo )
688 IF( iinfo.NE.0 )
THEN
689 info = 20 + abs( iinfo )
699 itmp = iwork( iindbl+j-1 )
700 w( j ) = w( j ) + e( iwork( iinspl+itmp-1 ) )
710 DO 39 jblk = 1, iwork( iindbl+m-1 )
711 iend = iwork( iinspl+jblk-1 )
712 in = iend - ibegin + 1
717 IF( iwork( iindbl+wend ).EQ.jblk )
THEN
722 IF( wend.LT.wbegin )
THEN
727 offset = iwork(iindw+wbegin-1)-1
728 ifirst = iwork(iindw+wbegin-1)
729 ilast = iwork(iindw+wend-1)
732 $ work(indd+ibegin-1), work(inde2+ibegin-1),
733 $ ifirst, ilast, rtol2, offset, w(wbegin),
734 $ work( inderr+wbegin-1 ),
735 $ work( indwrk ), iwork( iindwk ), pivmin,
744 IF( scale.NE.one )
THEN
745 CALL dscal( m, one / scale, w, 1 )
754 IF( nsplit.GT.1 .OR. n.EQ.2 )
THEN
755 IF( .NOT. wantz )
THEN
756 CALL dlasrt(
'I', m, w, iinfo )
757 IF( iinfo.NE.0 )
THEN
766 IF( w( jj ).LT.tmp )
THEN
775 CALL dswap( n, z( 1, i ), 1, z( 1, j ), 1 )
776 itmp = isuppz( 2*i-1 )
777 isuppz( 2*i-1 ) = isuppz( 2*j-1 )
778 isuppz( 2*j-1 ) = itmp
780 isuppz( 2*i ) = isuppz( 2*j )
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 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 ...