tgevc(3)

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

okay so bestie, this whole page is from the Library Functions Manual (section 3) and it's giving "linear algebra main character energy" ✨ β€” we're talking eigenvectors of a pair of matrices here, no cap. Buckle up. πŸŽ€


🌸 NAME 🌸

tgevc β€” tgevc: eigvec of pair of matrices


πŸ¦‹ SYNOPSIS πŸ¦‹

Functions

subroutine ctgevc (side, howmny, select, n, s, lds, p, ldp, vl, ldvl,
    vr, ldvr, mm, m, work, rwork, info)
    CTGEVC
subroutine dtgevc (side, howmny, select, n, s, lds, p, ldp, vl, ldvl,
    vr, ldvr, mm, m, work, info)
    DTGEVC
subroutine stgevc (side, howmny, select, n, s, lds, p, ldp, vl, ldvl,
    vr, ldvr, mm, m, work, info)
    STGEVC
subroutine ztgevc (side, howmny, select, n, s, lds, p, ldp, vl, ldvl,
    vr, ldvr, mm, m, work, rwork, info)
    ZTGEVC

πŸ”₯ Detailed Description πŸ”₯

Lowkey there's no prose here in the source β€” it just goes straight into the function docs. Respect the hustle honestly.

πŸ‘‘ Function Documentation πŸ‘‘

subroutine ctgevc

subroutine ctgevc (character side, character howmny, logical, dimension( * )
    select, integer n, complex, dimension( lds, * ) s, integer lds, complex,
    dimension( ldp, * ) p, integer ldp, complex, dimension( ldvl, * ) vl,
    integer ldvl, complex, dimension( ldvr, * ) vr, integer ldvr, integer
    mm, integer m, complex, dimension( * ) work, real, dimension( * ) rwork,
    integer info)

✨ CTGEVC ✨

πŸ’– Purpose πŸ’–

okay so here's the vibe: CTGEVC computes some or all of the right and/or left eigenvectors of a pair of complex matrices (S,P), where S and P are upper triangular. Matrix pairs of this type are produced by the generalized Schur factorization of a complex matrix pair (A,B):

A = Q*S*Z**H,  B = Q*P*Z**H

as computed by CGGHRD + CHGEQZ. slay. πŸ’…

So the right eigenvector x and the left eigenvector y of (S,P) corresponding to an eigenvalue w are defined by:

S*x = w*P*x,  (y**H)*S = w*(y**H)*P,

where y**H denotes the conjugate transpose of y. The eigenvalues are not input to this routine β€” nope, they're computed directly from the diagonal elements of S and P. it does its own thing. ✨

This routine returns the matrices X and/or Y of right and left eigenvectors of (S,P), or the products Z*X and/or Q*Y, where Z and Q are input matrices. And if Q and Z are the unitary factors from the generalized Schur factorization of a matrix pair (A,B), then Z*X and Q*Y are the matrices of right and left eigenvectors of (A,B). literally the whole pipeline. 🫢

