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 , 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
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 )
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,
667 IF( iinfo.NE.0 )
THEN
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 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 ...