LAPACK  3.10.0
LAPACK: Linear Algebra PACKage

◆ chegvd()

subroutine chegvd ( integer  ITYPE,
character  JOBZ,
character  UPLO,
integer  N,
complex, dimension( lda, * )  A,
integer  LDA,
complex, dimension( ldb, * )  B,
integer  LDB,
real, dimension( * )  W,
complex, dimension( * )  WORK,
integer  LWORK,
real, dimension( * )  RWORK,
integer  LRWORK,
integer, dimension( * )  IWORK,
integer  LIWORK,
integer  INFO 
)

CHEGVD

Download CHEGVD + dependencies [TGZ] [ZIP] [TXT]

Purpose:
 CHEGVD computes all the eigenvalues, and optionally, the eigenvectors
 of a complex generalized Hermitian-definite eigenproblem, of the form
 A*x=(lambda)*B*x,  A*Bx=(lambda)*x,  or B*A*x=(lambda)*x.  Here A and
 B are assumed to be Hermitian and B is also positive definite.
 If eigenvectors are desired, it uses a divide and conquer algorithm.

 The divide and conquer algorithm makes very mild assumptions about
 floating point arithmetic. It will work on machines with a guard
 digit in add/subtract, or on those binary machines without guard
 digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or
 Cray-2. It could conceivably fail on hexadecimal or decimal machines
 without guard digits, but we know of none.
Parameters
[in]ITYPE
          ITYPE is INTEGER
          Specifies the problem type to be solved:
          = 1:  A*x = (lambda)*B*x
          = 2:  A*B*x = (lambda)*x
          = 3:  B*A*x = (lambda)*x
[in]JOBZ
          JOBZ is CHARACTER*1
          = 'N':  Compute eigenvalues only;
          = 'V':  Compute eigenvalues and eigenvectors.
[in]UPLO
          UPLO is CHARACTER*1
          = 'U':  Upper triangles of A and B are stored;
          = 'L':  Lower triangles of A and B are stored.
[in]N
          N is INTEGER
          The order of the matrices A and B.  N >= 0.
[in,out]A
          A is COMPLEX array, dimension (LDA, N)
          On entry, the Hermitian matrix A.  If UPLO = 'U', the
          leading N-by-N upper triangular part of A contains the
          upper triangular part of the matrix A.  If UPLO = 'L',
          the leading N-by-N lower triangular part of A contains
          the lower triangular part of the matrix A.

          On exit, if JOBZ = 'V', then if INFO = 0, A contains the
          matrix Z of eigenvectors.  The eigenvectors are normalized
          as follows:
          if ITYPE = 1 or 2, Z**H*B*Z = I;
          if ITYPE = 3, Z**H*inv(B)*Z = I.
          If JOBZ = 'N', then on exit the upper triangle (if UPLO='U')
          or the lower triangle (if UPLO='L') of A, including the
          diagonal, is destroyed.
[in]LDA
          LDA is INTEGER
          The leading dimension of the array A.  LDA >= max(1,N).
[in,out]B
          B is COMPLEX array, dimension (LDB, N)
          On entry, the Hermitian matrix B.  If UPLO = 'U', the
          leading N-by-N upper triangular part of B contains the
          upper triangular part of the matrix B.  If UPLO = 'L',
          the leading N-by-N lower triangular part of B contains
          the lower triangular part of the matrix B.

          On exit, if INFO <= N, the part of B containing the matrix is
          overwritten by the triangular factor U or L from the Cholesky
          factorization B = U**H*U or B = L*L**H.
[in]LDB
          LDB is INTEGER
          The leading dimension of the array B.  LDB >= max(1,N).
[out]W
          W is REAL array, dimension (N)
          If INFO = 0, the eigenvalues in ascending order.
[out]WORK
          WORK is COMPLEX array, dimension (MAX(1,LWORK))
          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
[in]LWORK
          LWORK is INTEGER
          The length of the array WORK.
          If N <= 1,                LWORK >= 1.
          If JOBZ  = 'N' and N > 1, LWORK >= N + 1.
          If JOBZ  = 'V' and N > 1, LWORK >= 2*N + N**2.

          If LWORK = -1, then a workspace query is assumed; the routine
          only calculates the optimal sizes of the WORK, RWORK and
          IWORK arrays, returns these values as the first entries of
          the WORK, RWORK and IWORK arrays, and no error message
          related to LWORK or LRWORK or LIWORK is issued by XERBLA.
[out]RWORK
          RWORK is REAL array, dimension (MAX(1,LRWORK))
          On exit, if INFO = 0, RWORK(1) returns the optimal LRWORK.
