LAPACK 3.12.1
LAPACK: Linear Algebra PACKage
Loading...
Searching...
No Matches
dlarre.f
Go to the documentation of this file.
1*> \brief \b DLARRE given the tridiagonal matrix T, sets small off-diagonal elements to zero and for each unreduced block Ti, finds base representations and eigenvalues.
2*
3* =========== DOCUMENTATION ===========
4*
5* Online html documentation available at
6* http://www.netlib.org/lapack/explore-html/
7*
8*> Download DLARRE + dependencies
9*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlarre.f">
10*> [TGZ]</a>
11*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlarre.f">
12*> [ZIP]</a>
13*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlarre.f">
14*> [TXT]</a>
15*
16* Definition:
17* ===========
18*
19* SUBROUTINE DLARRE( RANGE, N, VL, VU, IL, IU, D, E, E2,
20* RTOL1, RTOL2, SPLTOL, NSPLIT, ISPLIT, M,
21* W, WERR, WGAP, IBLOCK, INDEXW, GERS, PIVMIN,
22* WORK, IWORK, INFO )
23*
24* .. Scalar Arguments ..
25* CHARACTER RANGE
26* INTEGER IL, INFO, IU, M, N, NSPLIT
27* DOUBLE PRECISION PIVMIN, RTOL1, RTOL2, SPLTOL, VL, VU
28* ..
29* .. Array Arguments ..
30* INTEGER IBLOCK( * ), ISPLIT( * ), IWORK( * ),
31* $ INDEXW( * )
32* DOUBLE PRECISION D( * ), E( * ), E2( * ), GERS( * ),
33* $ W( * ),WERR( * ), WGAP( * ), WORK( * )
34* ..
35*
36*
37*> \par Purpose:
38* =============
39*>
40*> \verbatim
41*>
42*> To find the desired eigenvalues of a given real symmetric
43*> tridiagonal matrix T, DLARRE sets any "small" off-diagonal
44*> elements to zero, and for each unreduced block T_i, it finds
45*> (a) a suitable shift at one end of the block's spectrum,
46*> (b) the base representation, T_i - sigma_i I = L_i D_i L_i^T, and
47*> (c) eigenvalues of each L_i D_i L_i^T.
48*> The representations and eigenvalues found are then used by
49*> DSTEMR to compute the eigenvectors of T.
50*> The accuracy varies depending on whether bisection is used to
51*> find a few eigenvalues or the dqds algorithm (subroutine DLASQ2) to
52*> compute all and then discard any unwanted one.
53*> As an added benefit, DLARRE also outputs the n
54*> Gerschgorin intervals for the matrices L_i D_i L_i^T.
55*> \endverbatim
56*
57* Arguments:
58* ==========
59*
60*> \param[in] RANGE
61*> \verbatim
62*> RANGE is CHARACTER*1
63*> = 'A': ("All") all eigenvalues will be found.
64*> = 'V': ("Value") all eigenvalues in the half-open interval
65*> (VL, VU] will be found.
66*> = 'I': ("Index") the IL-th through IU-th eigenvalues (of the
67*> entire matrix) will be found.
68*> \endverbatim
69*>
70*> \param[in] N
71*> \verbatim
72*> N is INTEGER
73*> The order of the matrix. N > 0.
74*> \endverbatim
75*>
76*> \param[in,out] VL
77*> \verbatim
78*> VL is DOUBLE PRECISION
79*> If RANGE='V', the lower bound for the eigenvalues.
80*> Eigenvalues less than or equal to VL, or greater than VU,
81*> will not be returned. VL < VU.
82*> If RANGE='I' or ='A', DLARRE computes bounds on the desired
83*> part of the spectrum.
84*> \endverbatim
85*>
86*> \param[in,out] VU
87*> \verbatim
88*> VU is DOUBLE PRECISION
89*> If RANGE='V', the upper bound for the eigenvalues.
90*> Eigenvalues less than or equal to VL, or greater than VU,
91*> will not be returned. VL < VU.
92*> If RANGE='I' or ='A', DLARRE computes bounds on the desired
93*> part of the spectrum.
94*> \endverbatim
95*>
96*> \param[in] IL
97*> \verbatim
98*> IL is INTEGER
99*> If RANGE='I', the index of the
100*> smallest eigenvalue to be returned.
101*> 1 <= IL <= IU <= N.
102*> \endverbatim
103*>
104*> \param[in] IU
105*> \verbatim
106*> IU is INTEGER
107*> If RANGE='I', the index of the
108*> largest eigenvalue to be returned.
109*> 1 <= IL <= IU <= N.
110*> \endverbatim
111*>
112*> \param[in,out] D
113*> \verbatim
114*> D is DOUBLE PRECISION array, dimension (N)
115*> On entry, the N diagonal elements of the tridiagonal
116*> matrix T.
117*> On exit, the N diagonal elements of the diagonal
118*> matrices D_i.
119*> \endverbatim
120*>
121*> \param[in,out] E
122*> \verbatim
123*> E is DOUBLE PRECISION array, dimension (N)
124*> On entry, the first (N-1) entries contain the subdiagonal
125*> elements of the tridiagonal matrix T; E(N) need not be set.
126*> On exit, E contains the subdiagonal elements of the unit
127*> bidiagonal matrices L_i. The entries E( ISPLIT( I ) ),
128*> 1 <= I <= NSPLIT, contain the base points sigma_i on output.
129*> \endverbatim
130*>
131*> \param[in,out] E2
132*> \verbatim
133*> E2 is DOUBLE PRECISION array, dimension (N)
134*> On entry, the first (N-1) entries contain the SQUARES of the
135*> subdiagonal elements of the tridiagonal matrix T;
136*> E2(N) need not be set.
137*> On exit, the entries E2( ISPLIT( I ) ),
138*> 1 <= I <= NSPLIT, have been set to zero
139*> \endverbatim
140*>
141*> \param[in] RTOL1
142*> \verbatim
143*> RTOL1 is DOUBLE PRECISION
144*> \endverbatim
145*>
146*> \param[in] RTOL2
147*> \verbatim
148*> RTOL2 is DOUBLE PRECISION
149*> Parameters for bisection.
150*> An interval [LEFT,RIGHT] has converged if
151*> RIGHT-LEFT < MAX( RTOL1*GAP, RTOL2*MAX(|LEFT|,|RIGHT|) )
152*> \endverbatim
153*>
154*> \param[in] SPLTOL
155*> \verbatim
156*> SPLTOL is DOUBLE PRECISION
157*> The threshold for splitting.
158*> \endverbatim
159*>
160*> \param[out] NSPLIT
161*> \verbatim
162*> NSPLIT is INTEGER
163*> The number of blocks T splits into. 1 <= NSPLIT <= N.
164*> \endverbatim
165*>
166*> \param[out] ISPLIT
167*> \verbatim
168*> ISPLIT is INTEGER array, dimension (N)
169*> The splitting points, at which T breaks up into blocks.
170*> The first block consists of rows/columns 1 to ISPLIT(1),
171*> the second of rows/columns ISPLIT(1)+1 through ISPLIT(2),
172*> etc., and the NSPLIT-th consists of rows/columns
173*> ISPLIT(NSPLIT-1)+1 through ISPLIT(NSPLIT)=N.
174*> \endverbatim
175*>
176*> \param[out] M
177*> \verbatim
178*> M is INTEGER
179*> The total number of eigenvalues (of all L_i D_i L_i^T)
180*> found.
181*> \endverbatim
182*>
183*> \param[out] W
184*> \verbatim
185*> W is DOUBLE PRECISION array, dimension (N)
186*> The first M elements contain the eigenvalues. The
187*> eigenvalues of each of the blocks, L_i D_i L_i^T, are
188*> sorted in ascending order ( DLARRE may use the
189*> remaining N-M elements as workspace).
190*> \endverbatim
191*>
192*> \param[out] WERR
193*> \verbatim
194*> WERR is DOUBLE PRECISION array, dimension (N)
195*> The error bound on the corresponding eigenvalue in W.
196*> \endverbatim
197*>
198*> \param[out] WGAP
199*> \verbatim
200*> WGAP is DOUBLE PRECISION array, dimension (N)
201*> The separation from the right neighbor eigenvalue in W.
202*> The gap is only with respect to the eigenvalues of the same block
203*> as each block has its own representation tree.
204*> Exception: at the right end of a block we store the left gap
205*> \endverbatim
206*>
207*> \param[out] IBLOCK
208*> \verbatim
209*> IBLOCK is INTEGER array, dimension (N)
210*> The indices of the blocks (submatrices) associated with the
211*> corresponding eigenvalues in W; IBLOCK(i)=1 if eigenvalue
212*> W(i) belongs to the first block from the top, =2 if W(i)
213*> belongs to the second block, etc.
214*> \endverbatim
215*>
216*> \param[out] INDEXW
217*> \verbatim
218*> INDEXW is INTEGER array, dimension (N)
219*> The indices of the eigenvalues within each block (submatrix);
220*> for example, INDEXW(i)= 10 and IBLOCK(i)=2 imply that the
221*> i-th eigenvalue W(i) is the 10-th eigenvalue in block 2
222*> \endverbatim
223*>
224*> \param[out] GERS
225*> \verbatim
226*> GERS is DOUBLE PRECISION array, dimension (2*N)
227*> The N Gerschgorin intervals (the i-th Gerschgorin interval
228*> is (GERS(2*i-1), GERS(2*i)).
229*> \endverbatim
230*>
231*> \param[out] PIVMIN
232*> \verbatim
233*> PIVMIN is DOUBLE PRECISION
234*> The minimum pivot in the Sturm sequence for T.
235*> \endverbatim
236*>
237*> \param[out] WORK
238*> \verbatim
239*> WORK is DOUBLE PRECISION array, dimension (6*N)
240*> Workspace.
241*> \endverbatim
242*>
243*> \param[out] IWORK
244*> \verbatim
245*> IWORK is INTEGER array, dimension (5*N)
246*> Workspace.
247*> \endverbatim
248*>
249*> \param[out] INFO
250*> \verbatim
251*> INFO is INTEGER
252*> = 0: successful exit
253*> > 0: A problem occurred in DLARRE.
254*> < 0: One of the called subroutines signaled an internal problem.
255*> Needs inspection of the corresponding parameter IINFO
256*> for further information.
257*>
258*> =-1: Problem in DLARRD.
259*> = 2: No base representation could be found in MAXTRY iterations.
260*> Increasing MAXTRY and recompilation might be a remedy.
261*> =-3: Problem in DLARRB when computing the refined root
262*> representation for DLASQ2.
263*> =-4: Problem in DLARRB when preforming bisection on the
264*> desired part of the spectrum.
265*> =-5: Problem in DLASQ2.
266*> =-6: Problem in DLASQ2.
267*> \endverbatim
268*
269* Authors:
270* ========
271*
272*> \author Univ. of Tennessee
273*> \author Univ. of California Berkeley
274*> \author Univ. of Colorado Denver
275*> \author NAG Ltd.
276*
277*> \ingroup larre
278*
279*> \par Further Details:
280* =====================
281*>
282*> \verbatim
283*>
284*> The base representations are required to suffer very little
285*> element growth and consequently define all their eigenvalues to
286*> high relative accuracy.
287*> \endverbatim
288*
289*> \par Contributors:
290* ==================
291*>
292*> Beresford Parlett, University of California, Berkeley, USA \n
293*> Jim Demmel, University of California, Berkeley, USA \n
294*> Inderjit Dhillon, University of Texas, Austin, USA \n
295*> Osni Marques, LBNL/NERSC, USA \n
296*> Christof Voemel, University of California, Berkeley, USA \n
297*>
298* =====================================================================
299 SUBROUTINE dlarre( RANGE, N, VL, VU, IL, IU, D, E, E2,
300 $ RTOL1, RTOL2, SPLTOL, NSPLIT, ISPLIT, M,
301 $ W, WERR, WGAP, IBLOCK, INDEXW, GERS, PIVMIN,
302 $ WORK, IWORK, INFO )
303*
304* -- LAPACK auxiliary routine --
305* -- LAPACK is a software package provided by Univ. of Tennessee, --
306* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
307*
308* .. Scalar Arguments ..
309 CHARACTER RANGE
310 INTEGER IL, INFO, IU, M, N, NSPLIT
311 DOUBLE PRECISION PIVMIN, RTOL1, RTOL2, SPLTOL, VL, VU
312* ..
313* .. Array Arguments ..
314 INTEGER IBLOCK( * ), ISPLIT( * ), IWORK( * ),
315 $ INDEXW( * )
316 DOUBLE PRECISION D( * ), E( * ), E2( * ), GERS( * ),
317 $ w( * ),werr( * ), wgap( * ), work( * )
318* ..
319*
320* =====================================================================
321*
322* .. Parameters ..
323 DOUBLE PRECISION FAC, FOUR, FOURTH, FUDGE, HALF, HNDRD,
324 $ MAXGROWTH, ONE, PERT, TWO, ZERO
325 PARAMETER ( ZERO = 0.0d0, one = 1.0d0,
326 $ two = 2.0d0, four=4.0d0,
327 $ hndrd = 100.0d0,
328 $ pert = 8.0d0,
329 $ half = one/two, fourth = one/four, fac= half,
330 $ maxgrowth = 64.0d0, fudge = 2.0d0 )
331 INTEGER MAXTRY, ALLRNG, INDRNG, VALRNG
332 PARAMETER ( MAXTRY = 6, allrng = 1, indrng = 2,
333 $ valrng = 3 )
334* ..
335* .. Local Scalars ..
336 LOGICAL FORCEB, NOREP, USEDQD
337 INTEGER CNT, CNT1, CNT2, I, IBEGIN, IDUM, IEND, IINFO,
338 $ IN, INDL, INDU, IRANGE, J, JBLK, MB, MM,
339 $ wbegin, wend
340 DOUBLE PRECISION AVGAP, BSRTOL, CLWDTH, DMAX, DPIVOT, EABS,
341 $ EMAX, EOLD, EPS, GL, GU, ISLEFT, ISRGHT, RTL,
342 $ RTOL, S1, S2, SAFMIN, SGNDEF, SIGMA, SPDIAM,
343 $ tau, tmp, tmp1
344
345
346* ..
347* .. Local Arrays ..
348 INTEGER ISEED( 4 )
349* ..
350* .. External Functions ..
351 LOGICAL LSAME
352 DOUBLE PRECISION DLAMCH
353 EXTERNAL DLAMCH, LSAME
354
355* ..
356* .. External Subroutines ..
357 EXTERNAL dcopy, dlarnv, dlarra, dlarrb, dlarrc,
358 $ dlarrd,
359 $ dlasq2, dlarrk
360* ..
361* .. Intrinsic Functions ..
362 INTRINSIC abs, max, min
363
364* ..
365* .. Executable Statements ..
366*
367
368 info = 0
369 nsplit = 0
370 m = 0
371*
372* Quick return if possible
373*
374 IF( n.LE.0 ) THEN
375 RETURN
376 END IF
377*
378* Decode RANGE
379*
380 IF( lsame( range, 'A' ) ) THEN
381 irange = allrng
382 ELSE IF( lsame( range, 'V' ) ) THEN
383 irange = valrng
384 ELSE IF( lsame( range, 'I' ) ) THEN
385 irange = indrng
386 END IF
387
388* Get machine constants
389 safmin = dlamch( 'S' )
390 eps = dlamch( 'P' )
391
392* Set parameters
393 rtl = sqrt(eps)
394 bsrtol = sqrt(eps)
395
396* Treat case of 1x1 matrix for quick return
397 IF( n.EQ.1 ) THEN
398 IF( (irange.EQ.allrng).OR.
399 $ ((irange.EQ.valrng).AND.(d(1).GT.vl).AND.(d(1).LE.vu)).OR.
400 $ ((irange.EQ.indrng).AND.(il.EQ.1).AND.(iu.EQ.1)) ) THEN
401 m = 1
402 w(1) = d(1)
403* The computation error of the eigenvalue is zero
404 werr(1) = zero
405 wgap(1) = zero
406 iblock( 1 ) = 1
407 indexw( 1 ) = 1
408 gers(1) = d( 1 )
409 gers(2) = d( 1 )
410 ENDIF
411* store the shift for the initial RRR, which is zero in this case
412 e(1) = zero
413 RETURN
414 END IF
415
416* General case: tridiagonal matrix of order > 1
417*
418* Init WERR, WGAP. Compute Gerschgorin intervals and spectral diameter.
419* Compute maximum off-diagonal entry and pivmin.
420 gl = d(1)
421 gu = d(1)
422 eold = zero
423 emax = zero
424 e(n) = zero
425 DO 5 i = 1,n
426 werr(i) = zero
427 wgap(i) = zero
428 eabs = abs( e(i) )
429 IF( eabs .GE. emax ) THEN
430 emax = eabs
431 END IF
432 tmp1 = eabs + eold
433 gers( 2*i-1) = d(i) - tmp1
434 gl = min( gl, gers( 2*i - 1))
435 gers( 2*i ) = d(i) + tmp1
436 gu = max( gu, gers(2*i) )
437 eold = eabs
438 5 CONTINUE
439* The minimum pivot allowed in the Sturm sequence for T
440 pivmin = safmin * max( one, emax**2 )
441* Compute spectral diameter. The Gerschgorin bounds give an
442* estimate that is wrong by at most a factor of SQRT(2)
443 spdiam = gu - gl
444
445* Compute splitting points
446 CALL dlarra( n, d, e, e2, spltol, spdiam,
447 $ nsplit, isplit, iinfo )
448
449* Can force use of bisection instead of faster DQDS.
450* Option left in the code for future multisection work.
451 forceb = .false.
452
453* Initialize USEDQD, DQDS should be used for ALLRNG unless someone
454* explicitly wants bisection.
455 usedqd = (( irange.EQ.allrng ) .AND. (.NOT.forceb))
456
457 IF( (irange.EQ.allrng) .AND. (.NOT. forceb) ) THEN
458* Set interval [VL,VU] that contains all eigenvalues
459 vl = gl
460 vu = gu
461 ELSE
462* We call DLARRD to find crude approximations to the eigenvalues
463* in the desired range. In case IRANGE = INDRNG, we also obtain the
464* interval (VL,VU] that contains all the wanted eigenvalues.
465* An interval [LEFT,RIGHT] has converged if
466* RIGHT-LEFT.LT.RTOL*MAX(ABS(LEFT),ABS(RIGHT))
467* DLARRD needs a WORK of size 4*N, IWORK of size 3*N
468 CALL dlarrd( range, 'B', n, vl, vu, il, iu, gers,
469 $ bsrtol, d, e, e2, pivmin, nsplit, isplit,
470 $ mm, w, werr, vl, vu, iblock, indexw,
471 $ work, iwork, iinfo )
472 IF( iinfo.NE.0 ) THEN
473 info = -1
474 RETURN
475 ENDIF
476* Make sure that the entries M+1 to N in W, WERR, IBLOCK, INDEXW are 0
477 DO 14 i = mm+1,n
478 w( i ) = zero
479 werr( i ) = zero
480 iblock( i ) = 0
481 indexw( i ) = 0
482 14 CONTINUE
483 END IF
484
485
486***
487* Loop over unreduced blocks
488 ibegin = 1
489 wbegin = 1
490 DO 170 jblk = 1, nsplit
491 iend = isplit( jblk )
492 in = iend - ibegin + 1
493
494* 1 X 1 block
495 IF( in.EQ.1 ) THEN
496 IF( (irange.EQ.allrng).OR.( (irange.EQ.valrng).AND.
497 $ ( d( ibegin ).GT.vl ).AND.( d( ibegin ).LE.vu ) )
498 $ .OR. ( (irange.EQ.indrng).AND.(iblock(wbegin).EQ.jblk))
499 $ ) THEN
500 m = m + 1
501 w( m ) = d( ibegin )
502 werr(m) = zero
503* The gap for a single block doesn't matter for the later
504* algorithm and is assigned an arbitrary large value
505 wgap(m) = zero
506 iblock( m ) = jblk
507 indexw( m ) = 1
508 wbegin = wbegin + 1
509 ENDIF
510* E( IEND ) holds the shift for the initial RRR
511 e( iend ) = zero
512 ibegin = iend + 1
513 GO TO 170
514 END IF
515*
516* Blocks of size larger than 1x1
517*
518* E( IEND ) will hold the shift for the initial RRR, for now set it =0
519 e( iend ) = zero
520*
521* Find local outer bounds GL,GU for the block
522 gl = d(ibegin)
523 gu = d(ibegin)
524 DO 15 i = ibegin , iend
525 gl = min( gers( 2*i-1 ), gl )
526 gu = max( gers( 2*i ), gu )
527 15 CONTINUE
528 spdiam = gu - gl
529
530 IF(.NOT. ((irange.EQ.allrng).AND.(.NOT.forceb)) ) THEN
531* Count the number of eigenvalues in the current block.
532 mb = 0
533 DO 20 i = wbegin,mm
534 IF( iblock(i).EQ.jblk ) THEN
535 mb = mb+1
536 ELSE
537 GOTO 21
538 ENDIF
539 20 CONTINUE
540 21 CONTINUE
541
542 IF( mb.EQ.0) THEN
543* No eigenvalue in the current block lies in the desired range
544* E( IEND ) holds the shift for the initial RRR
545 e( iend ) = zero
546 ibegin = iend + 1
547 GO TO 170
548 ELSE
549
550* Decide whether dqds or bisection is more efficient
551 usedqd = ( (mb .GT. fac*in) .AND. (.NOT.forceb) )
552 wend = wbegin + mb - 1
553* Calculate gaps for the current block
554* In later stages, when representations for individual
555* eigenvalues are different, we use SIGMA = E( IEND ).
556 sigma = zero
557 DO 30 i = wbegin, wend - 1
558 wgap( i ) = max( zero,
559 $ w(i+1)-werr(i+1) - (w(i)+werr(i)) )
560 30 CONTINUE
561 wgap( wend ) = max( zero,
562 $ vu - sigma - (w( wend )+werr( wend )))
563* Find local index of the first and last desired evalue.
564 indl = indexw(wbegin)
565 indu = indexw( wend )
566 ENDIF
567 ENDIF
568 IF(( (irange.EQ.allrng) .AND. (.NOT. forceb) ).OR.usedqd) THEN
569* Case of DQDS
570* Find approximations to the extremal eigenvalues of the block
571 CALL dlarrk( in, 1, gl, gu, d(ibegin),
572 $ e2(ibegin), pivmin, rtl, tmp, tmp1, iinfo )
573 IF( iinfo.NE.0 ) THEN
574 info = -1
575 RETURN
576 ENDIF
577 isleft = max(gl, tmp - tmp1
578 $ - hndrd * eps* abs(tmp - tmp1))
579
580 CALL dlarrk( in, in, gl, gu, d(ibegin),
581 $ e2(ibegin), pivmin, rtl, tmp, tmp1, iinfo )
582 IF( iinfo.NE.0 ) THEN
583 info = -1
584 RETURN
585 ENDIF
586 isrght = min(gu, tmp + tmp1
587 $ + hndrd * eps * abs(tmp + tmp1))
588* Improve the estimate of the spectral diameter
589 spdiam = isrght - isleft
590 ELSE
591* Case of bisection
592* Find approximations to the wanted extremal eigenvalues
593 isleft = max(gl, w(wbegin) - werr(wbegin)
594 $ - hndrd * eps*abs(w(wbegin)- werr(wbegin) ))
595 isrght = min(gu,w(wend) + werr(wend)
596 $ + hndrd * eps * abs(w(wend)+ werr(wend)))
597 ENDIF
598
599
600* Decide whether the base representation for the current block
601* L_JBLK D_JBLK L_JBLK^T = T_JBLK - sigma_JBLK I
602* should be on the left or the right end of the current block.
603* The strategy is to shift to the end which is "more populated"
604* Furthermore, decide whether to use DQDS for the computation of
605* the eigenvalue approximations at the end of DLARRE or bisection.
606* dqds is chosen if all eigenvalues are desired or the number of
607* eigenvalues to be computed is large compared to the blocksize.
608 IF( ( irange.EQ.allrng ) .AND. (.NOT.forceb) ) THEN
609* If all the eigenvalues have to be computed, we use dqd
610 usedqd = .true.
611* INDL is the local index of the first eigenvalue to compute
612 indl = 1
613 indu = in
614* MB = number of eigenvalues to compute
615 mb = in
616 wend = wbegin + mb - 1
617* Define 1/4 and 3/4 points of the spectrum
618 s1 = isleft + fourth * spdiam
619 s2 = isrght - fourth * spdiam
620 ELSE
621* DLARRD has computed IBLOCK and INDEXW for each eigenvalue
622* approximation.
623* choose sigma
624 IF( usedqd ) THEN
625 s1 = isleft + fourth * spdiam
626 s2 = isrght - fourth * spdiam
627 ELSE
628 tmp = min(isrght,vu) - max(isleft,vl)
629 s1 = max(isleft,vl) + fourth * tmp
630 s2 = min(isrght,vu) - fourth * tmp
631 ENDIF
632 ENDIF
633
634* Compute the negcount at the 1/4 and 3/4 points
635 IF(mb.GT.1) THEN
636 CALL dlarrc( 'T', in, s1, s2, d(ibegin),
637 $ e(ibegin), pivmin, cnt, cnt1, cnt2, iinfo)
638 ENDIF
639
640 IF(mb.EQ.1) THEN
641 sigma = gl
642 sgndef = one
643 ELSEIF( cnt1 - indl .GE. indu - cnt2 ) THEN
644 IF( ( irange.EQ.allrng ) .AND. (.NOT.forceb) ) THEN
645 sigma = max(isleft,gl)
646 ELSEIF( usedqd ) THEN
647* use Gerschgorin bound as shift to get pos def matrix
648* for dqds
649 sigma = isleft
650 ELSE
651* use approximation of the first desired eigenvalue of the
652* block as shift
653 sigma = max(isleft,vl)
654 ENDIF
655 sgndef = one
656 ELSE
657 IF( ( irange.EQ.allrng ) .AND. (.NOT.forceb) ) THEN
658 sigma = min(isrght,gu)
659 ELSEIF( usedqd ) THEN
660* use Gerschgorin bound as shift to get neg def matrix
661* for dqds
662 sigma = isrght
663 ELSE
664* use approximation of the first desired eigenvalue of the
665* block as shift
666 sigma = min(isrght,vu)
667 ENDIF
668 sgndef = -one
669 ENDIF
670
671
672* An initial SIGMA has been chosen that will be used for computing
673* T - SIGMA I = L D L^T
674* Define the increment TAU of the shift in case the initial shift
675* needs to be refined to obtain a factorization with not too much
676* element growth.
677 IF( usedqd ) THEN
678* The initial SIGMA was to the outer end of the spectrum
679* the matrix is definite and we need not retreat.
680 tau = spdiam*eps*n + two*pivmin
681 tau = max( tau,two*eps*abs(sigma) )
682 ELSE
683 IF(mb.GT.1) THEN
684 clwdth = w(wend) + werr(wend) - w(wbegin) - werr(wbegin)
685 avgap = abs(clwdth / dble(wend-wbegin))
686 IF( sgndef.EQ.one ) THEN
687 tau = half*max(wgap(wbegin),avgap)
688 tau = max(tau,werr(wbegin))
689 ELSE
690 tau = half*max(wgap(wend-1),avgap)
691 tau = max(tau,werr(wend))
692 ENDIF
693 ELSE
694 tau = werr(wbegin)
695 ENDIF
696 ENDIF
697*
698 DO 80 idum = 1, maxtry
699* Compute L D L^T factorization of tridiagonal matrix T - sigma I.
700* Store D in WORK(1:IN), L in WORK(IN+1:2*IN), and reciprocals of
701* pivots in WORK(2*IN+1:3*IN)
702 dpivot = d( ibegin ) - sigma
703 work( 1 ) = dpivot
704 dmax = abs( work(1) )
705 j = ibegin
706 DO 70 i = 1, in - 1
707 work( 2*in+i ) = one / work( i )
708 tmp = e( j )*work( 2*in+i )
709 work( in+i ) = tmp
710 dpivot = ( d( j+1 )-sigma ) - tmp*e( j )
711 work( i+1 ) = dpivot
712 dmax = max( dmax, abs(dpivot) )
713 j = j + 1
714 70 CONTINUE
715* check for element growth
716 IF( dmax .GT. maxgrowth*spdiam ) THEN
717 norep = .true.
718 ELSE
719 norep = .false.
720 ENDIF
721 IF( usedqd .AND. .NOT.norep ) THEN
722* Ensure the definiteness of the representation
723* All entries of D (of L D L^T) must have the same sign
724 DO 71 i = 1, in
725 tmp = sgndef*work( i )
726 IF( tmp.LT.zero ) norep = .true.
727 71 CONTINUE
728 ENDIF
729 IF(norep) THEN
730* Note that in the case of IRANGE=ALLRNG, we use the Gerschgorin
731* shift which makes the matrix definite. So we should end up
732* here really only in the case of IRANGE = VALRNG or INDRNG.
733 IF( idum.EQ.maxtry-1 ) THEN
734 IF( sgndef.EQ.one ) THEN
735* The fudged Gerschgorin shift should succeed
736 sigma =
737 $ gl - fudge*spdiam*eps*n - fudge*two*pivmin
738 ELSE
739 sigma =
740 $ gu + fudge*spdiam*eps*n + fudge*two*pivmin
741 END IF
742 ELSE
743 sigma = sigma - sgndef * tau
744 tau = two * tau
745 END IF
746 ELSE
747* an initial RRR is found
748 GO TO 83
749 END IF
750 80 CONTINUE
751* if the program reaches this point, no base representation could be
752* found in MAXTRY iterations.
753 info = 2
754 RETURN
755
756 83 CONTINUE
757* At this point, we have found an initial base representation
758* T - SIGMA I = L D L^T with not too much element growth.
759* Store the shift.
760 e( iend ) = sigma
761* Store D and L.
762 CALL dcopy( in, work, 1, d( ibegin ), 1 )
763 CALL dcopy( in-1, work( in+1 ), 1, e( ibegin ), 1 )
764
765
766 IF(mb.GT.1 ) THEN
767*
768* Perturb each entry of the base representation by a small
769* (but random) relative amount to overcome difficulties with
770* glued matrices.
771*
772 DO 122 i = 1, 4
773 iseed( i ) = 1
774 122 CONTINUE
775
776 CALL dlarnv(2, iseed, 2*in-1, work(1))
777 DO 125 i = 1,in-1
778 d(ibegin+i-1) = d(ibegin+i-1)*(one+eps*pert*work(i))
779 e(ibegin+i-1) = e(ibegin+i-1)*(one+eps*pert*work(in+i))
780 125 CONTINUE
781 d(iend) = d(iend)*(one+eps*four*work(in))
782*
783 ENDIF
784*
785* Don't update the Gerschgorin intervals because keeping track
786* of the updates would be too much work in DLARRV.
787* We update W instead and use it to locate the proper Gerschgorin
788* intervals.
789
790* Compute the required eigenvalues of L D L' by bisection or dqds
791 IF ( .NOT.usedqd ) THEN
792* If DLARRD has been used, shift the eigenvalue approximations
793* according to their representation. This is necessary for
794* a uniform DLARRV since dqds computes eigenvalues of the
795* shifted representation. In DLARRV, W will always hold the
796* UNshifted eigenvalue approximation.
797 DO 134 j=wbegin,wend
798 w(j) = w(j) - sigma
799 werr(j) = werr(j) + abs(w(j)) * eps
800 134 CONTINUE
801* call DLARRB to reduce eigenvalue error of the approximations
802* from DLARRD
803 DO 135 i = ibegin, iend-1
804 work( i ) = d( i ) * e( i )**2
805 135 CONTINUE
806* use bisection to find EV from INDL to INDU
807 CALL dlarrb(in, d(ibegin), work(ibegin),
808 $ indl, indu, rtol1, rtol2, indl-1,
809 $ w(wbegin), wgap(wbegin), werr(wbegin),
810 $ work( 2*n+1 ), iwork, pivmin, spdiam,
811 $ in, iinfo )
812 IF( iinfo .NE. 0 ) THEN
813 info = -4
814 RETURN
815 END IF
816* DLARRB computes all gaps correctly except for the last one
817* Record distance to VU/GU
818 wgap( wend ) = max( zero,
819 $ ( vu-sigma ) - ( w( wend ) + werr( wend ) ) )
820 DO 138 i = indl, indu
821 m = m + 1
822 iblock(m) = jblk
823 indexw(m) = i
824 138 CONTINUE
825 ELSE
826* Call dqds to get all eigs (and then possibly delete unwanted
827* eigenvalues).
828* Note that dqds finds the eigenvalues of the L D L^T representation
829* of T to high relative accuracy. High relative accuracy
830* might be lost when the shift of the RRR is subtracted to obtain
831* the eigenvalues of T. However, T is not guaranteed to define its
832* eigenvalues to high relative accuracy anyway.
833* Set RTOL to the order of the tolerance used in DLASQ2
834* This is an ESTIMATED error, the worst case bound is 4*N*EPS
835* which is usually too large and requires unnecessary work to be
836* done by bisection when computing the eigenvectors
837 rtol = log(dble(in)) * four * eps
838 j = ibegin
839 DO 140 i = 1, in - 1
840 work( 2*i-1 ) = abs( d( j ) )
841 work( 2*i ) = e( j )*e( j )*work( 2*i-1 )
842 j = j + 1
843 140 CONTINUE
844 work( 2*in-1 ) = abs( d( iend ) )
845 work( 2*in ) = zero
846 CALL dlasq2( in, work, iinfo )
847 IF( iinfo .NE. 0 ) THEN
848* If IINFO = -5 then an index is part of a tight cluster
849* and should be changed. The index is in IWORK(1) and the
850* gap is in WORK(N+1)
851 info = -5
852 RETURN
853 ELSE
854* Test that all eigenvalues are positive as expected
855 DO 149 i = 1, in
856 IF( work( i ).LT.zero ) THEN
857 info = -6
858 RETURN
859 ENDIF
860 149 CONTINUE
861 END IF
862 IF( sgndef.GT.zero ) THEN
863 DO 150 i = indl, indu
864 m = m + 1
865 w( m ) = work( in-i+1 )
866 iblock( m ) = jblk
867 indexw( m ) = i
868 150 CONTINUE
869 ELSE
870 DO 160 i = indl, indu
871 m = m + 1
872 w( m ) = -work( i )
873 iblock( m ) = jblk
874 indexw( m ) = i
875 160 CONTINUE
876 END IF
877
878 DO 165 i = m - mb + 1, m
879* the value of RTOL below should be the tolerance in DLASQ2
880 werr( i ) = rtol * abs( w(i) )
881 165 CONTINUE
882 DO 166 i = m - mb + 1, m - 1
883* compute the right gap between the intervals
884 wgap( i ) = max( zero,
885 $ w(i+1)-werr(i+1) - (w(i)+werr(i)) )
886 166 CONTINUE
887 wgap( m ) = max( zero,
888 $ ( vu-sigma ) - ( w( m ) + werr( m ) ) )
889 END IF
890* proceed with next block
891 ibegin = iend + 1
892 wbegin = wend + 1
893 170 CONTINUE
894*
895
896 RETURN
897*
898* End of DLARRE
899*
900 END
subroutine dcopy(n, dx, incx, dy, incy)
DCOPY
Definition dcopy.f:82
subroutine dlarnv(idist, iseed, n, x)
DLARNV returns a vector of random numbers from a uniform or normal distribution.
Definition dlarnv.f:95
subroutine dlarra(n, d, e, e2, spltol, tnrm, nsplit, isplit, info)
DLARRA computes the splitting points with the specified threshold.
Definition dlarra.f:134
subroutine dlarrb(n, d, lld, ifirst, ilast, rtol1, rtol2, offset, w, wgap, werr, work, iwork, pivmin, spdiam, twist, info)
DLARRB provides limited bisection to locate eigenvalues for more accuracy.
Definition dlarrb.f:194
subroutine dlarrc(jobt, n, vl, vu, d, e, pivmin, eigcnt, lcnt, rcnt, info)
DLARRC computes the number of eigenvalues of the symmetric tridiagonal matrix.
Definition dlarrc.f:135
subroutine dlarrd(range, order, n, vl, vu, il, iu, gers, reltol, d, e, e2, pivmin, nsplit, isplit, m, w, werr, wl, wu, iblock, indexw, work, iwork, info)
DLARRD computes the eigenvalues of a symmetric tridiagonal matrix to suitable accuracy.
Definition dlarrd.f:327
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...
Definition dlarre.f:303
subroutine dlarrk(n, iw, gl, gu, d, e2, pivmin, reltol, w, werr, info)
DLARRK computes one eigenvalue of a symmetric tridiagonal matrix T to suitable accuracy.
Definition dlarrk.f:143
subroutine dlasq2(n, z, info)
DLASQ2 computes all the eigenvalues of the symmetric positive definite tridiagonal matrix associated ...
Definition dlasq2.f:110