LAPACK 3.12.1
LAPACK: Linear Algebra PACKage
Loading...
Searching...
No Matches
dsbgvx.f
Go to the documentation of this file.
1*> \brief \b DSBGVX
2*
3* =========== DOCUMENTATION ===========
4*
5* Online html documentation available at
6* http://www.netlib.org/lapack/explore-html/
7*
8*> Download DSBGVX + dependencies
9*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dsbgvx.f">
10*> [TGZ]</a>
11*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dsbgvx.f">
12*> [ZIP]</a>
13*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dsbgvx.f">
14*> [TXT]</a>
15*
16* Definition:
17* ===========
18*
19* SUBROUTINE DSBGVX( JOBZ, RANGE, UPLO, N, KA, KB, AB, LDAB, BB,
20* LDBB, Q, LDQ, VL, VU, IL, IU, ABSTOL, M, W, Z,
21* LDZ, WORK, IWORK, IFAIL, INFO )
22*
23* .. Scalar Arguments ..
24* CHARACTER JOBZ, RANGE, UPLO
25* INTEGER IL, INFO, IU, KA, KB, LDAB, LDBB, LDQ, LDZ, M,
26* $ N
27* DOUBLE PRECISION ABSTOL, VL, VU
28* ..
29* .. Array Arguments ..
30* INTEGER IFAIL( * ), IWORK( * )
31* DOUBLE PRECISION AB( LDAB, * ), BB( LDBB, * ), Q( LDQ, * ),
32* $ W( * ), WORK( * ), Z( LDZ, * )
33* ..
34*
35*
36*> \par Purpose:
37* =============
38*>
39*> \verbatim
40*>
41*> DSBGVX computes selected eigenvalues, and optionally, eigenvectors
42*> of a real generalized symmetric-definite banded eigenproblem, of
43*> the form A*x=(lambda)*B*x. Here A and B are assumed to be symmetric
44*> and banded, and B is also positive definite. Eigenvalues and
45*> eigenvectors can be selected by specifying either all eigenvalues,
46*> a range of values or a range of indices for the desired eigenvalues.
47*> \endverbatim
48*
49* Arguments:
50* ==========
51*
52*> \param[in] JOBZ
53*> \verbatim
54*> JOBZ is CHARACTER*1
55*> = 'N': Compute eigenvalues only;
56*> = 'V': Compute eigenvalues and eigenvectors.
57*> \endverbatim
58*>
59*> \param[in] RANGE
60*> \verbatim
61*> RANGE is CHARACTER*1
62*> = 'A': all eigenvalues will be found.
63*> = 'V': all eigenvalues in the half-open interval (VL,VU]
64*> will be found.
65*> = 'I': the IL-th through IU-th eigenvalues will be found.
66*> \endverbatim
67*>
68*> \param[in] UPLO
69*> \verbatim
70*> UPLO is CHARACTER*1
71*> = 'U': Upper triangles of A and B are stored;
72*> = 'L': Lower triangles of A and B are stored.
73*> \endverbatim
74*>
75*> \param[in] N
76*> \verbatim
77*> N is INTEGER
78*> The order of the matrices A and B. N >= 0.
79*> \endverbatim
80*>
81*> \param[in] KA
82*> \verbatim
83*> KA is INTEGER
84*> The number of superdiagonals of the matrix A if UPLO = 'U',
85*> or the number of subdiagonals if UPLO = 'L'. KA >= 0.
86*> \endverbatim
87*>
88*> \param[in] KB
89*> \verbatim
90*> KB is INTEGER
91*> The number of superdiagonals of the matrix B if UPLO = 'U',
92*> or the number of subdiagonals if UPLO = 'L'. KB >= 0.
93*> \endverbatim
94*>
95*> \param[in,out] AB
96*> \verbatim
97*> AB is DOUBLE PRECISION array, dimension (LDAB, N)
98*> On entry, the upper or lower triangle of the symmetric band
99*> matrix A, stored in the first ka+1 rows of the array. The
100*> j-th column of A is stored in the j-th column of the array AB
101*> as follows:
102*> if UPLO = 'U', AB(ka+1+i-j,j) = A(i,j) for max(1,j-ka)<=i<=j;
103*> if UPLO = 'L', AB(1+i-j,j) = A(i,j) for j<=i<=min(n,j+ka).
104*>
105*> On exit, the contents of AB are destroyed.
106*> \endverbatim
107*>
108*> \param[in] LDAB
109*> \verbatim
110*> LDAB is INTEGER
111*> The leading dimension of the array AB. LDAB >= KA+1.
112*> \endverbatim
113*>
114*> \param[in,out] BB
115*> \verbatim
116*> BB is DOUBLE PRECISION array, dimension (LDBB, N)
117*> On entry, the upper or lower triangle of the symmetric band
118*> matrix B, stored in the first kb+1 rows of the array. The
119*> j-th column of B is stored in the j-th column of the array BB
120*> as follows:
121*> if UPLO = 'U', BB(ka+1+i-j,j) = B(i,j) for max(1,j-kb)<=i<=j;
122*> if UPLO = 'L', BB(1+i-j,j) = B(i,j) for j<=i<=min(n,j+kb).
123*>
124*> On exit, the factor S from the split Cholesky factorization
125*> B = S**T*S, as returned by DPBSTF.
126*> \endverbatim
127*>
128*> \param[in] LDBB
129*> \verbatim
130*> LDBB is INTEGER
131*> The leading dimension of the array BB. LDBB >= KB+1.
132*> \endverbatim
133*>
134*> \param[out] Q
135*> \verbatim
136*> Q is DOUBLE PRECISION array, dimension (LDQ, N)
137*> If JOBZ = 'V', the n-by-n matrix used in the reduction of
138*> A*x = (lambda)*B*x to standard form, i.e. C*x = (lambda)*x,
139*> and consequently C to tridiagonal form.
140*> If JOBZ = 'N', the array Q is not referenced.
141*> \endverbatim
142*>
143*> \param[in] LDQ
144*> \verbatim
145*> LDQ is INTEGER
146*> The leading dimension of the array Q. If JOBZ = 'N',
147*> LDQ >= 1. If JOBZ = 'V', LDQ >= max(1,N).
148*> \endverbatim
149*>
150*> \param[in] VL
151*> \verbatim
152*> VL is DOUBLE PRECISION
153*>
154*> If RANGE='V', the lower bound of the interval to
155*> be searched for eigenvalues. VL < VU.
156*> Not referenced if RANGE = 'A' or 'I'.
157*> \endverbatim
158*>
159*> \param[in] VU
160*> \verbatim
161*> VU is DOUBLE PRECISION
162*>
163*> If RANGE='V', the upper bound of the interval to
164*> be searched for eigenvalues. VL < VU.
165*> Not referenced if RANGE = 'A' or 'I'.
166*> \endverbatim
167*>
168*> \param[in] IL
169*> \verbatim
170*> IL is INTEGER
171*>
172*> If RANGE='I', the index of the
173*> smallest eigenvalue to be returned.
174*> 1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
175*> Not referenced if RANGE = 'A' or 'V'.
176*> \endverbatim
177*>
178*> \param[in] IU
179*> \verbatim
180*> IU is INTEGER
181*>
182*> If RANGE='I', the index of the
183*> largest eigenvalue to be returned.
184*> 1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
185*> Not referenced if RANGE = 'A' or 'V'.
186*> \endverbatim
187*>
188*> \param[in] ABSTOL
189*> \verbatim
190*> ABSTOL is DOUBLE PRECISION
191*> The absolute error tolerance for the eigenvalues.
192*> An approximate eigenvalue is accepted as converged
193*> when it is determined to lie in an interval [a,b]
194*> of width less than or equal to
195*>
196*> ABSTOL + EPS * max( |a|,|b| ) ,
197*>
198*> where EPS is the machine precision. If ABSTOL is less than
199*> or equal to zero, then EPS*|T| will be used in its place,
200*> where |T| is the 1-norm of the tridiagonal matrix obtained
201*> by reducing A to tridiagonal form.
202*>
203*> Eigenvalues will be computed most accurately when ABSTOL is
204*> set to twice the underflow threshold 2*DLAMCH('S'), not zero.
205*> If this routine returns with INFO>0, indicating that some
206*> eigenvectors did not converge, try setting ABSTOL to
207*> 2*DLAMCH('S').
208*> \endverbatim
209*>
210*> \param[out] M
211*> \verbatim
212*> M is INTEGER
213*> The total number of eigenvalues found. 0 <= M <= N.
214*> If RANGE = 'A', M = N, and if RANGE = 'I', M = IU-IL+1.
215*> \endverbatim
216*>
217*> \param[out] W
218*> \verbatim
219*> W is DOUBLE PRECISION array, dimension (N)
220*> If INFO = 0, the eigenvalues in ascending order.
221*> \endverbatim
222*>
223*> \param[out] Z
224*> \verbatim
225*> Z is DOUBLE PRECISION array, dimension (LDZ, N)
226*> If JOBZ = 'V', then if INFO = 0, Z contains the matrix Z of
227*> eigenvectors, with the i-th column of Z holding the
228*> eigenvector associated with W(i). The eigenvectors are
229*> normalized so Z**T*B*Z = I.
230*> If JOBZ = 'N', then Z is not referenced.
231*> \endverbatim
232*>
233*> \param[in] LDZ
234*> \verbatim
235*> LDZ is INTEGER
236*> The leading dimension of the array Z. LDZ >= 1, and if
237*> JOBZ = 'V', LDZ >= max(1,N).
238*> \endverbatim
239*>
240*> \param[out] WORK
241*> \verbatim
242*> WORK is DOUBLE PRECISION array, dimension (7*N)
243*> \endverbatim
244*>
245*> \param[out] IWORK
246*> \verbatim
247*> IWORK is INTEGER array, dimension (5*N)
248*> \endverbatim
249*>
250*> \param[out] IFAIL
251*> \verbatim
252*> IFAIL is INTEGER array, dimension (M)
253*> If JOBZ = 'V', then if INFO = 0, the first M elements of
254*> IFAIL are zero. If INFO > 0, then IFAIL contains the
255*> indices of the eigenvalues that failed to converge.
256*> If JOBZ = 'N', then IFAIL is not referenced.
257*> \endverbatim
258*>
259*> \param[out] INFO
260*> \verbatim
261*> INFO is INTEGER
262*> = 0: successful exit
263*> < 0: if INFO = -i, the i-th argument had an illegal value
264*> <= N: if INFO = i, then i eigenvectors failed to converge.
265*> Their indices are stored in IFAIL.
266*> > N: DPBSTF returned an error code; i.e.,
267*> if INFO = N + i, for 1 <= i <= N, then the leading
268*> principal minor of order i of B is not positive.
269*> The factorization of B could not be completed and
270*> no eigenvalues or eigenvectors were computed.
271*> \endverbatim
272*
273* Authors:
274* ========
275*
276*> \author Univ. of Tennessee
277*> \author Univ. of California Berkeley
278*> \author Univ. of Colorado Denver
279*> \author NAG Ltd.
280*
281*> \ingroup hbgvx
282*
283*> \par Contributors:
284* ==================
285*>
286*> Mark Fahey, Department of Mathematics, Univ. of Kentucky, USA
287*
288* =====================================================================
289 SUBROUTINE dsbgvx( JOBZ, RANGE, UPLO, N, KA, KB, AB, LDAB, BB,
290 $ LDBB, Q, LDQ, VL, VU, IL, IU, ABSTOL, M, W, Z,
291 $ LDZ, WORK, IWORK, IFAIL, INFO )
292*
293* -- LAPACK driver routine --
294* -- LAPACK is a software package provided by Univ. of Tennessee, --
295* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
296*
297* .. Scalar Arguments ..
298 CHARACTER JOBZ, RANGE, UPLO
299 INTEGER IL, INFO, IU, KA, KB, LDAB, LDBB, LDQ, LDZ, M,
300 $ n
301 DOUBLE PRECISION ABSTOL, VL, VU
302* ..
303* .. Array Arguments ..
304 INTEGER IFAIL( * ), IWORK( * )
305 DOUBLE PRECISION AB( LDAB, * ), BB( LDBB, * ), Q( LDQ, * ),
306 $ w( * ), work( * ), z( ldz, * )
307* ..
308*
309* =====================================================================
310*
311* .. Parameters ..
312 DOUBLE PRECISION ZERO, ONE
313 PARAMETER ( ZERO = 0.0d+0, one = 1.0d+0 )
314* ..
315* .. Local Scalars ..
316 LOGICAL ALLEIG, INDEIG, TEST, UPPER, VALEIG, WANTZ
317 CHARACTER ORDER, VECT
318 INTEGER I, IINFO, INDD, INDE, INDEE, INDISP,
319 $ indiwo, indwrk, itmp1, j, jj, nsplit
320 DOUBLE PRECISION TMP1
321* ..
322* .. External Functions ..
323 LOGICAL LSAME
324 EXTERNAL LSAME
325* ..
326* .. External Subroutines ..
327 EXTERNAL dcopy, dgemv, dlacpy, dpbstf, dsbgst,
328 $ dsbtrd,
330* ..
331* .. Intrinsic Functions ..
332 INTRINSIC min
333* ..
334* .. Executable Statements ..
335*
336* Test the input parameters.
337*
338 wantz = lsame( jobz, 'V' )
339 upper = lsame( uplo, 'U' )
340 alleig = lsame( range, 'A' )
341 valeig = lsame( range, 'V' )
342 indeig = lsame( range, 'I' )
343*
344 info = 0
345 IF( .NOT.( wantz .OR. lsame( jobz, 'N' ) ) ) THEN
346 info = -1
347 ELSE IF( .NOT.( alleig .OR. valeig .OR. indeig ) ) THEN
348 info = -2
349 ELSE IF( .NOT.( upper .OR. lsame( uplo, 'L' ) ) ) THEN
350 info = -3
351 ELSE IF( n.LT.0 ) THEN
352 info = -4
353 ELSE IF( ka.LT.0 ) THEN
354 info = -5
355 ELSE IF( kb.LT.0 .OR. kb.GT.ka ) THEN
356 info = -6
357 ELSE IF( ldab.LT.ka+1 ) THEN
358 info = -8
359 ELSE IF( ldbb.LT.kb+1 ) THEN
360 info = -10
361 ELSE IF( ldq.LT.1 .OR. ( wantz .AND. ldq.LT.n ) ) THEN
362 info = -12
363 ELSE
364 IF( valeig ) THEN
365 IF( n.GT.0 .AND. vu.LE.vl )
366 $ info = -14
367 ELSE IF( indeig ) THEN
368 IF( il.LT.1 .OR. il.GT.max( 1, n ) ) THEN
369 info = -15
370 ELSE IF ( iu.LT.min( n, il ) .OR. iu.GT.n ) THEN
371 info = -16
372 END IF
373 END IF
374 END IF
375 IF( info.EQ.0) THEN
376 IF( ldz.LT.1 .OR. ( wantz .AND. ldz.LT.n ) ) THEN
377 info = -21
378 END IF
379 END IF
380*
381 IF( info.NE.0 ) THEN
382 CALL xerbla( 'DSBGVX', -info )
383 RETURN
384 END IF
385*
386* Quick return if possible
387*
388 m = 0
389 IF( n.EQ.0 )
390 $ RETURN
391*
392* Form a split Cholesky factorization of B.
393*
394 CALL dpbstf( uplo, n, kb, bb, ldbb, info )
395 IF( info.NE.0 ) THEN
396 info = n + info
397 RETURN
398 END IF
399*
400* Transform problem to standard eigenvalue problem.
401*
402 CALL dsbgst( jobz, uplo, n, ka, kb, ab, ldab, bb, ldbb, q, ldq,
403 $ work, iinfo )
404*
405* Reduce symmetric band matrix to tridiagonal form.
406*
407 indd = 1
408 inde = indd + n
409 indwrk = inde + n
410 IF( wantz ) THEN
411 vect = 'U'
412 ELSE
413 vect = 'N'
414 END IF
415 CALL dsbtrd( vect, uplo, n, ka, ab, ldab, work( indd ),
416 $ work( inde ), q, ldq, work( indwrk ), iinfo )
417*
418* If all eigenvalues are desired and ABSTOL is less than or equal
419* to zero, then call DSTERF or SSTEQR. If this fails for some
420* eigenvalue, then try DSTEBZ.
421*
422 test = .false.
423 IF( indeig ) THEN
424 IF( il.EQ.1 .AND. iu.EQ.n ) THEN
425 test = .true.
426 END IF
427 END IF
428 IF( ( alleig .OR. test ) .AND. ( abstol.LE.zero ) ) THEN
429 CALL dcopy( n, work( indd ), 1, w, 1 )
430 indee = indwrk + 2*n
431 CALL dcopy( n-1, work( inde ), 1, work( indee ), 1 )
432 IF( .NOT.wantz ) THEN
433 CALL dsterf( n, w, work( indee ), info )
434 ELSE
435 CALL dlacpy( 'A', n, n, q, ldq, z, ldz )
436 CALL dsteqr( jobz, n, w, work( indee ), z, ldz,
437 $ work( indwrk ), info )
438 IF( info.EQ.0 ) THEN
439 DO 10 i = 1, n
440 ifail( i ) = 0
441 10 CONTINUE
442 END IF
443 END IF
444 IF( info.EQ.0 ) THEN
445 m = n
446 GO TO 30
447 END IF
448 info = 0
449 END IF
450*
451* Otherwise, call DSTEBZ and, if eigenvectors are desired,
452* call DSTEIN.
453*
454 IF( wantz ) THEN
455 order = 'B'
456 ELSE
457 order = 'E'
458 END IF
459 indisp = 1 + n
460 indiwo = indisp + n
461 CALL dstebz( range, order, n, vl, vu, il, iu, abstol,
462 $ work( indd ), work( inde ), m, nsplit, w,
463 $ iwork( 1 ), iwork( indisp ), work( indwrk ),
464 $ iwork( indiwo ), info )
465*
466 IF( wantz ) THEN
467 CALL dstein( n, work( indd ), work( inde ), m, w,
468 $ iwork( 1 ), iwork( indisp ), z, ldz,
469 $ work( indwrk ), iwork( indiwo ), ifail, info )
470*
471* Apply transformation matrix used in reduction to tridiagonal
472* form to eigenvectors returned by DSTEIN.
473*
474 DO 20 j = 1, m
475 CALL dcopy( n, z( 1, j ), 1, work( 1 ), 1 )
476 CALL dgemv( 'N', n, n, one, q, ldq, work, 1, zero,
477 $ z( 1, j ), 1 )
478 20 CONTINUE
479 END IF
480*
481 30 CONTINUE
482*
483* If eigenvalues are not in order, then sort them, along with
484* eigenvectors.
485*
486 IF( wantz ) THEN
487 DO 50 j = 1, m - 1
488 i = 0
489 tmp1 = w( j )
490 DO 40 jj = j + 1, m
491 IF( w( jj ).LT.tmp1 ) THEN
492 i = jj
493 tmp1 = w( jj )
494 END IF
495 40 CONTINUE
496*
497 IF( i.NE.0 ) THEN
498 itmp1 = iwork( 1 + i-1 )
499 w( i ) = w( j )
500 iwork( 1 + i-1 ) = iwork( 1 + j-1 )
501 w( j ) = tmp1
502 iwork( 1 + j-1 ) = itmp1
503 CALL dswap( n, z( 1, i ), 1, z( 1, j ), 1 )
504 IF( info.NE.0 ) THEN
505 itmp1 = ifail( i )
506 ifail( i ) = ifail( j )
507 ifail( j ) = itmp1
508 END IF
509 END IF
510 50 CONTINUE
511 END IF
512*
513 RETURN
514*
515* End of DSBGVX
516*
517 END
subroutine xerbla(srname, info)
Definition cblat2.f:3285
subroutine dcopy(n, dx, incx, dy, incy)
DCOPY
Definition dcopy.f:82
subroutine dgemv(trans, m, n, alpha, a, lda, x, incx, beta, y, incy)
DGEMV
Definition dgemv.f:158
subroutine dsbgst(vect, uplo, n, ka, kb, ab, ldab, bb, ldbb, x, ldx, work, info)
DSBGST
Definition dsbgst.f:158
subroutine dsbgvx(jobz, range, uplo, n, ka, kb, ab, ldab, bb, ldbb, q, ldq, vl, vu, il, iu, abstol, m, w, z, ldz, work, iwork, ifail, info)
DSBGVX
Definition dsbgvx.f:292
subroutine dsbtrd(vect, uplo, n, kd, ab, ldab, d, e, q, ldq, work, info)
DSBTRD
Definition dsbtrd.f:161
subroutine dlacpy(uplo, m, n, a, lda, b, ldb)
DLACPY copies all or part of one two-dimensional array to another.
Definition dlacpy.f:101
subroutine dpbstf(uplo, n, kd, ab, ldab, info)
DPBSTF
Definition dpbstf.f:150
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 dstein(n, d, e, m, w, iblock, isplit, z, ldz, work, iwork, ifail, info)
DSTEIN
Definition dstein.f:172
subroutine dsteqr(compz, n, d, e, z, ldz, work, info)
DSTEQR
Definition dsteqr.f:129
subroutine dsterf(n, d, e, info)
DSTERF
Definition dsterf.f:84
subroutine dswap(n, dx, incx, dy, incy)
DSWAP
Definition dswap.f:82