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


swiftnav
Author(s):
autogenerated on Sat Jun 8 2019 18:55:27