1 SUBROUTINE dstegr2( JOBZ, RANGE, N, D, E, VL, VU, IL, IU,
2 $ M, W, Z, LDZ, NZC, ISUPPZ, WORK, LWORK, IWORK,
3 $ LIWORK, DOL, DOU, ZOFFSET, INFO )
11 INTEGER DOL, DOU, IL, INFO, IU,
12 $ ldz, nzc, liwork, lwork, m, n, zoffset
13 DOUBLE PRECISION VL, VU
17 INTEGER ISUPPZ( * ), IWORK( * )
18 DOUBLE PRECISION D( * ), E( * ), W( * ), WORK( * )
19 DOUBLE PRECISION Z( LDZ, * )
188 DOUBLE PRECISION ZERO, ONE, FOUR, MINRGP
189 PARAMETER ( ZERO = 0.0d0, one = 1.0d0,
194 LOGICAL ALLEIG, INDEIG, LQUERY, VALEIG, WANTZ, ZQUERY
195 INTEGER I, IIL, IINDBL, IINDW, IINDWK, IINFO, IINSPL,
196 $ iiu, inde2, inderr, indgp, indgrs, indwrk,
197 $ itmp, itmp2, j, jj, liwmin, lwmin, nsplit,
199 DOUBLE PRECISION BIGNUM, EPS, PIVMIN, RMAX, RMIN, RTOL1, RTOL2,
200 $ SAFMIN, SCALE, SMLNUM, THRESH, TMP, TNRM, WL,
205 DOUBLE PRECISION DLAMCH, DLANST
206 EXTERNAL lsame, dlamch, dlanst
209 EXTERNAL dcopy, dlae2, dlaev2, dlarrc,
dlarre2,
210 $ dlarrv, dlasrt, dscal, dswap
213 INTRINSIC dble,
max,
min, sqrt
219 wantz = lsame( jobz,
'V' )
220 alleig = lsame( range,
'A' )
221 valeig = lsame( range,
'V' )
222 indeig = lsame( range,
'I' )
224 lquery = ( ( lwork.EQ.-1 ).OR.( liwork.EQ.-1 ) )
225 zquery = ( nzc.EQ.-1 )
250 ELSEIF( indeig )
THEN
257 IF( .NOT.( wantz .OR. lsame( jobz,
'N' ) ) )
THEN
259 ELSE IF( .NOT.( alleig .OR. valeig .OR. indeig ) )
THEN
261 ELSE IF( n.LT.0 )
THEN
263 ELSE IF( valeig .AND. n.GT.0 .AND. wu.LE.wl )
THEN
265 ELSE IF( indeig .AND. ( iil.LT.1 .OR. iil.GT.n ) )
THEN
267 ELSE IF( indeig .AND. ( iiu.LT.iil .OR. iiu.GT.n ) )
THEN
269 ELSE IF( ldz.LT.1 .OR. ( wantz .AND. ldz.LT.n ) )
THEN
271 ELSE IF( lwork.LT.lwmin .AND. .NOT.lquery )
THEN
273 ELSE IF( liwork.LT.liwmin .AND. .NOT.lquery )
THEN
279 safmin = dlamch(
'Safe minimum' )
280 eps = dlamch(
'Precision' )
281 smlnum = safmin / eps
282 bignum = one / smlnum
283 rmin = sqrt( smlnum )
284 rmax =
min( sqrt( bignum ), one / sqrt( sqrt( safmin ) ) )
290 IF( wantz .AND. alleig )
THEN
294 ELSE IF( wantz .AND. valeig )
THEN
295 CALL dlarrc(
'T', n, vl, vu, d, e, safmin,
296 $ nzcmin, itmp, itmp2, info )
299 ELSE IF( wantz .AND. indeig )
THEN
305 IF( zquery .AND. info.EQ.0 )
THEN
307 ELSE IF( nzc.LT.nzcmin .AND. .NOT.zquery )
THEN
313 IF ( dol.LT.1 .OR. dol.GT.nzcmin )
THEN
316 IF ( dou.LT.1 .OR. dou.GT.nzcmin .OR. dou.LT.dol)
THEN
328 ELSE IF( lquery .OR. zquery )
THEN
339 IF( alleig .OR. indeig )
THEN
343 IF( wl.LT.d( 1 ) .AND. wu.GE.d( 1 ) )
THEN
367 tnrm = dlanst(
'M', n, d, e )
368 IF( tnrm.GT.zero .AND. tnrm.LT.rmin )
THEN
370 ELSE IF( tnrm.GT.rmax )
THEN
373 IF( scale.NE.one )
THEN
374 CALL dscal( n, scale, d, 1 )
375 CALL dscal( n-1, scale, e, 1 )
403 work( inde2+j-1 ) = e(j)**2
407 IF( .NOT.wantz )
THEN
417 rtol2 =
max( sqrt(eps)*5.0d-3, four * eps )
419 CALL dlarre2( range, n, wl, wu, iil, iiu, d, e,
420 $ work(inde2), rtol1, rtol2, thresh, nsplit,
421 $ iwork( iinspl ), m, dol, dou,
423 $ work( indgp ), iwork( iindbl ),
424 $ iwork( iindw ), work( indgrs ), pivmin,
425 $ work( indwrk ), iwork( iindwk ), iinfo )
426 IF( iinfo.NE.0 )
THEN
427 info = 100 + abs( iinfo )
440 CALL dlarrv( n, wl, wu, d, e,
441 $ pivmin, iwork( iinspl ), m,
442 $ dol, dou, minrgp, rtol1, rtol2,
443 $ w, work( inderr ), work( indgp ), iwork( iindbl ),
444 $ iwork( iindw ), work( indgrs ), z, ldz,
445 $ isuppz, work( indwrk ), iwork( iindwk ), iinfo )
446 IF( iinfo.NE.0 )
THEN
447 info = 200 + abs( iinfo )
457 itmp = iwork( iindbl+j-1 )
458 w( j ) = w( j ) + e( iwork( iinspl+itmp-1 ) )
466 IF( scale.NE.one )
THEN
467 CALL dscal( m, one / scale, w, 1 )
473 IF( dol.NE.1 .OR. dou.NE.m )
THEN
481 IF( nsplit.GT.1 )
THEN
482 IF( .NOT. wantz )
THEN
483 CALL dlasrt(
'I', dou - dol +1, w(dol), iinfo )
484 IF( iinfo.NE.0 )
THEN
489 DO 60 j = dol, dou - 1
493 IF( w( jj ).LT.tmp )
THEN
502 CALL dswap( n, z( 1, i-zoffset ),
503 $ 1, z( 1, j-zoffset ), 1 )
504 itmp = isuppz( 2*i-1 )
505 isuppz( 2*i-1 ) = isuppz( 2*j-1 )
506 isuppz( 2*j-1 ) = itmp
508 isuppz( 2*i ) = isuppz( 2*j )