LAPACK 3.12.1
LAPACK: Linear Algebra PACKage
Loading...
Searching...
No Matches
cheevr.f
Go to the documentation of this file.
1*> \brief <b> CHEEVR computes the eigenvalues and, optionally, the left and/or right eigenvectors for HE matrices</b>
2*
3* =========== DOCUMENTATION ===========
4*
5* Online html documentation available at
6* http://www.netlib.org/lapack/explore-html/
7*
8*> Download CHEEVR + dependencies
9*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/cheevr.f">
10*> [TGZ]</a>
11*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/cheevr.f">
12*> [ZIP]</a>
13*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/cheevr.f">
14*> [TXT]</a>
15*
16* Definition:
17* ===========
18*
19* SUBROUTINE CHEEVR( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, IL, IU,
20* ABSTOL, M, W, Z, LDZ, ISUPPZ, WORK, LWORK,
21* RWORK, LRWORK, IWORK, LIWORK, INFO )
22*
23* .. Scalar Arguments ..
24* CHARACTER JOBZ, RANGE, UPLO
25* INTEGER IL, INFO, IU, LDA, LDZ, LIWORK, LRWORK, LWORK,
26* $ M, N
27* REAL ABSTOL, VL, VU
28* ..
29* .. Array Arguments ..
30* INTEGER ISUPPZ( * ), IWORK( * )
31* REAL RWORK( * ), W( * )
32* COMPLEX A( LDA, * ), WORK( * ), Z( LDZ, * )
33* ..
34*
35*
36*> \par Purpose:
37* =============
38*>
39*> \verbatim
40*>
41*> CHEEVR computes selected eigenvalues and, optionally, eigenvectors
42*> of a complex Hermitian matrix A. Eigenvalues and eigenvectors can be
43*> selected by specifying either a range of values or a range of indices
44*> for the desired eigenvalues. Invocations with different choices for
45*> these parameters may result in the computation of slightly different
46*> eigenvalues and/or eigenvectors for the same matrix. The reason for
47*> this behavior is that there exists a variety of algorithms (each
48*> performing best for a particular set of options) with CHEEVR
49*> attempting to select the best based on the various parameters. In all
50*> cases, the computed values are accurate within the limits of finite
51*> precision arithmetic.
52*>
53*> CHEEVR first reduces the matrix A to tridiagonal form T with a call
54*> to CHETRD. Then, whenever possible, CHEEVR calls CSTEMR to compute
55*> the eigenspectrum using Relatively Robust Representations. CSTEMR
56*> computes eigenvalues by the dqds algorithm, while orthogonal
57*> eigenvectors are computed from various "good" L D L^T representations
58*> (also known as Relatively Robust Representations). Gram-Schmidt
59*> orthogonalization is avoided as far as possible. More specifically,
60*> the various steps of the algorithm are as follows.
61*>
62*> For each unreduced block (submatrix) of T,
63*> (a) Compute T - sigma I = L D L^T, so that L and D
64*> define all the wanted eigenvalues to high relative accuracy.
65*> This means that small relative changes in the entries of D and L
66*> cause only small relative changes in the eigenvalues and
67*> eigenvectors. The standard (unfactored) representation of the
68*> tridiagonal matrix T does not have this property in general.
69*> (b) Compute the eigenvalues to suitable accuracy.
70*> If the eigenvectors are desired, the algorithm attains full
71*> accuracy of the computed eigenvalues only right before
72*> the corresponding vectors have to be computed, see steps c) and d).
73*> (c) For each cluster of close eigenvalues, select a new
74*> shift close to the cluster, find a new factorization, and refine
75*> the shifted eigenvalues to suitable accuracy.
76*> (d) For each eigenvalue with a large enough relative separation compute
77*> the corresponding eigenvector by forming a rank revealing twisted
78*> factorization. Go back to (c) for any clusters that remain.
79*>
80*> The desired accuracy of the output can be specified by the input
81*> parameter ABSTOL.
82*>
83*> For more details, see CSTEMR's documentation and:
84*> - Inderjit S. Dhillon and Beresford N. Parlett: "Multiple representations
85*> to compute orthogonal eigenvectors of symmetric tridiagonal matrices,"
86*> Linear Algebra and its Applications, 387(1), pp. 1-28, August 2004.
87*> - Inderjit Dhillon and Beresford Parlett: "Orthogonal Eigenvectors and
88*> Relative Gaps," SIAM Journal on Matrix Analysis and Applications, Vol. 25,
89*> 2004. Also LAPACK Working Note 154.
90*> - Inderjit Dhillon: "A new O(n^2) algorithm for the symmetric
91*> tridiagonal eigenvalue/eigenvector problem",
92*> Computer Science Division Technical Report No. UCB/CSD-97-971,
93*> UC Berkeley, May 1997.
94*>
95*>
96*> Note 1 : CHEEVR calls CSTEMR when the full spectrum is requested
97*> on machines which conform to the ieee-754 floating point standard.
98*> CHEEVR calls SSTEBZ and CSTEIN on non-ieee machines and
99*> when partial spectrum requests are made.
100*>
101*> Normal execution of CSTEMR may create NaNs and infinities and
102*> hence may abort due to a floating point exception in environments
103*> which do not handle NaNs and infinities in the ieee standard default
104*> manner.
105*> \endverbatim
106*
107* Arguments:
108* ==========
109*
110*> \param[in] JOBZ
111*> \verbatim
112*> JOBZ is CHARACTER*1
113*> = 'N': Compute eigenvalues only;
114*> = 'V': Compute eigenvalues and eigenvectors.
115*>
116*> This parameter influences the choice of the algorithm and
117*> may alter the computed values.
118*> \endverbatim
119*>
120*> \param[in] RANGE
121*> \verbatim
122*> RANGE is CHARACTER*1
123*> = 'A': all eigenvalues will be found.
124*> = 'V': all eigenvalues in the half-open interval (VL,VU]
125*> will be found.
126*> = 'I': the IL-th through IU-th eigenvalues will be found.
127*> For RANGE = 'V' or 'I' and IU - IL < N - 1, SSTEBZ and
128*> CSTEIN are called
129*>
130*> This parameter influences the choice of the algorithm and
131*> may alter the computed values.
132*> \endverbatim
133*>
134*> \param[in] UPLO
135*> \verbatim
136*> UPLO is CHARACTER*1
137*> = 'U': Upper triangle of A is stored;
138*> = 'L': Lower triangle of A is stored.
139*> \endverbatim
140*>
141*> \param[in] N
142*> \verbatim
143*> N is INTEGER
144*> The order of the matrix A. N >= 0.
145*> \endverbatim
146*>
147*> \param[in,out] A
148*> \verbatim
149*> A is COMPLEX array, dimension (LDA, N)
150*> On entry, the Hermitian matrix A. If UPLO = 'U', the
151*> leading N-by-N upper triangular part of A contains the
152*> upper triangular part of the matrix A. If UPLO = 'L',
153*> the leading N-by-N lower triangular part of A contains
154*> the lower triangular part of the matrix A.
155*> On exit, the lower triangle (if UPLO='L') or the upper
156*> triangle (if UPLO='U') of A, including the diagonal, is
157*> destroyed.
158*> \endverbatim
159*>
160*> \param[in] LDA
161*> \verbatim
162*> LDA is INTEGER
163*> The leading dimension of the array A. LDA >= max(1,N).
164*> \endverbatim
165*>
166*> \param[in] VL
167*> \verbatim
168*> VL is REAL
169*> If RANGE='V', the lower bound of the interval to
170*> be searched for eigenvalues. VL < VU.
171*> Not referenced if RANGE = 'A' or 'I'.
172*> \endverbatim
173*>
174*> \param[in] VU
175*> \verbatim
176*> VU is REAL
177*> If RANGE='V', the upper bound of the interval to
178*> be searched for eigenvalues. VL < VU.
179*> Not referenced if RANGE = 'A' or 'I'.
180*> \endverbatim
181*>
182*> \param[in] IL
183*> \verbatim
184*> IL is INTEGER
185*> If RANGE='I', the index of the
186*> smallest eigenvalue to be returned.
187*> 1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
188*> Not referenced if RANGE = 'A' or 'V'.
189*> \endverbatim
190*>
191*> \param[in] IU
192*> \verbatim
193*> IU is INTEGER
194*> If RANGE='I', the index of the
195*> largest eigenvalue to be returned.
196*> 1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
197*> Not referenced if RANGE = 'A' or 'V'.
198*> \endverbatim
199*>
200*> \param[in] ABSTOL
201*> \verbatim
202*> ABSTOL is REAL
203*> The absolute error tolerance for the eigenvalues.
204*> An approximate eigenvalue is accepted as converged
205*> when it is determined to lie in an interval [a,b]
206*> of width less than or equal to
207*>
208*> ABSTOL + EPS * max( |a|,|b| ) ,
209*>
210*> where EPS is the machine precision. If ABSTOL is less than
211*> or equal to zero, then EPS*|T| will be used in its place,
212*> where |T| is the 1-norm of the tridiagonal matrix obtained
213*> by reducing A to tridiagonal form.
214*>
215*> See "Computing Small Singular Values of Bidiagonal Matrices
216*> with Guaranteed High Relative Accuracy," by Demmel and
217*> Kahan, LAPACK Working Note #3.
218*>
219*> If high relative accuracy is important, set ABSTOL to
220*> SLAMCH( 'Safe minimum' ). Doing so will guarantee that
221*> eigenvalues are computed to high relative accuracy when
222*> possible in future releases. The current code does not
223*> make any guarantees about high relative accuracy, but
224*> future releases will. See J. Barlow and J. Demmel,
225*> "Computing Accurate Eigensystems of Scaled Diagonally
226*> Dominant Matrices", LAPACK Working Note #7, for a discussion
227*> of which matrices define their eigenvalues to high relative
228*> accuracy.
229*> \endverbatim
230*>
231*> \param[out] M
232*> \verbatim
233*> M is INTEGER
234*> The total number of eigenvalues found. 0 <= M <= N.
235*> If RANGE = 'A', M = N, and if RANGE = 'I', M = IU-IL+1.
236*> \endverbatim
237*>
238*> \param[out] W
239*> \verbatim
240*> W is REAL array, dimension (N)
241*> The first M elements contain the selected eigenvalues in
242*> ascending order.
243*> \endverbatim
244*>
245*> \param[out] Z
246*> \verbatim
247*> Z is COMPLEX array, dimension (LDZ, max(1,M))
248*> If JOBZ = 'V', then if INFO = 0, the first M columns of Z
249*> contain the orthonormal eigenvectors of the matrix A
250*> corresponding to the selected eigenvalues, with the i-th
251*> column of Z holding the eigenvector associated with W(i).
252*> If JOBZ = 'N', then Z is not referenced.
253*> Note: the user must ensure that at least max(1,M) columns are
254*> supplied in the array Z; if RANGE = 'V', the exact value of M
255*> is not known in advance and an upper bound must be used.
256*> Supplying N columns is always safe.
257*> \endverbatim
258*>
259*> \param[in] LDZ
260*> \verbatim
261*> LDZ is INTEGER
262*> The leading dimension of the array Z. LDZ >= 1, and if
263*> JOBZ = 'V', LDZ >= max(1,N).
264*> \endverbatim
265*>
266*> \param[out] ISUPPZ
267*> \verbatim
268*> ISUPPZ is INTEGER array, dimension ( 2*max(1,M) )
269*> The support of the eigenvectors in Z, i.e., the indices
270*> indicating the nonzero elements in Z. The i-th eigenvector
271*> is nonzero only in elements ISUPPZ( 2*i-1 ) through
272*> ISUPPZ( 2*i ). This is an output of CSTEMR (tridiagonal
273*> matrix). The support of the eigenvectors of A is typically
274*> 1:N because of the unitary transformations applied by CUNMTR.
275*> Implemented only for RANGE = 'A' or 'I' and IU - IL = N - 1
276*> \endverbatim
277*>
278*> \param[out] WORK
279*> \verbatim
280*> WORK is COMPLEX array, dimension (MAX(1,LWORK))
281*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
282*> \endverbatim
283*>
284*> \param[in] LWORK
285*> \verbatim
286*> LWORK is INTEGER
287*> The length of the array WORK.
288*> If N <= 1, LWORK >= 1, else LWORK >= 2*N.
289*> For optimal efficiency, LWORK >= (NB+1)*N,
290*> where NB is the max of the blocksize for CHETRD and for
291*> CUNMTR as returned by ILAENV.
292*>
293*> If LWORK = -1, then a workspace query is assumed; the routine
294*> only calculates the optimal sizes of the WORK, RWORK and
295*> IWORK arrays, returns these values as the first entries of
296*> the WORK, RWORK and IWORK arrays, and no error message
297*> related to LWORK or LRWORK or LIWORK is issued by XERBLA.
298*> \endverbatim
299*>
300*> \param[out] RWORK
301*> \verbatim
302*> RWORK is REAL array, dimension (MAX(1,LRWORK))
303*> On exit, if INFO = 0, RWORK(1) returns the optimal
304*> (and minimal) LRWORK.
305*> \endverbatim
306*>
307*> \param[in] LRWORK
308*> \verbatim
309*> LRWORK is INTEGER
310*> The length of the array RWORK.
311*> If N <= 1, LRWORK >= 1, else LRWORK >= 24*N.
312*>
313*> If LRWORK = -1, then a workspace query is assumed; the
314*> routine only calculates the optimal sizes of the WORK, RWORK
315*> and IWORK arrays, returns these values as the first entries
316*> of the WORK, RWORK and IWORK arrays, and no error message
317*> related to LWORK or LRWORK or LIWORK is issued by XERBLA.
318*> \endverbatim
319*>
320*> \param[out] IWORK
321*> \verbatim
322*> IWORK is INTEGER array, dimension (MAX(1,LIWORK))
323*> On exit, if INFO = 0, IWORK(1) returns the optimal
324*> (and minimal) LIWORK.
325*> \endverbatim
326*>
327*> \param[in] LIWORK
328*> \verbatim
329*> LIWORK is INTEGER
330*> The dimension of the array IWORK.
331*> If N <= 1, LIWORK >= 1, else LIWORK >= 10*N.
332*>
333*> If LIWORK = -1, then a workspace query is assumed; the
334*> routine only calculates the optimal sizes of the WORK, RWORK
335*> and IWORK arrays, returns these values as the first entries
336*> of the WORK, RWORK and IWORK arrays, and no error message
337*> related to LWORK or LRWORK or LIWORK is issued by XERBLA.
338*> \endverbatim
339*>
340*> \param[out] INFO
341*> \verbatim
342*> INFO is INTEGER
343*> = 0: successful exit
344*> < 0: if INFO = -i, the i-th argument had an illegal value
345*> > 0: Internal error
346*> \endverbatim
347*
348* Authors:
349* ========
350*
351*> \author Univ. of Tennessee
352*> \author Univ. of California Berkeley
353*> \author Univ. of Colorado Denver
354*> \author NAG Ltd.
355*
356*> \ingroup heevr
357*
358*> \par Contributors:
359* ==================
360*>
361*> Inderjit Dhillon, IBM Almaden, USA \n
362*> Osni Marques, LBNL/NERSC, USA \n
363*> Ken Stanley, Computer Science Division, University of
364*> California at Berkeley, USA \n
365*> Jason Riedy, Computer Science Division, University of
366*> California at Berkeley, USA \n
367*>
368* =====================================================================
369 SUBROUTINE cheevr( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, IL,
370 $ IU,
371 $ ABSTOL, M, W, Z, LDZ, ISUPPZ, WORK, LWORK,
372 $ RWORK, LRWORK, IWORK, LIWORK, INFO )
373*
374* -- LAPACK driver routine --
375* -- LAPACK is a software package provided by Univ. of Tennessee, --
376* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
377*
378* .. Scalar Arguments ..
379 CHARACTER JOBZ, RANGE, UPLO
380 INTEGER IL, INFO, IU, LDA, LDZ, LIWORK, LRWORK, LWORK,
381 $ M, N
382 REAL ABSTOL, VL, VU
383* ..
384* .. Array Arguments ..
385 INTEGER ISUPPZ( * ), IWORK( * )
386 REAL RWORK( * ), W( * )
387 COMPLEX A( LDA, * ), WORK( * ), Z( LDZ, * )
388* ..
389*
390* =====================================================================
391*
392* .. Parameters ..
393 REAL ZERO, ONE, TWO
394 PARAMETER ( ZERO = 0.0e+0, one = 1.0e+0, two = 2.0e+0 )
395* ..
396* .. Local Scalars ..
397 LOGICAL ALLEIG, INDEIG, LOWER, LQUERY, TEST, VALEIG,
398 $ WANTZ, TRYRAC
399 CHARACTER ORDER
400 INTEGER I, IEEEOK, IINFO, IMAX, INDIBL, INDIFL, INDISP,
401 $ INDIWO, INDRD, INDRDD, INDRE, INDREE, INDRWK,
402 $ indtau, indwk, indwkn, iscale, itmp1, j, jj,
403 $ liwmin, llwork, llrwork, llwrkn, lrwmin,
404 $ lwkopt, lwmin, nb, nsplit
405 REAL ABSTLL, ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN,
406 $ SIGMA, SMLNUM, TMP1, VLL, VUU
407* ..
408* .. External Functions ..
409 LOGICAL LSAME
410 INTEGER ILAENV
411 REAL CLANSY, SLAMCH, SROUNDUP_LWORK
412 EXTERNAL lsame, ilaenv, clansy, slamch,
413 $ sroundup_lwork
414* ..
415* .. External Subroutines ..
416 EXTERNAL chetrd, csscal, cstemr, cstein, cswap,
417 $ cunmtr,
419* ..
420* .. Intrinsic Functions ..
421 INTRINSIC max, min, real, sqrt
422* ..
423* .. Executable Statements ..
424*
425* Test the input parameters.
426*
427 ieeeok = ilaenv( 10, 'CHEEVR', 'N', 1, 2, 3, 4 )
428*
429 lower = lsame( uplo, 'L' )
430 wantz = lsame( jobz, 'V' )
431 alleig = lsame( range, 'A' )
432 valeig = lsame( range, 'V' )
433 indeig = lsame( range, 'I' )
434*
435 lquery = ( ( lwork.EQ.-1 ) .OR. ( lrwork.EQ.-1 ) .OR.
436 $ ( liwork.EQ.-1 ) )
437*
438 IF( n.LE.1 ) THEN
439 lwmin = 1
440 lrwmin = 1
441 liwmin = 1
442 ELSE
443 lwmin = 2*n
444 lrwmin = 24*n
445 liwmin = 10*n
446 END IF
447*
448 info = 0
449 IF( .NOT.( wantz .OR. lsame( jobz, 'N' ) ) ) THEN
450 info = -1
451 ELSE IF( .NOT.( alleig .OR. valeig .OR. indeig ) ) THEN
452 info = -2
453 ELSE IF( .NOT.( lower .OR. lsame( uplo, 'U' ) ) ) THEN
454 info = -3
455 ELSE IF( n.LT.0 ) THEN
456 info = -4
457 ELSE IF( lda.LT.max( 1, n ) ) THEN
458 info = -6
459 ELSE
460 IF( valeig ) THEN
461 IF( n.GT.0 .AND. vu.LE.vl )
462 $ info = -8
463 ELSE IF( indeig ) THEN
464 IF( il.LT.1 .OR. il.GT.max( 1, n ) ) THEN
465 info = -9
466 ELSE IF( iu.LT.min( n, il ) .OR. iu.GT.n ) THEN
467 info = -10
468 END IF
469 END IF
470 END IF
471 IF( info.EQ.0 ) THEN
472 IF( ldz.LT.1 .OR. ( wantz .AND. ldz.LT.n ) ) THEN
473 info = -15
474 END IF
475 END IF
476*
477 IF( info.EQ.0 ) THEN
478 nb = ilaenv( 1, 'CHETRD', uplo, n, -1, -1, -1 )
479 nb = max( nb, ilaenv( 1, 'CUNMTR', uplo, n, -1, -1, -1 ) )
480 lwkopt = max( ( nb+1 )*n, lwmin )
481 work( 1 ) = sroundup_lwork( lwkopt )
482 rwork( 1 ) = sroundup_lwork( lrwmin )
483 iwork( 1 ) = liwmin
484*
485 IF( lwork.LT.lwmin .AND. .NOT.lquery ) THEN
486 info = -18
487 ELSE IF( lrwork.LT.lrwmin .AND. .NOT.lquery ) THEN
488 info = -20
489 ELSE IF( liwork.LT.liwmin .AND. .NOT.lquery ) THEN
490 info = -22
491 END IF
492 END IF
493*
494 IF( info.NE.0 ) THEN
495 CALL xerbla( 'CHEEVR', -info )
496 RETURN
497 ELSE IF( lquery ) THEN
498 RETURN
499 END IF
500*
501* Quick return if possible
502*
503 m = 0
504 IF( n.EQ.0 ) THEN
505 work( 1 ) = 1
506 RETURN
507 END IF
508*
509 IF( n.EQ.1 ) THEN
510 work( 1 ) = 1
511 IF( alleig .OR. indeig ) THEN
512 m = 1
513 w( 1 ) = real( a( 1, 1 ) )
514 ELSE
515 IF( vl.LT.real( a( 1, 1 ) ) .AND. vu.GE.real( a( 1, 1 ) ) )
516 $ THEN
517 m = 1
518 w( 1 ) = real( a( 1, 1 ) )
519 END IF
520 END IF
521 IF( wantz ) THEN
522 z( 1, 1 ) = one
523 isuppz( 1 ) = 1
524 isuppz( 2 ) = 1
525 END IF
526 RETURN
527 END IF
528*
529* Get machine constants.
530*
531 safmin = slamch( 'Safe minimum' )
532 eps = slamch( 'Precision' )
533 smlnum = safmin / eps
534 bignum = one / smlnum
535 rmin = sqrt( smlnum )
536 rmax = min( sqrt( bignum ), one / sqrt( sqrt( safmin ) ) )
537*
538* Scale matrix to allowable range, if necessary.
539*
540 iscale = 0
541 abstll = abstol
542 IF (valeig) THEN
543 vll = vl
544 vuu = vu
545 END IF
546 anrm = clansy( 'M', uplo, n, a, lda, rwork )
547 IF( anrm.GT.zero .AND. anrm.LT.rmin ) THEN
548 iscale = 1
549 sigma = rmin / anrm
550 ELSE IF( anrm.GT.rmax ) THEN
551 iscale = 1
552 sigma = rmax / anrm
553 END IF
554 IF( iscale.EQ.1 ) THEN
555 IF( lower ) THEN
556 DO 10 j = 1, n
557 CALL csscal( n-j+1, sigma, a( j, j ), 1 )
558 10 CONTINUE
559 ELSE
560 DO 20 j = 1, n
561 CALL csscal( j, sigma, a( 1, j ), 1 )
562 20 CONTINUE
563 END IF
564 IF( abstol.GT.0 )
565 $ abstll = abstol*sigma
566 IF( valeig ) THEN
567 vll = vl*sigma
568 vuu = vu*sigma
569 END IF
570 END IF
571
572* Initialize indices into workspaces. Note: The IWORK indices are
573* used only if SSTERF or CSTEMR fail.
574
575* WORK(INDTAU:INDTAU+N-1) stores the complex scalar factors of the
576* elementary reflectors used in CHETRD.
577 indtau = 1
578* INDWK is the starting offset of the remaining complex workspace,
579* and LLWORK is the remaining complex workspace size.
580 indwk = indtau + n
581 llwork = lwork - indwk + 1
582
583* RWORK(INDRD:INDRD+N-1) stores the real tridiagonal's diagonal
584* entries.
585 indrd = 1
586* RWORK(INDRE:INDRE+N-1) stores the off-diagonal entries of the
587* tridiagonal matrix from CHETRD.
588 indre = indrd + n
589* RWORK(INDRDD:INDRDD+N-1) is a copy of the diagonal entries over
590* -written by CSTEMR (the SSTERF path copies the diagonal to W).
591 indrdd = indre + n
592* RWORK(INDREE:INDREE+N-1) is a copy of the off-diagonal entries over
593* -written while computing the eigenvalues in SSTERF and CSTEMR.
594 indree = indrdd + n
595* INDRWK is the starting offset of the left-over real workspace, and
596* LLRWORK is the remaining workspace size.
597 indrwk = indree + n
598 llrwork = lrwork - indrwk + 1
599
600* IWORK(INDIBL:INDIBL+M-1) corresponds to IBLOCK in SSTEBZ and
601* stores the block indices of each of the M<=N eigenvalues.
602 indibl = 1
603* IWORK(INDISP:INDISP+NSPLIT-1) corresponds to ISPLIT in SSTEBZ and
604* stores the starting and finishing indices of each block.
605 indisp = indibl + n
606* IWORK(INDIFL:INDIFL+N-1) stores the indices of eigenvectors
607* that corresponding to eigenvectors that fail to converge in
608* SSTEIN. This information is discarded; if any fail, the driver
609* returns INFO > 0.
610 indifl = indisp + n
611* INDIWO is the offset of the remaining integer workspace.
612 indiwo = indifl + n
613
614*
615* Call CHETRD to reduce Hermitian matrix to tridiagonal form.
616*
617 CALL chetrd( uplo, n, a, lda, rwork( indrd ), rwork( indre ),
618 $ work( indtau ), work( indwk ), llwork, iinfo )
619*
620* If all eigenvalues are desired
621* then call SSTERF or CSTEMR and CUNMTR.
622*
623 test = .false.
624 IF( indeig ) THEN
625 IF( il.EQ.1 .AND. iu.EQ.n ) THEN
626 test = .true.
627 END IF
628 END IF
629 IF( ( alleig.OR.test ) .AND. ( ieeeok.EQ.1 ) ) THEN
630 IF( .NOT.wantz ) THEN
631 CALL scopy( n, rwork( indrd ), 1, w, 1 )
632 CALL scopy( n-1, rwork( indre ), 1, rwork( indree ), 1 )
633 CALL ssterf( n, w, rwork( indree ), info )
634 ELSE
635 CALL scopy( n-1, rwork( indre ), 1, rwork( indree ), 1 )
636 CALL scopy( n, rwork( indrd ), 1, rwork( indrdd ), 1 )
637*
638 IF (abstol .LE. two*real( n )*eps) THEN
639 tryrac = .true.
640 ELSE
641 tryrac = .false.
642 END IF
643 CALL cstemr( jobz, 'A', n, rwork( indrdd ),
644 $ rwork( indree ), vl, vu, il, iu, m, w,
645 $ z, ldz, n, isuppz, tryrac,
646 $ rwork( indrwk ), llrwork,
647 $ iwork, liwork, info )
648*
649* Apply unitary matrix used in reduction to tridiagonal
650* form to eigenvectors returned by CSTEMR.
651*
652 IF( wantz .AND. info.EQ.0 ) THEN
653 indwkn = indwk
654 llwrkn = lwork - indwkn + 1
655 CALL cunmtr( 'L', uplo, 'N', n, m, a, lda,
656 $ work( indtau ), z, ldz, work( indwkn ),
657 $ llwrkn, iinfo )
658 END IF
659 END IF
660*
661*
662 IF( info.EQ.0 ) THEN
663 m = n
664 GO TO 30
665 END IF
666 info = 0
667 END IF
668*
669* Otherwise, call SSTEBZ and, if eigenvectors are desired, CSTEIN.
670* Also call SSTEBZ and CSTEIN if CSTEMR fails.
671*
672 IF( wantz ) THEN
673 order = 'B'
674 ELSE
675 order = 'E'
676 END IF
677
678 CALL sstebz( range, order, n, vll, vuu, il, iu, abstll,
679 $ rwork( indrd ), rwork( indre ), m, nsplit, w,
680 $ iwork( indibl ), iwork( indisp ), rwork( indrwk ),
681 $ iwork( indiwo ), info )
682*
683 IF( wantz ) THEN
684 CALL cstein( n, rwork( indrd ), rwork( indre ), m, w,
685 $ iwork( indibl ), iwork( indisp ), z, ldz,
686 $ rwork( indrwk ), iwork( indiwo ), iwork( indifl ),
687 $ info )
688*
689* Apply unitary matrix used in reduction to tridiagonal
690* form to eigenvectors returned by CSTEIN.
691*
692 indwkn = indwk
693 llwrkn = lwork - indwkn + 1
694 CALL cunmtr( 'L', uplo, 'N', n, m, a, lda, work( indtau ),
695 $ z,
696 $ ldz, work( indwkn ), llwrkn, iinfo )
697 END IF
698*
699* If matrix was scaled, then rescale eigenvalues appropriately.
700*
701 30 CONTINUE
702 IF( iscale.EQ.1 ) THEN
703 IF( info.EQ.0 ) THEN
704 imax = m
705 ELSE
706 imax = info - 1
707 END IF
708 CALL sscal( imax, one / sigma, w, 1 )
709 END IF
710*
711* If eigenvalues are not in order, then sort them, along with
712* eigenvectors.
713*
714 IF( wantz ) THEN
715 DO 50 j = 1, m - 1
716 i = 0
717 tmp1 = w( j )
718 DO 40 jj = j + 1, m
719 IF( w( jj ).LT.tmp1 ) THEN
720 i = jj
721 tmp1 = w( jj )
722 END IF
723 40 CONTINUE
724*
725 IF( i.NE.0 ) THEN
726 itmp1 = iwork( indibl+i-1 )
727 w( i ) = w( j )
728 iwork( indibl+i-1 ) = iwork( indibl+j-1 )
729 w( j ) = tmp1
730 iwork( indibl+j-1 ) = itmp1
731 CALL cswap( n, z( 1, i ), 1, z( 1, j ), 1 )
732 END IF
733 50 CONTINUE
734 END IF
735*
736* Set WORK(1) to optimal workspace size.
737*
738 work( 1 ) = sroundup_lwork( lwkopt )
739 rwork( 1 ) = sroundup_lwork( lrwmin )
740 iwork( 1 ) = liwmin
741*
742 RETURN
743*
744* End of CHEEVR
745*
746 END
subroutine xerbla(srname, info)
Definition cblat2.f:3285
subroutine scopy(n, sx, incx, sy, incy)
SCOPY
Definition scopy.f:82
subroutine cheevr(jobz, range, uplo, n, a, lda, vl, vu, il, iu, abstol, m, w, z, ldz, isuppz, work, lwork, rwork, lrwork, iwork, liwork, info)
CHEEVR computes the eigenvalues and, optionally, the left and/or right eigenvectors for HE matrices
Definition cheevr.f:373
subroutine chetrd(uplo, n, a, lda, d, e, tau, work, lwork, info)
CHETRD
Definition chetrd.f:191
subroutine csscal(n, sa, cx, incx)
CSSCAL
Definition csscal.f:78
subroutine sscal(n, sa, sx, incx)
SSCAL
Definition sscal.f:79
subroutine sstebz(range, order, n, vl, vu, il, iu, abstol, d, e, m, nsplit, w, iblock, isplit, work, iwork, info)
SSTEBZ
Definition sstebz.f:272
subroutine cstein(n, d, e, m, w, iblock, isplit, z, ldz, work, iwork, ifail, info)
CSTEIN
Definition cstein.f:180
subroutine cstemr(jobz, range, n, d, e, vl, vu, il, iu, m, w, z, ldz, nzc, isuppz, tryrac, work, lwork, iwork, liwork, info)
CSTEMR
Definition cstemr.f:337
subroutine ssterf(n, d, e, info)
SSTERF
Definition ssterf.f:84
subroutine cswap(n, cx, incx, cy, incy)
CSWAP
Definition cswap.f:81
subroutine cunmtr(side, uplo, trans, m, n, a, lda, tau, c, ldc, work, lwork, info)
CUNMTR
Definition cunmtr.f:171