LAPACK 3.12.1
LAPACK: Linear Algebra PACKage
Loading...
Searching...
No Matches
zhpevx.f
Go to the documentation of this file.
1*> \brief <b> ZHPEVX computes the eigenvalues and, optionally, the left and/or right eigenvectors for OTHER matrices</b>
2*
3* =========== DOCUMENTATION ===========
4*
5* Online html documentation available at
6* http://www.netlib.org/lapack/explore-html/
7*
8*> Download ZHPEVX + dependencies
9*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/zhpevx.f">
10*> [TGZ]</a>
11*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/zhpevx.f">
12*> [ZIP]</a>
13*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/zhpevx.f">
14*> [TXT]</a>
15*
16* Definition:
17* ===========
18*
19* SUBROUTINE ZHPEVX( JOBZ, RANGE, UPLO, N, AP, VL, VU, IL, IU,
20* ABSTOL, M, W, Z, LDZ, WORK, RWORK, IWORK,
21* IFAIL, INFO )
22*
23* .. Scalar Arguments ..
24* CHARACTER JOBZ, RANGE, UPLO
25* INTEGER IL, INFO, IU, LDZ, M, N
26* DOUBLE PRECISION ABSTOL, VL, VU
27* ..
28* .. Array Arguments ..
29* INTEGER IFAIL( * ), IWORK( * )
30* DOUBLE PRECISION RWORK( * ), W( * )
31* COMPLEX*16 AP( * ), WORK( * ), Z( LDZ, * )
32* ..
33*
34*
35*> \par Purpose:
36* =============
37*>
38*> \verbatim
39*>
40*> ZHPEVX computes selected eigenvalues and, optionally, eigenvectors
41*> of a complex Hermitian matrix A in packed storage.
42*> Eigenvalues/vectors can be selected by specifying either a range of
43*> values or a range of indices for the desired eigenvalues.
44*> \endverbatim
45*
46* Arguments:
47* ==========
48*
49*> \param[in] JOBZ
50*> \verbatim
51*> JOBZ is CHARACTER*1
52*> = 'N': Compute eigenvalues only;
53*> = 'V': Compute eigenvalues and eigenvectors.
54*> \endverbatim
55*>
56*> \param[in] RANGE
57*> \verbatim
58*> RANGE is CHARACTER*1
59*> = 'A': all eigenvalues will be found;
60*> = 'V': all eigenvalues in the half-open interval (VL,VU]
61*> will be found;
62*> = 'I': the IL-th through IU-th eigenvalues will be found.
63*> \endverbatim
64*>
65*> \param[in] UPLO
66*> \verbatim
67*> UPLO is CHARACTER*1
68*> = 'U': Upper triangle of A is stored;
69*> = 'L': Lower triangle of A is stored.
70*> \endverbatim
71*>
72*> \param[in] N
73*> \verbatim
74*> N is INTEGER
75*> The order of the matrix A. N >= 0.
76*> \endverbatim
77*>
78*> \param[in,out] AP
79*> \verbatim
80*> AP is COMPLEX*16 array, dimension (N*(N+1)/2)
81*> On entry, the upper or lower triangle of the Hermitian matrix
82*> A, packed columnwise in a linear array. The j-th column of A
83*> is stored in the array AP as follows:
84*> if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j;
85*> if UPLO = 'L', AP(i + (j-1)*(2*n-j)/2) = A(i,j) for j<=i<=n.
86*>
87*> On exit, AP is overwritten by values generated during the
88*> reduction to tridiagonal form. If UPLO = 'U', the diagonal
89*> and first superdiagonal of the tridiagonal matrix T overwrite
90*> the corresponding elements of A, and if UPLO = 'L', the
91*> diagonal and first subdiagonal of T overwrite the
92*> corresponding elements of A.
93*> \endverbatim
94*>
95*> \param[in] VL
96*> \verbatim
97*> VL is DOUBLE PRECISION
98*> If RANGE='V', the lower bound of the interval to
99*> be searched for eigenvalues. VL < VU.
100*> Not referenced if RANGE = 'A' or 'I'.
101*> \endverbatim
102*>
103*> \param[in] VU
104*> \verbatim
105*> VU is DOUBLE PRECISION
106*> If RANGE='V', the upper bound of the interval to
107*> be searched for eigenvalues. VL < VU.
108*> Not referenced if RANGE = 'A' or 'I'.
109*> \endverbatim
110*>
111*> \param[in] IL
112*> \verbatim
113*> IL is INTEGER
114*> If RANGE='I', the index of the
115*> smallest eigenvalue to be returned.
116*> 1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
117*> Not referenced if RANGE = 'A' or 'V'.
118*> \endverbatim
119*>
120*> \param[in] IU
121*> \verbatim
122*> IU is INTEGER
123*> If RANGE='I', the index of the
124*> largest eigenvalue to be returned.
125*> 1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
126*> Not referenced if RANGE = 'A' or 'V'.
127*> \endverbatim
128*>
129*> \param[in] ABSTOL
130*> \verbatim
131*> ABSTOL is DOUBLE PRECISION
132*> The absolute error tolerance for the eigenvalues.
133*> An approximate eigenvalue is accepted as converged
134*> when it is determined to lie in an interval [a,b]
135*> of width less than or equal to
136*>
137*> ABSTOL + EPS * max( |a|,|b| ) ,
138*>
139*> where EPS is the machine precision. If ABSTOL is less than
140*> or equal to zero, then EPS*|T| will be used in its place,
141*> where |T| is the 1-norm of the tridiagonal matrix obtained
142*> by reducing AP to tridiagonal form.
143*>
144*> Eigenvalues will be computed most accurately when ABSTOL is
145*> set to twice the underflow threshold 2*DLAMCH('S'), not zero.
146*> If this routine returns with INFO>0, indicating that some
147*> eigenvectors did not converge, try setting ABSTOL to
148*> 2*DLAMCH('S').
149*>
150*> See "Computing Small Singular Values of Bidiagonal Matrices
151*> with Guaranteed High Relative Accuracy," by Demmel and
152*> Kahan, LAPACK Working Note #3.
153*> \endverbatim
154*>
155*> \param[out] M
156*> \verbatim
157*> M is INTEGER
158*> The total number of eigenvalues found. 0 <= M <= N.
159*> If RANGE = 'A', M = N, and if RANGE = 'I', M = IU-IL+1.
160*> \endverbatim
161*>
162*> \param[out] W
163*> \verbatim
164*> W is DOUBLE PRECISION array, dimension (N)
165*> If INFO = 0, the selected eigenvalues in ascending order.
166*> \endverbatim
167*>
168*> \param[out] Z
169*> \verbatim
170*> Z is COMPLEX*16 array, dimension (LDZ, max(1,M))
171*> If JOBZ = 'V', then if INFO = 0, the first M columns of Z
172*> contain the orthonormal eigenvectors of the matrix A
173*> corresponding to the selected eigenvalues, with the i-th
174*> column of Z holding the eigenvector associated with W(i).
175*> If an eigenvector fails to converge, then that column of Z
176*> contains the latest approximation to the eigenvector, and
177*> the index of the eigenvector is returned in IFAIL.
178*> If JOBZ = 'N', then Z is not referenced.
179*> Note: the user must ensure that at least max(1,M) columns are
180*> supplied in the array Z; if RANGE = 'V', the exact value of M
181*> is not known in advance and an upper bound must be used.
182*> \endverbatim
183*>
184*> \param[in] LDZ
185*> \verbatim
186*> LDZ is INTEGER
187*> The leading dimension of the array Z. LDZ >= 1, and if
188*> JOBZ = 'V', LDZ >= max(1,N).
189*> \endverbatim
190*>
191*> \param[out] WORK
192*> \verbatim
193*> WORK is COMPLEX*16 array, dimension (2*N)
194*> \endverbatim
195*>
196*> \param[out] RWORK
197*> \verbatim
198*> RWORK is DOUBLE PRECISION array, dimension (7*N)
199*> \endverbatim
200*>
201*> \param[out] IWORK
202*> \verbatim
203*> IWORK is INTEGER array, dimension (5*N)
204*> \endverbatim
205*>
206*> \param[out] IFAIL
207*> \verbatim
208*> IFAIL is INTEGER array, dimension (N)
209*> If JOBZ = 'V', then if INFO = 0, the first M elements of
210*> IFAIL are zero. If INFO > 0, then IFAIL contains the
211*> indices of the eigenvectors that failed to converge.
212*> If JOBZ = 'N', then IFAIL is not referenced.
213*> \endverbatim
214*>
215*> \param[out] INFO
216*> \verbatim
217*> INFO is INTEGER
218*> = 0: successful exit
219*> < 0: if INFO = -i, the i-th argument had an illegal value
220*> > 0: if INFO = i, then i eigenvectors failed to converge.
221*> Their indices are stored in array IFAIL.
222*> \endverbatim
223*
224* Authors:
225* ========
226*
227*> \author Univ. of Tennessee
228*> \author Univ. of California Berkeley
229*> \author Univ. of Colorado Denver
230*> \author NAG Ltd.
231*
232*> \ingroup hpevx
233*
234* =====================================================================
235 SUBROUTINE zhpevx( JOBZ, RANGE, UPLO, N, AP, VL, VU, IL, IU,
236 $ ABSTOL, M, W, Z, LDZ, WORK, RWORK, IWORK,
237 $ IFAIL, INFO )
238*
239* -- LAPACK driver routine --
240* -- LAPACK is a software package provided by Univ. of Tennessee, --
241* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
242*
243* .. Scalar Arguments ..
244 CHARACTER JOBZ, RANGE, UPLO
245 INTEGER IL, INFO, IU, LDZ, M, N
246 DOUBLE PRECISION ABSTOL, VL, VU
247* ..
248* .. Array Arguments ..
249 INTEGER IFAIL( * ), IWORK( * )
250 DOUBLE PRECISION RWORK( * ), W( * )
251 COMPLEX*16 AP( * ), WORK( * ), Z( LDZ, * )
252* ..
253*
254* =====================================================================
255*
256* .. Parameters ..
257 DOUBLE PRECISION ZERO, ONE
258 PARAMETER ( ZERO = 0.0d0, one = 1.0d0 )
259 COMPLEX*16 CONE
260 parameter( cone = ( 1.0d0, 0.0d0 ) )
261* ..
262* .. Local Scalars ..
263 LOGICAL ALLEIG, INDEIG, TEST, VALEIG, WANTZ
264 CHARACTER ORDER
265 INTEGER I, IINFO, IMAX, INDD, INDE, INDEE,
266 $ indisp, indiwk, indrwk, indtau, indwrk, iscale,
267 $ itmp1, j, jj, nsplit
268 DOUBLE PRECISION ABSTLL, ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN,
269 $ SIGMA, SMLNUM, TMP1, VLL, VUU
270* ..
271* .. External Functions ..
272 LOGICAL LSAME
273 DOUBLE PRECISION DLAMCH, ZLANHP
274 EXTERNAL lsame, dlamch, zlanhp
275* ..
276* .. External Subroutines ..
277 EXTERNAL dcopy, dscal, dstebz, dsterf, xerbla,
278 $ zdscal,
280* ..
281* .. Intrinsic Functions ..
282 INTRINSIC dble, max, min, sqrt
283* ..
284* .. Executable Statements ..
285*
286* Test the input parameters.
287*
288 wantz = lsame( jobz, 'V' )
289 alleig = lsame( range, 'A' )
290 valeig = lsame( range, 'V' )
291 indeig = lsame( range, 'I' )
292*
293 info = 0
294 IF( .NOT.( wantz .OR. lsame( jobz, 'N' ) ) ) THEN
295 info = -1
296 ELSE IF( .NOT.( alleig .OR. valeig .OR. indeig ) ) THEN
297 info = -2
298 ELSE IF( .NOT.( lsame( uplo, 'L' ) .OR.
299 $ lsame( uplo, 'U' ) ) )
300 $ THEN
301 info = -3
302 ELSE IF( n.LT.0 ) THEN
303 info = -4
304 ELSE
305 IF( valeig ) THEN
306 IF( n.GT.0 .AND. vu.LE.vl )
307 $ info = -7
308 ELSE IF( indeig ) THEN
309 IF( il.LT.1 .OR. il.GT.max( 1, n ) ) THEN
310 info = -8
311 ELSE IF( iu.LT.min( n, il ) .OR. iu.GT.n ) THEN
312 info = -9
313 END IF
314 END IF
315 END IF
316 IF( info.EQ.0 ) THEN
317 IF( ldz.LT.1 .OR. ( wantz .AND. ldz.LT.n ) )
318 $ info = -14
319 END IF
320*
321 IF( info.NE.0 ) THEN
322 CALL xerbla( 'ZHPEVX', -info )
323 RETURN
324 END IF
325*
326* Quick return if possible
327*
328 m = 0
329 IF( n.EQ.0 )
330 $ RETURN
331*
332 IF( n.EQ.1 ) THEN
333 IF( alleig .OR. indeig ) THEN
334 m = 1
335 w( 1 ) = dble( ap( 1 ) )
336 ELSE
337 IF( vl.LT.dble( ap( 1 ) ) .AND. vu.GE.dble( ap( 1 ) ) ) THEN
338 m = 1
339 w( 1 ) = dble( ap( 1 ) )
340 END IF
341 END IF
342 IF( wantz )
343 $ z( 1, 1 ) = cone
344 RETURN
345 END IF
346*
347* Get machine constants.
348*
349 safmin = dlamch( 'Safe minimum' )
350 eps = dlamch( 'Precision' )
351 smlnum = safmin / eps
352 bignum = one / smlnum
353 rmin = sqrt( smlnum )
354 rmax = min( sqrt( bignum ), one / sqrt( sqrt( safmin ) ) )
355*
356* Scale matrix to allowable range, if necessary.
357*
358 iscale = 0
359 abstll = abstol
360 IF( valeig ) THEN
361 vll = vl
362 vuu = vu
363 ELSE
364 vll = zero
365 vuu = zero
366 END IF
367 anrm = zlanhp( 'M', uplo, n, ap, rwork )
368 IF( anrm.GT.zero .AND. anrm.LT.rmin ) THEN
369 iscale = 1
370 sigma = rmin / anrm
371 ELSE IF( anrm.GT.rmax ) THEN
372 iscale = 1
373 sigma = rmax / anrm
374 END IF
375 IF( iscale.EQ.1 ) THEN
376 CALL zdscal( ( n*( n+1 ) ) / 2, sigma, ap, 1 )
377 IF( abstol.GT.0 )
378 $ abstll = abstol*sigma
379 IF( valeig ) THEN
380 vll = vl*sigma
381 vuu = vu*sigma
382 END IF
383 END IF
384*
385* Call ZHPTRD to reduce Hermitian packed matrix to tridiagonal form.
386*
387 indd = 1
388 inde = indd + n
389 indrwk = inde + n
390 indtau = 1
391 indwrk = indtau + n
392 CALL zhptrd( uplo, n, ap, rwork( indd ), rwork( inde ),
393 $ work( indtau ), iinfo )
394*
395* If all eigenvalues are desired and ABSTOL is less than or equal
396* to zero, then call DSTERF or ZUPGTR and ZSTEQR. If this fails
397* for some eigenvalue, then try DSTEBZ.
398*
399 test = .false.
400 IF (indeig) THEN
401 IF (il.EQ.1 .AND. iu.EQ.n) THEN
402 test = .true.
403 END IF
404 END IF
405 IF ((alleig .OR. test) .AND. (abstol.LE.zero)) THEN
406 CALL dcopy( n, rwork( indd ), 1, w, 1 )
407 indee = indrwk + 2*n
408 IF( .NOT.wantz ) THEN
409 CALL dcopy( n-1, rwork( inde ), 1, rwork( indee ), 1 )
410 CALL dsterf( n, w, rwork( indee ), info )
411 ELSE
412 CALL zupgtr( uplo, n, ap, work( indtau ), z, ldz,
413 $ work( indwrk ), iinfo )
414 CALL dcopy( n-1, rwork( inde ), 1, rwork( indee ), 1 )
415 CALL zsteqr( jobz, n, w, rwork( indee ), z, ldz,
416 $ rwork( indrwk ), info )
417 IF( info.EQ.0 ) THEN
418 DO 10 i = 1, n
419 ifail( i ) = 0
420 10 CONTINUE
421 END IF
422 END IF
423 IF( info.EQ.0 ) THEN
424 m = n
425 GO TO 20
426 END IF
427 info = 0
428 END IF
429*
430* Otherwise, call DSTEBZ and, if eigenvectors are desired, ZSTEIN.
431*
432 IF( wantz ) THEN
433 order = 'B'
434 ELSE
435 order = 'E'
436 END IF
437 indisp = 1 + n
438 indiwk = indisp + n
439 CALL dstebz( range, order, n, vll, vuu, il, iu, abstll,
440 $ rwork( indd ), rwork( inde ), m, nsplit, w,
441 $ iwork( 1 ), iwork( indisp ), rwork( indrwk ),
442 $ iwork( indiwk ), info )
443*
444 IF( wantz ) THEN
445 CALL zstein( n, rwork( indd ), rwork( inde ), m, w,
446 $ iwork( 1 ), iwork( indisp ), z, ldz,
447 $ rwork( indrwk ), iwork( indiwk ), ifail, info )
448*
449* Apply unitary matrix used in reduction to tridiagonal
450* form to eigenvectors returned by ZSTEIN.
451*
452 indwrk = indtau + n
453 CALL zupmtr( 'L', uplo, 'N', n, m, ap, work( indtau ), z,
454 $ ldz,
455 $ work( indwrk ), iinfo )
456 END IF
457*
458* If matrix was scaled, then rescale eigenvalues appropriately.
459*
460 20 CONTINUE
461 IF( iscale.EQ.1 ) THEN
462 IF( info.EQ.0 ) THEN
463 imax = m
464 ELSE
465 imax = info - 1
466 END IF
467 CALL dscal( imax, one / sigma, w, 1 )
468 END IF
469*
470* If eigenvalues are not in order, then sort them, along with
471* eigenvectors.
472*
473 IF( wantz ) THEN
474 DO 40 j = 1, m - 1
475 i = 0
476 tmp1 = w( j )
477 DO 30 jj = j + 1, m
478 IF( w( jj ).LT.tmp1 ) THEN
479 i = jj
480 tmp1 = w( jj )
481 END IF
482 30 CONTINUE
483*
484 IF( i.NE.0 ) THEN
485 itmp1 = iwork( 1 + i-1 )
486 w( i ) = w( j )
487 iwork( 1 + i-1 ) = iwork( 1 + j-1 )
488 w( j ) = tmp1
489 iwork( 1 + j-1 ) = itmp1
490 CALL zswap( n, z( 1, i ), 1, z( 1, j ), 1 )
491 IF( info.NE.0 ) THEN
492 itmp1 = ifail( i )
493 ifail( i ) = ifail( j )
494 ifail( j ) = itmp1
495 END IF
496 END IF
497 40 CONTINUE
498 END IF
499*
500 RETURN
501*
502* End of ZHPEVX
503*
504 END
subroutine xerbla(srname, info)
Definition cblat2.f:3285
subroutine dcopy(n, dx, incx, dy, incy)
DCOPY
Definition dcopy.f:82
subroutine zhpevx(jobz, range, uplo, n, ap, vl, vu, il, iu, abstol, m, w, z, ldz, work, rwork, iwork, ifail, info)
ZHPEVX computes the eigenvalues and, optionally, the left and/or right eigenvectors for OTHER matrice...
Definition zhpevx.f:238
subroutine zhptrd(uplo, n, ap, d, e, tau, info)
ZHPTRD
Definition zhptrd.f:149
subroutine dscal(n, da, dx, incx)
DSCAL
Definition dscal.f:79
subroutine zdscal(n, da, zx, incx)
ZDSCAL
Definition zdscal.f:78
subroutine dstebz(range, order, n, vl, vu, il, iu, abstol, d, e, m, nsplit, w, iblock, isplit, work, iwork, info)
DSTEBZ
Definition dstebz.f:272
subroutine zstein(n, d, e, m, w, iblock, isplit, z, ldz, work, iwork, ifail, info)
ZSTEIN
Definition zstein.f:180
subroutine zsteqr(compz, n, d, e, z, ldz, work, info)
ZSTEQR
Definition zsteqr.f:130
subroutine dsterf(n, d, e, info)
DSTERF
Definition dsterf.f:84
subroutine zswap(n, zx, incx, zy, incy)
ZSWAP
Definition zswap.f:81
subroutine zupgtr(uplo, n, ap, tau, q, ldq, work, info)
ZUPGTR
Definition zupgtr.f:112
subroutine zupmtr(side, uplo, trans, m, n, ap, tau, c, ldc, work, info)
ZUPMTR
Definition zupmtr.f:149