🌈 Parameters 🌈

  • SIDE β€” SIDE is CHARACTER*1
    • = 'R': compute right eigenvectors only;
    • = 'L': compute left eigenvectors only;
    • = 'B': compute both right and left eigenvectors.
  • HOWMNY β€” HOWMNY is CHARACTER*1
    • = 'A': compute all right and/or left eigenvectors;
    • = 'B': compute all right and/or left eigenvectors, backtransformed by the matrices in VR and/or VL;
    • = 'S': compute selected right and/or left eigenvectors, specified by the logical array SELECT.
  • SELECT β€” SELECT is LOGICAL array, dimension (N). If HOWMNY='S', SELECT specifies the eigenvectors to be computed. The eigenvector corresponding to the j-th eigenvalue is computed if SELECT(j) = .TRUE.. Not referenced if HOWMNY = 'A' or 'B'.
  • N β€” N is INTEGER. The order of the matrices S and P. N >= 0.
  • S β€” S is COMPLEX array, dimension (LDS,N). The upper triangular matrix S from a generalized Schur factorization, as computed by CHGEQZ.
  • LDS β€” LDS is INTEGER. The leading dimension of array S. LDS >= max(1,N).
  • P β€” P is COMPLEX array, dimension (LDP,N). The upper triangular matrix P from a generalized Schur factorization, as computed by CHGEQZ. P must have real diagonal elements. πŸ‘€ yeah, that's a requirement, not a suggestion.
  • LDP β€” LDP is INTEGER. The leading dimension of array P. LDP >= max(1,N).
  • VL β€” VL is COMPLEX array, dimension (LDVL,MM). On entry, if SIDE = 'L' or 'B' and HOWMNY = 'B', VL must contain an N-by-N matrix Q (usually the unitary matrix Q of left Schur vectors returned by CHGEQZ). On exit, if SIDE = 'L' or 'B', VL contains:
    • if HOWMNY = 'A', the matrix Y of left eigenvectors of (S,P);
    • if HOWMNY = 'B', the matrix Q*Y;
    • if HOWMNY = 'S', the left eigenvectors of (S,P) specified by SELECT, stored consecutively in the columns of VL, in the same order as their eigenvalues.

Not referenced if SIDE = 'R'.

  • LDVL β€” LDVL is INTEGER. The leading dimension of array VL. LDVL >= 1, and if SIDE = 'L' or 'l' or 'B' or 'b', LDVL >= N. (yes bestie, they really do list both cases, keep up πŸ’–)
  • VR β€” VR is COMPLEX array, dimension (LDVR,MM). On entry, if SIDE = 'R' or 'B' and HOWMNY = 'B', VR must contain an N-by-N matrix Z (usually the unitary matrix Z of right Schur vectors returned by CHGEQZ). On exit, if SIDE = 'R' or 'B', VR contains:
    • if HOWMNY = 'A', the matrix X of right eigenvectors of (S,P);
    • if HOWMNY = 'B', the matrix Z*X;
    • if HOWMNY = 'S', the right eigenvectors of (S,P) specified by SELECT, stored consecutively in the columns of VR, in the same order as their eigenvalues.

Not referenced if SIDE = 'L'.

  • LDVR β€” LDVR is INTEGER. The leading dimension of the array VR. LDVR >= 1, and if SIDE = 'R' or 'B', LDVR >= N.
  • MM β€” MM is INTEGER. The number of columns in the arrays VL and/or VR. MM >= M.
  • M β€” M is INTEGER. The number of columns in the arrays VL and/or VR actually used to store the eigenvectors. If HOWMNY = 'A' or 'B', M is set to N. Each selected eigenvector occupies one column.
  • WORK β€” WORK is COMPLEX array, dimension (2*N)
  • RWORK β€” RWORK is REAL array, dimension (2*N)
  • INFO β€” INFO is INTEGER
    • = 0: successful exit. πŸŽ‰
    • < 0: if INFO = -i, the i-th argument had an illegal value. πŸ’€

🧚 Author 🧚

Univ. of Tennessee

Univ. of California Berkeley

Univ. of Colorado Denver

NAG Ltd.

Definition at line 217 of file ctgevc.f.


subroutine dtgevc

subroutine dtgevc (character side, character howmny, logical, dimension( * )
    select, integer n, double precision, dimension( lds, * ) s, integer lds,
    double precision, dimension( ldp, * ) p, integer ldp, double precision,
    dimension( ldvl, * ) vl, integer ldvl, double precision, dimension(
    ldvr, * ) vr, integer ldvr, integer mm, integer m, double precision,
    dimension( * ) work, integer info)

✨ DTGEVC ✨

πŸ’– Purpose πŸ’–

So DTGEVC computes some or all of the right and/or left eigenvectors of a pair of real matrices (S,P), where S is a quasi-triangular matrix and P is upper triangular. Matrix pairs of this type are produced by the generalized Schur factorization of a matrix pair (A,B):

A = Q*S*Z**T,  B = Q*P*Z**T

as computed by DGGHRD + DHGEQZ. (note the **T this time, not **H β€” real ones do be like that πŸŒ€)

