zggevx.c
Go to the documentation of this file.
00001 /* zggevx.f -- translated by f2c (version 20061008).
00002    You must link the resulting object file with libf2c:
00003         on Microsoft Windows system, link with libf2c.lib;
00004         on Linux or Unix systems, link with .../path/to/libf2c.a -lm
00005         or, if you install libf2c.a in a standard place, with -lf2c -lm
00006         -- in that order, at the end of the command line, as in
00007                 cc *.o -lf2c -lm
00008         Source for libf2c is in /netlib/f2c/libf2c.zip, e.g.,
00009 
00010                 http://www.netlib.org/f2c/libf2c.zip
00011 */
00012 
00013 #include "f2c.h"
00014 #include "blaswrap.h"
00015 
00016 /* Table of constant values */
00017 
00018 static doublecomplex c_b1 = {0.,0.};
00019 static doublecomplex c_b2 = {1.,0.};
00020 static integer c__1 = 1;
00021 static integer c__0 = 0;
00022 
00023 /* Subroutine */ int zggevx_(char *balanc, char *jobvl, char *jobvr, char *
00024         sense, integer *n, doublecomplex *a, integer *lda, doublecomplex *b, 
00025         integer *ldb, doublecomplex *alpha, doublecomplex *beta, 
00026         doublecomplex *vl, integer *ldvl, doublecomplex *vr, integer *ldvr, 
00027         integer *ilo, integer *ihi, doublereal *lscale, doublereal *rscale, 
00028         doublereal *abnrm, doublereal *bbnrm, doublereal *rconde, doublereal *
00029         rcondv, doublecomplex *work, integer *lwork, doublereal *rwork, 
00030         integer *iwork, logical *bwork, integer *info)
00031 {
00032     /* System generated locals */
00033     integer a_dim1, a_offset, b_dim1, b_offset, vl_dim1, vl_offset, vr_dim1, 
00034             vr_offset, i__1, i__2, i__3, i__4;
00035     doublereal d__1, d__2, d__3, d__4;
00036     doublecomplex z__1;
00037 
00038     /* Builtin functions */
00039     double sqrt(doublereal), d_imag(doublecomplex *);
00040 
00041     /* Local variables */
00042     integer i__, j, m, jc, in, jr;
00043     doublereal eps;
00044     logical ilv;
00045     doublereal anrm, bnrm;
00046     integer ierr, itau;
00047     doublereal temp;
00048     logical ilvl, ilvr;
00049     integer iwrk, iwrk1;
00050     extern logical lsame_(char *, char *);
00051     integer icols;
00052     logical noscl;
00053     integer irows;
00054     extern /* Subroutine */ int dlabad_(doublereal *, doublereal *);
00055     extern doublereal dlamch_(char *);
00056     extern /* Subroutine */ int dlascl_(char *, integer *, integer *, 
00057             doublereal *, doublereal *, integer *, integer *, doublereal *, 
00058             integer *, integer *), zggbak_(char *, char *, integer *, 
00059             integer *, integer *, doublereal *, doublereal *, integer *, 
00060             doublecomplex *, integer *, integer *), zggbal_(
00061             char *, integer *, doublecomplex *, integer *, doublecomplex *, 
00062             integer *, integer *, integer *, doublereal *, doublereal *, 
00063             doublereal *, integer *);
00064     logical ilascl, ilbscl;
00065     extern /* Subroutine */ int xerbla_(char *, integer *);
00066     extern integer ilaenv_(integer *, char *, char *, integer *, integer *, 
00067             integer *, integer *);
00068     logical ldumma[1];
00069     char chtemp[1];
00070     doublereal bignum;
00071     extern doublereal zlange_(char *, integer *, integer *, doublecomplex *, 
00072             integer *, doublereal *);
00073     integer ijobvl;
00074     extern /* Subroutine */ int zgghrd_(char *, char *, integer *, integer *, 
00075             integer *, doublecomplex *, integer *, doublecomplex *, integer *, 
00076              doublecomplex *, integer *, doublecomplex *, integer *, integer *
00077 ), zlascl_(char *, integer *, integer *, 
00078             doublereal *, doublereal *, integer *, integer *, doublecomplex *, 
00079              integer *, integer *);
00080     integer ijobvr;
00081     logical wantsb;
00082     extern /* Subroutine */ int zgeqrf_(integer *, integer *, doublecomplex *, 
00083              integer *, doublecomplex *, doublecomplex *, integer *, integer *
00084 );
00085     doublereal anrmto;
00086     logical wantse;
00087     doublereal bnrmto;
00088     extern /* Subroutine */ int zlacpy_(char *, integer *, integer *, 
00089             doublecomplex *, integer *, doublecomplex *, integer *), 
00090             zlaset_(char *, integer *, integer *, doublecomplex *, 
00091             doublecomplex *, doublecomplex *, integer *), ztgevc_(
00092             char *, char *, logical *, integer *, doublecomplex *, integer *, 
00093             doublecomplex *, integer *, doublecomplex *, integer *, 
00094             doublecomplex *, integer *, integer *, integer *, doublecomplex *, 
00095              doublereal *, integer *), ztgsna_(char *, char *, 
00096              logical *, integer *, doublecomplex *, integer *, doublecomplex *
00097 , integer *, doublecomplex *, integer *, doublecomplex *, integer 
00098             *, doublereal *, doublereal *, integer *, integer *, 
00099             doublecomplex *, integer *, integer *, integer *);
00100     integer minwrk;
00101     extern /* Subroutine */ int zhgeqz_(char *, char *, char *, integer *, 
00102             integer *, integer *, doublecomplex *, integer *, doublecomplex *, 
00103              integer *, doublecomplex *, doublecomplex *, doublecomplex *, 
00104             integer *, doublecomplex *, integer *, doublecomplex *, integer *, 
00105              doublereal *, integer *);
00106     integer maxwrk;
00107     logical wantsn;
00108     doublereal smlnum;
00109     logical lquery, wantsv;
00110     extern /* Subroutine */ int zungqr_(integer *, integer *, integer *, 
00111             doublecomplex *, integer *, doublecomplex *, doublecomplex *, 
00112             integer *, integer *), zunmqr_(char *, char *, integer *, integer 
00113             *, integer *, doublecomplex *, integer *, doublecomplex *, 
00114             doublecomplex *, integer *, doublecomplex *, integer *, integer *);
00115 
00116 
00117 /*  -- LAPACK driver routine (version 3.2) -- */
00118 /*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
00119 /*     November 2006 */
00120 
00121 /*     .. Scalar Arguments .. */
00122 /*     .. */
00123 /*     .. Array Arguments .. */
00124 /*     .. */
00125 
00126 /*  Purpose */
00127 /*  ======= */
00128 
00129 /*  ZGGEVX computes for a pair of N-by-N complex nonsymmetric matrices */
00130 /*  (A,B) the generalized eigenvalues, and optionally, the left and/or */
00131 /*  right generalized eigenvectors. */
00132 
00133 /*  Optionally, it also computes a balancing transformation to improve */
00134 /*  the conditioning of the eigenvalues and eigenvectors (ILO, IHI, */
00135 /*  LSCALE, RSCALE, ABNRM, and BBNRM), reciprocal condition numbers for */
00136 /*  the eigenvalues (RCONDE), and reciprocal condition numbers for the */
00137 /*  right eigenvectors (RCONDV). */
00138 
00139 /*  A generalized eigenvalue for a pair of matrices (A,B) is a scalar */
00140 /*  lambda or a ratio alpha/beta = lambda, such that A - lambda*B is */
00141 /*  singular. It is usually represented as the pair (alpha,beta), as */
00142 /*  there is a reasonable interpretation for beta=0, and even for both */
00143 /*  being zero. */
00144 
00145 /*  The right eigenvector v(j) corresponding to the eigenvalue lambda(j) */
00146 /*  of (A,B) satisfies */
00147 /*                   A * v(j) = lambda(j) * B * v(j) . */
00148 /*  The left eigenvector u(j) corresponding to the eigenvalue lambda(j) */
00149 /*  of (A,B) satisfies */
00150 /*                   u(j)**H * A  = lambda(j) * u(j)**H * B. */
00151 /*  where u(j)**H is the conjugate-transpose of u(j). */
00152 
00153 
00154 /*  Arguments */
00155 /*  ========= */
00156 
00157 /*  BALANC  (input) CHARACTER*1 */
00158 /*          Specifies the balance option to be performed: */
00159 /*          = 'N':  do not diagonally scale or permute; */
00160 /*          = 'P':  permute only; */
00161 /*          = 'S':  scale only; */
00162 /*          = 'B':  both permute and scale. */
00163 /*          Computed reciprocal condition numbers will be for the */
00164 /*          matrices after permuting and/or balancing. Permuting does */
00165 /*          not change condition numbers (in exact arithmetic), but */
00166 /*          balancing does. */
00167 
00168 /*  JOBVL   (input) CHARACTER*1 */
00169 /*          = 'N':  do not compute the left generalized eigenvectors; */
00170 /*          = 'V':  compute the left generalized eigenvectors. */
00171 
00172 /*  JOBVR   (input) CHARACTER*1 */
00173 /*          = 'N':  do not compute the right generalized eigenvectors; */
00174 /*          = 'V':  compute the right generalized eigenvectors. */
00175 
00176 /*  SENSE   (input) CHARACTER*1 */
00177 /*          Determines which reciprocal condition numbers are computed. */
00178 /*          = 'N': none are computed; */
00179 /*          = 'E': computed for eigenvalues only; */
00180 /*          = 'V': computed for eigenvectors only; */
00181 /*          = 'B': computed for eigenvalues and eigenvectors. */
00182 
00183 /*  N       (input) INTEGER */
00184 /*          The order of the matrices A, B, VL, and VR.  N >= 0. */
00185 
00186 /*  A       (input/output) COMPLEX*16 array, dimension (LDA, N) */
00187 /*          On entry, the matrix A in the pair (A,B). */
00188 /*          On exit, A has been overwritten. If JOBVL='V' or JOBVR='V' */
00189 /*          or both, then A contains the first part of the complex Schur */
00190 /*          form of the "balanced" versions of the input A and B. */
00191 
00192 /*  LDA     (input) INTEGER */
00193 /*          The leading dimension of A.  LDA >= max(1,N). */
00194 
00195 /*  B       (input/output) COMPLEX*16 array, dimension (LDB, N) */
00196 /*          On entry, the matrix B in the pair (A,B). */
00197 /*          On exit, B has been overwritten. If JOBVL='V' or JOBVR='V' */
00198 /*          or both, then B contains the second part of the complex */
00199 /*          Schur form of the "balanced" versions of the input A and B. */
00200 
00201 /*  LDB     (input) INTEGER */
00202 /*          The leading dimension of B.  LDB >= max(1,N). */
00203 
00204 /*  ALPHA   (output) COMPLEX*16 array, dimension (N) */
00205 /*  BETA    (output) COMPLEX*16 array, dimension (N) */
00206 /*          On exit, ALPHA(j)/BETA(j), j=1,...,N, will be the generalized */
00207 /*          eigenvalues. */
00208 
00209 /*          Note: the quotient ALPHA(j)/BETA(j) ) may easily over- or */
00210 /*          underflow, and BETA(j) may even be zero.  Thus, the user */
00211 /*          should avoid naively computing the ratio ALPHA/BETA. */
00212 /*          However, ALPHA will be always less than and usually */
00213 /*          comparable with norm(A) in magnitude, and BETA always less */
00214 /*          than and usually comparable with norm(B). */
00215 
00216 /*  VL      (output) COMPLEX*16 array, dimension (LDVL,N) */
00217 /*          If JOBVL = 'V', the left generalized eigenvectors u(j) are */
00218 /*          stored one after another in the columns of VL, in the same */
00219 /*          order as their eigenvalues. */
00220 /*          Each eigenvector will be scaled so the largest component */
00221 /*          will have abs(real part) + abs(imag. part) = 1. */
00222 /*          Not referenced if JOBVL = 'N'. */
00223 
00224 /*  LDVL    (input) INTEGER */
00225 /*          The leading dimension of the matrix VL. LDVL >= 1, and */
00226 /*          if JOBVL = 'V', LDVL >= N. */
00227 
00228 /*  VR      (output) COMPLEX*16 array, dimension (LDVR,N) */
00229 /*          If JOBVR = 'V', the right generalized eigenvectors v(j) are */
00230 /*          stored one after another in the columns of VR, in the same */
00231 /*          order as their eigenvalues. */
00232 /*          Each eigenvector will be scaled so the largest component */
00233 /*          will have abs(real part) + abs(imag. part) = 1. */
00234 /*          Not referenced if JOBVR = 'N'. */
00235 
00236 /*  LDVR    (input) INTEGER */
00237 /*          The leading dimension of the matrix VR. LDVR >= 1, and */
00238 /*          if JOBVR = 'V', LDVR >= N. */
00239 
00240 /*  ILO     (output) INTEGER */
00241 /*  IHI     (output) INTEGER */
00242 /*          ILO and IHI are integer values such that on exit */
00243 /*          A(i,j) = 0 and B(i,j) = 0 if i > j and */
00244 /*          j = 1,...,ILO-1 or i = IHI+1,...,N. */
00245 /*          If BALANC = 'N' or 'S', ILO = 1 and IHI = N. */
00246 
00247 /*  LSCALE  (output) DOUBLE PRECISION array, dimension (N) */
00248 /*          Details of the permutations and scaling factors applied */
00249 /*          to the left side of A and B.  If PL(j) is the index of the */
00250 /*          row interchanged with row j, and DL(j) is the scaling */
00251 /*          factor applied to row j, then */
00252 /*            LSCALE(j) = PL(j)  for j = 1,...,ILO-1 */
00253 /*                      = DL(j)  for j = ILO,...,IHI */
00254 /*                      = PL(j)  for j = IHI+1,...,N. */
00255 /*          The order in which the interchanges are made is N to IHI+1, */
00256 /*          then 1 to ILO-1. */
00257 
00258 /*  RSCALE  (output) DOUBLE PRECISION array, dimension (N) */
00259 /*          Details of the permutations and scaling factors applied */
00260 /*          to the right side of A and B.  If PR(j) is the index of the */
00261 /*          column interchanged with column j, and DR(j) is the scaling */
00262 /*          factor applied to column j, then */
00263 /*            RSCALE(j) = PR(j)  for j = 1,...,ILO-1 */
00264 /*                      = DR(j)  for j = ILO,...,IHI */
00265 /*                      = PR(j)  for j = IHI+1,...,N */
00266 /*          The order in which the interchanges are made is N to IHI+1, */
00267 /*          then 1 to ILO-1. */
00268 
00269 /*  ABNRM   (output) DOUBLE PRECISION */
00270 /*          The one-norm of the balanced matrix A. */
00271 
00272 /*  BBNRM   (output) DOUBLE PRECISION */
00273 /*          The one-norm of the balanced matrix B. */
00274 
00275 /*  RCONDE  (output) DOUBLE PRECISION array, dimension (N) */
00276 /*          If SENSE = 'E' or 'B', the reciprocal condition numbers of */
00277 /*          the eigenvalues, stored in consecutive elements of the array. */
00278 /*          If SENSE = 'N' or 'V', RCONDE is not referenced. */
00279 
00280 /*  RCONDV  (output) DOUBLE PRECISION array, dimension (N) */
00281 /*          If JOB = 'V' or 'B', the estimated reciprocal condition */
00282 /*          numbers of the eigenvectors, stored in consecutive elements */
00283 /*          of the array. If the eigenvalues cannot be reordered to */
00284 /*          compute RCONDV(j), RCONDV(j) is set to 0; this can only occur */
00285 /*          when the true value would be very small anyway. */
00286 /*          If SENSE = 'N' or 'E', RCONDV is not referenced. */
00287 
00288 /*  WORK    (workspace/output) COMPLEX*16 array, dimension (MAX(1,LWORK)) */
00289 /*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK. */
00290 
00291 /*  LWORK   (input) INTEGER */
00292 /*          The dimension of the array WORK. LWORK >= max(1,2*N). */
00293 /*          If SENSE = 'E', LWORK >= max(1,4*N). */
00294 /*          If SENSE = 'V' or 'B', LWORK >= max(1,2*N*N+2*N). */
00295 
00296 /*          If LWORK = -1, then a workspace query is assumed; the routine */
00297 /*          only calculates the optimal size of the WORK array, returns */
00298 /*          this value as the first entry of the WORK array, and no error */
00299 /*          message related to LWORK is issued by XERBLA. */
00300 
00301 /*  RWORK   (workspace) REAL array, dimension (lrwork) */
00302 /*          lrwork must be at least max(1,6*N) if BALANC = 'S' or 'B', */
00303 /*          and at least max(1,2*N) otherwise. */
00304 /*          Real workspace. */
00305 
00306 /*  IWORK   (workspace) INTEGER array, dimension (N+2) */
00307 /*          If SENSE = 'E', IWORK is not referenced. */
00308 
00309 /*  BWORK   (workspace) LOGICAL array, dimension (N) */
00310 /*          If SENSE = 'N', BWORK is not referenced. */
00311 
00312 /*  INFO    (output) INTEGER */
00313 /*          = 0:  successful exit */
00314 /*          < 0:  if INFO = -i, the i-th argument had an illegal value. */
00315 /*          = 1,...,N: */
00316 /*                The QZ iteration failed.  No eigenvectors have been */
00317 /*                calculated, but ALPHA(j) and BETA(j) should be correct */
00318 /*                for j=INFO+1,...,N. */
00319 /*          > N:  =N+1: other than QZ iteration failed in ZHGEQZ. */
00320 /*                =N+2: error return from ZTGEVC. */
00321 
00322 /*  Further Details */
00323 /*  =============== */
00324 
00325 /*  Balancing a matrix pair (A,B) includes, first, permuting rows and */
00326 /*  columns to isolate eigenvalues, second, applying diagonal similarity */
00327 /*  transformation to the rows and columns to make the rows and columns */
00328 /*  as close in norm as possible. The computed reciprocal condition */
00329 /*  numbers correspond to the balanced matrix. Permuting rows and columns */
00330 /*  will not change the condition numbers (in exact arithmetic) but */
00331 /*  diagonal scaling will.  For further explanation of balancing, see */
00332 /*  section 4.11.1.2 of LAPACK Users' Guide. */
00333 
00334 /*  An approximate error bound on the chordal distance between the i-th */
00335 /*  computed generalized eigenvalue w and the corresponding exact */
00336 /*  eigenvalue lambda is */
00337 
00338 /*       chord(w, lambda) <= EPS * norm(ABNRM, BBNRM) / RCONDE(I) */
00339 
00340 /*  An approximate error bound for the angle between the i-th computed */
00341 /*  eigenvector VL(i) or VR(i) is given by */
00342 
00343 /*       EPS * norm(ABNRM, BBNRM) / DIF(i). */
00344 
00345 /*  For further explanation of the reciprocal condition numbers RCONDE */
00346 /*  and RCONDV, see section 4.11 of LAPACK User's Guide. */
00347 
00348 /*     .. Parameters .. */
00349 /*     .. */
00350 /*     .. Local Scalars .. */
00351 /*     .. */
00352 /*     .. Local Arrays .. */
00353 /*     .. */
00354 /*     .. External Subroutines .. */
00355 /*     .. */
00356 /*     .. External Functions .. */
00357 /*     .. */
00358 /*     .. Intrinsic Functions .. */
00359 /*     .. */
00360 /*     .. Statement Functions .. */
00361 /*     .. */
00362 /*     .. Statement Function definitions .. */
00363 /*     .. */
00364 /*     .. Executable Statements .. */
00365 
00366 /*     Decode the input arguments */
00367 
00368     /* Parameter adjustments */
00369     a_dim1 = *lda;
00370     a_offset = 1 + a_dim1;
00371     a -= a_offset;
00372     b_dim1 = *ldb;
00373     b_offset = 1 + b_dim1;
00374     b -= b_offset;
00375     --alpha;
00376     --beta;
00377     vl_dim1 = *ldvl;
00378     vl_offset = 1 + vl_dim1;
00379     vl -= vl_offset;
00380     vr_dim1 = *ldvr;
00381     vr_offset = 1 + vr_dim1;
00382     vr -= vr_offset;
00383     --lscale;
00384     --rscale;
00385     --rconde;
00386     --rcondv;
00387     --work;
00388     --rwork;
00389     --iwork;
00390     --bwork;
00391 
00392     /* Function Body */
00393     if (lsame_(jobvl, "N")) {
00394         ijobvl = 1;
00395         ilvl = FALSE_;
00396     } else if (lsame_(jobvl, "V")) {
00397         ijobvl = 2;
00398         ilvl = TRUE_;
00399     } else {
00400         ijobvl = -1;
00401         ilvl = FALSE_;
00402     }
00403 
00404     if (lsame_(jobvr, "N")) {
00405         ijobvr = 1;
00406         ilvr = FALSE_;
00407     } else if (lsame_(jobvr, "V")) {
00408         ijobvr = 2;
00409         ilvr = TRUE_;
00410     } else {
00411         ijobvr = -1;
00412         ilvr = FALSE_;
00413     }
00414     ilv = ilvl || ilvr;
00415 
00416     noscl = lsame_(balanc, "N") || lsame_(balanc, "P");
00417     wantsn = lsame_(sense, "N");
00418     wantse = lsame_(sense, "E");
00419     wantsv = lsame_(sense, "V");
00420     wantsb = lsame_(sense, "B");
00421 
00422 /*     Test the input arguments */
00423 
00424     *info = 0;
00425     lquery = *lwork == -1;
00426     if (! (noscl || lsame_(balanc, "S") || lsame_(
00427             balanc, "B"))) {
00428         *info = -1;
00429     } else if (ijobvl <= 0) {
00430         *info = -2;
00431     } else if (ijobvr <= 0) {
00432         *info = -3;
00433     } else if (! (wantsn || wantse || wantsb || wantsv)) {
00434         *info = -4;
00435     } else if (*n < 0) {
00436         *info = -5;
00437     } else if (*lda < max(1,*n)) {
00438         *info = -7;
00439     } else if (*ldb < max(1,*n)) {
00440         *info = -9;
00441     } else if (*ldvl < 1 || ilvl && *ldvl < *n) {
00442         *info = -13;
00443     } else if (*ldvr < 1 || ilvr && *ldvr < *n) {
00444         *info = -15;
00445     }
00446 
00447 /*     Compute workspace */
00448 /*      (Note: Comments in the code beginning "Workspace:" describe the */
00449 /*       minimal amount of workspace needed at that point in the code, */
00450 /*       as well as the preferred amount for good performance. */
00451 /*       NB refers to the optimal block size for the immediately */
00452 /*       following subroutine, as returned by ILAENV. The workspace is */
00453 /*       computed assuming ILO = 1 and IHI = N, the worst case.) */
00454 
00455     if (*info == 0) {
00456         if (*n == 0) {
00457             minwrk = 1;
00458             maxwrk = 1;
00459         } else {
00460             minwrk = *n << 1;
00461             if (wantse) {
00462                 minwrk = *n << 2;
00463             } else if (wantsv || wantsb) {
00464                 minwrk = (*n << 1) * (*n + 1);
00465             }
00466             maxwrk = minwrk;
00467 /* Computing MAX */
00468             i__1 = maxwrk, i__2 = *n + *n * ilaenv_(&c__1, "ZGEQRF", " ", n, &
00469                     c__1, n, &c__0);
00470             maxwrk = max(i__1,i__2);
00471 /* Computing MAX */
00472             i__1 = maxwrk, i__2 = *n + *n * ilaenv_(&c__1, "ZUNMQR", " ", n, &
00473                     c__1, n, &c__0);
00474             maxwrk = max(i__1,i__2);
00475             if (ilvl) {
00476 /* Computing MAX */
00477                 i__1 = maxwrk, i__2 = *n + *n * ilaenv_(&c__1, "ZUNGQR", 
00478                         " ", n, &c__1, n, &c__0);
00479                 maxwrk = max(i__1,i__2);
00480             }
00481         }
00482         work[1].r = (doublereal) maxwrk, work[1].i = 0.;
00483 
00484         if (*lwork < minwrk && ! lquery) {
00485             *info = -25;
00486         }
00487     }
00488 
00489     if (*info != 0) {
00490         i__1 = -(*info);
00491         xerbla_("ZGGEVX", &i__1);
00492         return 0;
00493     } else if (lquery) {
00494         return 0;
00495     }
00496 
00497 /*     Quick return if possible */
00498 
00499     if (*n == 0) {
00500         return 0;
00501     }
00502 
00503 /*     Get machine constants */
00504 
00505     eps = dlamch_("P");
00506     smlnum = dlamch_("S");
00507     bignum = 1. / smlnum;
00508     dlabad_(&smlnum, &bignum);
00509     smlnum = sqrt(smlnum) / eps;
00510     bignum = 1. / smlnum;
00511 
00512 /*     Scale A if max element outside range [SMLNUM,BIGNUM] */
00513 
00514     anrm = zlange_("M", n, n, &a[a_offset], lda, &rwork[1]);
00515     ilascl = FALSE_;
00516     if (anrm > 0. && anrm < smlnum) {
00517         anrmto = smlnum;
00518         ilascl = TRUE_;
00519     } else if (anrm > bignum) {
00520         anrmto = bignum;
00521         ilascl = TRUE_;
00522     }
00523     if (ilascl) {
00524         zlascl_("G", &c__0, &c__0, &anrm, &anrmto, n, n, &a[a_offset], lda, &
00525                 ierr);
00526     }
00527 
00528 /*     Scale B if max element outside range [SMLNUM,BIGNUM] */
00529 
00530     bnrm = zlange_("M", n, n, &b[b_offset], ldb, &rwork[1]);
00531     ilbscl = FALSE_;
00532     if (bnrm > 0. && bnrm < smlnum) {
00533         bnrmto = smlnum;
00534         ilbscl = TRUE_;
00535     } else if (bnrm > bignum) {
00536         bnrmto = bignum;
00537         ilbscl = TRUE_;
00538     }
00539     if (ilbscl) {
00540         zlascl_("G", &c__0, &c__0, &bnrm, &bnrmto, n, n, &b[b_offset], ldb, &
00541                 ierr);
00542     }
00543 
00544 /*     Permute and/or balance the matrix pair (A,B) */
00545 /*     (Real Workspace: need 6*N if BALANC = 'S' or 'B', 1 otherwise) */
00546 
00547     zggbal_(balanc, n, &a[a_offset], lda, &b[b_offset], ldb, ilo, ihi, &
00548             lscale[1], &rscale[1], &rwork[1], &ierr);
00549 
00550 /*     Compute ABNRM and BBNRM */
00551 
00552     *abnrm = zlange_("1", n, n, &a[a_offset], lda, &rwork[1]);
00553     if (ilascl) {
00554         rwork[1] = *abnrm;
00555         dlascl_("G", &c__0, &c__0, &anrmto, &anrm, &c__1, &c__1, &rwork[1], &
00556                 c__1, &ierr);
00557         *abnrm = rwork[1];
00558     }
00559 
00560     *bbnrm = zlange_("1", n, n, &b[b_offset], ldb, &rwork[1]);
00561     if (ilbscl) {
00562         rwork[1] = *bbnrm;
00563         dlascl_("G", &c__0, &c__0, &bnrmto, &bnrm, &c__1, &c__1, &rwork[1], &
00564                 c__1, &ierr);
00565         *bbnrm = rwork[1];
00566     }
00567 
00568 /*     Reduce B to triangular form (QR decomposition of B) */
00569 /*     (Complex Workspace: need N, prefer N*NB ) */
00570 
00571     irows = *ihi + 1 - *ilo;
00572     if (ilv || ! wantsn) {
00573         icols = *n + 1 - *ilo;
00574     } else {
00575         icols = irows;
00576     }
00577     itau = 1;
00578     iwrk = itau + irows;
00579     i__1 = *lwork + 1 - iwrk;
00580     zgeqrf_(&irows, &icols, &b[*ilo + *ilo * b_dim1], ldb, &work[itau], &work[
00581             iwrk], &i__1, &ierr);
00582 
00583 /*     Apply the unitary transformation to A */
00584 /*     (Complex Workspace: need N, prefer N*NB) */
00585 
00586     i__1 = *lwork + 1 - iwrk;
00587     zunmqr_("L", "C", &irows, &icols, &irows, &b[*ilo + *ilo * b_dim1], ldb, &
00588             work[itau], &a[*ilo + *ilo * a_dim1], lda, &work[iwrk], &i__1, &
00589             ierr);
00590 
00591 /*     Initialize VL and/or VR */
00592 /*     (Workspace: need N, prefer N*NB) */
00593 
00594     if (ilvl) {
00595         zlaset_("Full", n, n, &c_b1, &c_b2, &vl[vl_offset], ldvl);
00596         if (irows > 1) {
00597             i__1 = irows - 1;
00598             i__2 = irows - 1;
00599             zlacpy_("L", &i__1, &i__2, &b[*ilo + 1 + *ilo * b_dim1], ldb, &vl[
00600                     *ilo + 1 + *ilo * vl_dim1], ldvl);
00601         }
00602         i__1 = *lwork + 1 - iwrk;
00603         zungqr_(&irows, &irows, &irows, &vl[*ilo + *ilo * vl_dim1], ldvl, &
00604                 work[itau], &work[iwrk], &i__1, &ierr);
00605     }
00606 
00607     if (ilvr) {
00608         zlaset_("Full", n, n, &c_b1, &c_b2, &vr[vr_offset], ldvr);
00609     }
00610 
00611 /*     Reduce to generalized Hessenberg form */
00612 /*     (Workspace: none needed) */
00613 
00614     if (ilv || ! wantsn) {
00615 
00616 /*        Eigenvectors requested -- work on whole matrix. */
00617 
00618         zgghrd_(jobvl, jobvr, n, ilo, ihi, &a[a_offset], lda, &b[b_offset], 
00619                 ldb, &vl[vl_offset], ldvl, &vr[vr_offset], ldvr, &ierr);
00620     } else {
00621         zgghrd_("N", "N", &irows, &c__1, &irows, &a[*ilo + *ilo * a_dim1], 
00622                 lda, &b[*ilo + *ilo * b_dim1], ldb, &vl[vl_offset], ldvl, &vr[
00623                 vr_offset], ldvr, &ierr);
00624     }
00625 
00626 /*     Perform QZ algorithm (Compute eigenvalues, and optionally, the */
00627 /*     Schur forms and Schur vectors) */
00628 /*     (Complex Workspace: need N) */
00629 /*     (Real Workspace: need N) */
00630 
00631     iwrk = itau;
00632     if (ilv || ! wantsn) {
00633         *(unsigned char *)chtemp = 'S';
00634     } else {
00635         *(unsigned char *)chtemp = 'E';
00636     }
00637 
00638     i__1 = *lwork + 1 - iwrk;
00639     zhgeqz_(chtemp, jobvl, jobvr, n, ilo, ihi, &a[a_offset], lda, &b[b_offset]
00640 , ldb, &alpha[1], &beta[1], &vl[vl_offset], ldvl, &vr[vr_offset], 
00641             ldvr, &work[iwrk], &i__1, &rwork[1], &ierr);
00642     if (ierr != 0) {
00643         if (ierr > 0 && ierr <= *n) {
00644             *info = ierr;
00645         } else if (ierr > *n && ierr <= *n << 1) {
00646             *info = ierr - *n;
00647         } else {
00648             *info = *n + 1;
00649         }
00650         goto L90;
00651     }
00652 
00653 /*     Compute Eigenvectors and estimate condition numbers if desired */
00654 /*     ZTGEVC: (Complex Workspace: need 2*N ) */
00655 /*             (Real Workspace:    need 2*N ) */
00656 /*     ZTGSNA: (Complex Workspace: need 2*N*N if SENSE='V' or 'B') */
00657 /*             (Integer Workspace: need N+2 ) */
00658 
00659     if (ilv || ! wantsn) {
00660         if (ilv) {
00661             if (ilvl) {
00662                 if (ilvr) {
00663                     *(unsigned char *)chtemp = 'B';
00664                 } else {
00665                     *(unsigned char *)chtemp = 'L';
00666                 }
00667             } else {
00668                 *(unsigned char *)chtemp = 'R';
00669             }
00670 
00671             ztgevc_(chtemp, "B", ldumma, n, &a[a_offset], lda, &b[b_offset], 
00672                     ldb, &vl[vl_offset], ldvl, &vr[vr_offset], ldvr, n, &in, &
00673                     work[iwrk], &rwork[1], &ierr);
00674             if (ierr != 0) {
00675                 *info = *n + 2;
00676                 goto L90;
00677             }
00678         }
00679 
00680         if (! wantsn) {
00681 
00682 /*           compute eigenvectors (DTGEVC) and estimate condition */
00683 /*           numbers (DTGSNA). Note that the definition of the condition */
00684 /*           number is not invariant under transformation (u,v) to */
00685 /*           (Q*u, Z*v), where (u,v) are eigenvectors of the generalized */
00686 /*           Schur form (S,T), Q and Z are orthogonal matrices. In order */
00687 /*           to avoid using extra 2*N*N workspace, we have to */
00688 /*           re-calculate eigenvectors and estimate the condition numbers */
00689 /*           one at a time. */
00690 
00691             i__1 = *n;
00692             for (i__ = 1; i__ <= i__1; ++i__) {
00693 
00694                 i__2 = *n;
00695                 for (j = 1; j <= i__2; ++j) {
00696                     bwork[j] = FALSE_;
00697 /* L10: */
00698                 }
00699                 bwork[i__] = TRUE_;
00700 
00701                 iwrk = *n + 1;
00702                 iwrk1 = iwrk + *n;
00703 
00704                 if (wantse || wantsb) {
00705                     ztgevc_("B", "S", &bwork[1], n, &a[a_offset], lda, &b[
00706                             b_offset], ldb, &work[1], n, &work[iwrk], n, &
00707                             c__1, &m, &work[iwrk1], &rwork[1], &ierr);
00708                     if (ierr != 0) {
00709                         *info = *n + 2;
00710                         goto L90;
00711                     }
00712                 }
00713 
00714                 i__2 = *lwork - iwrk1 + 1;
00715                 ztgsna_(sense, "S", &bwork[1], n, &a[a_offset], lda, &b[
00716                         b_offset], ldb, &work[1], n, &work[iwrk], n, &rconde[
00717                         i__], &rcondv[i__], &c__1, &m, &work[iwrk1], &i__2, &
00718                         iwork[1], &ierr);
00719 
00720 /* L20: */
00721             }
00722         }
00723     }
00724 
00725 /*     Undo balancing on VL and VR and normalization */
00726 /*     (Workspace: none needed) */
00727 
00728     if (ilvl) {
00729         zggbak_(balanc, "L", n, ilo, ihi, &lscale[1], &rscale[1], n, &vl[
00730                 vl_offset], ldvl, &ierr);
00731 
00732         i__1 = *n;
00733         for (jc = 1; jc <= i__1; ++jc) {
00734             temp = 0.;
00735             i__2 = *n;
00736             for (jr = 1; jr <= i__2; ++jr) {
00737 /* Computing MAX */
00738                 i__3 = jr + jc * vl_dim1;
00739                 d__3 = temp, d__4 = (d__1 = vl[i__3].r, abs(d__1)) + (d__2 = 
00740                         d_imag(&vl[jr + jc * vl_dim1]), abs(d__2));
00741                 temp = max(d__3,d__4);
00742 /* L30: */
00743             }
00744             if (temp < smlnum) {
00745                 goto L50;
00746             }
00747             temp = 1. / temp;
00748             i__2 = *n;
00749             for (jr = 1; jr <= i__2; ++jr) {
00750                 i__3 = jr + jc * vl_dim1;
00751                 i__4 = jr + jc * vl_dim1;
00752                 z__1.r = temp * vl[i__4].r, z__1.i = temp * vl[i__4].i;
00753                 vl[i__3].r = z__1.r, vl[i__3].i = z__1.i;
00754 /* L40: */
00755             }
00756 L50:
00757             ;
00758         }
00759     }
00760 
00761     if (ilvr) {
00762         zggbak_(balanc, "R", n, ilo, ihi, &lscale[1], &rscale[1], n, &vr[
00763                 vr_offset], ldvr, &ierr);
00764         i__1 = *n;
00765         for (jc = 1; jc <= i__1; ++jc) {
00766             temp = 0.;
00767             i__2 = *n;
00768             for (jr = 1; jr <= i__2; ++jr) {
00769 /* Computing MAX */
00770                 i__3 = jr + jc * vr_dim1;
00771                 d__3 = temp, d__4 = (d__1 = vr[i__3].r, abs(d__1)) + (d__2 = 
00772                         d_imag(&vr[jr + jc * vr_dim1]), abs(d__2));
00773                 temp = max(d__3,d__4);
00774 /* L60: */
00775             }
00776             if (temp < smlnum) {
00777                 goto L80;
00778             }
00779             temp = 1. / temp;
00780             i__2 = *n;
00781             for (jr = 1; jr <= i__2; ++jr) {
00782                 i__3 = jr + jc * vr_dim1;
00783                 i__4 = jr + jc * vr_dim1;
00784                 z__1.r = temp * vr[i__4].r, z__1.i = temp * vr[i__4].i;
00785                 vr[i__3].r = z__1.r, vr[i__3].i = z__1.i;
00786 /* L70: */
00787             }
00788 L80:
00789             ;
00790         }
00791     }
00792 
00793 /*     Undo scaling if necessary */
00794 
00795     if (ilascl) {
00796         zlascl_("G", &c__0, &c__0, &anrmto, &anrm, n, &c__1, &alpha[1], n, &
00797                 ierr);
00798     }
00799 
00800     if (ilbscl) {
00801         zlascl_("G", &c__0, &c__0, &bnrmto, &bnrm, n, &c__1, &beta[1], n, &
00802                 ierr);
00803     }
00804 
00805 L90:
00806     work[1].r = (doublereal) maxwrk, work[1].i = 0.;
00807 
00808     return 0;
00809 
00810 /*     End of ZGGEVX */
00811 
00812 } /* zggevx_ */


swiftnav
Author(s):
autogenerated on Sat Jun 8 2019 18:56:36