ggevx(3)

πŸ’… ggevx(3) β€” Library Functions Manual πŸ’…

okay bestie, this is the ggevx(3) page from the Library Functions Manual, and it is very expert-eig-coded. no cap. let’s get into it πŸ’–


🌸 NAME 🌸

ggevx β€” ggevx: eig, expert


✨ SYNOPSIS ✨

okay so this page is giving β€œa whole little family of subroutines,” and they all compute eigenvalues and, optionally, the left and/or right eigenvectors for GE matrices. iconic behavior, honestly 🫢

🧚 Functions 🧚

  • subroutine cggevx (...)
subroutine cggevx (balanc, jobvl, jobvr, sense, n, a, lda, b, ldb,
           alpha, beta, vl, ldvl, vr, ldvr, ilo, ihi, lscale, rscale, abnrm,
           bbnrm, rconde, rcondv, work, lwork, rwork, iwork, bwork, info)

CGGEVX computes the eigenvalues and, optionally, the left and/or right eigenvectors for GE matrices

  • subroutine dggevx (...)
subroutine dggevx (balanc, jobvl, jobvr, sense, n, a, lda, b, ldb,
           alphar, alphai, beta, vl, ldvl, vr, ldvr, ilo, ihi, lscale, rscale,
           abnrm, bbnrm, rconde, rcondv, work, lwork, iwork, bwork, info)

DGGEVX computes the eigenvalues and, optionally, the left and/or right eigenvectors for GE matrices

  • subroutine sggevx (...)
subroutine sggevx (balanc, jobvl, jobvr, sense, n, a, lda, b, ldb,
           alphar, alphai, beta, vl, ldvl, vr, ldvr, ilo, ihi, lscale, rscale,
           abnrm, bbnrm, rconde, rcondv, work, lwork, iwork, bwork, info)

SGGEVX computes the eigenvalues and, optionally, the left and/or right eigenvectors for GE matrices

  • subroutine zggevx (...)
subroutine zggevx (balanc, jobvl, jobvr, sense, n, a, lda, b, ldb,
           alpha, beta, vl, ldvl, vr, ldvr, ilo, ihi, lscale, rscale, abnrm,
           bbnrm, rconde, rcondv, work, lwork, rwork, iwork, bwork, info)

ZGGEVX computes the eigenvalues and, optionally, the left and/or right eigenvectors for GE matrices


🫢 Detailed Description 🫢

this is the part where the page says β€œokay, function docs time,” and honestly that is the vibe. we are heading straight into the cggevx breakdown, bestie. ✨

πŸ’– Function Documentation πŸ’–

🌟 subroutine cggevx 🌟

subroutine cggevx (character balanc, character jobvl, character jobvr,
     character sense, integer n, complex, dimension( lda, * ) a, integer lda,
     complex, dimension( ldb, * ) b, integer ldb, complex, dimension( * )
     alpha, complex, dimension( * ) beta, complex, dimension( ldvl, * ) vl,
     integer ldvl, complex, dimension( ldvr, * ) vr, integer ldvr, integer
     ilo, integer ihi, real, dimension( * ) lscale, real, dimension( * )
     rscale, real abnrm, real bbnrm, real, dimension( * ) rconde, real,
     dimension( * ) rcondv, complex, dimension( * ) work, integer lwork,
     real, dimension( * ) rwork, integer, dimension( * ) iwork, logical,
     dimension( * ) bwork, integer info)

CGGEVX computes the eigenvalues and, optionally, the left and/or right eigenvectors for GE matrices

🎯 Purpose 🎯

CGGEVX computes, for a pair of N-by-N complex nonsymmetric matrices (A,B), the generalized eigenvalues, and optionally, the left and/or right generalized eigenvectors. πŸ’…

Optionally, it also computes a balancing transformation to improve the conditioning of the eigenvalues and eigenvectors (ILO, IHI, LSCALE, RSCALE, ABNRM, and BBNRM), reciprocal condition numbers for the eigenvalues (RCONDE), and reciprocal condition numbers for the right eigenvectors (RCONDV). πŸŽ€

A generalized eigenvalue for a pair of matrices (A,B) is a scalar lambda or a ratio alpha/beta = lambda, such that A - lambda*B is singular. It is usually represented as the pair (alpha,beta), as there is a reasonable interpretation for beta=0, and even for both being zero. bestie, that zero-beta situation is not a typo, it’s just giving generalized eigenvalue realness. πŸ¦‹

The right eigenvector v(j) corresponding to the eigenvalue lambda(j) of (A,B) satisfies

A * v(j) = lambda(j) * B * v(j) .

The left eigenvector u(j) corresponding to the eigenvalue lambda(j) of (A,B) satisfies

u(j)**H * A  = lambda(j) * u(j)**H * B.

where u(j)**H is the conjugate-transpose of u(j).

πŸ” Parameters πŸ”

  • BALANC β€” BALANC is CHARACTER*1. Specifies the balance option to be performed:
    • = 'N': do not diagonally scale or permute;
    • = 'P': permute only;
    • = 'S': scale only;
    • = 'B': both permute and scale.

Computed reciprocal condition numbers will be for the matrices after permuting and/or balancing. Permuting does not change condition numbers (in exact arithmetic), but balancing does.

  • JOBVL β€” JOBVL is CHARACTER*1
    • = 'N': do not compute the left generalized eigenvectors;
    • = 'V': compute the left generalized eigenvectors.
  • JOBVR β€” JOBVR is CHARACTER*1
    • = 'N': do not compute the right generalized eigenvectors;
    • = 'V': compute the right generalized eigenvectors.
  • SENSE β€” SENSE is CHARACTER*1. Determines which reciprocal condition numbers are computed.
    • = 'N': none are computed;
    • = 'E': computed for eigenvalues only;
    • = 'V': computed for eigenvectors only;
    • = 'B': computed for eigenvalues and eigenvectors.
  • N β€” N is INTEGER. The order of the matrices A, B, VL, and VR. N >= 0.
  • A β€” A is COMPLEX array, dimension (LDA, N)
    • On entry, the matrix A in the pair (A,B).
    • On exit, A has been overwritten. If JOBVL='V' or JOBVR='V' or both, then A contains the first part of the complex Schur form of the versions of the input A and B.
  • LDA β€” LDA is INTEGER. The leading dimension of A. LDA >= max(1,N).
  • B β€” B is COMPLEX array, dimension (LDB, N)
    • On entry, the matrix B in the pair (A,B).
    • On exit, B has been overwritten. If JOBVL='V' or JOBVR='V' or both, then B contains the second part of the complex Schur form of the versions of the input A and B.
  • LDB β€” LDB is INTEGER. The leading dimension of B. LDB >= max(1,N).
  • ALPHA β€” ALPHA is COMPLEX array, dimension (N)
  • BETA β€” BETA is COMPLEX array, dimension (N). On exit, ALPHA(j)/BETA(j), j=1,...,N, will be the generalized eigenvalues.