The right eigenvector x and the left eigenvector y of (S,P) corresponding to an eigenvalue w are defined by:

S*x = w*P*x,  (y**H)*S = w*(y**H)*P,

where y**H denotes the conjugate transpose of y. The eigenvalues are not input to this routine, but are computed directly from the diagonal blocks of S and P. blocks, bestie, not just elements. 🧱

This routine returns the matrices X and/or Y of right and left eigenvectors of (S,P), or the products Z*X and/or Q*Y, where Z and Q are input matrices. If Q and Z are the orthogonal factors from the generalized Schur factorization of a matrix pair (A,B), then Z*X and Q*Y are the matrices of right and left eigenvectors of (A,B). 🫢

🌈 Parameters 🌈

  • SIDE β€” SIDE is CHARACTER*1
    • = 'R': compute right eigenvectors only;
    • = 'L': compute left eigenvectors only;
    • = 'B': compute both right and left eigenvectors.
  • HOWMNY β€” HOWMNY is CHARACTER*1
    • = 'A': compute all right and/or left eigenvectors;
    • = 'B': compute all right and/or left eigenvectors, backtransformed by the matrices in VR and/or VL;
    • = 'S': compute selected right and/or left eigenvectors, specified by the logical array SELECT.
  • SELECT β€” SELECT is LOGICAL array, dimension (N). If HOWMNY='S', SELECT specifies the eigenvectors to be computed. If w(j) is a real eigenvalue, the corresponding real eigenvector is computed if SELECT(j) is .TRUE.. If w(j) and w(j+1) are the real and imaginary parts of a complex eigenvalue, the corresponding complex eigenvector is computed if either SELECT(j) or SELECT(j+1) is .TRUE., and on exit SELECT(j) is set to .TRUE. and SELECT(j+1) is set to .FALSE.. Not referenced if HOWMNY = 'A' or 'B'. (yes it edits your array back at you, iconic behavior honestly πŸ”₯)
  • N β€” N is INTEGER. The order of the matrices S and P. N >= 0.
  • S β€” S is DOUBLE PRECISION array, dimension (LDS,N). The upper quasi-triangular matrix S from a generalized Schur factorization, as computed by DHGEQZ.
  • LDS β€” LDS is INTEGER. The leading dimension of array S. LDS >= max(1,N).
  • P β€” P is DOUBLE PRECISION array, dimension (LDP,N). The upper triangular matrix P from a generalized Schur factorization, as computed by DHGEQZ. 2-by-2 diagonal blocks of P corresponding to 2-by-2 blocks of S must be in positive diagonal form. ⭐ requirements stay requirements.
  • LDP β€” πŸ’€ okay bestie the source text cuts off right here at LDP, so that's where this part ends β€” more incoming.
  • VL β€” DOUBLE PRECISION array, dimension (LDVL,MM)</p>. On entry, if SIDE = 'L' or 'B' and HOWMNY = 'B', VL has to already contain an N-by-N matrix Q (usually the orthogonal matrix Q of left Schur vectors that DHGEQZ handed back to you πŸ’…). On exit, if SIDE = 'L' or 'B', VL contains:
    • if HOWMNY = 'A', the matrix Y of left eigenvectors of (S,P);
    • if HOWMNY = 'B', the matrix Q*Y;
    • if HOWMNY = 'S', the left eigenvectors of (S,P) specified by SELECT, stored consecutively in the columns of VL, in the same order as their eigenvalues.

A complex eigenvector corresponding to a complex eigenvalue is stored in two consecutive columns β€” first column holds the real part, second holds the imaginary part 🫢. Not referenced if SIDE = 'R'.

  • LDVL β€” INTEGER</p>. The leading dimension of array VL. LDVL >= 1, and if SIDE = 'L' or 'B', then LDVL >= N.
  • VR β€” DOUBLE PRECISION array, dimension (LDVR,MM). On entry, if SIDE = 'R' or 'B' and HOWMNY = 'B', VR must contain an N-by-N matrix Z (usually the orthogonal matrix Z of right Schur vectors returned by DHGEQZ). On exit, if SIDE = 'R' or 'B', VR contains:
    • if HOWMNY = 'A', the matrix X of right eigenvectors of (S,P);
    • if HOWMNY = 'B' or 'b', the matrix Z*X;
    • if HOWMNY = 'S' or 's', the right eigenvectors of (S,P) specified by SELECT, stored consecutively in the columns of VR, in the same order as their eigenvalues.

