CGGESX(3)

πŸ“¦ version 3.12.0, in opensuse-leap 16.0

🌸 NAME 🌸

/home/abuild/rpmbuild/BUILD/lapack-static-3.12.0-build/lapack-3.12.0/SRC/cggesx.f

Okay bestie, welcome to the cggesx.f(3) page from the Library Functions Manual β€” yes, that exact cggesx.f(3) manual name, and yes, this is the file path, no cap. πŸ’…βœ¨

✨ SYNOPSIS ✨

πŸŽ€ Functions/Subroutines πŸŽ€

       subroutine CGGESX (jobvsl, jobvsr, sort, selctg, sense, n, a, lda, b,
           ldb, sdim, alpha, beta, vsl, ldvsl, vsr, ldvsr, rconde, rcondv,
           work, lwork, rwork, iwork, liwork, bwork, info)

CGGESX β€” okay so this icon literally computes the eigenvalues, the Schur form, and, optionally, the matrix of Schur vectors for GE matrices. 🫢πŸ”₯ Eigenvalues? slay. Schur form? periodt. Schur vectors? only if you optionally want them, bestie. πŸ’–

πŸ’… Function/Subroutine Documentation πŸ’…

ok so here's the actual signature, bestie β€” this is what you type, and every single arg matters, no skips:

   subroutine CGGESX (character jobvsl, character jobvsr, character sort,
       external selctg, character sense, integer n, complex, dimension( lda, *
       ) a, integer lda, complex, dimension( ldb, * ) b, integer ldb, integer
       sdim, complex, dimension( * ) alpha, complex, dimension( * ) beta,
       complex, dimension( ldvsl, * ) vsl, integer ldvsl, complex, dimension(
       ldvsr, * ) vsr, integer ldvsr, real, dimension( 2 ) rconde, real,
       dimension( 2 ) rcondv, complex, dimension( * ) work, integer lwork,
       real, dimension( * ) rwork, integer, dimension( * ) iwork, integer
       liwork, logical, dimension( * ) bwork, integer info)

and the one-liner that describes the whole vibe: CGGESX computes the eigenvalues, the Schur form, and, optionally, the matrix of Schur vectors for GE matrices. that's the whole assignment. πŸ’–


✨ Purpose ✨

okay so picture this: you've got a pair of N-by-N complex nonsymmetric matrices β€” a cute little duo, (A,B). CGGESX computes the generalized eigenvalues for them, plus the complex Schur form (S,T), and, if you ask nicely (aka optionally), the left and/or right matrices of Schur vectors, VSL and VSR.

what you get out of it is the generalized Schur factorization:

      (A,B) = ( (VSL) S (VSR)**H, (VSL) T (VSR)**H )

where (VSR)**H is the conjugate-transpose of VSR. the way that conjugate-transpose just shows up and does its thing. πŸ”₯

optionally β€” and this is the extra-credit part, bestie β€” it orders the eigenvalues so that a selected cluster of eigenvalues appears in the leading diagonal blocks of the upper triangular matrix S and the upper triangular matrix T. it also computes a reciprocal condition number for the average of the selected eigenvalues (RCONDE), and computes a reciprocal condition number for the right and left deflating subspaces corresponding to the selected eigenvalues (RCONDV). and then the leading columns of VSL and VSR form an orthonormal basis for the corresponding left and right eigenspaces (deflating subspaces). iconic behavior honestly. πŸ‘‘

so what even is a generalized eigenvalue for a pair of matrices (A,B)? it's a scalar w, or a ratio alpha/beta = w, such that A - w*B is singular. it's usually represented as the pair (alpha,beta), because there's a reasonable interpretation for beta=0 or for both of them being zero. no cap, that's the definition. πŸ¦‹

and a pair of matrices (S,T) is in generalized complex Schur form if T is upper triangular with non-negative diagonal and S is upper triangular. that's the finish line. 🏁


πŸŽ€ Parameters πŸŽ€

get comfy, there's a lot of them, but we're going through every single one together. group chat style. 🫢

JOBVSL

JOBVSL is CHARACTER*1

  • 'N' β€” do not compute the left Schur vectors. we're leaving them alone, not our problem today. πŸ™ˆ
  • 'V' β€” compute the left Schur vectors. yes ma'am. ✨

JOBVSR