Note: the quotient ALPHA(j)/BETA(j) ) may easily over- or underflow, and BETA(j) may even be zero. Thus, the user should avoid naively computing the ratio ALPHA/BETA. However, ALPHA will be always less than and usually comparable with norm(A) in magnitude, and BETA always less than and usually comparable with norm(B).

  • VL β€” VL is COMPLEX array, dimension (LDVL,N). If JOBVL = 'V', the left generalized eigenvectors u(j) are stored one after another in the columns of VL, in the same order as their eigenvalues. Each eigenvector will be scaled so the largest component will have abs(real part) + abs(imag. part) = 1. Not referenced if JOBVL = 'N'.
  • LDVL β€” LDVL is INTEGER. The leading dimension of the matrix VL. LDVL >= 1, and if JOBVL = 'V', LDVL >= N.
  • VR β€” VR is COMPLEX array, dimension (LDVR,N). If JOBVR = 'V', the right generalized eigenvectors v(j) are stored one after another in the columns of VR, in the same order as their eigenvalues. Each eigenvector will be scaled so the largest component will have abs(real part) + abs(imag. part) = 1. Not referenced if JOBVR = 'N'.
  • LDVR β€” LDVR is INTEGER. The leading dimension of the matrix VR. LDVR >= 1, and if JOBVR = 'V', LDVR >= N.
  • ILO β€” ILO is INTEGER
  • IHI β€” IHI is INTEGER. ILO and IHI are integer values such that on exit A(i,j) = 0 and B(i,j) = 0 if i > j and j = 1,...,ILO-1 or i = IHI+1,...,N. If BALANC = 'N' or 'S', ILO = 1 and IHI = N.
  • LSCALE β€” LSCALE is REAL array, dimension (N). Details of the permutations and scaling factors applied to the left side of A and B. If PL(j) is the index of the row interchanged with row j, and DL(j) is the scaling factor applied to row j, then
LSCALE(j) = PL(j)  for j = 1,...,ILO-1
          = DL(j)  for j = ILO,...,IHI
          = PL(j)  for j = IHI+1,...,N.

The order in which the interchanges are made is N to IHI+1, then 1 to ILO-1.

  • RSCALE β€” RSCALE is REAL array, dimension (N). Details of the permutations and scaling factors applied to the right side of A and B. If PR(j) is the index of the column interchanged with column j, and DR(j) is the scaling factor applied to column j, then
RSCALE(j) = PR(j)  for j = 1,...,ILO-1
          = DR(j)  for j = ILO,...,IHI
          = PR(j)  for j = IHI+1,...,N

The order in which the interchanges are made is N to IHI+1, then 1 to ILO-1.

  • ABNRM β€” ABNRM is REAL. The one-norm of the balanced matrix A.
  • BBNRM β€” BBNRM is REAL. The one-norm of the balanced matrix B.
  • RCONDE β€” RCONDE is REAL array, dimension (N). If SENSE = 'E' or 'B', the reciprocal condition numbers of the eigenvalues, stored in consecutive elements of the array. If SENSE = 'N' or 'V', RCONDE is not referenced.
  • RCONDV β€” RCONDV is REAL array, dimension (N). If SENSE = 'V' or 'B', the estimated reciprocal condition numbers of the eigenvectors, stored in consecutive elements of the array. If the eigenvalues cannot be reordered to compute RCONDV(j), RCONDV(j) is set to 0; this can only occur when the true value would be very small anyway. If SENSE = 'N' or 'E', RCONDV is not referenced.
  • WORK β€” WORK is COMPLEX array, dimension (MAX(1,LWORK)). On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
  • LWORK β€”
  • LWORK β€” INTEGER, the dimension of the WORK array. How much room you're giving it to vibe in. Minimums, no cap: LWORK >= max(1,2*N) in general, LWORK >= max(1,4*N) if SENSE = 'E', and LWORK >= max(1,2*N*N+2*N) if SENSE = 'V' or 'B'.

And the iconic part: if LWORK = -1, a workspace query is assumed β€” the routine literally only calculates the optimal size of the WORK array, returns that value as the first entry of the WORK array, and XERBLA does not issue any error message related to LWORK. It's giving "ask me what I need and I'll tell you" πŸ’…

  • RWORK β€” RWORK is REAL array, dimension (lrwork). And lrwork must be at least max(1,6*N) if BALANC = 'S' or 'B', and at least max(1,2*N) otherwise. Real workspace, real ones know.
  • IWORK β€” IWORK is INTEGER array, dimension (N+2). But bestie β€” if SENSE = 'E', IWORK is not referenced. She's off duty that day 🫢
  • BWORK β€” BWORK is LOGICAL array, dimension (N). Same deal: if SENSE = 'N', BWORK is not referenced. Unbothered, moisturized, not called.
  • INFO β€” INFO is INTEGER, the receipts:
    • = 0: successful exit πŸŽ‰
    • < 0: if INFO = -i, the i-th argument had an illegal value. Rude of you, honestly.
    • = 1,...,N: The QZ iteration failed. No eigenvectors have been calculated, but ALPHA(j) and BETA(j) should be correct for j=INFO+1,...,N. So like β€” partial credit, the eigenvalues made it, the eigenvectors ghosted 😭
    • > N:
      • =N+1: other than QZ iteration failed in CHGEQZ.
      • =N+2: error return from CTGEVC.

πŸ‘‘ Author πŸ‘‘

Univ. of Tennessee

Univ. of California Berkeley

Univ. of Colorado Denver

NAG Ltd.

Like, four whole institutions collaborated on this. Main character energy across state lines πŸ’–


✨ Further Details ✨

Okay so here's the tea about balancing a matrix pair (A,B). It happens in two steps: first, permuting rows and columns to isolate eigenvalues; second, applying a diagonal similarity transformation to the rows and columns so they end up as close in norm as possible. Slay. The computed reciprocal condition numbers correspond to the balanced matrix. Permuting rows and columns won't change the condition numbers (in exact arithmetic) β€” but diagonal scaling will. So keep that in mind. For further explanation of balancing, see section 4.11.1.2 of LAPACK Users' Guide.