A complex eigenvector corresponding to a complex eigenvalue is stored in two consecutive columns β€” real part first, imaginary part second 😌. Not referenced if SIDE = 'L'.

ok so tiny vibe check πŸ•΅οΈβ€β™€οΈ β€” the source is literally inconsistent here: VL only lists 'B' and 'S' (big letters only) while VR lists 'B' or 'b' and 'S' or 's'. That's exactly what it says, so that's exactly what I'm telling you. Don't come for me, come for the Fortran πŸ’€
  • LDVR β€” INTEGER</p>. The leading dimension of the array VR. LDVR >= 1, and if SIDE = 'R' or 'B', then LDVR >= N.
  • MM β€” INTEGER</p>. The number of columns in the arrays VL and/or VR. Gotta be MM >= M.
  • M β€” INTEGER</p>. The number of columns in VL and/or VR that are actually used to store the eigenvectors πŸ”₯. If HOWMNY = 'A' or 'B', then M is set to N. Each selected real eigenvector occupies one column, and each selected complex eigenvector occupies two columns. (Yes bestie, that's the whole reason MM exists. Math said "it depends" 😭)
  • WORK β€” DOUBLE PRECISION array, dimension (6*N). Scratch space, six whole blocks of it, all accounted for down below ⬇️
  • INFO β€” INTEGER</p>, the status code, the moment of truth πŸ‘‘:
    • = 0: successful exit. slay ✨
    • < 0: if INFO = -i, the i-th argument had an illegal value πŸ™ˆ
    • > 0: the 2-by-2 block (INFO:INFO+1) does not have a complex eigenvalue πŸ’€

✍️ Author

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

πŸ” Further Details

Allocation of workspace 🧚 (the original underlines this with ---------- -- ---------, which is very "I typed this in 1994" of it, but we move):

   WORK( j ) = 1-norm of j-th column of A, above the diagonal
   WORK( N+j ) = 1-norm of j-th column of B, above the diagonal
   WORK( 2*N+1:3*N ) = real part of eigenvector
   WORK( 3*N+1:4*N ) = imaginary part of eigenvector
   WORK( 4*N+1:5*N ) = real part of back-transformed eigenvector
   WORK( 5*N+1:6*N ) = imaginary part of back-transformed eigenvector

Nice and tidy β€” six chunks of N, one job each πŸ’…

Rowwise vs. columnwise solution methods πŸ¦‹

Finding a generalized eigenvector basically means solving the singular triangular system

(A - w B) x = 0     (for right) or:   (A - w B)**H y = 0  (for left)

So say you're finding the i-th right eigenvector (assume every eigenvalue is real, keep it cute). The equation you're solving is:

     n                   i
0 = sum  C(j,k) v(k)  = sum  C(j,k) v(k)     for j = i,. . .,1
    k=j                 k=j

where C = (A - w B) β€” and heads up, the components v(i+1:n) are 0.

The method goes like this:

(1)  v(i) := 1
for j = i-1,. . .,1:
                        i
    (2) compute  s = - sum C(j,k) v(k)   and
                      k=j+1

    (3) v(j) := s / C(j,j)

Step 2 is sometimes called the step (no cap, there's a word missing in the source right there β€” some formatting gremlin ate it 😭 β€” I'm not making one up for you), since it's an inner product between the j-th row and the portion of the eigenvector that's been computed so far.

The other method (also with a word missing in the original β€” same gremlin, same energy 🫠) consists basically in doing the sums for all the rows in parallel. As each v(j) gets computed, the contribution of v(j) times the j-th column of C is added to the partial sums. And because FORTRAN arrays are stored columnwise, this is a whole glow-up: at each step, the elements of C you're touching are adjacent to each other 😍 β€” whereas with the rowwise method, the elements accessed at a step are spaced LDS (and LDP) words apart. Painful. Not the vibe.

And here's the plot twist: when you're finding left eigenvectors, the matrix in question is the transpose of the one in storage 🀯 so the rowwise method is actually the one accessing columns of A and B at each step β€” which makes it the preferred method over there. It's giving "the answer depends on which side you're on", periodt.


Definition at line 293 of file dtgevc.f.


🌟 stgevc β€” same energy, single precision

subroutine stgevc (character side, character howmny, logical, dimension( * )
select, integer n, real, dimension( lds, * ) s, integer lds, real,
dimension( ldp, * ) p, integer ldp, real, dimension( ldvl, * ) vl,
integer ldvl, real, dimension( ldvr, * ) vr, integer ldvr, integer mm,
integer m, real, dimension( * ) work, integer info)

🎯 Purpose

STGEVC computes some or all of the right and/or left eigenvectors of a pair of real matrices (S,P), where S is a quasi-triangular matrix and P is upper triangular πŸ”Ί. Matrix pairs of this type are produced by the generalized Schur factorization of a matrix pair (A,B):

A = Q*S*Z**T,  B = Q*P*Z**T

as computed by SGGHRD + SHGEQZ.

The right eigenvector x and the left eigenvector y of (S,P) corresponding to an eigenvalue w are defined by:

S*x = w*P*x,  (y**H)*S = w*(y**H)*P,

where y**H denotes the conjugate transpose of y. And here's the iconic part: the eigenvalues are not input to this routine β€” they're computed directly from the diagonal blocks of S and P πŸ‘‘. It knows. It just knows.

This routine returns the matrices X and/or Y of right and left eigenvectors of (S,P), or the products Z*X and/or Q*Y, where Z and Q are input matrices. And if Q and Z are the orthogonal factors from the generalized Schur factorization of a matrix pair (A,B), then Z*X and Q*Y are the matrices of right and left eigenvectors of (A,B). Full circle, no cap πŸŒ€

βš™οΈ Parameters

  • SIDE β€” CHARACTER*1:
    • = 'R': compute right eigenvectors only;
    • = 'L': compute left eigenvectors only;
    • = 'B': compute both right and left eigenvectors. go big πŸ’…
  • HOWMNY β€” CHARACTER*1:
    • = 'A': compute all right and/or left eigenvectors;
    • = 'B': compute all right and/or left eigenvectors, backtransformed by the matrices in VR and/or VL;
    • = 'S': compute selected right and/or left eigenvectors, specified by the logical array SELECT.
  • SELECT β€” LOGICAL array, dimension (N). If HOWMNY='S', SELECT specifies the eigenvectors to be computed 🎯. If w(j) is a real eigenvalue, the corresponding real eigenvector is computed if SELECT(j) is .TRUE.. If w(j) and w(j+1) are the real and imaginary parts of a complex eigenvalue, the corresponding complex eigenvector is computed if either SELECT(j) or SELECT(j+1) is .TRUE. β€” and on exit, SELECT(j) is set to .TRUE. and SELECT(j+1) is set to .FALSE.. So it tidies up after itself, we love that πŸ™Œ. Not referenced if HOWMNY = 'A' or 'B'.
  • N β€” INTEGER. The order of the matrices S and P. N >= 0.
  • S β€” REAL array, dimension (LDS,N). The upper quasi-triangular matrix S from a generalized Schur factorization, as computed by SHGEQZ.
  • LDS β€” INTEGER. The leading dimension of array S. LDS >= max(1,N).
  • P β€” REAL array, dimension (LDP,N). The upper triangular matrix P from a generalized Schur factorization, as computed by SHGEQZ. Important caveat bestie 🚨: the 2-by-2 diagonal blocks of P corresponding to 2-by-2 blocks of S must be in positive diagonal form.
  • LDP β€” INTEGER. The leading dimension of array P. LDP >= max(1,N).

Still in STGEVC land, bestie β€” here’s the rest of the real-version parameter list, no details skipped πŸ’…

  • VL β€” okay so VL is a REAL array, dimension (LDVL,MM). On entry, if SIDE = 'L' or 'B' and HOWMNY = 'B', VL must contain an N-by-N matrix Q (usually the orthogonal matrix Q of left Schur vectors returned by SHGEQZ). On exit, if SIDE = 'L' or 'B', VL contains: if HOWMNY = 'A', the matrix Y of left eigenvectors of (S,P); if HOWMNY = 'B', the matrix Q*Y; if HOWMNY = 'S', the left eigenvectors of (S,P) specified by SELECT, stored consecutively in the columns of VL, in the same order as their eigenvalues. A complex eigenvector corresponding to a complex eigenvalue is stored in two consecutive columns, the first holding the real part, and the second the imaginary part. Not referenced if SIDE = 'R'.
  • LDVL β€” LDVL is INTEGER. It’s the leading dimension of array VL. LDVL >= 1, and if SIDE = 'L' or 'B', LDVL >= N. periodt πŸ’…
  • VR β€” VR is a REAL array, dimension (LDVR,MM). On entry, if SIDE = 'R' or 'B' and HOWMNY = 'B', VR must contain an N-by-N matrix Z (usually the orthogonal matrix Z of right Schur vectors returned by SHGEQZ). On exit, if SIDE = 'R' or 'B', VR contains: if HOWMNY = 'A', the matrix X of right eigenvectors of (S,P); if HOWMNY = 'B' or 'b', the matrix Z*X; if HOWMNY = 'S' or 's', the right eigenvectors of (S,P) specified by SELECT, stored consecutively in the columns of VR, in the same order as their eigenvalues. A complex eigenvector corresponding to a complex eigenvalue is stored in two consecutive columns, the first holding the real part and the second the imaginary part. Not referenced if SIDE = 'L'.
  • LDVR β€” LDVR is INTEGER. It’s the leading dimension of the array VR. LDVR >= 1, and if SIDE = 'R' or 'B', LDVR >= N. slay, constraints understood 🫢
  • MM β€” MM is INTEGER. It’s the number of columns in the arrays VL and/or VR. MM >= M. yes bestie, MM has to be at least M 😌
  • M β€” M is INTEGER. It’s the number of columns in the arrays VL and/or VR actually used to store the eigenvectors. If HOWMNY = 'A' or 'B', M is set to N. Each selected real eigenvector occupies one column and each selected complex eigenvector occupies two columns. two columns for complex vibes, no cap πŸ’–
  • WORK β€” WORK is a REAL array, dimension (6*N). six times N, she’s got room to work πŸ’…
  • INFO β€” INFO is INTEGER. = 0: successful exit. < 0: if INFO = -i, the i-th argument had an illegal value. > 0: the 2-by-2 block (INFO:INFO+1) does not have a complex eigenvalue. so if INFO > 0, that 2-by-2 block is not giving complex eigenvalue energy 😭

✨ Author ✨

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

🧚 Further Details: 🧚

Allocation of workspace:

WORK( j ) = 1-norm of j-th column of A, above the diagonal
WORK( N+j ) = 1-norm of j-th column of B, above the diagonal
WORK( 2*N+1:3*N ) = real part of eigenvector
WORK( 3*N+1:4*N ) = imaginary part of eigenvector
WORK( 4*N+1:5*N ) = real part of back-transformed eigenvector
WORK( 5*N+1:6*N ) = imaginary part of back-transformed eigenvector

Rowwise vs. columnwise solution methods:

Finding a generalized eigenvector consists basically of solving the singular triangular system

(A - w B) x = 0     (for right) or:   (A - w B)**H y = 0  (for left)

Consider finding the i-th right eigenvector (assume all eigenvalues are real). The equation to be solved is:

     n                   i
0 = sum  C(j,k) v(k)  = sum  C(j,k) v(k)     for j = i,. . .,1
    k=j                 k=j

where C = (A - w B) (The components v(i+1:n) are 0.)

The method is:

(1)  v(i) := 1
for j = i-1,. . .,1:
                        i
    (2) compute  s = - sum C(j,k) v(k)   and
                      k=j+1

    (3) v(j) := s / C(j,j)

Step 2 is sometimes called the step β€” yes, bestie, the blank is literally in the source, not me 😭 β€” since it is an inner product between the j-th row and the portion of the eigenvector that has been computed so far.

The method β€” again, blank in the source, I’m just the messenger πŸ’€ β€” consists basically in doing the sums for all the rows in parallel. As each v(j) is computed, the contribution of v(j) times the j-th column of C is added to the partial sums. Since FORTRAN arrays are stored columnwise, this has the advantage that at each step, the elements of C that are accessed are adjacent to one another, whereas with the rowwise method, the elements accessed at a step are spaced LDS (and LDP) words apart.

When finding left eigenvectors, the matrix in question is the transpose of the one in storage, so the rowwise method then actually accesses columns of A and B at each step, and so is the preferred method.

πŸ“œ And the source says: Definition at line 293 of file stgevc.f.


subroutine ztgevc (character side, character howmny, logical, dimension( * )
    select, integer n, complex*16, dimension( lds, * ) s, integer lds,
    complex*16, dimension( ldp, * ) p, integer ldp, complex*16, dimension(
    ldvl, * ) vl, integer ldvl, complex*16, dimension( ldvr, * ) vr, integer
    ldvr, integer mm, integer m, complex*16, dimension( * ) work, double
    precision, dimension( * ) rwork, integer info)

πŸ’œ ZTGEVC πŸ’œ

πŸŽ€ Purpose: πŸŽ€

ZTGEVC computes some or all of the right and/or left eigenvectors of a pair of complex matrices (S,P), where S and P are upper triangular. Matrix pairs of this type are produced by the generalized Schur factorization of a complex matrix pair (A,B):

A = Q*S*Z**H,  B = Q*P*Z**H

as computed by ZGGHRD + ZHGEQZ.

The right eigenvector x and the left eigenvector y of (S,P) corresponding to an eigenvalue w are defined by:

S*x = w*P*x,  (y**H)*S = w*(y**H)*P,

where y**H denotes the conjugate transpose of y. The eigenvalues are not input to this routine, but are computed directly from the diagonal elements of S and P.

This routine returns the matrices X and/or Y of right and left eigenvectors of (S,P), or the products Z*X and/or Q*Y, where Z and Q are input matrices. If Q and Z are the unitary factors from the generalized Schur factorization of a matrix pair (A,B), then Z*X and Q*Y are the matrices of right and left eigenvectors of (A,B). iconic behavior, honestly πŸ’…

πŸ’… Parameters πŸ’…

  • SIDE β€” SIDE is CHARACTER*1. = 'R': compute right eigenvectors only; = 'L': compute left eigenvectors only; = 'B': compute both right and left eigenvectors. pick your vibe, bestie πŸ¦‹
  • HOWMNY β€” HOWMNY is CHARACTER*1. = 'A': compute all right and/or left eigenvectors; = 'B': compute all right and/or left eigenvectors, backtransformed by the matrices in VR and/or VL; = 'S': compute selected right and/or left eigenvectors, specified by the logical array SELECT. all, backtransformed, or selected β€” she contains multitudes ✨
  • SELECT β€” SELECT is a LOGICAL array, dimension (N). If HOWMNY='S', SELECT specifies the eigenvectors to be computed. The eigenvector corresponding to the j-th eigenvalue is computed if SELECT(j) = .TRUE.. Not referenced if HOWMNY = 'A' or 'B'.
  • N β€” N is INTEGER. It’s the order of the matrices S and P. N >= 0. nonnegative order, we love to see it πŸ’š
  • S β€” S is a COMPLEX*16 array, dimension (LDS,N). It’s the upper triangular matrix S from a generalized Schur factorization, as computed by ZHGEQZ. upper triangular and unbothered πŸ’…
  • LDS β€” LDS is INTEGER. It’s the leading dimension of array S. LDS >= max(1,N). max of 1 and N, don’t forget 😌
  • P β€” P is a COMPLEX*16 array, dimension (LDP,N). It’s the upper triangular matrix P from a generalized Schur factorization, as computed by ZHGEQZ. P must have real diagonal elements. real diagonal elements β€” that part is not optional, bestie 🚨
  • LDP β€” LDP is INTEGER. It’s the leading dimension of array P. LDP >= max(1,N). same energy as LDS, just for P 🫢
  • VL β€” VL is a COMPLEX*16 array, dimension (LDVL,MM). On entry, if SIDE = 'L' or 'B' and HOWMNY = 'B', VL must contain an N-by-N matrix Q (usually the unitary matrix Q of left Schur vectors returned by ZHGEQZ). On exit, if SIDE = 'L' or 'B', VL contains: if HOWMNY = 'A', the matrix Y of left eigenvectors of (S,P); if HOWMNY = 'B', the matrix Q*Y; if HOWMNY = 'S', the left eigenvectors of (S,P) specified by SELECT, stored consecutively in the columns of VL, in the same order as their eigenvalues. Not referenced if SIDE = 'R'.
  • LDVL β€” LDVL is INTEGER. It’s the leading dimension of array VL. LDVL >= 1, and if SIDE = 'L' or 'l' or 'B' or 'b', LDVL >= N. lowercase and uppercase both count here, iykyk πŸ’…
  • VR β€”

…and we're finishing up VR (the COMPLEX*16 array, dimension (LDVR,MM), remember her πŸ‘‘):

  • on entry, if SIDE = 'R' or 'B' and HOWMNY = 'B', VR must contain an N-by-N matrix Z β€” usually the unitary matrix Z of right Schur vectors returned by ZHGEQZ. no cap, she has to be pre-loaded 🫢
  • on exit, if SIDE = 'R' or 'B', VR contains:
    • if HOWMNY = 'A', the matrix X of right eigenvectors of (S,P);
    • if HOWMNY = 'B', the matrix Z*X;
    • if HOWMNY = 'S', the right eigenvectors of (S,P) specified by SELECT, stored consecutively in the columns of VR, in the same order as their eigenvalues. iconic ordering behaviour, love that for us ✨
  • not referenced if SIDE = 'L'. she's literally off duty bestie πŸ’…
  • LDVR β€” LDVR is INTEGER. the leading dimension of the array VR. LDVR >= 1, and if SIDE = 'R' or 'B', then LDVR >= N. respect the leading dimension or suffer the consequences πŸ™ˆ
  • MM β€” MM is INTEGER. the number of columns in the arrays VL and/or VR. MM >= M. give her some room to breathe bestie 🌸
  • M β€” M is INTEGER. the number of columns in the arrays VL and/or VR actually used to store the eigenvectors. if HOWMNY = 'A' or 'B', M is set to N. each selected eigenvector occupies one column. one eigenvector, one column, that's the vibe check βœ…
  • WORK β€” WORK is COMPLEX*16 array, dimension (2*N). scratch space, she's just here to do the work 🧚
  • RWORK β€” RWORK is DOUBLE PRECISION array, dimension (2*N). more scratch space, this time the real kind πŸ’œ
  • INFO β€” INFO is INTEGER, and she is the main character of error reporting πŸ”₯
    • = 0: successful exit. we ate and left no crumbs πŸ‘‘
    • < 0: if INFO = -i, the i-th argument had an illegal value. not me getting called out by an index 😭

✨ Author ✨

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

Definition at line 217 of file ztgevc.f. (yes, the whole vibe lives at line 217, iykyk πŸ“)

✨ Author ✨

Generated automatically by Doxygen for LAPACK from the source code. the robots wrote this one fr fr πŸ€–πŸ’–


and that's the whole page bestie!! πŸŽ€ this beauty is from LAPACK, Version 3.12.0 β€” the tgevc(3) page β€” and honestly? she's a lot, but she's our lot. go forth and compute those eigenvectors. slay, periodt, and remember: leading dimensions are not a suggestion πŸ’…πŸŒˆπŸ¦‹

πŸ“¦ where this page comes from