SRC/zhpgvx.f(3)

πŸ’… NAME πŸ’…

SRC/zhpgvx.f β€” bestie, this is the LAPACK routine zhpgvx, and it's literally out here computing selected eigenvalues and (optionally!) eigenvectors of a complex generalized Hermitian-definite eigenproblem. Sound like a lot? It is. But we're gonna get through it together 🫢


✨ SYNOPSIS ✨

Functions/Subroutines

subroutine zhpgvx (itype, jobz, range, uplo, n, ap, bp, vl, vu, il, iu,
    abstol, m, w, z, ldz, work, rwork, iwork, ifail, info)

ZHPGVX β€” that's her name, that's her whole brand πŸ‘‘


πŸ¦‹ Function/Subroutine Documentation πŸ¦‹

subroutine zhpgvx β€” the full signature, no cap

subroutine zhpgvx (integer itype, character jobz, character range, character
    uplo, integer n, complex*16, dimension( * ) ap, complex*16, dimension( *
    ) bp, double precision vl, double precision vu, integer il, integer iu,
    double precision abstol, integer m, double precision, dimension( * ) w,
    complex*16, dimension( ldz, * ) z, integer ldz, complex*16, dimension( *
    ) work, double precision, dimension( * ) rwork, integer, dimension( * )
    iwork, integer, dimension( * ) ifail, integer info)

ZHPGVX

πŸŽ€ Purpose πŸŽ€

!> !> ZHPGVX computes selected eigenvalues and, optionally, 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, stored in packed format, and B is also !> positive definite. Eigenvalues and eigenvectors can be selected by !> specifying either a range of values or a range of indices for the !> desired eigenvalues. !>

So like β€” A and B are Hermitian, they're living their packed-format life, B is also positive definite (she's gotta be, it's the rules), and you get to pick which eigenvalues you want. Main character selection energy, honestly.

🌸 Parameters 🌸

  • ITYPE β€” ITYPE is INTEGER. It's the problem type, and she comes in three flavors:
!> 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 !>
  • JOBZ β€” JOBZ is CHARACTER*1, aka the "do you want the eigenvectors or nah" switch:
!> = 'N': Compute eigenvalues only; !> = 'V': Compute eigenvalues and eigenvectors. !>
  • RANGE β€” RANGE is CHARACTER*1, the picker:
!> = 'A': all eigenvalues will be found; !> = 'V': all eigenvalues in the half-open interval (VL,VU] !> will be found; !> = 'I': the IL-th through IU-th eigenvalues will be found. !>
  • UPLO β€” UPLO is CHARACTER*1, which triangle of A and B is stored:
!> = 'U': Upper triangles of A and B are stored; !> = 'L': Lower triangles of A and B are stored. !>
  • N β€” N is INTEGER. The order of the matrices A and B. N >= 0. That's it, that's the whole vibe check.
  • AP β€” AP is COMPLEX*16 array, dimension (N*(N+1)/2)
!> On entry, the upper or lower triangle of the Hermitian matrix !> A, packed columnwise in a linear array. The j-th column of A !> is stored in the array AP as follows: !> if UPLO = 'U', AP(i + (j-1)j/2) = A(i,j) for 1<=i<=j; !> if UPLO = 'L', AP(i + (j-1)(2*n-j)/2) = A(i,j) for j<=i<=n. !> !> On exit, the contents of AP are destroyed. !>

⚠️ Yes bestie, destroyed. On exit AP is gone-gone. Do not come looking for her.

  • BP β€” BP is COMPLEX*16 array, dimension (N*(N+1)/2)
!> On entry, the upper or lower triangle of the Hermitian matrix !> B, packed columnwise in a linear array. The j-th column of B !> is stored in the array BP as follows: !> if UPLO = 'U', BP(i + (j-1)j/2) = B(i,j) for 1<=i<=j; !> if UPLO = 'L', BP(i + (j-1)(2*n-j)/2) = B(i,j) for j<=i<=n. !> !> On exit, the triangular factor U or L from the Cholesky !> factorization B = UH*U or B = L*LH, in the same storage !> format as B. !>

So BP gets a glow-up on exit: she comes back as the triangular factor U or L from the Cholesky factorization B = U**H*U or B = L*L**H, same storage format as before. Iconic transformation arc πŸ’«

  • VL β€” VL is DOUBLE PRECISION
!> !> If RANGE='V', the lower bound of the interval to !> be searched for eigenvalues. VL < VU. !> Not referenced if RANGE = 'A' or 'I'. !>
  • VU β€” VU is DOUBLE PRECISION
!> !> If RANGE='V', the upper bound of the interval to !> be searched for eigenvalues. VL < VU. !> Not referenced if RANGE = 'A' or 'I'. !>

Note the duo: VL < VU, strictly. No equality shenanigans.

  • IL β€” IL is INTEGER
!> !> If RANGE='I', the index of the !> smallest eigenvalue to be returned. !> 1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0. !> Not referenced if RANGE = 'A' or 'V'. !>
  • IU β€” IU is INTEGER
