NAME

dtgevc - compute some or all of the right and/or left generalized eigenvectors of a pair of real upper triangular matrices (A,B)


SYNOPSIS

  SUBROUTINE DTGEVC( SIDE, HOWMNY, SELECT, N, A, LDA, B, LDB, VL, 
 *      LDVL, VR, LDVR, MM, M, WORK, INFO)
  CHARACTER * 1 SIDE, HOWMNY
  INTEGER N, LDA, LDB, LDVL, LDVR, MM, M, INFO
  LOGICAL SELECT(*)
  DOUBLE PRECISION A(LDA,*), B(LDB,*), VL(LDVL,*), VR(LDVR,*), WORK(*)
  SUBROUTINE DTGEVC_64( SIDE, HOWMNY, SELECT, N, A, LDA, B, LDB, VL, 
 *      LDVL, VR, LDVR, MM, M, WORK, INFO)
  CHARACTER * 1 SIDE, HOWMNY
  INTEGER*8 N, LDA, LDB, LDVL, LDVR, MM, M, INFO
  LOGICAL*8 SELECT(*)
  DOUBLE PRECISION A(LDA,*), B(LDB,*), VL(LDVL,*), VR(LDVR,*), WORK(*)

F95 INTERFACE

  SUBROUTINE TGEVC( SIDE, HOWMNY, SELECT, [N], A, [LDA], B, [LDB], VL, 
 *       [LDVL], VR, [LDVR], MM, M, [WORK], [INFO])
  CHARACTER(LEN=1) :: SIDE, HOWMNY
  INTEGER :: N, LDA, LDB, LDVL, LDVR, MM, M, INFO
  LOGICAL, DIMENSION(:) :: SELECT
  REAL(8), DIMENSION(:) :: WORK
  REAL(8), DIMENSION(:,:) :: A, B, VL, VR
  SUBROUTINE TGEVC_64( SIDE, HOWMNY, SELECT, [N], A, [LDA], B, [LDB], 
 *       VL, [LDVL], VR, [LDVR], MM, M, [WORK], [INFO])
  CHARACTER(LEN=1) :: SIDE, HOWMNY
  INTEGER(8) :: N, LDA, LDB, LDVL, LDVR, MM, M, INFO
  LOGICAL(8), DIMENSION(:) :: SELECT
  REAL(8), DIMENSION(:) :: WORK
  REAL(8), DIMENSION(:,:) :: A, B, VL, VR

C INTERFACE

#include <sunperf.h>

void dtgevc(char side, char howmny, logical *select, int n, double *a, int lda, double *b, int ldb, double *vl, int ldvl, double *vr, int ldvr, int mm, int *m, int *info);

void dtgevc_64(char side, char howmny, logical *select, long n, double *a, long lda, double *b, long ldb, double *vl, long ldvl, double *vr, long ldvr, long mm, long *m, long *info);


PURPOSE

dtgevc computes some or all of the right and/or left generalized eigenvectors of a pair of real upper triangular matrices (A,B).

The right generalized eigenvector x and the left generalized eigenvector y of (A,B) corresponding to a generalized eigenvalue w are defined by:

        (A - wB) * x = 0  and  y**H * (A - wB) = 0

where y**H denotes the conjugate tranpose of y.

If an eigenvalue w is determined by zero diagonal elements of both A and B, a unit vector is returned as the corresponding eigenvector.

If all eigenvectors are requested, the routine may either return the matrices X and/or Y of right or left eigenvectors of (A,B), or the products Z*X and/or Q*Y, where Z and Q are input orthogonal matrices. If (A,B) was obtained from the generalized real-Schur factorization of an original pair of matrices

   (A0,B0) = (Q*A*Z**H,Q*B*Z**H),

then Z*X and Q*Y are the matrices of right or left eigenvectors of A.

A must be block upper triangular, with 1-by-1 and 2-by-2 diagonal blocks. Corresponding to each 2-by-2 diagonal block is a complex conjugate pair of eigenvalues and eigenvectors; only one

eigenvector of the pair is computed, namely the one corresponding to the eigenvalue with positive imaginary part.


ARGUMENTS


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: 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 ``rowwise'' 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 ``dot product'' step, since it is an inner product between the j-th row and the portion of the eigenvector that has been computed so far.

The ``columnwise'' method 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 LDA (and LDB) 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.