[in]LRWORK
          LRWORK is INTEGER
          The dimension of the array RWORK.
          If N <= 1,                LRWORK >= 1.
          If JOBZ  = 'N' and N > 1, LRWORK >= N.
          If JOBZ  = 'V' and N > 1, LRWORK >= 1 + 5*N + 2*N**2.

          If LRWORK = -1, then a workspace query is assumed; the
          routine only calculates the optimal sizes of the WORK, RWORK
          and IWORK arrays, returns these values as the first entries
          of the WORK, RWORK and IWORK arrays, and no error message
          related to LWORK or LRWORK or LIWORK is issued by XERBLA.
[out]IWORK
          IWORK is INTEGER array, dimension (MAX(1,LIWORK))
          On exit, if INFO = 0, IWORK(1) returns the optimal LIWORK.
[in]LIWORK
          LIWORK is INTEGER
          The dimension of the array IWORK.
          If N <= 1,                LIWORK >= 1.
          If JOBZ  = 'N' and N > 1, LIWORK >= 1.
          If JOBZ  = 'V' and N > 1, LIWORK >= 3 + 5*N.

          If LIWORK = -1, then a workspace query is assumed; the
          routine only calculates the optimal sizes of the WORK, RWORK
          and IWORK arrays, returns these values as the first entries
          of the WORK, RWORK and IWORK arrays, and no error message
          related to LWORK or LRWORK or LIWORK is issued by XERBLA.
[out]INFO
          INFO is INTEGER
          = 0:  successful exit
          < 0:  if INFO = -i, the i-th argument had an illegal value
          > 0:  CPOTRF or CHEEVD returned an error code:
             <= N:  if INFO = i and JOBZ = 'N', then the algorithm
                    failed to converge; i off-diagonal elements of an
                    intermediate tridiagonal form did not converge to
                    zero;
                    if INFO = i and JOBZ = 'V', then the algorithm
                    failed to compute an eigenvalue while working on
                    the submatrix lying in rows and columns INFO/(N+1)
                    through mod(INFO,N+1);
             > N:   if INFO = N + i, for 1 <= i <= N, then the leading
                    minor of order i of B is not positive definite.
                    The factorization of B could not be completed and
                    no eigenvalues or eigenvectors were computed.
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Further Details:
  Modified so that no backsubstitution is performed if CHEEVD fails to
  converge (NEIG in old code could be greater than N causing out of
  bounds reference to A - reported by Ralf Meyer).  Also corrected the
  description of INFO and the test on ITYPE. Sven, 16 Feb 05.
Contributors:
Mark Fahey, Department of Mathematics, Univ. of Kentucky, USA

Definition at line 247 of file chegvd.f.