!> !> If RANGE='I', the index of the !> largest eigenvalue to be returned. !> 1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0. !> Not referenced if RANGE = 'A' or 'V'. !>
  • ABSTOL β€” ABSTOL is DOUBLE PRECISION. The absolute error tolerance for the eigenvalues. She's the "close enough is close enough" queen:
!> An approximate eigenvalue is accepted as converged !> when it is determined to lie in an interval [a,b] !> of width less than or equal to !> !> ABSTOL + EPS * max( |a|,|b| ) , !> !> where EPS is the machine precision. If ABSTOL is less than !> or equal to zero, then EPS*|T| will be used in its place, !> where |T| is the 1-norm of the tridiagonal matrix obtained !> by reducing AP to tridiagonal form. !> !> Eigenvalues will be computed most accurately when ABSTOL is !> set to twice the underflow threshold 2*DLAMCH('S'), not zero. !> If this routine returns with INFO>0, indicating that some !> eigenvectors did not converge, try setting ABSTOL to !> 2*DLAMCH('S'). !>

🎯 Real talk: set it to 2*DLAMCH('S') for max accuracy, not zero. And if it comes back with INFO>0 (some eigenvectors didn't converge), your move is setting ABSTOL to 2*DLAMCH('S'). That's the tip, take it.

  • M β€” M is INTEGER. The total number of eigenvalues found. 0 <= M <= N. If RANGE = 'A', M = N, and if RANGE = 'I', M = IU-IL+1.
  • W β€” W is DOUBLE PRECISION array, dimension (N)
!> On normal exit, the first M elements contain the selected !> eigenvalues in ascending order. !>

Ascending order, as she should πŸ“ˆ

  • Z β€” Z is COMPLEX*16 array, dimension (LDZ, N)
!> If JOBZ = 'N', then Z is not referenced. !> If JOBZ = 'V', then if INFO = 0, the first M columns of Z !> contain the orthonormal eigenvectors of the matrix A !> corresponding to the selected eigenvalues, with the i-th !> column of Z holding the eigenvector associated with W(i). !> The eigenvectors are normalized as follows: !> if ITYPE = 1 or 2, ZH*B*Z = I; !> if ITYPE = 3, ZH*inv(B)*Z = I. !> !> If an eigenvector fails to converge, then that column of Z !> contains the latest approximation to the eigenvector, and the !> index of the eigenvector is returned in IFAIL. !> Note: the user must ensure that at least max(1,M) columns are !> supplied in the array Z; if RANGE = 'V', the exact value of M !> is not known in advance and an upper bound must be used. !>

🚨 Pay attention to that note, bestie: you have to make sure at least max(1,M) columns are supplied in Z. And if RANGE = 'V', the exact value of M isn't known in advance so you gotta use an upper bound. Don't get caught lacking.

  • LDZ β€” LDZ is INTEGER. The leading dimension of the array Z. LDZ >= 1, and if JOBZ = 'V', LDZ >= max(1,N).
  • WORK β€” WORK is COMPLEX*16 array, dimension (2*N)
  • RWORK β€” RWORK is DOUBLE PRECISION array, dimension (7*N)
  • IWORK β€” IWORK is INTEGER array, dimension (5*N)

The workspace trio πŸ’… they don't do much talking, they just hold space. Respect.

  • IFAIL β€” IFAIL is INTEGER array, dimension (N)
!> If JOBZ = 'V', then if INFO = 0, the first M elements of !> IFAIL are zero. If INFO > 0, then IFAIL contains the !> indices of the eigenvectors that failed to converge. !> If JOBZ = 'N', then IFAIL is not referenced. !>

The receipts array. If something flopped, the indices are in here πŸ“‹

  • INFO β€” INFO is INTEGER, the final verdict:
!> = 0: successful exit !> < 0: if INFO = -i, the i-th argument had an illegal value !> > 0: ZPPTRF or ZHPEVX returned an error code: !> <= N: if INFO = i, ZHPEVX failed to converge; !> i eigenvectors failed to converge. Their indices !> are stored in array IFAIL. !> > N: if INFO = N + i, for 1 <= i <= n, then the leading !> principal minor of order i of B is not positive. !> The factorization of B could not be completed and !> no eigenvalues or eigenvectors were computed. !>

⚠️ Read the > N case carefully: if INFO = N + i for 1 <= i <= n, the leading principal minor of order i of B is not positive β€” the factorization of B could not be completed and no eigenvalues or eigenvectors were computed. Nothing. Zero. Zilch. 😭

πŸ‘‘ Author πŸ‘‘

  • Univ. of Tennessee
  • Univ. of California Berkeley
  • Univ. of Colorado Denver
  • NAG Ltd.

🧚 Contributors: 🧚

Mark Fahey, Department of Mathematics, Univ. of Kentucky, USA

⭐ Definition ⭐

Definition at line 274 of file zhpgvx.f.


🌈 Author 🌈

Generated automatically by Doxygen for LAPACK from the source code.


And that's the whole page, bestie β€” no notes, no crumbs, periodt πŸ’…βœ¨

Sign-off szn: this glamorous little document is LAPACK, Version 3.12.0, dated SRC/zhpgvx.f(3) πŸŽ€ Go forth and diagonalize responsibly πŸ¦‹

πŸ“¦ where this page comes from