317 SUBROUTINE sstemr( 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
332 INTEGER ISUPPZ( * ), IWORK( * )
333 REAL D( * ), E( * ), W( * ), WORK( * )
340 REAL ZERO, ONE, FOUR, MINRGP
341 PARAMETER ( ZERO = 0.0e0, one = 1.0e0,
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 REAL BIGNUM, CS, EPS, PIVMIN, R1, R2, RMAX, RMIN,
354 $ RTOL1, RTOL2, SAFMIN, SCALE, SMLNUM, SN,
355 $ thresh, tmp, tnrm, wl, wu
360 REAL SLAMCH, SLANST, SROUNDUP_LWORK
361 EXTERNAL lsame, slamch, slanst, sroundup_lwork
369 INTRINSIC max, min, sqrt
375 wantz = lsame( jobz,
'V' )
376 alleig = lsame( range,
'A' )
377 valeig = lsame( range,
'V' )
378 indeig = lsame( range,
'I' )
380 lquery = ( ( lwork.EQ.-1 ).OR.( liwork.EQ.-1 ) )
381 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 = slamch(
'Safe minimum' )
438 eps = slamch(
'Precision' )
439 smlnum = safmin / eps
440 bignum = one / smlnum
441 rmin = sqrt( smlnum )
442 rmax = min( sqrt( bignum ), one / sqrt( sqrt( safmin ) ) )
445 work( 1 ) = sroundup_lwork(lwmin)
448 IF( wantz .AND. alleig )
THEN
450 ELSE IF( wantz .AND. valeig )
THEN
451 CALL slarrc(
'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
460 z( 1,1 ) = real( nzcmin )
461 ELSE IF( nzc.LT.nzcmin .AND. .NOT.zquery )
THEN
468 CALL xerbla(
'SSTEMR', -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 slae2( d(1), e(1), d(2), r1, r2 )
502 ELSE IF( wantz.AND.(.NOT.zquery) )
THEN
503 CALL slaev2( d(1), e(1), d(2), r1, r2, cs, sn )
515 $ (valeig.AND.(r2.GT.wl).AND.
517 $ (indeig.AND.(iil.EQ.1)) )
THEN
520 IF( wantz.AND.(.NOT.zquery) )
THEN
544 $ (valeig.AND.(r1.GT.wl).AND.
546 $ (indeig.AND.(iiu.EQ.2)) )
THEN
549 IF( wantz.AND.(.NOT.zquery) )
THEN
595 tnrm = slanst(
'M', n, d, e )
596 IF( tnrm.GT.zero .AND. tnrm.LT.rmin )
THEN
598 ELSE IF( tnrm.GT.rmax )
THEN
601 IF( scale.NE.one )
THEN
602 CALL sscal( n, scale, d, 1 )
603 CALL sscal( n-1, scale, e, 1 )
623 CALL slarrr( n, d, e, iinfo )
639 CALL scopy(n,d,1,work(indd),1)
643 work( inde2+j-1 ) = e(j)**2
647 IF( .NOT.wantz )
THEN
656 rtol1 = max( sqrt(eps)*5.0e-2, four * eps )
657 rtol2 = max( sqrt(eps)*5.0e-3, four * eps )
659 CALL slarre( range, n, wl, wu, iil, iiu, d, e,
660 $ work(inde2), rtol1, rtol2, thresh, nsplit,
661 $ iwork( iinspl ), m, w, work( inderr ),
662 $ work( indgp ), iwork( iindbl ),
663 $ iwork( iindw ), work( indgrs ), pivmin,
664 $ work( indwrk ), iwork( iindwk ), iinfo )
665 IF( iinfo.NE.0 )
THEN
666 info = 10 + abs( iinfo )
679 CALL slarrv( n, wl, wu, d, e,
680 $ pivmin, iwork( iinspl ), m,
681 $ 1, m, minrgp, rtol1, rtol2,
682 $ w, work( inderr ), work( indgp ), iwork( iindbl ),
683 $ iwork( iindw ), work( indgrs ), z, ldz,
684 $ isuppz, work( indwrk ), iwork( iindwk ), iinfo )
685 IF( iinfo.NE.0 )
THEN
686 info = 20 + abs( iinfo )
696 itmp = iwork( iindbl+j-1 )
697 w( j ) = w( j ) + e( iwork( iinspl+itmp-1 ) )
707 DO 39 jblk = 1, iwork( iindbl+m-1 )
708 iend = iwork( iinspl+jblk-1 )
709 in = iend - ibegin + 1
714 IF( iwork( iindbl+wend ).EQ.jblk )
THEN
719 IF( wend.LT.wbegin )
THEN
724 offset = iwork(iindw+wbegin-1)-1
725 ifirst = iwork(iindw+wbegin-1)
726 ilast = iwork(iindw+wend-1)
729 $ work(indd+ibegin-1), work(inde2+ibegin-1),
730 $ ifirst, ilast, rtol2, offset, w(wbegin),
731 $ work( inderr+wbegin-1 ),
732 $ work( indwrk ), iwork( iindwk ), pivmin,
741 IF( scale.NE.one )
THEN
742 CALL sscal( m, one / scale, w, 1 )
749 IF( nsplit.GT.1 .OR. n.EQ.2 )
THEN
750 IF( .NOT. wantz )
THEN
751 CALL slasrt(
'I', m, w, iinfo )
752 IF( iinfo.NE.0 )
THEN
761 IF( w( jj ).LT.tmp )
THEN
770 CALL sswap( n, z( 1, i ), 1, z( 1, j ), 1 )
771 itmp = isuppz( 2*i-1 )
772 isuppz( 2*i-1 ) = isuppz( 2*j-1 )
773 isuppz( 2*j-1 ) = itmp
775 isuppz( 2*i ) = isuppz( 2*j )
784 work( 1 ) = sroundup_lwork(lwmin)