Now, an approximate error bound on the chordal distance between the i-th computed generalized eigenvalue w and the corresponding exact eigenvalue lambda is:

chord(w, lambda) <= EPS * norm(ABNRM, BBNRM) / RCONDE(I)

And an approximate error bound for the angle between the i-th computed eigenvector VL(i) or VR(i) is given by:

EPS * norm(ABNRM, BBNRM) / DIF(i).

For further explanation of the reciprocal condition numbers RCONDE and RCONDV, see section 4.11 of LAPACK User's Guide. Go read it, it's a whole thing πŸ“š


Definition at line 370 of file cggevx.f.


πŸ¦‹ subroutine dggevx πŸ¦‹

subroutine dggevx (character balanc, character jobvl, character jobvr,
    character sense, integer n, double precision, dimension( lda, * ) a,
    integer lda, double precision, dimension( ldb, * ) b, integer ldb,
    double precision, dimension( * ) alphar, double precision, dimension( *
    ) alphai, double precision, dimension( * ) beta, double precision,
    dimension( ldvl, * ) vl, integer ldvl, double precision, dimension(
    ldvr, * ) vr, integer ldvr, integer ilo, integer ihi, double precision,
    dimension( * ) lscale, double precision, dimension( * ) rscale, double
    precision abnrm, double precision bbnrm, double precision, dimension( *
    ) rconde, double precision, dimension( * ) rcondv, double precision,
    dimension( * ) work, integer lwork, integer, dimension( * ) iwork,
    logical, dimension( * ) bwork, integer info)

DGGEVX computes the eigenvalues and, optionally, the left and/or right eigenvectors for GE matrices

🌸 Purpose 🌸

DGGEVX computes for a pair of N-by-N real nonsymmetric matrices (A,B) the generalized eigenvalues, and optionally, the left and/or right generalized eigenvectors.

Optionally also, it computes a balancing transformation to improve the conditioning of the eigenvalues and eigenvectors (ILO, IHI, LSCALE, RSCALE, ABNRM, and BBNRM), reciprocal condition numbers for the eigenvalues (RCONDE), and reciprocal condition numbers for the right eigenvectors (RCONDV). It's a whole glow-up for your conditioning πŸ”₯

A generalized eigenvalue for a pair of matrices (A,B) is a scalar lambda or a ratio alpha/beta = lambda, such that A - lambda*B is singular. It is usually represented as the pair (alpha,beta), as there is a reasonable interpretation for beta=0, and even for both being zero. Zero and zero? Valid. We don't judge here πŸ’œ

The right eigenvector v(j) corresponding to the eigenvalue lambda(j) of (A,B) satisfies

A * v(j) = lambda(j) * B * v(j) .

The left eigenvector u(j) corresponding to the eigenvalue lambda(j) of (A,B) satisfies

u(j)**H * A  = lambda(j) * u(j)**H * B.

where u(j)**H is the conjugate-transpose of u(j). Conjugate-transpose is that girl, ngl.

πŸŽ€ Parameters πŸŽ€

  • BALANC β€” BALANC is CHARACTER*1. Specifies the balance option to be performed:
    • = 'N': do not diagonally scale or permute;
    • = 'P': permute only;
    • = 'S': scale only;
    • = 'B': both permute and scale.

Computed reciprocal condition numbers will be for the matrices after permuting and/or balancing. Permuting does not change condition numbers (in exact arithmetic), but balancing does. So pick your fighter wisely.

  • JOBVL β€” JOBVL is CHARACTER*1:
    • = 'N': do not compute the left generalized eigenvectors;
    • = 'V': compute the left generalized eigenvectors.
  • JOBVR β€” JOBVR is CHARACTER*1:
    • = 'N': do not compute the right generalized eigenvectors;
    • = 'V': compute the right generalized eigenvectors.
  • SENSE β€” SENSE is CHARACTER*1. Determines which reciprocal condition numbers are computed:
    • = 'N': none are computed;
    • = 'E': computed for eigenvalues only;
    • = 'V': computed for eigenvectors only;
    • = 'B': computed for eigenvalues and eigenvectors.

Pick your SENSE, bestie, literally.

  • N β€” N is INTEGER. The order of the matrices A, B, VL, and VR. Constraint: N >= 0.
  • A β€” A is DOUBLE PRECISION array, dimension (LDA, N). On entry, the matrix A in the pair (A,B). On exit, A has been overwritten. If JOBVL='V' or JOBVR='V' or both, then A contains the first part of the real Schur form of the versions of the input A and B. She's been through something, but she came out the other side πŸ’…
  • LDA β€” LDA is INTEGER. The leading dimension of A. LDA >= max(1,N).
  • B β€” B is DOUBLE PRECISION array, dimension (LDB, N). On entry, the matrix B in the pair (A,B). On exit, B has been overwritten. If JOBVL='V' or JOBVR='V' or both, then B contains the second part of the real Schur form of the versions of the input A and B. Matching set with A, iconic.
  • LDB β€” LDB is INTEGER. The leading dimension of B. LDB >= max(1,N).
  • ALPHAR β€” ALPHAR is DOUBLE PRECISION array, dimension (N). Real part of the alpha, keeping it together while ALPHAI handles the drama.
  • ALPHAI β€” ALPHAI is DOUBLE PRECISION array, dimension (N). The imaginary part, doing the most.
  • BETA β€” BETA is DOUBLE PRECISION array, dimension (N). On exit, (ALPHAR(j) + ALPHAI(j)*i)/BETA(j), j=1,...,N, will be the generalized eigenvalues. If ALPHAI(j) is zero, then the j-th eigenvalue is real; if positive, then the j-th and (j+1)-st eigenvalues are a complex conjugate pair, with ALPHAI(j+1) negative.
