LAPACK 3.12.1
LAPACK: Linear Algebra PACKage
Loading...
Searching...
No Matches
dstemr.f
Go to the documentation of this file.
1*> \brief \b DSTEMR
2*
3* =========== DOCUMENTATION ===========
4*
5* Online html documentation available at
6* http://www.netlib.org/lapack/explore-html/
7*
8*> Download DSTEMR + dependencies
9*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dstemr.f">
10*> [TGZ]</a>
11*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dstemr.f">
12*> [ZIP]</a>
13*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dstemr.f">
14*> [TXT]</a>
15*
16* Definition:
17* ===========
18*
19* SUBROUTINE DSTEMR( JOBZ, RANGE, N, D, E, VL, VU, IL, IU,
20* M, W, Z, LDZ, NZC, ISUPPZ, TRYRAC, WORK, LWORK,
21* IWORK, LIWORK, INFO )
22*
23* .. Scalar Arguments ..
24* CHARACTER JOBZ, RANGE
25* LOGICAL TRYRAC
26* INTEGER IL, INFO, IU, LDZ, NZC, LIWORK, LWORK, M, N
27* DOUBLE PRECISION VL, VU
28* ..
29* .. Array Arguments ..
30* INTEGER ISUPPZ( * ), IWORK( * )
31* DOUBLE PRECISION D( * ), E( * ), W( * ), WORK( * )
32* DOUBLE PRECISION Z( LDZ, * )
33* ..
34*
35*
36*> \par Purpose:
37* =============
38*>
39*> \verbatim
40*>
41*> DSTEMR computes selected eigenvalues and, optionally, eigenvectors
42*> of a real symmetric tridiagonal matrix T. Any such unreduced matrix has
43*> a well defined set of pairwise different real eigenvalues, the corresponding
44*> real eigenvectors are pairwise orthogonal.
45*>
46*> The spectrum may be computed either completely or partially by specifying
47*> either an interval (VL,VU] or a range of indices IL:IU for the desired
48*> eigenvalues.
49*>
50*> Depending on the number of desired eigenvalues, these are computed either
51*> by bisection or the dqds algorithm. Numerically orthogonal eigenvectors are
52*> computed by the use of various suitable L D L^T factorizations near clusters
53*> of close eigenvalues (referred to as RRRs, Relatively Robust
54*> Representations). An informal sketch of the algorithm follows.
55*>
56*> For each unreduced block (submatrix) of T,
57*> (a) Compute T - sigma I = L D L^T, so that L and D
58*> define all the wanted eigenvalues to high relative accuracy.
59*> This means that small relative changes in the entries of D and L
60*> cause only small relative changes in the eigenvalues and
61*> eigenvectors. The standard (unfactored) representation of the
62*> tridiagonal matrix T does not have this property in general.
63*> (b) Compute the eigenvalues to suitable accuracy.
64*> If the eigenvectors are desired, the algorithm attains full
65*> accuracy of the computed eigenvalues only right before
66*> the corresponding vectors have to be computed, see steps c) and d).
67*> (c) For each cluster of close eigenvalues, select a new
68*> shift close to the cluster, find a new factorization, and refine
69*> the shifted eigenvalues to suitable accuracy.
70*> (d) For each eigenvalue with a large enough relative separation compute
71*> the corresponding eigenvector by forming a rank revealing twisted
72*> factorization. Go back to (c) for any clusters that remain.
73*>
74*> For more details, see:
75*> - Inderjit S. Dhillon and Beresford N. Parlett: "Multiple representations
76*> to compute orthogonal eigenvectors of symmetric tridiagonal matrices,"
77*> Linear Algebra and its Applications, 387(1), pp. 1-28, August 2004.
78*> - Inderjit Dhillon and Beresford Parlett: "Orthogonal Eigenvectors and
79*> Relative Gaps," SIAM Journal on Matrix Analysis and Applications, Vol. 25,
80*> 2004. Also LAPACK Working Note 154.
81*> - Inderjit Dhillon: "A new O(n^2) algorithm for the symmetric
82*> tridiagonal eigenvalue/eigenvector problem",
83*> Computer Science Division Technical Report No. UCB/CSD-97-971,
84*> UC Berkeley, May 1997.
85*>
86*> Further Details
87*> 1.DSTEMR works only on machines which follow IEEE-754
88*> floating-point standard in their handling of infinities and NaNs.
89*> This permits the use of efficient inner loops avoiding a check for
90*> zero divisors.
91*> \endverbatim
92*
93* Arguments:
94* ==========
95*
96*> \param[in] JOBZ
97*> \verbatim
98*> JOBZ is CHARACTER*1
99*> = 'N': Compute eigenvalues only;
100*> = 'V': Compute eigenvalues and eigenvectors.
101*> \endverbatim
102*>
103*> \param[in] RANGE
104*> \verbatim
105*> RANGE is CHARACTER*1
106*> = 'A': all eigenvalues will be found.
107*> = 'V': all eigenvalues in the half-open interval (VL,VU]
108*> will be found.
109*> = 'I': the IL-th through IU-th eigenvalues will be found.
110*> \endverbatim
111*>
112*> \param[in] N
113*> \verbatim
114*> N is INTEGER
115*> The order of the matrix. N >= 0.
116*> \endverbatim
117*>
118*> \param[in,out] D
119*> \verbatim
120*> D is DOUBLE PRECISION array, dimension (N)
121*> On entry, the N diagonal elements of the tridiagonal matrix
122*> T. On exit, D is overwritten.
123*> \endverbatim
124*>
125*> \param[in,out] E
126*> \verbatim
127*> E is DOUBLE PRECISION array, dimension (N)
128*> On entry, the (N-1) subdiagonal elements of the tridiagonal
129*> matrix T in elements 1 to N-1 of E. E(N) need not be set on
130*> input, but is used internally as workspace.
131*> On exit, E is overwritten.
132*> \endverbatim
133*>
134*> \param[in] VL
135*> \verbatim
136*> VL is DOUBLE PRECISION
137*>
138*> If RANGE='V', the lower bound of the interval to
139*> be searched for eigenvalues. VL < VU.
140*> Not referenced if RANGE = 'A' or 'I'.
141*> \endverbatim
142*>
143*> \param[in] VU
144*> \verbatim
145*> VU is DOUBLE PRECISION
146*>
147*> If RANGE='V', the upper bound of the interval to
148*> be searched for eigenvalues. VL < VU.
149*> Not referenced if RANGE = 'A' or 'I'.
150*> \endverbatim
151*>
152*> \param[in] IL
153*> \verbatim
154*> IL is INTEGER
155*>
156*> If RANGE='I', the index of the
157*> smallest eigenvalue to be returned.
158*> 1 <= IL <= IU <= N, if N > 0.
159*> Not referenced if RANGE = 'A' or 'V'.
160*> \endverbatim
161*>
162*> \param[in] IU
163*> \verbatim
164*> IU is INTEGER
165*>
166*> If RANGE='I', the index of the
167*> largest eigenvalue to be returned.
168*> 1 <= IL <= IU <= N, if N > 0.
169*> Not referenced if RANGE = 'A' or 'V'.
170*> \endverbatim
171*>
172*> \param[out] M
173*> \verbatim
174*> M is INTEGER
175*> The total number of eigenvalues found. 0 <= M <= N.
176*> If RANGE = 'A', M = N, and if RANGE = 'I', M = IU-IL+1.
177*> \endverbatim
178*>
179*> \param[out] W
180*> \verbatim
181*> W is DOUBLE PRECISION array, dimension (N)
182*> The first M elements contain the selected eigenvalues in
183*> ascending order.
184*> \endverbatim
185*>
186*> \param[out] Z
187*> \verbatim
188*> Z is DOUBLE PRECISION array, dimension (LDZ, max(1,M) )
189*> If JOBZ = 'V', and if INFO = 0, then the first M columns of Z
190*> contain the orthonormal eigenvectors of the matrix T
191*> corresponding to the selected eigenvalues, with the i-th
192*> column of Z holding the eigenvector associated with W(i).
193*> If JOBZ = 'N', then Z is not referenced.
194*> Note: the user must ensure that at least max(1,M) columns are
195*> supplied in the array Z; if RANGE = 'V', the exact value of M
196*> is not known in advance and can be computed with a workspace
197*> query by setting NZC = -1, see below.
198*> \endverbatim
199*>
200*> \param[in] LDZ
201*> \verbatim
202*> LDZ is INTEGER
203*> The leading dimension of the array Z. LDZ >= 1, and if
204*> JOBZ = 'V', then LDZ >= max(1,N).
205*> \endverbatim
206*>
207*> \param[in] NZC
208*> \verbatim
209*> NZC is INTEGER
210*> The number of eigenvectors to be held in the array Z.
211*> If RANGE = 'A', then NZC >= max(1,N).
212*> If RANGE = 'V', then NZC >= the number of eigenvalues in (VL,VU].
213*> If RANGE = 'I', then NZC >= IU-IL+1.
214*> If NZC = -1, then a workspace query is assumed; the
215*> routine calculates the number of columns of the array Z that
216*> are needed to hold the eigenvectors.
217*> This value is returned as the first entry of the Z array, and
218*> no error message related to NZC is issued by XERBLA.
219*> \endverbatim
220*>
221*> \param[out] ISUPPZ
222*> \verbatim
223*> ISUPPZ is INTEGER array, dimension ( 2*max(1,M) )
224*> The support of the eigenvectors in Z, i.e., the indices
225*> indicating the nonzero elements in Z. The i-th computed eigenvector
226*> is nonzero only in elements ISUPPZ( 2*i-1 ) through
227*> ISUPPZ( 2*i ). This is relevant in the case when the matrix
228*> is split. ISUPPZ is only accessed when JOBZ is 'V' and N > 0.
229*> \endverbatim
230*>
231*> \param[in,out] TRYRAC
232*> \verbatim
233*> TRYRAC is LOGICAL
234*> If TRYRAC = .TRUE., indicates that the code should check whether
235*> the tridiagonal matrix defines its eigenvalues to high relative
236*> accuracy. If so, the code uses relative-accuracy preserving
237*> algorithms that might be (a bit) slower depending on the matrix.
238*> If the matrix does not define its eigenvalues to high relative
239*> accuracy, the code can uses possibly faster algorithms.
240*> If TRYRAC = .FALSE., the code is not required to guarantee
241*> relatively accurate eigenvalues and can use the fastest possible
242*> techniques.
243*> On exit, a .TRUE. TRYRAC will be set to .FALSE. if the matrix
244*> does not define its eigenvalues to high relative accuracy.
245*> \endverbatim
246*>
247*> \param[out] WORK
248*> \verbatim
249*> WORK is DOUBLE PRECISION array, dimension (LWORK)
250*> On exit, if INFO = 0, WORK(1) returns the optimal
251*> (and minimal) LWORK.
252*> \endverbatim
253*>
254*> \param[in] LWORK
255*> \verbatim
256*> LWORK is INTEGER
257*> The dimension of the array WORK. LWORK >= max(1,18*N)
258*> if JOBZ = 'V', and LWORK >= max(1,12*N) if JOBZ = 'N'.
259*> If LWORK = -1, then a workspace query is assumed; the routine
260*> only calculates the optimal size of the WORK array, returns
261*> this value as the first entry of the WORK array, and no error
262*> message related to LWORK is issued by XERBLA.
263*> \endverbatim
264*>
265*> \param[out] IWORK
266*> \verbatim
267*> IWORK is INTEGER array, dimension (LIWORK)
268*> On exit, if INFO = 0, IWORK(1) returns the optimal LIWORK.
269*> \endverbatim
270*>
271*> \param[in] LIWORK
272*> \verbatim
273*> LIWORK is INTEGER
274*> The dimension of the array IWORK. LIWORK >= max(1,10*N)
275*> if the eigenvectors are desired, and LIWORK >= max(1,8*N)
276*> if only the eigenvalues are to be computed.
277*> If LIWORK = -1, then a workspace query is assumed; the
278*> routine only calculates the optimal size of the IWORK array,
279*> returns this value as the first entry of the IWORK array, and
280*> no error message related to LIWORK is issued by XERBLA.
281*> \endverbatim
282*>
283*> \param[out] INFO
284*> \verbatim
285*> INFO is INTEGER
286*> On exit, INFO
287*> = 0: successful exit
288*> < 0: if INFO = -i, the i-th argument had an illegal value
289*> > 0: if INFO = 1X, internal error in DLARRE,
290*> if INFO = 2X, internal error in DLARRV.
291*> Here, the digit X = ABS( IINFO ) < 10, where IINFO is
292*> the nonzero error code returned by DLARRE or
293*> DLARRV, respectively.
294*> \endverbatim
295*
296* Authors:
297* ========
298*
299*> \author Univ. of Tennessee
300*> \author Univ. of California Berkeley
301*> \author Univ. of Colorado Denver
302*> \author NAG Ltd.
303*
304*> \ingroup stemr
305*
306*> \par Contributors:
307* ==================
308*>
309*> Beresford Parlett, University of California, Berkeley, USA \n
310*> Jim Demmel, University of California, Berkeley, USA \n
311*> Inderjit Dhillon, University of Texas, Austin, USA \n
312*> Osni Marques, LBNL/NERSC, USA \n
313*> Christof Voemel, University of California, Berkeley, USA \n
314*> Aravindh Krishnamoorthy, FAU, Erlangen, Germany \n
315*
316* =====================================================================
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 )
320*
321* -- LAPACK computational routine --
322* -- LAPACK is a software package provided by Univ. of Tennessee, --
323* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
324*
325* .. Scalar Arguments ..
326 CHARACTER JOBZ, RANGE
327 LOGICAL TRYRAC
328 INTEGER IL, INFO, IU, LDZ, NZC, LIWORK, LWORK, M, N
329 DOUBLE PRECISION VL, VU
330* ..
331* .. Array Arguments ..
332 INTEGER ISUPPZ( * ), IWORK( * )
333 DOUBLE PRECISION D( * ), E( * ), W( * ), WORK( * )
334 DOUBLE PRECISION Z( LDZ, * )
335* ..
336*
337* =====================================================================
338*
339* .. Parameters ..
340 DOUBLE PRECISION ZERO, ONE, FOUR, MINRGP
341 PARAMETER ( ZERO = 0.0d0, one = 1.0d0,
342 $ four = 4.0d0,
343 $ minrgp = 1.0d-3 )
344* ..
345* .. Local Scalars ..
346 LOGICAL ALLEIG, INDEIG, LQUERY, VALEIG, WANTZ, ZQUERY,
347 $ LAESWAP
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
356* ..
357* ..
358* .. External Functions ..
359 LOGICAL LSAME
360 DOUBLE PRECISION DLAMCH, DLANST
361 EXTERNAL lsame, dlamch, dlanst
362* ..
363* .. External Subroutines ..
364 EXTERNAL dcopy, dlae2, dlaev2, dlarrc, dlarre,
365 $ dlarrj,
367* ..
368* .. Intrinsic Functions ..
369 INTRINSIC max, min, sqrt
370
371
372* ..
373* .. Executable Statements ..
374*
375* Test the input parameters.
376*
377 wantz = lsame( jobz, 'V' )
378 alleig = lsame( range, 'A' )
379 valeig = lsame( range, 'V' )
380 indeig = lsame( range, 'I' )
381*
382 lquery = ( ( lwork.EQ.-1 ).OR.( liwork.EQ.-1 ) )
383 zquery = ( nzc.EQ.-1 )
384 laeswap = .false.
385
386* DSTEMR needs WORK of size 6*N, IWORK of size 3*N.
387* In addition, DLARRE needs WORK of size 6*N, IWORK of size 5*N.
388* Furthermore, DLARRV needs WORK of size 12*N, IWORK of size 7*N.
389 IF( wantz ) THEN
390 lwmin = 18*n
391 liwmin = 10*n
392 ELSE
393* need less workspace if only the eigenvalues are wanted
394 lwmin = 12*n
395 liwmin = 8*n
396 ENDIF
397
398 wl = zero
399 wu = zero
400 iil = 0
401 iiu = 0
402 nsplit = 0
403
404 IF( valeig ) THEN
405* We do not reference VL, VU in the cases RANGE = 'I','A'
406* The interval (WL, WU] contains all the wanted eigenvalues.
407* It is either given by the user or computed in DLARRE.
408 wl = vl
409 wu = vu
410 ELSEIF( indeig ) THEN
411* We do not reference IL, IU in the cases RANGE = 'V','A'
412 iil = il
413 iiu = iu
414 ENDIF
415*
416 info = 0
417 IF( .NOT.( wantz .OR. lsame( jobz, 'N' ) ) ) THEN
418 info = -1
419 ELSE IF( .NOT.( alleig .OR. valeig .OR. indeig ) ) THEN
420 info = -2
421 ELSE IF( n.LT.0 ) THEN
422 info = -3
423 ELSE IF( valeig .AND. n.GT.0 .AND. wu.LE.wl ) THEN
424 info = -7
425 ELSE IF( indeig .AND. ( iil.LT.1 .OR. iil.GT.n ) ) THEN
426 info = -8
427 ELSE IF( indeig .AND. ( iiu.LT.iil .OR. iiu.GT.n ) ) THEN
428 info = -9
429 ELSE IF( ldz.LT.1 .OR. ( wantz .AND. ldz.LT.n ) ) THEN
430 info = -13
431 ELSE IF( lwork.LT.lwmin .AND. .NOT.lquery ) THEN
432 info = -17
433 ELSE IF( liwork.LT.liwmin .AND. .NOT.lquery ) THEN
434 info = -19
435 END IF
436*
437* Get machine constants.
438*
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 ) ) )
445*
446 IF( info.EQ.0 ) THEN
447 work( 1 ) = lwmin
448 iwork( 1 ) = liwmin
449*
450 IF( wantz .AND. alleig ) THEN
451 nzcmin = n
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
456 nzcmin = iiu-iil+1
457 ELSE
458* WANTZ .EQ. FALSE.
459 nzcmin = 0
460 ENDIF
461 IF( zquery .AND. info.EQ.0 ) THEN
462 z( 1,1 ) = nzcmin
463 ELSE IF( nzc.LT.nzcmin .AND. .NOT.zquery ) THEN
464 info = -14
465 END IF
466 END IF
467
468 IF( info.NE.0 ) THEN
469*
470 CALL xerbla( 'DSTEMR', -info )
471*
472 RETURN
473 ELSE IF( lquery .OR. zquery ) THEN
474 RETURN
475 END IF
476*
477* Handle N = 0, 1, and 2 cases immediately
478*
479 m = 0
480 IF( n.EQ.0 )
481 $ RETURN
482*
483 IF( n.EQ.1 ) THEN
484 IF( alleig .OR. indeig ) THEN
485 m = 1
486 w( 1 ) = d( 1 )
487 ELSE
488 IF( wl.LT.d( 1 ) .AND. wu.GE.d( 1 ) ) THEN
489 m = 1
490 w( 1 ) = d( 1 )
491 END IF
492 END IF
493 IF( wantz.AND.(.NOT.zquery) ) THEN
494 z( 1, 1 ) = one
495 isuppz(1) = 1
496 isuppz(2) = 1
497 END IF
498 RETURN
499 END IF
500*
501 IF( n.EQ.2 ) 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 )
506 END IF
507* D/S/LAE2 and D/S/LAEV2 outputs satisfy |R1| >= |R2|. However,
508* the following code requires R1 >= R2. Hence, we correct
509* the order of R1, R2, CS, SN if R1 < R2 before further processing.
510 IF( r1.LT.r2 ) THEN
511 e(2) = r1
512 r1 = r2
513 r2 = e(2)
514 laeswap = .true.
515 ENDIF
516 IF( alleig.OR.
517 $ (valeig.AND.(r2.GT.wl).AND.
518 $ (r2.LE.wu)).OR.
519 $ (indeig.AND.(iil.EQ.1)) ) THEN
520 m = m+1
521 w( m ) = r2
522 IF( wantz.AND.(.NOT.zquery) ) THEN
523 IF( laeswap ) THEN
524 z( 1, m ) = cs
525 z( 2, m ) = sn
526 ELSE
527 z( 1, m ) = -sn
528 z( 2, m ) = cs
529 ENDIF
530* Note: At most one of SN and CS can be zero.
531 IF (sn.NE.zero) THEN
532 IF (cs.NE.zero) THEN
533 isuppz(2*m-1) = 1
534 isuppz(2*m) = 2
535 ELSE
536 isuppz(2*m-1) = 1
537 isuppz(2*m) = 1
538 END IF
539 ELSE
540 isuppz(2*m-1) = 2
541 isuppz(2*m) = 2
542 END IF
543 ENDIF
544 ENDIF
545 IF( alleig.OR.
546 $ (valeig.AND.(r1.GT.wl).AND.
547 $ (r1.LE.wu)).OR.
548 $ (indeig.AND.(iiu.EQ.2)) ) THEN
549 m = m+1
550 w( m ) = r1
551 IF( wantz.AND.(.NOT.zquery) ) THEN
552 IF( laeswap ) THEN
553 z( 1, m ) = -sn
554 z( 2, m ) = cs
555 ELSE
556 z( 1, m ) = cs
557 z( 2, m ) = sn
558 ENDIF
559* Note: At most one of SN and CS can be zero.
560 IF (sn.NE.zero) THEN
561 IF (cs.NE.zero) THEN
562 isuppz(2*m-1) = 1
563 isuppz(2*m) = 2
564 ELSE
565 isuppz(2*m-1) = 1
566 isuppz(2*m) = 1
567 END IF
568 ELSE
569 isuppz(2*m-1) = 2
570 isuppz(2*m) = 2
571 END IF
572 ENDIF
573 ENDIF
574
575 ELSE
576
577* Continue with general N
578
579 indgrs = 1
580 inderr = 2*n + 1
581 indgp = 3*n + 1
582 indd = 4*n + 1
583 inde2 = 5*n + 1
584 indwrk = 6*n + 1
585*
586 iinspl = 1
587 iindbl = n + 1
588 iindw = 2*n + 1
589 iindwk = 3*n + 1
590*
591* Scale matrix to allowable range, if necessary.
592* The allowable range is related to the PIVMIN parameter; see the
593* comments in DLARRD. The preference for scaling small values
594* up is heuristic; we expect users' matrices not to be close to the
595* RMAX threshold.
596*
597 scale = one
598 tnrm = dlanst( 'M', n, d, e )
599 IF( tnrm.GT.zero .AND. tnrm.LT.rmin ) THEN
600 scale = rmin / tnrm
601 ELSE IF( tnrm.GT.rmax ) THEN
602 scale = rmax / tnrm
603 END IF
604 IF( scale.NE.one ) THEN
605 CALL dscal( n, scale, d, 1 )
606 CALL dscal( n-1, scale, e, 1 )
607 tnrm = tnrm*scale
608 IF( valeig ) THEN
609* If eigenvalues in interval have to be found,
610* scale (WL, WU] accordingly
611 wl = wl*scale
612 wu = wu*scale
613 ENDIF
614 END IF
615*
616* Compute the desired eigenvalues of the tridiagonal after splitting
617* into smaller subblocks if the corresponding off-diagonal elements
618* are small
619* THRESH is the splitting parameter for DLARRE
620* A negative THRESH forces the old splitting criterion based on the
621* size of the off-diagonal. A positive THRESH switches to splitting
622* which preserves relative accuracy.
623*
624 IF( tryrac ) THEN
625* Test whether the matrix warrants the more expensive relative approach.
626 CALL dlarrr( n, d, e, iinfo )
627 ELSE
628* The user does not care about relative accurately eigenvalues
629 iinfo = -1
630 ENDIF
631* Set the splitting criterion
632 IF (iinfo.EQ.0) THEN
633 thresh = eps
634 ELSE
635 thresh = -eps
636* relative accuracy is desired but T does not guarantee it
637 tryrac = .false.
638 ENDIF
639*
640 IF( tryrac ) THEN
641* Copy original diagonal, needed to guarantee relative accuracy
642 CALL dcopy(n,d,1,work(indd),1)
643 ENDIF
644* Store the squares of the offdiagonal values of T
645 DO 5 j = 1, n-1
646 work( inde2+j-1 ) = e(j)**2
647 5 CONTINUE
648
649* Set the tolerance parameters for bisection
650 IF( .NOT.wantz ) THEN
651* DLARRE computes the eigenvalues to full precision.
652 rtol1 = four * eps
653 rtol2 = four * eps
654 ELSE
655* DLARRE computes the eigenvalues to less than full precision.
656* DLARRV will refine the eigenvalue approximations, and we can
657* need less accurate initial bisection in DLARRE.
658* Note: these settings do only affect the subset case and DLARRE
659 rtol1 = sqrt(eps)
660 rtol2 = max( sqrt(eps)*5.0d-3, four * eps )
661 ENDIF
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 )
670 RETURN
671 END IF
672* Note that if RANGE .NE. 'V', DLARRE computes bounds on the desired
673* part of the spectrum. All desired eigenvalues are contained in
674* (WL,WU]
675
676
677 IF( wantz ) THEN
678*
679* Compute the desired eigenvectors corresponding to the computed
680* eigenvalues
681*
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 )
690 RETURN
691 END IF
692 ELSE
693* DLARRE computes eigenvalues of the (shifted) root representation
694* DLARRV returns the eigenvalues of the unshifted matrix.
695* However, if the eigenvectors are not desired by the user, we need
696* to apply the corresponding shifts from DLARRE to obtain the
697* eigenvalues of the original matrix.
698 DO 20 j = 1, m
699 itmp = iwork( iindbl+j-1 )
700 w( j ) = w( j ) + e( iwork( iinspl+itmp-1 ) )
701 20 CONTINUE
702 END IF
703*
704
705 IF ( tryrac ) THEN
706* Refine computed eigenvalues so that they are relatively accurate
707* with respect to the original matrix T.
708 ibegin = 1
709 wbegin = 1
710 DO 39 jblk = 1, iwork( iindbl+m-1 )
711 iend = iwork( iinspl+jblk-1 )
712 in = iend - ibegin + 1
713 wend = wbegin - 1
714* check if any eigenvalues have to be refined in this block
715 36 CONTINUE
716 IF( wend.LT.m ) THEN
717 IF( iwork( iindbl+wend ).EQ.jblk ) THEN
718 wend = wend + 1
719 GO TO 36
720 END IF
721 END IF
722 IF( wend.LT.wbegin ) THEN
723 ibegin = iend + 1
724 GO TO 39
725 END IF
726
727 offset = iwork(iindw+wbegin-1)-1
728 ifirst = iwork(iindw+wbegin-1)
729 ilast = iwork(iindw+wend-1)
730 rtol2 = four * eps
731 CALL dlarrj( in,
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,
736 $ tnrm, iinfo )
737 ibegin = iend + 1
738 wbegin = wend + 1
739 39 CONTINUE
740 ENDIF
741*
742* If matrix was scaled, then rescale eigenvalues appropriately.
743*
744 IF( scale.NE.one ) THEN
745 CALL dscal( m, one / scale, w, 1 )
746 END IF
747
748 END IF
749
750*
751* If eigenvalues are not in increasing order, then sort them,
752* possibly along with eigenvectors.
753*
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
758 info = 3
759 RETURN
760 END IF
761 ELSE
762 DO 60 j = 1, m - 1
763 i = 0
764 tmp = w( j )
765 DO 50 jj = j + 1, m
766 IF( w( jj ).LT.tmp ) THEN
767 i = jj
768 tmp = w( jj )
769 END IF
770 50 CONTINUE
771 IF( i.NE.0 ) THEN
772 w( i ) = w( j )
773 w( j ) = tmp
774 IF( wantz ) 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
779 itmp = isuppz( 2*i )
780 isuppz( 2*i ) = isuppz( 2*j )
781 isuppz( 2*j ) = itmp
782 END IF
783 END IF
784 60 CONTINUE
785 END IF
786 ENDIF
787*
788*
789 work( 1 ) = lwmin
790 iwork( 1 ) = liwmin
791 RETURN
792*
793* End of DSTEMR
794*
795 END
subroutine xerbla(srname, info)
Definition cblat2.f:3285
subroutine dcopy(n, dx, incx, dy, incy)
DCOPY
Definition dcopy.f:82
subroutine dlae2(a, b, c, rt1, rt2)
DLAE2 computes the eigenvalues of a 2-by-2 symmetric matrix.
Definition dlae2.f:100
subroutine dlaev2(a, b, c, rt1, rt2, cs1, sn1)
DLAEV2 computes the eigenvalues and eigenvectors of a 2-by-2 symmetric/Hermitian matrix.
Definition dlaev2.f:118
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 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 dlarrj(n, d, e2, ifirst, ilast, rtol, offset, w, werr, work, iwork, pivmin, spdiam, info)
DLARRJ performs refinement of the initial estimates of the eigenvalues of the matrix T.
Definition dlarrj.f:166
subroutine dlarrr(n, d, e, info)
DLARRR performs tests to decide whether the symmetric tridiagonal matrix T warrants expensive computa...
Definition dlarrr.f:92
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 ...
Definition dlarrv.f:290
subroutine dlasrt(id, n, d, info)
DLASRT sorts numbers in increasing or decreasing order.
Definition dlasrt.f:86
subroutine dscal(n, da, dx, incx)
DSCAL
Definition dscal.f:79
subroutine dstemr(jobz, range, n, d, e, vl, vu, il, iu, m, w, z, ldz, nzc, isuppz, tryrac, work, lwork, iwork, liwork, info)
DSTEMR
Definition dstemr.f:320
subroutine dswap(n, dx, incx, dy, incy)
DSWAP
Definition dswap.f:82