JOBVSR is CHARACTER*1

  • 'N' β€” do not compute the right Schur vectors.
  • 'V' β€” compute the right Schur vectors. 🌸

SORT

SORT is CHARACTER*1

specifies whether or not to order the eigenvalues on the diagonal of the generalized Schur form.

  • 'N' β€” eigenvalues are not ordered.
  • 'S' β€” eigenvalues are ordered (see SELCTG).

SELCTG

SELCTG is a LOGICAL FUNCTION of two COMPLEX arguments. and listen β€” SELCTG must be declared EXTERNAL in the calling subroutine. do not forget this, it's giving classic "why is my code broken" energy. 😭

  • if SORT = 'N', SELCTG is not referenced. it's just vibing, unused.
  • if SORT = 'S', SELCTG is used to select eigenvalues to sort to the top left of the Schur form.
⚠️ important warning, bestie, read this twice: note that a selected complex eigenvalue may no longer satisfy SELCTG(ALPHA(j),BETA(j)) = .TRUE. after ordering, since ordering may change the value of complex eigenvalues (especially if the eigenvalue is ill-conditioned). in this case INFO is set to N+3 β€” see INFO below. the ordering genuinely can move the numbers around, so the thing you selected might not look selected anymore. not a bug, just math being math. πŸ’€

SENSE

SENSE is CHARACTER*1

determines which reciprocal condition numbers are computed.

  • 'N' β€” none are computed. we're doing the bare minimum today and that's valid. πŸ’…
  • 'E' β€” computed for average of selected eigenvalues only.
  • 'V' β€” computed for selected deflating subspaces only.
  • 'B' β€” computed for both. overachiever behavior, we love it. πŸ‘‘
if SENSE = 'E', 'V', or 'B', then SORT must equal 'S'. that's a hard requirement, not a suggestion.

N

N is INTEGER

the order of the matrices A, B, VSL, and VSR. and N >= 0. zero is allowed, negative is not. 🚫

A

A is COMPLEX array, dimension (LDA, N)

  • on entry, the first of the pair of matrices.
  • on exit, A has been overwritten by its generalized Schur form S. yeah she's gone, that's the deal. πŸ”₯

LDA

LDA is INTEGER

the leading dimension of A. LDA >= max(1,N). simple as that.

B

B is COMPLEX array, dimension (LDB, N)

  • on entry, the second of the pair of matrices.
  • on exit, B has been overwritten by its generalized Schur form T. same situation, she's transformed. ✨

LDB

LDB is INTEGER

the leading dimension of B. LDB >= max(1,N).

SDIM

SDIM is INTEGER

  • if SORT = 'N', then SDIM = 0.
  • if SORT = 'S', then SDIM = number of eigenvalues (after sorting) for which SELCTG is true. so it's literally "how many did my little function say yes to". πŸŽ€

ALPHA

ALPHA is COMPLEX array, dimension (N) β€” that's it, that's the whole note. no extra commentary in the source, so I'm not making anything up. moving on. πŸ™ˆ

BETA

BETA is COMPLEX array, dimension (N)

on exit, ALPHA(j)/BETA(j), j=1,...,N, will be the generalized eigenvalues. ALPHA(j) and BETA(j), j=1,...,N are the diagonals of the complex Schur form (S,T). and BETA(j) will be non-negative real. 🌈

⚠️ note, and this one's a real one: the quotients 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). so don't just divide, bestie, actually think about it first. 😭

VSL

VSL is COMPLEX array, dimension (LDVSL,N)

if JOBVSL = 'V', VSL will contain the left Schur vectors. not referenced if JOBVSL = 'N'. πŸ¦‹

LDVSL

LDVSL is INTEGER

the leading dimension of the matrix VSL. LDVSL >=1, and if JOBVSL = 'V', LDVSL >= N.

VSR

VSR is COMPLEX array, dimension (LDVSR,N)

if JOBVSR = 'V', VSR will contain the right Schur vectors. not referenced if JOBVSR = 'N'. πŸ’œ

LDVSR

LDVSR is INTEGER

the leading dimension of the matrix VSR. LDVSR >= 1, and if JOBVSR = 'V', LDVSR >= N.

RCONDE

RCONDE is REAL array, dimension ( 2 )

if SENSE = 'E' or 'B', RCONDE(1) and RCONDE(2) contain the reciprocal condition numbers for the average of the selected eigenvalues. not referenced if SENSE = 'N' or 'V'. πŸ“