Note (read this, fr fr): the quotients ALPHAR(j)/BETA(j) and ALPHAI(j)/BETA(j) may easily over- or underflow, and BETA(j) may even be zero. So please don't naively compute the ratio ALPHA/BETA β€” that's how you end up with Inf in your output at 3am 😭. However, ALPHAR and ALPHAI will be always less than and usually comparable with norm(A) in magnitude, and BETA always less than and usually comparable with norm(B). So the pieces themselves are well-behaved.
  • VL β€” VL is DOUBLE PRECISION array, dimension (LDVL,N). If JOBVL = 'V', the left eigenvectors u(j) are stored one after another in the columns of VL, in the same order as their eigenvalues. If the j-th eigenvalue is real, then u(j) = VL(:,j), the j-th column of VL. If the j-th and (j+1)-th eigenvalues form a complex conjugate pair, then u(j) = VL(:,j)+i*VL(:,j+1) and u(j+1) = VL(:,j)-i*VL(:,j+1). Each eigenvector will be scaled so the largest component have abs(real part) + abs(imag. part) = 1. Not referenced if JOBVL = 'N'.
  • LDVL β€” LDVL is INTEGER. The leading dimension of the matrix VL. LDVL >= 1, and if JOBVL = 'V', LDVL >= N.
  • VR β€” VR is DOUBLE PRECISION array, dimension (LDVR,N). If JOBVR = 'V', the right eigenvectors v(j) are stored one after another in the columns of VR, in the same order as their eigenvalues. If the j-th eigenvalue is real, then v(j) = VR(:,j), the j-th column of VR. If the j-th and (j+1)-th eigenvalues form a complex conjugate pair, then v(j) = VR(:,j)+i*VR(:,j+1) and v(j+1) = VR(:,j)-i*VR(:,j+1). Each eigenvector will be scaled so the largest component have abs(real part) + abs(imag. part) = 1. Not referenced if JOBVR = 'N'. Symmetry with VL, we love a coordinated duo 🫢
  • LDVR β€” LDVR is INTEGER. The leading dimension of the matrix VR. LDVR >= 1, and if JOBVR = 'V', LDVR >= N.
  • ILO β€” ILO is INTEGER. (That's literally all the page says about her β€” mysterious, lowkey.)
  • IHI β€”
  • IHI β€” INTEGER. So here's the tea: ILO and IHI are the ranges where stuff actually still lives. On exit, A(i,j) = 0 and B(i,j) = 0 if i > j and j = 1,...,ILO-1, or if i = IHI+1,...,N. Basically everything outside the interesting block got zeroed out, slay. And if BALANC = 'N' or 'S', then ILO = 1 and IHI = N β€” no permuting happened, so the whole matrix is the main character. πŸ‘‘
  • LSCALE β€” DOUBLE PRECISION array, dimension (N). This is the receipts for all the permutations and scaling factors that got applied to the left side of A and B. So if PL(j) is the index of the row interchanged with row j, and DL(j) is the scaling factor applied to row j, then:
LSCALE(j) = PL(j)  for j = 1,...,ILO-1
          = DL(j)  for j = ILO,...,IHI
          = PL(j)  for j = IHI+1,...,N.

And the order in which the interchanges are made is N to IHI+1, then 1 to ILO-1. That's the sequence, don't come for me. πŸ’…

  • RSCALE β€” DOUBLE PRECISION array, dimension (N). Literally the same situation but for the right side of A and B. If PR(j) is the index of the column interchanged with column j, and DR(j) is the scaling factor applied to column j, then:
RSCALE(j) = PR(j)  for j = 1,...,ILO-1
          = DR(j)  for j = ILO,...,IHI
          = PR(j)  for j = IHI+1,...,N

Same interchange order, bestie: N to IHI+1, then 1 to ILO-1. No cap. ✨

  • ABNRM β€” DOUBLE PRECISION. The one-norm of the balanced matrix A. That's it, that's the whole vibe. πŸŽ€
  • BBNRM β€” DOUBLE PRECISION. The one-norm of the balanced matrix B. Matching set, we love a coordinated moment. πŸ¦‹
  • RCONDE β€” DOUBLE PRECISION array, dimension (N). If SENSE = 'E' or 'B', this holds the reciprocal condition numbers of the eigenvalues, stored in consecutive elements of the array. For a complex conjugate pair of eigenvalues, two consecutive elements of RCONDE are set to the same value β€” twins! So RCONDE(j), RCONDV(j), and the j-th columns of VL and VR all correspond to the j-th eigenpair. Everything lines up, it's giving organized. 🌸 If SENSE = 'N or 'V', RCONDE is not referenced. (Yes, the original really does have that stray quote in 'N β€” leaving it exactly as found, don't @ me πŸ’€)
  • RCONDV β€” DOUBLE PRECISION array, dimension (N). If SENSE = 'V' or 'B', these are the estimated reciprocal condition numbers of the eigenvectors, stored in consecutive elements of the array. For a complex eigenvector, two consecutive elements of RCONDV are set to the same value. And heads up: if the eigenvalues cannot be reordered to compute RCONDV(j), then RCONDV(j) is set to 0 β€” and per the page, this can only occur when the true value would be very small anyway. So like, not a crisis. πŸ™ˆ If SENSE = 'N' or 'E', RCONDV is not referenced.
  • WORK β€” DOUBLE PRECISION array, dimension (MAX(1,LWORK)). On exit, if INFO = 0, WORK(1) returns the optimal LWORK. Free real estate info, we stan. πŸ”₯
  • LWORK β€” INTEGER. The dimension of the array WORK. Buckle up:
LWORK >= max(1,2*N).
If BALANC = 'S' or 'B', or JOBVL = 'V', or JOBVR = 'V',
LWORK >= max(1,6*N).
If SENSE = 'E' or 'B', LWORK >= max(1,10*N).
If SENSE = 'V' or 'B', LWORK >= 2*N*N+8*N+16.

And the cute part: if LWORK = -1, then a workspace query is assumed β€” the routine only calculates the optimal size of the WORK array, returns this value as the first entry of the WORK array, and no error message related to LWORK is issued by XERBLA. Sneaky little size-checker, I love her. 😌

  • IWORK β€” INTEGER array, dimension (N+6). If SENSE = 'E', IWORK is not referenced. That's the whole paragraph, she's short and to the point. 🫢
  • BWORK β€” LOGICAL array, dimension (N). If SENSE = 'N', BWORK is not referenced. Same energy. ⭐
  • INFO β€” INTEGER. The report card, let's read it together:
    • = 0: successful exit. We love a clean finish. πŸ’–
    • < 0: if INFO = -i, the i-th argument had an illegal value.
    • = 1,...,N: The QZ iteration failed. No eigenvectors have been calculated, but ALPHAR(j), ALPHAI(j), and BETA(j) should be correct for j=INFO+1,...,N.
    • > N: =N+1: other than QZ iteration failed in DHGEQZ. =N+2: error return from DTGEVC.
Okay so lowkey the INFO = 1,...,N case is the dramatic one β€” the iteration failed, no eigenvectors for you, but the eigenvalue pieces are still valid. Don't panic-delete anything. 😭

🫢 Author

Univ. of Tennessee

Univ. of California Berkeley

Univ. of Colorado Denver

NAG Ltd.

The whole squad showed up. Respect. πŸ‘‘


πŸ” Further Details

Balancing a matrix pair (A,B) includes, first, permuting rows and columns to isolate eigenvalues, and second, applying a diagonal similarity transformation to the rows and columns to make the rows and columns as close in norm as possible. The computed reciprocal condition numbers correspond to the balanced matrix. Permuting rows and columns will not change the condition numbers (in exact arithmetic) but diagonal scaling will. For further explanation of balancing, see section 4.11.1.2 of LAPACK Users' Guide. It's giving "read the textbook, bestie." πŸ“š

So here's the error-bound situation. An approximate error bound on the chordal distance between the i-th computed generalized eigenvalue w and the corresponding exact eigenvalue lambda is:

chord(w, lambda) <= EPS * norm(ABNRM, BBNRM) / RCONDE(I)

And an approximate error bound for the angle between the i-th computed eigenvector VL(i) or VR(i) is given by:

EPS * norm(ABNRM, BBNRM) / DIF(i).

For further explanation of the reciprocal condition numbers RCONDE and RCONDV, see section 4.11 of LAPACK User's Guide. Yes, another section. Go read it, it's worth it. ✨


Definition at line 387 of file dggevx.f. πŸ“


🌈 sggevx β€” the single-precision twin, obvs

Like, same energy, REAL instead of DOUBLE PRECISION. The glow-up:

subroutine sggevx (character balanc, character jobvl, character jobvr,
    character sense, integer n, real, dimension( lda, * ) a, integer lda,
    real, dimension( ldb, * ) b, integer ldb, real, dimension( * ) alphar,
    real, dimension( * ) alphai, real, dimension( * ) beta, real, dimension(
    ldvl, * ) vl, integer ldvl, real, dimension( ldvr, * ) vr, integer ldvr,
    integer ilo, integer ihi, real, dimension( * ) lscale, real, dimension(
    * ) rscale, real abnrm, real bbnrm, real, dimension( * ) rconde, real,
    dimension( * ) rcondv, real, dimension( * ) work, integer lwork,
    integer, dimension( * ) iwork, logical, dimension( * ) bwork, integer
    info)

SGGEVX computes the eigenvalues and, optionally, the left and/or right eigenvectors for GE matrices. πŸ¦‹

✨ Purpose ✨

So SGGEVX computes, for a pair of N-by-N real nonsymmetric matrices (A,B), the generalized eigenvalues, and optionally, the left and/or right generalized eigenvectors. Main character behaviour. πŸ’…

Optionally also, it computes a balancing transformation to improve the conditioning of the eigenvalues and eigenvectors (ILO, IHI, LSCALE, RSCALE, ABNRM, and BBNRM), reciprocal condition numbers for the eigenvalues (RCONDE), and reciprocal condition numbers for the right eigenvectors (RCONDV). Look at all those outputs, thriving. 🌟

A generalized eigenvalue for a pair of matrices (A,B) is a scalar lambda or a ratio alpha/beta = lambda, such that A - lambda*B is singular. It is usually represented as the pair (alpha,beta), as there is a reasonable interpretation for beta=0, and even for both being zero. Equality, but make it linear algebra. 😌

The right eigenvector v(j) corresponding to the eigenvalue lambda(j) of (A,B) satisfies:

A * v(j) = lambda(j) * B * v(j) .

The left eigenvector u(j) corresponding to the eigenvalue lambda(j) of (A,B) satisfies:

u(j)**H * A  = lambda(j) * u(j)**H * B.

where u(j)**H is the conjugate-transpose of u(j). Get you a routine that does both directions. πŸ”₯

πŸŽ€ Parameters

  • BALANC β€” CHARACTER*1. Specifies the balance option to be performed. The menu:
    • = 'N': do not diagonally scale or permute;
    • = 'P': permute only;
    • = 'S': scale only;
    • = 'B': both permute and scale.

Computed reciprocal condition numbers will be for the matrices after permuting and/or balancing. Permuting does not change condition numbers (in exact arithmetic), but balancing does. Choose wisely, bestie. 🧚

  • JOBVL β€” CHARACTER*1.
    • = 'N': do not compute the left generalized eigenvectors;
    • = 'V': compute the left generalized eigenvectors.
  • JOBVR β€” CHARACTER*1.
    • = 'N': do not compute the right generalized eigenvectors;
    • = 'V': compute the right generalized eigenvectors.
  • SENSE β€” CHARACTER*1. Determines which reciprocal condition numbers are computed.
    • = 'N': none are computed;
    • = 'E': computed for eigenvalues only;
    • = 'V': computed for eigenvectors only;
    • = 'B': computed for eigenvalues and eigenvectors.

Pick your fighter. πŸ‘‘

  • N β€” INTEGER. The order of the matrices A, B, VL, and VR. Constraint: N >= 0. Not negotiable, it's a dimension. πŸ’€
  • A β€” REAL array, dimension (LDA, N). On entry, the matrix A in the pair (A,B). On exit, A has been overwritten. If JOBVL='V' or JOBVR='V' or both, then A contains the first part of the real Schur form of the versions of the input A and B. She's been through something, but she's fine. πŸ™ˆ
  • LDA β€” INTEGER. The leading dimension of A. Constraint: LDA >= max(1,N).
  • B β€” REAL array, dimension (LDB, N). On entry, the matrix B in the pair (A,B). On exit, B has been overwritten. If JOBVL='V' or JOBVR='V' or both, then B contains the second part of the real Schur form of the versions of the input A and B. Matching set with A, as it should be. πŸŽ€
  • LDB β€” INTEGER. The leading dimension of B. Constraint: LDB >= max(1,N).
  • ALPHAR β€” REAL array, dimension (N). (That's literally all this page says here β€” the real parts are just vibing in their own array. πŸ’œ)
  • ALPHAI β€” okay so the imaginary parts are next, and that's exactly where we're picking this back up β€” don't go anywhere, bestie, the description of this one is literally right there on the next page πŸ’…βœ¨
  • ALPHAI β€” REAL array, dimension (N) πŸŽ€
  • BETA β€” REAL array, dimension (N). On exit, (ALPHAR(j) + ALPHAI(j)*i)/BETA(j), for j=1,...,N, gives you the generalized eigenvalues πŸ’– If ALPHAI(j) is zero then the j-th eigenvalue is real, if it's positive then the j-th and (j+1)-st eigenvalues are a complex conjugate pair, with ALPHAI(j+1) negative. No cap.
Ok so massive heads-up here bestie, this is the "don't do the obvious thing" warning 😭 The quotients ALPHAR(j)/BETA(j) and ALPHAI(j)/BETA(j) can easily over- or underflow, and BETA(j) might legitimately be zero. So pls pls pls do not naively compute the ratio ALPHA/BETA. The good news: ALPHAR and ALPHAI are always less than, and usually comparable with, norm(A) in magnitude, and BETA is always less than, and usually comparable with, norm(B). Slay.
  • VL β€” REAL array, dimension (LDVL,N). If JOBVL = 'V', the left eigenvectors u(j) are stored one after another in the columns of VL, in the same order as their eigenvalues ⭐ If the j-th eigenvalue is real, then u(j) = VL(:,j), the j-th column of VL. If the j-th and (j+1)-th eigenvalues form a complex conjugate pair, then u(j) = VL(:,j)+i*VL(:,j+1) and u(j+1) = VL(:,j)-i*VL(:,j+1). Each eigenvector gets scaled so the largest component has abs(real part) + abs(imag. part) = 1. Not referenced if JOBVL = 'N' πŸ™ˆ
  • LDVL β€” INTEGER. The leading dimension of the matrix VL. LDVL >= 1, and if JOBVL = 'V', LDVL >= N πŸ¦‹
  • VR β€” REAL array, dimension (LDVR,N). If JOBVR = 'V', the right eigenvectors v(j) are stored one after another in the columns of VR, in the same order as their eigenvalues ✨ Same energy as VL: if the j-th eigenvalue is real, then v(j) = VR(:,j), the j-th column of VR. If the j-th and (j+1)-th eigenvalues form a complex conjugate pair, then v(j) = VR(:,j)+i*VR(:,j+1) and v(j+1) = VR(:,j)-i*VR(:,j+1). Each eigenvector is scaled so the largest component has abs(real part) + abs(imag. part) = 1. Not referenced if JOBVR = 'N' πŸ’…
  • LDVR β€” INTEGER. The leading dimension of the matrix VR. LDVR >= 1, and if JOBVR = 'V', LDVR >= N 🌸
  • ILO β€” INTEGER 🫢
  • IHI β€” INTEGER. ILO and IHI are integer values such that on exit A(i,j) = 0 and B(i,j) = 0 if i > j and j = 1,...,ILO-1 or i = IHI+1,...,N. If BALANC = 'N' or 'S', then ILO = 1 and IHI = N πŸ‘‘
  • LSCALE β€” REAL array, dimension (N). All the deets of the permutations and scaling factors applied to the left side of A and B πŸ’œ If PL(j) is the index of the row interchanged with row j, and DL(j) is the scaling factor applied to row j, then:
LSCALE(j) = PL(j)  for j = 1,...,ILO-1
          = DL(j)  for j = ILO,...,IHI
          = PL(j)  for j = IHI+1,...,N.

The order in which the interchanges are made is N to IHI+1, then 1 to ILO-1 ⭐

  • RSCALE β€” REAL array, dimension (N). Same vibe but for the right side of A and B 🌈 If PR(j) is the index of the column interchanged with column j, and DR(j) is the scaling factor applied to column j, then:
RSCALE(j) = PR(j)  for j = 1,...,ILO-1
          = DR(j)  for j = ILO,...,IHI
          = PR(j)  for j = IHI+1,...,N

The order in which the interchanges are made is N to IHI+1, then 1 to ILO-1 πŸ’«

  • ABNRM β€” REAL. The one-norm of the balanced matrix A πŸŽ€
  • BBNRM β€” REAL. The one-norm of the balanced matrix B πŸŽ€
  • RCONDE β€” REAL array, dimension (N). If SENSE = 'E' or 'B', this holds the reciprocal condition numbers of the eigenvalues, stored in consecutive elements of the array. For a complex conjugate pair of eigenvalues, two consecutive elements of RCONDE get set to the same value. So RCONDE(j), RCONDV(j), and the j-th columns of VL and VR all correspond to the j-th eigenpair β€” matching set, iconic πŸ’… If SENSE = 'N' or 'V', RCONDE is not referenced πŸ™ˆ
  • RCONDV β€” REAL array, dimension (N). If SENSE = 'V' or 'B', these are the estimated reciprocal condition numbers of the eigenvectors, stored in consecutive elements of the array. For a complex eigenvector, two consecutive elements of RCONDV are set to the same value. If the eigenvalues cannot be reordered to compute RCONDV(j), then RCONDV(j) is set to 0 β€” and ngl that can only happen when the true value would be very small anyway, so it's not the tragedy it sounds like 😌 If SENSE = 'N' or 'E', RCONDV is not referenced.
  • WORK β€” REAL array, dimension (MAX(1,LWORK)). On exit, if INFO = 0, WORK(1) returns the optimal LWORK ✨
  • LWORK β€” INTEGER. The dimension of the array WORK. LWORK >= max(1,2*N). And then it escalates, bestie:
    • If BALANC = 'S' or 'B', or JOBVL = 'V', or JOBVR = 'V', then LWORK >= max(1,6*N).
    • If SENSE = 'E', then LWORK >= max(1,10*N).
    • If SENSE = 'V' or 'B', then LWORK >= 2*N*N+8*N+16.

If LWORK = -1, then a workspace query is assumed πŸ” The routine only calculates the optimal size of the WORK array, returns this value as the first entry of the WORK array, and no error message related to LWORK is issued by XERBLA. Literally just asking "how much room do u need", no drama πŸ’–

  • IWORK β€” INTEGER array, dimension (N+6). If SENSE = 'E', IWORK is not referenced πŸ¦‹
  • BWORK β€” LOGICAL array, dimension (N). If SENSE = 'N', BWORK is not referenced πŸ¦‹
  • INFO β€” INTEGER, the vibe check at the end of the run:
    • = 0: successful exit πŸŽ‰ slay
    • < 0: if INFO = -i, the i-th argument had an illegal value πŸ’€
    • = 1,...,N: the QZ iteration failed 😭 No eigenvectors have been calculated, but ALPHAR(j), ALPHAI(j), and BETA(j) should be correct for j=INFO+1,...,N β€” so you still get partial credit.
    • > N: =N+1: something other than QZ iteration failed in SHGEQZ. =N+2: error return from STGEVC 🫠

πŸ‘‘ Author

Univ. of Tennessee

Univ. of California Berkeley

Univ. of Colorado Denver

NAG Ltd.


🌸 Further Details:

Balancing a matrix pair (A,B) is a whole little two-step, ok: first, permuting rows and columns to isolate eigenvalues, second, applying diagonal similarity transformation to the rows and columns to make the rows and columns as close in norm as possible. The computed reciprocal condition numbers correspond to the balanced matrix. Permuting rows and columns will not change the condition numbers (in exact arithmetic) but diagonal scaling will. For further explanation of balancing, see section 4.11.1.2 of LAPACK Users' Guide πŸ“š

An approximate error bound on the chordal distance between the i-th computed generalized eigenvalue w and the corresponding exact eigenvalue lambda is:

chord(w, lambda) <= EPS * norm(ABNRM, BBNRM) / RCONDE(I)

An approximate error bound for the angle between the i-th computed eigenvector VL(i) or VR(i) is given by:

EPS * norm(ABNRM, BBNRM) / DIF(i).
For further explanation of the reciprocal condition numbers RCONDE and RCONDV, see section 4.11 of LAPACK User's Guide πŸ’œ

Definition at line 387 of file sggevx.f.


πŸ¦‹ subroutine zggevx πŸ¦‹

Fr fr, here's the complex sibling β€” same energy, different precision:

subroutine zggevx (character balanc, character jobvl, character jobvr,
    character sense, integer n, complex*16, dimension( lda, * ) a, integer
    lda, complex*16, dimension( ldb, * ) b, integer ldb, complex*16,
    dimension( * ) alpha, complex*16, dimension( * ) beta, complex*16,
    dimension( ldvl, * ) vl, integer ldvl, complex*16, dimension( ldvr, * )
    vr, integer ldvr, integer ilo, integer ihi, double precision, dimension(
    * ) lscale, double precision, dimension( * ) rscale, double precision
    abnrm, double precision bbnrm, double precision, dimension( * ) rconde,
    double precision, dimension( * ) rcondv, complex*16, dimension( * )
    work, integer lwork, double precision, dimension( * ) rwork, integer,
    dimension( * ) iwork, logical, dimension( * ) bwork, integer info)

ZGGEVX computes the eigenvalues and, optionally, the left and/or right eigenvectors for GE matrices πŸ’…βœ¨

Purpose:

ZGGEVX is out here computing, for a pair of N-by-N complex nonsymmetric matrices (A,B), the generalized eigenvalues β€” and optionally the left and/or right generalized eigenvectors. πŸ’…

Optionally it also computes a balancing transformation to improve the conditioning of the eigenvalues and eigenvectors (ILO, IHI, LSCALE, RSCALE, ABNRM, and BBNRM), reciprocal condition numbers for the eigenvalues (RCONDE), and reciprocal condition numbers for the right eigenvectors (RCONDV). ✨

A generalized eigenvalue for a pair of matrices (A,B) is a scalar lambda or a ratio alpha/beta = lambda, such that A - lambda*B is singular. It's usually represented as the pair (alpha,beta), because there's a reasonable interpretation for beta=0, and even for both being zero. πŸ‘‘

The right eigenvector v(j) corresponding to the eigenvalue lambda(j) of (A,B) satisfies

                 A * v(j) = lambda(j) * B * v(j) .

The left eigenvector u(j) corresponding to the eigenvalue lambda(j) of (A,B) satisfies

                 u(j)**H * A  = lambda(j) * u(j)**H * B.

where u(j)**H is the conjugate-transpose of u(j). πŸ¦‹


✨ Parameters ✨

🌸 BALANC

CHARACTER*1 β€” tells us which balance option to perform, bestie:

  • 'N': do not diagonally scale or permute;
  • 'P': permute only;
  • 'S': scale only;
  • 'B': both permute and scale.
Heads up fr: computed reciprocal condition numbers will be for the matrices after permuting and/or balancing. Permuting does not change condition numbers (in exact arithmetic), but balancing does. 🫢

🌸 JOBVL

CHARACTER*1:

  • 'N': do not compute the left generalized eigenvectors;
  • 'V': compute the left generalized eigenvectors.

🌸 JOBVR

CHARACTER*1:

  • 'N': do not compute the right generalized eigenvectors;
  • 'V': compute the right generalized eigenvectors.

🌸 SENSE

CHARACTER*1 β€” determines which reciprocal condition numbers are computed:

  • 'N': none are computed;
  • 'E': computed for eigenvalues only;
  • 'V': computed for eigenvectors only;
  • 'B': computed for eigenvalues and eigenvectors.

🌸 N

INTEGER β€” the order of the matrices A, B, VL, and VR. N >= 0. πŸŽ€

🌸 A

COMPLEX*16 array, dimension (LDA, N)

On entry, the matrix A in the pair (A,B). On exit, A has been overwritten. If JOBVL='V' or JOBVR='V' or both, then A contains the first part of the complex Schur form of the versions of the input A and B. πŸ’«

🌸 LDA

INTEGER β€” the leading dimension of A. LDA >= max(1,N).

🌸 B

COMPLEX*16 array, dimension (LDB, N)

On entry, the matrix B in the pair (A,B). On exit, B has been overwritten. If JOBVL='V' or JOBVR='V' or both, then B contains the second part of the complex Schur form of the versions of the input A and B. πŸ’«

🌸 LDB

INTEGER β€” the leading dimension of B. LDB >= max(1,N).

🌸 ALPHA

COMPLEX*16 array, dimension (N) β€” that's it, that's the whole description. iconic, honestly. πŸŽ€

🌸 BETA

COMPLEX*16 array, dimension (N)

On exit, ALPHA(j)/BETA(j), j=1,...,N, will be the generalized eigenvalues. πŸ‘‘

⚠️ okay so real talk: the quotient ALPHA(j)/BETA(j) may easily over- or underflow, and BETA(j) may even be zero. Thus, the user should avoid naively computing the ratio ALPHA/BETA. However, ALPHA will be always less than and usually comparable with norm(A) in magnitude, and BETA always less than and usually comparable with norm(B). πŸ’€

🌸 VL

COMPLEX*16 array, dimension (LDVL,N)

If JOBVL = 'V', the left generalized eigenvectors u(j) are stored one after another in the columns of VL, in the same order as their eigenvalues.

Each eigenvector will be scaled so the largest component will have abs(real part) + abs(imag. part) = 1. ✨

Not referenced if JOBVL = 'N'.

🌸 LDVL

INTEGER β€” the leading dimension of the matrix VL. LDVL >= 1, and if JOBVL = 'V', LDVL >= N.

🌸 VR

COMPLEX*16 array, dimension (LDVR,N)

If JOBVR = 'V', the right generalized eigenvectors v(j) are stored one after another in the columns of VR, in the same order as their eigenvalues.

Each eigenvector will be scaled so the largest component will have abs(real part) + abs(imag. part) = 1. ✨

Not referenced if JOBVR = 'N'.

🌸 LDVR

INTEGER β€” the leading dimension of the matrix VR. LDVR >= 1, and if JOBVR = 'V', LDVR >= N.

🌸 ILO

INTEGER β€” bestie, it's just an INTEGER. 🫢

🌸 IHI

INTEGER

ILO and IHI are integer values such that on exit A(i,j) = 0 and B(i,j) = 0 if i > j and j = 1,...,ILO-1 or i = IHI+1,...,N.

If BALANC = 'N' or 'S', ILO = 1 and IHI = N. πŸ¦‹

🌸 LSCALE

DOUBLE PRECISION array, dimension (N)

Details of the permutations and scaling factors applied to the left side of A and B. If PL(j) is the index of the row interchanged with row j, and DL(j) is the scaling factor applied to row j, then

  LSCALE(j) = PL(j)  for j = 1,...,ILO-1
            = DL(j)  for j = ILO,...,IHI
            = PL(j)  for j = IHI+1,...,N.

The order in which the interchanges are made is N to IHI+1, then 1 to ILO-1. πŸŽ€

🌸 RSCALE

DOUBLE PRECISION array, dimension (N)

Details of the permutations and scaling factors applied to the right side of A and B. If PR(j) is the index of the column interchanged with column j, and DR(j) is the scaling factor applied to column j, then

  RSCALE(j) = PR(j)  for j = 1,...,ILO-1
            = DR(j)  for j = ILO,...,IHI
            = PR(j)  for j = IHI+1,...,N

The order in which the interchanges are made is N to IHI+1, then 1 to ILO-1. πŸŽ€

🌸 ABNRM

DOUBLE PRECISION β€” the one-norm of the balanced matrix A. periodt. πŸ’œ

🌸 BBNRM

DOUBLE PRECISION β€” the one-norm of the balanced matrix B. πŸ’œ

🌸 RCONDE

DOUBLE PRECISION array, dimension (N)

If SENSE = 'E' or 'B', the reciprocal condition numbers of the eigenvalues, stored in consecutive elements of the array.

If SENSE = 'N' or 'V', RCONDE is not referenced. πŸ™ˆ

🌸 RCONDV

DOUBLE PRECISION array, dimension (N)

If JOB = 'V' or 'B', the estimated reciprocal condition numbers of the eigenvectors, stored in consecutive elements of the array. If the eigenvalues cannot be reordered to compute RCONDV(j), RCONDV(j) is set to 0; this can only occur when the true value would be very small anyway. 😭

If SENSE = 'N' or 'E', RCONDV is not referenced.

🌸 WORK

COMPLEX*16 array, dimension (MAX(1,LWORK))

On exit, if INFO = 0, WORK(1) returns the optimal LWORK. ⭐

🌸 LWORK

INTEGER β€” the dimension of the array WORK.

LWORK >= max(1,2*N).

If SENSE = 'E', LWORK >= max(1,4*N).

If SENSE = 'V' or 'B', LWORK >= max(1,2*N*N+2*N).

πŸ”₯ If LWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of the WORK array, returns this value as the first entry of the WORK array, and no error message related to LWORK is issued by XERBLA. big main character energy.

🌸 RWORK

DOUBLE PRECISION array, dimension (lrwork)

lrwork must be at least max(1,6*N) if BALANC = 'S' or 'B', and at least max(1,2*N) otherwise.

Real workspace. 🌈

🌸 IWORK

INTEGER array, dimension (N+2)

If SENSE = 'E', IWORK is not referenced. πŸ¦‹

🌸 BWORK

LOGICAL array, dimension (N)

If SENSE = 'N', BWORK is not referenced. πŸ¦‹

🌸 INFO

INTEGER β€” the vibe check at the end:

  • = 0: successful exit
  • < 0: if INFO = -i, the i-th argument had an illegal value.
  • = 1,...,N: The QZ iteration failed. No eigenvectors have been calculated, but ALPHA(j) and BETA(j) should be correct for j=INFO+1,...,N. 😭
  • > N: =N+1: other than QZ iteration failed in ZHGEQZ. =N+2: error return from ZTGEVC. πŸ’€

πŸ‘‘ Author

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

Further Details: πŸ‘€ (yes bestie, there's more, hold onβ€”)

okay so let's talk balancing real quick because it's lowkey doing the most πŸ’…

Balancing a matrix pair (A,B) is a two-step lil routine, in order: first, permuting rows and columns to isolate eigenvalues, and second, applying a diagonal similarity transformation to the rows and columns to make the rows and columns as close in norm as possible. Two separate moves, bestie, don't mix them up ✨

Now here's the tea that actually matters: the computed reciprocal condition numbers correspond to the balanced matrix. And ngl the two steps behave differently β€” permuting rows and columns will not change the condition numbers (in exact arithmetic), but diagonal scaling will. So like, one of them is a freebie and one of them actually moves the numbers 😭. For further explanation of balancing, see section 4.11.1.2 of LAPACK Users' Guide.


🌸 error bounds, aka how wrong are you actually

An approximate error bound on the chordal distance between the i-th computed generalized eigenvalue w and the corresponding exact eigenvalue lambda is:

chord(w, lambda) <= EPS * norm(ABNRM, BBNRM) / RCONDE(I)

And an approximate error bound for the angle between the i-th computed eigenvector VL(i) or VR(i) is given by:

EPS * norm(ABNRM, BBNRM) / DIF(i).

Like, those are bounds, not promises β€” approximate, bestie, keep that in mind πŸ™ˆ. For further explanation of the reciprocal condition numbers RCONDE and RCONDV, see section 4.11 of LAPACK Users' Guide. go read it, it's giving study session πŸ“š


πŸŽ€ where this even lives

Definition at line 370 of file zggevx.f.

πŸ‘‘ Author

Generated automatically by Doxygen for LAPACK from the source code. not a human, just a robot doing its little documentation duties 🫢


aaaand that's the whole page, bestie, you made it to the end πŸŽ‰πŸ’– This was LAPACK Version 3.12.0, the ggevx(3) page β€” that's the source and version, and the date is whatever your manpage build decided it was when it rendered this (the footer doesn't pin one down, so don't @ me 😭). mwah, go balance something πŸ’…βœ¨

πŸ“¦ where this page comes from