LAPACK 3.12.1
LAPACK: Linear Algebra PACKage
Loading...
Searching...
No Matches
dsygvx.f
Go to the documentation of this file.
1*> \brief \b DSYGVX
2*
3* =========== DOCUMENTATION ===========
4*
5* Online html documentation available at
6* http://www.netlib.org/lapack/explore-html/
7*
8*> Download DSYGVX + dependencies
9*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dsygvx.f">
10*> [TGZ]</a>
11*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dsygvx.f">
12*> [ZIP]</a>
13*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dsygvx.f">
14*> [TXT]</a>
15*
16* Definition:
17* ===========
18*
19* SUBROUTINE DSYGVX( ITYPE, JOBZ, RANGE, UPLO, N, A, LDA, B, LDB,
20* VL, VU, IL, IU, ABSTOL, M, W, Z, LDZ, WORK,
21* LWORK, IWORK, IFAIL, INFO )
22*
23* .. Scalar Arguments ..
24* CHARACTER JOBZ, RANGE, UPLO
25* INTEGER IL, INFO, ITYPE, IU, LDA, LDB, LDZ, LWORK, M, N
26* DOUBLE PRECISION ABSTOL, VL, VU
27* ..
28* .. Array Arguments ..
29* INTEGER IFAIL( * ), IWORK( * )
30* DOUBLE PRECISION A( LDA, * ), B( LDB, * ), W( * ), WORK( * ),
31* $ Z( LDZ, * )
32* ..
33*
34*
35*> \par Purpose:
36* =============
37*>
38*> \verbatim
39*>
40*> DSYGVX computes selected eigenvalues, and optionally, eigenvectors
41*> of a real generalized symmetric-definite eigenproblem, of the form
42*> A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x. Here A
43*> and B are assumed to be symmetric and B is also positive definite.
44*> Eigenvalues and eigenvectors can be selected by specifying either a
45*> range of values or a range of indices for the desired eigenvalues.
46*> \endverbatim
47*
48* Arguments:
49* ==========
50*
51*> \param[in] ITYPE
52*> \verbatim
53*> ITYPE is INTEGER
54*> Specifies the problem type to be solved:
55*> = 1: A*x = (lambda)*B*x
56*> = 2: A*B*x = (lambda)*x
57*> = 3: B*A*x = (lambda)*x
58*> \endverbatim
59*>
60*> \param[in] JOBZ
61*> \verbatim
62*> JOBZ is CHARACTER*1
63*> = 'N': Compute eigenvalues only;
64*> = 'V': Compute eigenvalues and eigenvectors.
65*> \endverbatim
66*>
67*> \param[in] RANGE
68*> \verbatim
69*> RANGE is CHARACTER*1
70*> = 'A': all eigenvalues will be found.
71*> = 'V': all eigenvalues in the half-open interval (VL,VU]
72*> will be found.
73*> = 'I': the IL-th through IU-th eigenvalues will be found.
74*> \endverbatim
75*>
76*> \param[in] UPLO
77*> \verbatim
78*> UPLO is CHARACTER*1
79*> = 'U': Upper triangle of A and B are stored;
80*> = 'L': Lower triangle of A and B are stored.
81*> \endverbatim
82*>
83*> \param[in] N
84*> \verbatim
85*> N is INTEGER
86*> The order of the matrix pencil (A,B). N >= 0.
87*> \endverbatim
88*>
89*> \param[in,out] A
90*> \verbatim
91*> A is DOUBLE PRECISION array, dimension (LDA, N)
92*> On entry, the symmetric matrix A. If UPLO = 'U', the
93*> leading N-by-N upper triangular part of A contains the
94*> upper triangular part of the matrix A. If UPLO = 'L',
95*> the leading N-by-N lower triangular part of A contains
96*> the lower triangular part of the matrix A.
97*>
98*> On exit, the lower triangle (if UPLO='L') or the upper
99*> triangle (if UPLO='U') of A, including the diagonal, is
100*> destroyed.
101*> \endverbatim
102*>
103*> \param[in] LDA
104*> \verbatim
105*> LDA is INTEGER
106*> The leading dimension of the array A. LDA >= max(1,N).
107*> \endverbatim
108*>
109*> \param[in,out] B
110*> \verbatim
111*> B is DOUBLE PRECISION array, dimension (LDB, N)
112*> On entry, the symmetric matrix B. If UPLO = 'U', the
113*> leading N-by-N upper triangular part of B contains the
114*> upper triangular part of the matrix B. If UPLO = 'L',
115*> the leading N-by-N lower triangular part of B contains
116*> the lower triangular part of the matrix B.
117*>
118*> On exit, if INFO <= N, the part of B containing the matrix is
119*> overwritten by the triangular factor U or L from the Cholesky
120*> factorization B = U**T*U or B = L*L**T.
121*> \endverbatim
122*>
123*> \param[in] LDB
124*> \verbatim
125*> LDB is INTEGER
126*> The leading dimension of the array B. LDB >= max(1,N).
127*> \endverbatim
128*>
129*> \param[in] VL
130*> \verbatim
131*> VL is DOUBLE PRECISION
132*> If RANGE='V', the lower bound of the interval to
133*> be searched for eigenvalues. VL < VU.
134*> Not referenced if RANGE = 'A' or 'I'.
135*> \endverbatim
136*>
137*> \param[in] VU
138*> \verbatim
139*> VU is DOUBLE PRECISION
140*> If RANGE='V', the upper bound of the interval to
141*> be searched for eigenvalues. VL < VU.
142*> Not referenced if RANGE = 'A' or 'I'.
143*> \endverbatim
144*>
145*> \param[in] IL
146*> \verbatim
147*> IL is INTEGER
148*> If RANGE='I', the index of the
149*> smallest eigenvalue to be returned.
150*> 1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
151*> Not referenced if RANGE = 'A' or 'V'.
152*> \endverbatim
153*>
154*> \param[in] IU
155*> \verbatim
156*> IU is INTEGER
157*> If RANGE='I', the index of the
158*> largest eigenvalue to be returned.
159*> 1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
160*> Not referenced if RANGE = 'A' or 'V'.
161*> \endverbatim
162*>
163*> \param[in] ABSTOL
164*> \verbatim
165*> ABSTOL is DOUBLE PRECISION
166*> The absolute error tolerance for the eigenvalues.
167*> An approximate eigenvalue is accepted as converged
168*> when it is determined to lie in an interval [a,b]
169*> of width less than or equal to
170*>
171*> ABSTOL + EPS * max( |a|,|b| ) ,
172*>
173*> where EPS is the machine precision. If ABSTOL is less than
174*> or equal to zero, then EPS*|T| will be used in its place,
175*> where |T| is the 1-norm of the tridiagonal matrix obtained
176*> by reducing C to tridiagonal form, where C is the symmetric
177*> matrix of the standard symmetric problem to which the
178*> generalized problem is transformed.
179*>
180*> Eigenvalues will be computed most accurately when ABSTOL is
181*> set to twice the underflow threshold 2*DLAMCH('S'), not zero.
182*> If this routine returns with INFO>0, indicating that some
183*> eigenvectors did not converge, try setting ABSTOL to
184*> 2*DLAMCH('S').
185*> \endverbatim
186*>
187*> \param[out] M
188*> \verbatim
189*> M is INTEGER
190*> The total number of eigenvalues found. 0 <= M <= N.
191*> If RANGE = 'A', M = N, and if RANGE = 'I', M = IU-IL+1.
192*> \endverbatim
193*>
194*> \param[out] W
195*> \verbatim
196*> W is DOUBLE PRECISION array, dimension (N)
197*> On normal exit, the first M elements contain the selected
198*> eigenvalues in ascending order.
199*> \endverbatim
200*>
201*> \param[out] Z
202*> \verbatim
203*> Z is DOUBLE PRECISION array, dimension (LDZ, max(1,M))
204*> If JOBZ = 'N', then Z is not referenced.
205*> If JOBZ = 'V', then if INFO = 0, the first M columns of Z
206*> contain the orthonormal eigenvectors of the matrix A
207*> corresponding to the selected eigenvalues, with the i-th
208*> column of Z holding the eigenvector associated with W(i).
209*> The eigenvectors are normalized as follows:
210*> if ITYPE = 1 or 2, Z**T*B*Z = I;
211*> if ITYPE = 3, Z**T*inv(B)*Z = I.
212*>
213*> If an eigenvector fails to converge, then that column of Z
214*> contains the latest approximation to the eigenvector, and the
215*> index of the eigenvector is returned in IFAIL.
216*> Note: the user must ensure that at least max(1,M) columns are
217*> supplied in the array Z; if RANGE = 'V', the exact value of M
218*> is not known in advance and an upper bound must be used.
219*> \endverbatim
220*>
221*> \param[in] LDZ
222*> \verbatim
223*> LDZ is INTEGER
224*> The leading dimension of the array Z. LDZ >= 1, and if
225*> JOBZ = 'V', LDZ >= max(1,N).
226*> \endverbatim
227*>
228*> \param[out] WORK
229*> \verbatim
230*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))
231*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
232*> \endverbatim
233*>
234*> \param[in] LWORK
235*> \verbatim
236*> LWORK is INTEGER
237*> The length of the array WORK. LWORK >= max(1,8*N).
238*> For optimal efficiency, LWORK >= (NB+3)*N,
239*> where NB is the blocksize for DSYTRD returned by ILAENV.
240*>
241*> If LWORK = -1, then a workspace query is assumed; the routine
242*> only calculates the optimal size of the WORK array, returns
243*> this value as the first entry of the WORK array, and no error
244*> message related to LWORK is issued by XERBLA.
245*> \endverbatim
246*>
247*> \param[out] IWORK
248*> \verbatim
249*> IWORK is INTEGER array, dimension (5*N)
250*> \endverbatim
251*>
252*> \param[out] IFAIL
253*> \verbatim
254*> IFAIL is INTEGER array, dimension (N)
255*> If JOBZ = 'V', then if INFO = 0, the first M elements of
256*> IFAIL are zero. If INFO > 0, then IFAIL contains the
257*> indices of the eigenvectors that failed to converge.
258*> If JOBZ = 'N', then IFAIL is not referenced.
259*> \endverbatim
260*>
261*> \param[out] INFO
262*> \verbatim
263*> INFO is INTEGER
264*> = 0: successful exit
265*> < 0: if INFO = -i, the i-th argument had an illegal value
266*> > 0: DPOTRF or DSYEVX returned an error code:
267*> <= N: if INFO = i, DSYEVX failed to converge;
268*> i eigenvectors failed to converge. Their indices
269*> are stored in array IFAIL.
270*> > N: if INFO = N + i, for 1 <= i <= N, then the leading
271*> principal minor of order i of B is not positive.
272*> The factorization of B could not be completed and
273*> no eigenvalues or eigenvectors were computed.
274*> \endverbatim
275*
276* Authors:
277* ========
278*
279*> \author Univ. of Tennessee
280*> \author Univ. of California Berkeley
281*> \author Univ. of Colorado Denver
282*> \author NAG Ltd.
283*
284*> \ingroup hegvx
285*
286*> \par Contributors:
287* ==================
288*>
289*> Mark Fahey, Department of Mathematics, Univ. of Kentucky, USA
290*
291* =====================================================================
292 SUBROUTINE dsygvx( ITYPE, JOBZ, RANGE, UPLO, N, A, LDA, B, LDB,
293 $ VL, VU, IL, IU, ABSTOL, M, W, Z, LDZ, WORK,
294 $ LWORK, IWORK, IFAIL, INFO )
295*
296* -- LAPACK driver routine --
297* -- LAPACK is a software package provided by Univ. of Tennessee, --
298* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
299*
300* .. Scalar Arguments ..
301 CHARACTER JOBZ, RANGE, UPLO
302 INTEGER IL, INFO, ITYPE, IU, LDA, LDB, LDZ, LWORK, M, N
303 DOUBLE PRECISION ABSTOL, VL, VU
304* ..
305* .. Array Arguments ..
306 INTEGER IFAIL( * ), IWORK( * )
307 DOUBLE PRECISION A( LDA, * ), B( LDB, * ), W( * ), WORK( * ),
308 $ z( ldz, * )
309* ..
310*
311* =====================================================================
312*
313* .. Parameters ..
314 DOUBLE PRECISION ONE
315 PARAMETER ( ONE = 1.0d+0 )
316* ..
317* .. Local Scalars ..
318 LOGICAL ALLEIG, INDEIG, LQUERY, UPPER, VALEIG, WANTZ
319 CHARACTER TRANS
320 INTEGER LWKMIN, LWKOPT, NB
321* ..
322* .. External Functions ..
323 LOGICAL LSAME
324 INTEGER ILAENV
325 EXTERNAL lsame, ilaenv
326* ..
327* .. External Subroutines ..
328 EXTERNAL dpotrf, dsyevx, dsygst, dtrmm, dtrsm,
329 $ xerbla
330* ..
331* .. Intrinsic Functions ..
332 INTRINSIC max, min
333* ..
334* .. Executable Statements ..
335*
336* Test the input parameters.
337*
338 upper = lsame( uplo, 'U' )
339 wantz = lsame( jobz, 'V' )
340 alleig = lsame( range, 'A' )
341 valeig = lsame( range, 'V' )
342 indeig = lsame( range, 'I' )
343 lquery = ( lwork.EQ.-1 )
344*
345 info = 0
346 IF( itype.LT.1 .OR. itype.GT.3 ) THEN
347 info = -1
348 ELSE IF( .NOT.( wantz .OR. lsame( jobz, 'N' ) ) ) THEN
349 info = -2
350 ELSE IF( .NOT.( alleig .OR. valeig .OR. indeig ) ) THEN
351 info = -3
352 ELSE IF( .NOT.( upper .OR. lsame( uplo, 'L' ) ) ) THEN
353 info = -4
354 ELSE IF( n.LT.0 ) THEN
355 info = -5
356 ELSE IF( lda.LT.max( 1, n ) ) THEN
357 info = -7
358 ELSE IF( ldb.LT.max( 1, n ) ) THEN
359 info = -9
360 ELSE
361 IF( valeig ) THEN
362 IF( n.GT.0 .AND. vu.LE.vl )
363 $ info = -11
364 ELSE IF( indeig ) THEN
365 IF( il.LT.1 .OR. il.GT.max( 1, n ) ) THEN
366 info = -12
367 ELSE IF( iu.LT.min( n, il ) .OR. iu.GT.n ) THEN
368 info = -13
369 END IF
370 END IF
371 END IF
372 IF (info.EQ.0) THEN
373 IF (ldz.LT.1 .OR. (wantz .AND. ldz.LT.n)) THEN
374 info = -18
375 END IF
376 END IF
377*
378 IF( info.EQ.0 ) THEN
379 lwkmin = max( 1, 8*n )
380 nb = ilaenv( 1, 'DSYTRD', uplo, n, -1, -1, -1 )
381 lwkopt = max( lwkmin, ( nb + 3 )*n )
382 work( 1 ) = lwkopt
383*
384 IF( lwork.LT.lwkmin .AND. .NOT.lquery ) THEN
385 info = -20
386 END IF
387 END IF
388*
389 IF( info.NE.0 ) THEN
390 CALL xerbla( 'DSYGVX', -info )
391 RETURN
392 ELSE IF( lquery ) THEN
393 RETURN
394 END IF
395*
396* Quick return if possible
397*
398 m = 0
399 IF( n.EQ.0 ) THEN
400 RETURN
401 END IF
402*
403* Form a Cholesky factorization of B.
404*
405 CALL dpotrf( uplo, n, b, ldb, info )
406 IF( info.NE.0 ) THEN
407 info = n + info
408 RETURN
409 END IF
410*
411* Transform problem to standard eigenvalue problem and solve.
412*
413 CALL dsygst( itype, uplo, n, a, lda, b, ldb, info )
414 CALL dsyevx( jobz, range, uplo, n, a, lda, vl, vu, il, iu,
415 $ abstol,
416 $ m, w, z, ldz, work, lwork, iwork, ifail, info )
417*
418 IF( wantz ) THEN
419*
420* Backtransform eigenvectors to the original problem.
421*
422 IF( info.GT.0 )
423 $ m = info - 1
424 IF( itype.EQ.1 .OR. itype.EQ.2 ) THEN
425*
426* For A*x=(lambda)*B*x and A*B*x=(lambda)*x;
427* backtransform eigenvectors: x = inv(L)**T*y or inv(U)*y
428*
429 IF( upper ) THEN
430 trans = 'N'
431 ELSE
432 trans = 'T'
433 END IF
434*
435 CALL dtrsm( 'Left', uplo, trans, 'Non-unit', n, m, one,
436 $ b,
437 $ ldb, z, ldz )
438*
439 ELSE IF( itype.EQ.3 ) THEN
440*
441* For B*A*x=(lambda)*x;
442* backtransform eigenvectors: x = L*y or U**T*y
443*
444 IF( upper ) THEN
445 trans = 'T'
446 ELSE
447 trans = 'N'
448 END IF
449*
450 CALL dtrmm( 'Left', uplo, trans, 'Non-unit', n, m, one,
451 $ b,
452 $ ldb, z, ldz )
453 END IF
454 END IF
455*
456* Set WORK(1) to optimal workspace size.
457*
458 work( 1 ) = lwkopt
459*
460 RETURN
461*
462* End of DSYGVX
463*
464 END
subroutine xerbla(srname, info)
Definition cblat2.f:3285
subroutine dsyevx(jobz, range, uplo, n, a, lda, vl, vu, il, iu, abstol, m, w, z, ldz, work, lwork, iwork, ifail, info)
DSYEVX computes the eigenvalues and, optionally, the left and/or right eigenvectors for SY matrices
Definition dsyevx.f:252
subroutine dsygst(itype, uplo, n, a, lda, b, ldb, info)
DSYGST
Definition dsygst.f:125
subroutine dsygvx(itype, jobz, range, uplo, n, a, lda, b, ldb, vl, vu, il, iu, abstol, m, w, z, ldz, work, lwork, iwork, ifail, info)
DSYGVX
Definition dsygvx.f:295
subroutine dpotrf(uplo, n, a, lda, info)
DPOTRF
Definition dpotrf.f:105
subroutine dtrmm(side, uplo, transa, diag, m, n, alpha, a, lda, b, ldb)
DTRMM
Definition dtrmm.f:177
subroutine dtrsm(side, uplo, transa, diag, m, n, alpha, a, lda, b, ldb)
DTRSM
Definition dtrsm.f:181