249 *
250 * -- LAPACK driver routine --
251 * -- LAPACK is a software package provided by Univ. of Tennessee, --
252 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
253 *
254 * .. Scalar Arguments ..
255  CHARACTER JOBZ, UPLO
256  INTEGER INFO, ITYPE, LDA, LDB, LIWORK, LRWORK, LWORK, N
257 * ..
258 * .. Array Arguments ..
259  INTEGER IWORK( * )
260  REAL RWORK( * ), W( * )
261  COMPLEX A( LDA, * ), B( LDB, * ), WORK( * )
262 * ..
263 *
264 * =====================================================================
265 *
266 * .. Parameters ..
267  COMPLEX CONE
268  parameter( cone = ( 1.0e+0, 0.0e+0 ) )
269 * ..
270 * .. Local Scalars ..
271  LOGICAL LQUERY, UPPER, WANTZ
272  CHARACTER TRANS
273  INTEGER LIOPT, LIWMIN, LOPT, LROPT, LRWMIN, LWMIN
274 * ..
275 * .. External Functions ..
276  LOGICAL LSAME
277  EXTERNAL lsame
278 * ..
279 * .. External Subroutines ..
280  EXTERNAL cheevd, chegst, cpotrf, ctrmm, ctrsm, xerbla
281 * ..
282 * .. Intrinsic Functions ..
283  INTRINSIC max, real
284 * ..
285 * .. Executable Statements ..
286 *
287 * Test the input parameters.
288 *
289  wantz = lsame( jobz, 'V' )
290  upper = lsame( uplo, 'U' )
291  lquery = ( lwork.EQ.-1 .OR. lrwork.EQ.-1 .OR. liwork.EQ.-1 )
292 *
293  info = 0
294  IF( n.LE.1 ) THEN
295  lwmin = 1
296  lrwmin = 1
297  liwmin = 1
298  ELSE IF( wantz ) THEN
299  lwmin = 2*n + n*n
300  lrwmin = 1 + 5*n + 2*n*n
301  liwmin = 3 + 5*n
302  ELSE
303  lwmin = n + 1
304  lrwmin = n
305  liwmin = 1
306  END IF
307  lopt = lwmin
308  lropt = lrwmin
309  liopt = liwmin
310  IF( itype.LT.1 .OR. itype.GT.3 ) THEN
311  info = -1
312  ELSE IF( .NOT.( wantz .OR. lsame( jobz, 'N' ) ) ) THEN
313  info = -2
314  ELSE IF( .NOT.( upper .OR. lsame( uplo, 'L' ) ) ) THEN
315  info = -3
316  ELSE IF( n.LT.0 ) THEN
317  info = -4
318  ELSE IF( lda.LT.max( 1, n ) ) THEN
319  info = -6
320  ELSE IF( ldb.LT.max( 1, n ) ) THEN
321  info = -8
322  END IF
323 *
324  IF( info.EQ.0 ) THEN
325  work( 1 ) = lopt
326  rwork( 1 ) = lropt
327  iwork( 1 ) = liopt
328 *
329  IF( lwork.LT.lwmin .AND. .NOT.lquery ) THEN
330  info = -11
331  ELSE IF( lrwork.LT.lrwmin .AND. .NOT.lquery ) THEN
332  info = -13
333  ELSE IF( liwork.LT.liwmin .AND. .NOT.lquery ) THEN
334  info = -15
335  END IF
336  END IF
337 *
338  IF( info.NE.0 ) THEN
339  CALL xerbla( 'CHEGVD', -info )
340  RETURN
341  ELSE IF( lquery ) THEN
342  RETURN
343  END IF
344 *
345 * Quick return if possible
346 *
347  IF( n.EQ.0 )
348  $ RETURN
349 *
350 * Form a Cholesky factorization of B.
351 *
352  CALL cpotrf( uplo, n, b, ldb, info )
353  IF( info.NE.0 ) THEN
354  info = n + info
355  RETURN
356  END IF
357 *
358 * Transform problem to standard eigenvalue problem and solve.
359 *
360  CALL chegst( itype, uplo, n, a, lda, b, ldb, info )
361  CALL cheevd( jobz, uplo, n, a, lda, w, work, lwork, rwork, lrwork,
362  $ iwork, liwork, info )
363  lopt = max( real( lopt ), real( work( 1 ) ) )
364  lropt = max( real( lropt ), real( rwork( 1 ) ) )
365  liopt = max( real( liopt ), real( iwork( 1 ) ) )
366 *
367  IF( wantz .AND. info.EQ.0 ) THEN
368 *
369 * Backtransform eigenvectors to the original problem.
370 *
371  IF( itype.EQ.1 .OR. itype.EQ.2 ) THEN
372 *
373 * For A*x=(lambda)*B*x and A*B*x=(lambda)*x;
374 * backtransform eigenvectors: x = inv(L)**H *y or inv(U)*y
375 *
376  IF( upper ) THEN
377  trans = 'N'
378  ELSE
379  trans = 'C'
380  END IF
381 *
382  CALL ctrsm( 'Left', uplo, trans, 'Non-unit', n, n, cone,
383  $ b, ldb, a, lda )
384 *
385  ELSE IF( itype.EQ.3 ) THEN
386 *
387 * For B*A*x=(lambda)*x;
388 * backtransform eigenvectors: x = L*y or U**H *y
389 *
390  IF( upper ) THEN
391  trans = 'C'
392  ELSE
393  trans = 'N'
394  END IF
395 *
396  CALL ctrmm( 'Left', uplo, trans, 'Non-unit', n, n, cone,
397  $ b, ldb, a, lda )
398  END IF
399  END IF
400 *
401  work( 1 ) = lopt
402  rwork( 1 ) = lropt
403  iwork( 1 ) = liopt
404 *
405  RETURN
406 *
407 * End of CHEGVD
408 *
subroutine xerbla(SRNAME, INFO)
XERBLA
Definition: xerbla.f:60
logical function lsame(CA, CB)
LSAME
Definition: lsame.f:53
subroutine ctrmm(SIDE, UPLO, TRANSA, DIAG, M, N, ALPHA, A, LDA, B, LDB)
CTRMM
Definition: ctrmm.f:177
subroutine ctrsm(SIDE, UPLO, TRANSA, DIAG, M, N, ALPHA, A, LDA, B, LDB)
CTRSM
Definition: ctrsm.f:180
subroutine chegst(ITYPE, UPLO, N, A, LDA, B, LDB, INFO)
CHEGST
Definition: chegst.f:128
subroutine cheevd(JOBZ, UPLO, N, A, LDA, W, WORK, LWORK, RWORK, LRWORK, IWORK, LIWORK, INFO)
CHEEVD computes the eigenvalues and, optionally, the left and/or right eigenvectors for HE matrices
Definition: cheevd.f:205
subroutine cpotrf(UPLO, N, A, LDA, INFO)
CPOTRF
Definition: cpotrf.f:107
Here is the call graph for this function:
Here is the caller graph for this function: