OpenRadioss 2025.1.11
OpenRadioss project
Loading...
Searching...
No Matches
chpevx.f
Go to the documentation of this file.
1*> \brief <b> CHPEVX 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*> \htmlonly
9*> Download CHPEVX + dependencies
10*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/chpevx.f">
11*> [TGZ]</a>
12*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/chpevx.f">
13*> [ZIP]</a>
14*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/chpevx.f">
15*> [TXT]</a>
16*> \endhtmlonly
17*
18* Definition:
19* ===========
20*
21* SUBROUTINE CHPEVX( JOBZ, RANGE, UPLO, N, AP, VL, VU, IL, IU,
22* ABSTOL, M, W, Z, LDZ, WORK, RWORK, IWORK,
23* IFAIL, INFO )
24*
25* .. Scalar Arguments ..
26* CHARACTER JOBZ, RANGE, UPLO
27* INTEGER IL, INFO, IU, LDZ, M, N
28* REAL ABSTOL, VL, VU
29* ..
30* .. Array Arguments ..
31* INTEGER IFAIL( * ), IWORK( * )
32* REAL RWORK( * ), W( * )
33* COMPLEX AP( * ), WORK( * ), Z( LDZ, * )
34* ..
35*
36*
37*> \par Purpose:
38* =============
39*>
40*> \verbatim
41*>
42*> CHPEVX computes selected eigenvalues and, optionally, eigenvectors
43*> of a complex Hermitian matrix A in packed storage.
44*> Eigenvalues/vectors can be selected by specifying either a range of
45*> values or a range of indices for the desired eigenvalues.
46*> \endverbatim
47*
48* Arguments:
49* ==========
50*
51*> \param[in] JOBZ
52*> \verbatim
53*> JOBZ is CHARACTER*1
54*> = 'N': Compute eigenvalues only;
55*> = 'V': Compute eigenvalues and eigenvectors.
56*> \endverbatim
57*>
58*> \param[in] RANGE
59*> \verbatim
60*> RANGE is CHARACTER*1
61*> = 'A': all eigenvalues will be found;
62*> = 'V': all eigenvalues in the half-open interval (VL,VU]
63*> will be found;
64*> = 'I': the IL-th through IU-th eigenvalues will be found.
65*> \endverbatim
66*>
67*> \param[in] UPLO
68*> \verbatim
69*> UPLO is CHARACTER*1
70*> = 'U': Upper triangle of A is stored;
71*> = 'L': Lower triangle of A is stored.
72*> \endverbatim
73*>
74*> \param[in] N
75*> \verbatim
76*> N is INTEGER
77*> The order of the matrix A. N >= 0.
78*> \endverbatim
79*>
80*> \param[in,out] AP
81*> \verbatim
82*> AP is COMPLEX array, dimension (N*(N+1)/2)
83*> On entry, the upper or lower triangle of the Hermitian matrix
84*> A, packed columnwise in a linear array. The j-th column of A
85*> is stored in the array AP as follows:
86*> if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j;
87*> if UPLO = 'L', AP(i + (j-1)*(2*n-j)/2) = A(i,j) for j<=i<=n.
88*>
89*> On exit, AP is overwritten by values generated during the
90*> reduction to tridiagonal form. If UPLO = 'U', the diagonal
91*> and first superdiagonal of the tridiagonal matrix T overwrite
92*> the corresponding elements of A, and if UPLO = 'L', the
93*> diagonal and first subdiagonal of T overwrite the
94*> corresponding elements of A.
95*> \endverbatim
96*>
97*> \param[in] VL
98*> \verbatim
99*> VL is REAL
100*> If RANGE='V', the lower bound of the interval to
101*> be searched for eigenvalues. VL < VU.
102*> Not referenced if RANGE = 'A' or 'I'.
103*> \endverbatim
104*>
105*> \param[in] VU
106*> \verbatim
107*> VU is REAL
108*> If RANGE='V', the upper bound of the interval to
109*> be searched for eigenvalues. VL < VU.
110*> Not referenced if RANGE = 'A' or 'I'.
111*> \endverbatim
112*>
113*> \param[in] IL
114*> \verbatim
115*> IL is INTEGER
116*> If RANGE='I', the index of the
117*> smallest eigenvalue to be returned.
118*> 1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
119*> Not referenced if RANGE = 'A' or 'V'.
120*> \endverbatim
121*>
122*> \param[in] IU
123*> \verbatim
124*> IU is INTEGER
125*> If RANGE='I', the index of the
126*> largest eigenvalue to be returned.
127*> 1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
128*> Not referenced if RANGE = 'A' or 'V'.
129*> \endverbatim
130*>
131*> \param[in] ABSTOL
132*> \verbatim
133*> ABSTOL is REAL
134*> The absolute error tolerance for the eigenvalues.
135*> An approximate eigenvalue is accepted as converged
136*> when it is determined to lie in an interval [a,b]
137*> of width less than or equal to
138*>
139*> ABSTOL + EPS * max( |a|,|b| ) ,
140*>
141*> where EPS is the machine precision. If ABSTOL is less than
142*> or equal to zero, then EPS*|T| will be used in its place,
143*> where |T| is the 1-norm of the tridiagonal matrix obtained
144*> by reducing AP to tridiagonal form.
145*>
146*> Eigenvalues will be computed most accurately when ABSTOL is
147*> set to twice the underflow threshold 2*SLAMCH('S'), not zero.
148*> If this routine returns with INFO>0, indicating that some
149*> eigenvectors did not converge, try setting ABSTOL to
150*> 2*SLAMCH('S').
151*>
152*> See "Computing Small Singular Values of Bidiagonal Matrices
153*> with Guaranteed High Relative Accuracy," by Demmel and
154*> Kahan, LAPACK Working Note #3.
155*> \endverbatim
156*>
157*> \param[out] M
158*> \verbatim
159*> M is INTEGER
160*> The total number of eigenvalues found. 0 <= M <= N.
161*> If RANGE = 'A', M = N, and if RANGE = 'I', M = IU-IL+1.
162*> \endverbatim
163*>
164*> \param[out] W
165*> \verbatim
166*> W is REAL array, dimension (N)
167*> If INFO = 0, the selected eigenvalues in ascending order.
168*> \endverbatim
169*>
170*> \param[out] Z
171*> \verbatim
172*> Z is COMPLEX array, dimension (LDZ, max(1,M))
173*> If JOBZ = 'V', then if INFO = 0, the first M columns of Z
174*> contain the orthonormal eigenvectors of the matrix A
175*> corresponding to the selected eigenvalues, with the i-th
176*> column of Z holding the eigenvector associated with W(i).
177*> If an eigenvector fails to converge, then that column of Z
178*> contains the latest approximation to the eigenvector, and
179*> the index of the eigenvector is returned in IFAIL.
180*> If JOBZ = 'N', then Z is not referenced.
181*> Note: the user must ensure that at least max(1,M) columns are
182*> supplied in the array Z; if RANGE = 'V', the exact value of M
183*> is not known in advance and an upper bound must be used.
184*> \endverbatim
185*>
186*> \param[in] LDZ
187*> \verbatim
188*> LDZ is INTEGER
189*> The leading dimension of the array Z. LDZ >= 1, and if
190*> JOBZ = 'V', LDZ >= max(1,N).
191*> \endverbatim
192*>
193*> \param[out] WORK
194*> \verbatim
195*> WORK is COMPLEX array, dimension (2*N)
196*> \endverbatim
197*>
198*> \param[out] RWORK
199*> \verbatim
200*> RWORK is REAL array, dimension (7*N)
201*> \endverbatim
202*>
203*> \param[out] IWORK
204*> \verbatim
205*> IWORK is INTEGER array, dimension (5*N)
206*> \endverbatim
207*>
208*> \param[out] IFAIL
209*> \verbatim
210*> IFAIL is INTEGER array, dimension (N)
211*> If JOBZ = 'V', then if INFO = 0, the first M elements of
212*> IFAIL are zero. If INFO > 0, then IFAIL contains the
213*> indices of the eigenvectors that failed to converge.
214*> If JOBZ = 'N', then IFAIL is not referenced.
215*> \endverbatim
216*>
217*> \param[out] INFO
218*> \verbatim
219*> INFO is INTEGER
220*> = 0: successful exit
221*> < 0: if INFO = -i, the i-th argument had an illegal value
222*> > 0: if INFO = i, then i eigenvectors failed to converge.
223*> Their indices are stored in array IFAIL.
224*> \endverbatim
225*
226* Authors:
227* ========
228*
229*> \author Univ. of Tennessee
230*> \author Univ. of California Berkeley
231*> \author Univ. of Colorado Denver
232*> \author NAG Ltd.
233*
234*> \ingroup complexOTHEReigen
235*
236* =====================================================================
237 SUBROUTINE chpevx( JOBZ, RANGE, UPLO, N, AP, VL, VU, IL, IU,
238 $ ABSTOL, M, W, Z, LDZ, WORK, RWORK, IWORK,
239 $ IFAIL, INFO )
240*
241* -- LAPACK driver routine --
242* -- LAPACK is a software package provided by Univ. of Tennessee, --
243* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
244*
245* .. Scalar Arguments ..
246 CHARACTER JOBZ, RANGE, UPLO
247 INTEGER IL, INFO, IU, LDZ, M, N
248 REAL ABSTOL, VL, VU
249* ..
250* .. Array Arguments ..
251 INTEGER IFAIL( * ), IWORK( * )
252 REAL RWORK( * ), W( * )
253 COMPLEX AP( * ), WORK( * ), Z( LDZ, * )
254* ..
255*
256* =====================================================================
257*
258* .. Parameters ..
259 REAL ZERO, ONE
260 PARAMETER ( ZERO = 0.0e0, one = 1.0e0 )
261 COMPLEX CONE
262 parameter( cone = ( 1.0e0, 0.0e0 ) )
263* ..
264* .. Local Scalars ..
265 LOGICAL ALLEIG, INDEIG, TEST, VALEIG, WANTZ
266 CHARACTER ORDER
267 INTEGER I, IINFO, IMAX, INDD, INDE, INDEE, INDIBL,
268 $ indisp, indiwk, indrwk, indtau, indwrk, iscale,
269 $ itmp1, j, jj, nsplit
270 REAL ABSTLL, ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN,
271 $ SIGMA, SMLNUM, TMP1, VLL, VUU
272* ..
273* .. External Functions ..
274 LOGICAL LSAME
275 REAL CLANHP, SLAMCH
276 EXTERNAL lsame, clanhp, slamch
277* ..
278* .. External Subroutines ..
279 EXTERNAL chptrd, csscal, cstein, csteqr, cswap, cupgtr,
281* ..
282* .. Intrinsic Functions ..
283 INTRINSIC max, min, real, sqrt
284* ..
285* .. Executable Statements ..
286*
287* Test the input parameters.
288*
289 wantz = lsame( jobz, 'V' )
290 alleig = lsame( range, 'A' )
291 valeig = lsame( range, 'V' )
292 indeig = lsame( range, 'I' )
293*
294 info = 0
295 IF( .NOT.( wantz .OR. lsame( jobz, 'N' ) ) ) THEN
296 info = -1
297 ELSE IF( .NOT.( alleig .OR. valeig .OR. indeig ) ) THEN
298 info = -2
299 ELSE IF( .NOT.( lsame( uplo, 'l.OR.' ) LSAME( UPLO, 'u' ) ) )
300 $ THEN
301 INFO = -3
302.LT. ELSE IF( N0 ) THEN
303 INFO = -4
304 ELSE
305 IF( VALEIG ) THEN
306.GT..AND..LE. IF( N0 VUVL )
307 $ INFO = -7
308 ELSE IF( INDEIG ) THEN
309.LT..OR..GT. IF( IL1 ILMAX( 1, N ) ) THEN
310 INFO = -8
311.LT..OR..GT. ELSE IF( IUMIN( N, IL ) IUN ) THEN
312 INFO = -9
313 END IF
314 END IF
315 END IF
316.EQ. IF( INFO0 ) THEN
317.LT..OR..AND..LT. IF( LDZ1 ( WANTZ LDZN ) )
318 $ INFO = -14
319 END IF
320*
321.NE. IF( INFO0 ) THEN
322 CALL XERBLA( 'chpevx', -INFO )
323 RETURN
324 END IF
325*
326* Quick return if possible
327*
328 M = 0
329.EQ. IF( N0 )
330 $ RETURN
331*
332.EQ. IF( N1 ) THEN
333.OR. IF( ALLEIG INDEIG ) THEN
334 M = 1
335 W( 1 ) = REAL( AP( 1 ) )
336 ELSE
337.LT..AND..GE. IF( VLREAL( AP( 1 ) ) VUREAL( AP( 1 ) ) ) THEN
338 M = 1
339 W( 1 ) = REAL( 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 = SLAMCH( 'safe minimum' )
350 EPS = SLAMCH( '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 ENDIF
367 ANRM = CLANHP( 'm', UPLO, N, AP, RWORK )
368.GT..AND..LT. IF( ANRMZERO ANRMRMIN ) THEN
369 ISCALE = 1
370 SIGMA = RMIN / ANRM
371.GT. ELSE IF( ANRMRMAX ) THEN
372 ISCALE = 1
373 SIGMA = RMAX / ANRM
374 END IF
375.EQ. IF( ISCALE1 ) THEN
376 CALL CSSCAL( ( N*( N+1 ) ) / 2, SIGMA, AP, 1 )
377.GT. IF( ABSTOL0 )
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 CHPTRD 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 CHPTRD( 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 SSTERF or CUPGTR and CSTEQR. If this fails
397* for some eigenvalue, then try SSTEBZ.
398*
399 TEST = .FALSE.
400 IF (INDEIG) THEN
401.EQ..AND..EQ. IF (IL1 IUN) THEN
402 TEST = .TRUE.
403 END IF
404 END IF
405.OR..AND..LE. IF ((ALLEIG TEST) (ABSTOLZERO)) THEN
406 CALL SCOPY( N, RWORK( INDD ), 1, W, 1 )
407 INDEE = INDRWK + 2*N
408.NOT. IF( WANTZ ) THEN
409 CALL SCOPY( N-1, RWORK( INDE ), 1, RWORK( INDEE ), 1 )
410 CALL SSTERF( N, W, RWORK( INDEE ), INFO )
411 ELSE
412 CALL CUPGTR( UPLO, N, AP, WORK( INDTAU ), Z, LDZ,
413 $ WORK( INDWRK ), IINFO )
414 CALL SCOPY( N-1, RWORK( INDE ), 1, RWORK( INDEE ), 1 )
415 CALL CSTEQR( JOBZ, N, W, RWORK( INDEE ), Z, LDZ,
416 $ RWORK( INDRWK ), INFO )
417.EQ. IF( INFO0 ) THEN
418 DO 10 I = 1, N
419 IFAIL( I ) = 0
420 10 CONTINUE
421 END IF
422 END IF
423.EQ. IF( INFO0 ) THEN
424 M = N
425 GO TO 20
426 END IF
427 INFO = 0
428 END IF
429*
430* Otherwise, call SSTEBZ and, if eigenvectors are desired, CSTEIN.
431*
432 IF( WANTZ ) THEN
433 ORDER = 'b'
434 ELSE
435 ORDER = 'e'
436 END IF
437 INDIBL = 1
438 INDISP = INDIBL + N
439 INDIWK = INDISP + N
440 CALL SSTEBZ( RANGE, ORDER, N, VLL, VUU, IL, IU, ABSTLL,
441 $ RWORK( INDD ), RWORK( INDE ), M, NSPLIT, W,
442 $ IWORK( INDIBL ), IWORK( INDISP ), RWORK( INDRWK ),
443 $ IWORK( INDIWK ), INFO )
444*
445 IF( WANTZ ) THEN
446 CALL CSTEIN( N, RWORK( INDD ), RWORK( INDE ), M, W,
447 $ IWORK( INDIBL ), IWORK( INDISP ), Z, LDZ,
448 $ RWORK( INDRWK ), IWORK( INDIWK ), IFAIL, INFO )
449*
450* Apply unitary matrix used in reduction to tridiagonal
451* form to eigenvectors returned by CSTEIN.
452*
453 INDWRK = INDTAU + N
454 CALL CUPMTR( 'l', UPLO, 'n', N, M, AP, WORK( INDTAU ), Z, LDZ,
455 $ WORK( INDWRK ), IINFO )
456 END IF
457*
458* If matrix was scaled, then rescale eigenvalues appropriately.
459*
460 20 CONTINUE
461.EQ. IF( ISCALE1 ) THEN
462.EQ. IF( INFO0 ) THEN
463 IMAX = M
464 ELSE
465 IMAX = INFO - 1
466 END IF
467 CALL SSCAL( 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.LT. IF( W( JJ )TMP1 ) THEN
479 I = JJ
480 TMP1 = W( JJ )
481 END IF
482 30 CONTINUE
483*
484.NE. IF( I0 ) THEN
485 ITMP1 = IWORK( INDIBL+I-1 )
486 W( I ) = W( J )
487 IWORK( INDIBL+I-1 ) = IWORK( INDIBL+J-1 )
488 W( J ) = TMP1
489 IWORK( INDIBL+J-1 ) = ITMP1
490 CALL CSWAP( N, Z( 1, I ), 1, Z( 1, J ), 1 )
491.NE. IF( INFO0 ) 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 CHPEVX
503*
504 END
subroutine sstebz(range, order, n, vl, vu, il, iu, abstol, d, e, m, nsplit, w, iblock, isplit, work, iwork, info)
SSTEBZ
Definition sstebz.f:273
subroutine ssterf(n, d, e, info)
SSTERF
Definition ssterf.f:86
subroutine xerbla(srname, info)
XERBLA
Definition xerbla.f:60
subroutine cstein(n, d, e, m, w, iblock, isplit, z, ldz, work, iwork, ifail, info)
CSTEIN
Definition cstein.f:182
subroutine cupgtr(uplo, n, ap, tau, q, ldq, work, info)
CUPGTR
Definition cupgtr.f:114
subroutine cupmtr(side, uplo, trans, m, n, ap, tau, c, ldc, work, info)
CUPMTR
Definition cupmtr.f:150
subroutine chptrd(uplo, n, ap, d, e, tau, info)
CHPTRD
Definition chptrd.f:151
subroutine csteqr(compz, n, d, e, z, ldz, work, info)
CSTEQR
Definition csteqr.f:132
subroutine chpevx(jobz, range, uplo, n, ap, vl, vu, il, iu, abstol, m, w, z, ldz, work, rwork, iwork, ifail, info)
CHPEVX computes the eigenvalues and, optionally, the left and/or right eigenvectors for OTHER matrice...
Definition chpevx.f:240
subroutine cswap(n, cx, incx, cy, incy)
CSWAP
Definition cswap.f:81
subroutine csscal(n, sa, cx, incx)
CSSCAL
Definition csscal.f:78
subroutine sscal(n, sa, sx, incx)
SSCAL
Definition sscal.f:79
subroutine scopy(n, sx, incx, sy, incy)
SCOPY
Definition scopy.f:82
#define min(a, b)
Definition macros.h:20
#define max(a, b)
Definition macros.h:21