RCONDV

RCONDV is REAL array, dimension ( 2 )

if SENSE = 'V' or 'B', RCONDV(1) and RCONDV(2) contain the reciprocal condition number for the selected deflating subspaces. not referenced if SENSE = 'N' or 'E'. 🧚

WORK

WORK is COMPLEX array, dimension (MAX(1,LWORK))

on exit, if INFO = 0, WORK(1) returns the optimal LWORK. she tells you what she wanted. 🫢

LWORK

LWORK is INTEGER

the dimension of the array WORK.

  • if N = 0, LWORK >= 1
  • else if SENSE = 'E', 'V', or 'B', LWORK >= MAX(1,2*N,2*SDIM*(N-SDIM))
  • else LWORK >= MAX(1,2*N)

note that 2*SDIM*(N-SDIM) <= N*N/2. note also that an error is only returned if LWORK < MAX(1,2*N), but if SENSE = 'E' or 'V' or 'B' this may not be large enough. so like β€” it won't yell at you, but it also won't be enough. read the room. πŸ’€

if LWORK = -1, then a workspace query is assumed; the routine only calculates the bound on the optimal size of the WORK array and the minimum size of the IWORK array, returns these values as the first entries of the WORK and IWORK arrays, and no error message related to LWORK or LIWORK is issued by XERBLA. that's the "just asking, not buying" mode. πŸŽ€

RWORK

RWORK is REAL array, dimension ( 8*N )

real workspace. that's the whole description. eight times N. don't skimp. ⭐

IWORK

IWORK is INTEGER array, dimension (MAX(1,LIWORK))

on exit, if INFO = 0, IWORK(1) returns the minimum LIWORK. she's helpful like that. ✨

LIWORK

LIWORK is INTEGER

the dimension of the array WORK. (yes, the docs literally say WORK here and not IWORK β€” we're all just gonna read past that together, ok? πŸ™ˆ)

  • if SENSE = 'N' or N = 0, LIWORK >= 1
  • otherwise LIWORK >= N+2

if LIWORK = -1, then a workspace query is assumed; the routine only calculates the bound on the optimal size of the WORK array and the minimum size of the IWORK array, returns these values as the first entries of the WORK and IWORK arrays, and no error message related to LWORK or LIWORK is issued by XERBLA. same deal as LWORK = -1, just for the integer side. πŸ¦‹

BWORK

BWORK is LOGICAL array, dimension (N)

not referenced if SORT = 'N'. she only clocks in when sorting is on. πŸ’…

INFO

INFO is INTEGER β€” this is the receipts section, bestie, read it carefully. πŸ“‹

  • = 0 β€” successful exit. slay. πŸŽ‰
  • < 0 β€” if INFO = -i, the i-th argument had an illegal value. check your args.
  • = 1,...,N β€” the QZ iteration failed. (A,B) are not in Schur form, but ALPHA(j) and BETA(j) should be correct for j=INFO+1,...,N. so partial progress, not a total loss.
  • > N β€” and here's the spicy breakdown:
    • =N+1 β€” other than QZ iteration failed in CHGEQZ.
    • =N+2 β€” after reordering, roundoff changed values of some complex eigenvalues so that leading eigenvalues in the Generalized Schur form no longer satisfy SELCTG=.TRUE.. this could also be caused due to scaling. 😭 roundoff said "not today".
    • =N+3 β€” reordering failed in CTGSEN.

πŸ‘‘ Author πŸ‘‘

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

the whole squad. 🫢


definition at line 326 of file cggesx.f. ✨

✨ Author ✨

So basically the whole thing was auto-generated by Doxygen for LAPACK, straight from the source code. Like, nobody hand-wrote this β€” the docs just spawned themselves from the .f file and honestly? iconic behavior. πŸ’…βœ¨

No cap, that's the entire author credit: Doxygen did the typing, LAPACK provided the source code, and the rest is history. 🫢


🌸 that's the whole page bestie, ily, go call CGGESX responsibly 🌸

Signing off from LAPACK Version 3.12.0, straight out of /home/abui...RC/cggesx.f(3) β€” generated automatically by Doxygen for LAPACK from the source code, and now lovingly narrated by me. πŸŽ€πŸ’–πŸ¦‹

πŸ“¦ where this page comes from