zggesx.c
Go to the documentation of this file.
00001 /* zggesx.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 static integer c_n1 = -1;
00023 
00024 /* Subroutine */ int zggesx_(char *jobvsl, char *jobvsr, char *sort, L_fp 
00025         selctg, char *sense, integer *n, doublecomplex *a, integer *lda, 
00026         doublecomplex *b, integer *ldb, integer *sdim, doublecomplex *alpha, 
00027         doublecomplex *beta, doublecomplex *vsl, integer *ldvsl, 
00028         doublecomplex *vsr, integer *ldvsr, doublereal *rconde, doublereal *
00029         rcondv, doublecomplex *work, integer *lwork, doublereal *rwork, 
00030         integer *iwork, integer *liwork, logical *bwork, integer *info)
00031 {
00032     /* System generated locals */
00033     integer a_dim1, a_offset, b_dim1, b_offset, vsl_dim1, vsl_offset, 
00034             vsr_dim1, vsr_offset, i__1, i__2;
00035 
00036     /* Builtin functions */
00037     double sqrt(doublereal);
00038 
00039     /* Local variables */
00040     integer i__;
00041     doublereal pl, pr, dif[2];
00042     integer ihi, ilo;
00043     doublereal eps;
00044     integer ijob;
00045     doublereal anrm, bnrm;
00046     integer ierr, itau, iwrk, lwrk;
00047     extern logical lsame_(char *, char *);
00048     integer ileft, icols;
00049     logical cursl, ilvsl, ilvsr;
00050     integer irwrk, irows;
00051     extern /* Subroutine */ int dlabad_(doublereal *, doublereal *);
00052     extern doublereal dlamch_(char *);
00053     extern /* Subroutine */ int zggbak_(char *, char *, integer *, integer *, 
00054             integer *, doublereal *, doublereal *, integer *, doublecomplex *, 
00055              integer *, integer *), zggbal_(char *, integer *, 
00056              doublecomplex *, integer *, doublecomplex *, integer *, integer *
00057 , integer *, doublereal *, doublereal *, doublereal *, integer *);
00058     logical ilascl, ilbscl;
00059     extern /* Subroutine */ int xerbla_(char *, integer *);
00060     extern integer ilaenv_(integer *, char *, char *, integer *, integer *, 
00061             integer *, integer *);
00062     extern doublereal zlange_(char *, integer *, integer *, doublecomplex *, 
00063             integer *, doublereal *);
00064     doublereal bignum;
00065     integer ijobvl, iright;
00066     extern /* Subroutine */ int zgghrd_(char *, char *, integer *, integer *, 
00067             integer *, doublecomplex *, integer *, doublecomplex *, integer *, 
00068              doublecomplex *, integer *, doublecomplex *, integer *, integer *
00069 ), zlascl_(char *, integer *, integer *, 
00070             doublereal *, doublereal *, integer *, integer *, doublecomplex *, 
00071              integer *, integer *);
00072     integer ijobvr;
00073     logical wantsb;
00074     integer liwmin;
00075     logical wantse, lastsl;
00076     doublereal anrmto, bnrmto;
00077     extern /* Subroutine */ int zgeqrf_(integer *, integer *, doublecomplex *, 
00078              integer *, doublecomplex *, doublecomplex *, integer *, integer *
00079 );
00080     integer maxwrk;
00081     logical wantsn;
00082     integer minwrk;
00083     doublereal smlnum;
00084     extern /* Subroutine */ int zhgeqz_(char *, char *, char *, integer *, 
00085             integer *, integer *, doublecomplex *, integer *, doublecomplex *, 
00086              integer *, doublecomplex *, doublecomplex *, doublecomplex *, 
00087             integer *, doublecomplex *, integer *, doublecomplex *, integer *, 
00088              doublereal *, integer *), zlacpy_(char *, 
00089              integer *, integer *, doublecomplex *, integer *, doublecomplex *
00090 , integer *), zlaset_(char *, integer *, integer *, 
00091             doublecomplex *, doublecomplex *, doublecomplex *, integer *);
00092     logical wantst, lquery, wantsv;
00093     extern /* Subroutine */ int ztgsen_(integer *, logical *, logical *, 
00094             logical *, integer *, doublecomplex *, integer *, doublecomplex *, 
00095              integer *, doublecomplex *, doublecomplex *, doublecomplex *, 
00096             integer *, doublecomplex *, integer *, integer *, doublereal *, 
00097             doublereal *, doublereal *, doublecomplex *, integer *, integer *, 
00098              integer *, integer *), zungqr_(integer *, integer *, integer *, 
00099             doublecomplex *, integer *, doublecomplex *, doublecomplex *, 
00100             integer *, integer *), zunmqr_(char *, char *, integer *, integer 
00101             *, integer *, doublecomplex *, integer *, doublecomplex *, 
00102             doublecomplex *, integer *, doublecomplex *, integer *, integer *);
00103 
00104 
00105 /*  -- LAPACK driver routine (version 3.2) -- */
00106 /*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
00107 /*     November 2006 */
00108 
00109 /*     .. Scalar Arguments .. */
00110 /*     .. */
00111 /*     .. Array Arguments .. */
00112 /*     .. */
00113 /*     .. Function Arguments .. */
00114 /*     .. */
00115 
00116 /*  Purpose */
00117 /*  ======= */
00118 
00119 /*  ZGGESX computes for a pair of N-by-N complex nonsymmetric matrices */
00120 /*  (A,B), the generalized eigenvalues, the complex Schur form (S,T), */
00121 /*  and, optionally, the left and/or right matrices of Schur vectors (VSL */
00122 /*  and VSR).  This gives the generalized Schur factorization */
00123 
00124 /*       (A,B) = ( (VSL) S (VSR)**H, (VSL) T (VSR)**H ) */
00125 
00126 /*  where (VSR)**H is the conjugate-transpose of VSR. */
00127 
00128 /*  Optionally, it also orders the eigenvalues so that a selected cluster */
00129 /*  of eigenvalues appears in the leading diagonal blocks of the upper */
00130 /*  triangular matrix S and the upper triangular matrix T; computes */
00131 /*  a reciprocal condition number for the average of the selected */
00132 /*  eigenvalues (RCONDE); and computes a reciprocal condition number for */
00133 /*  the right and left deflating subspaces corresponding to the selected */
00134 /*  eigenvalues (RCONDV). The leading columns of VSL and VSR then form */
00135 /*  an orthonormal basis for the corresponding left and right eigenspaces */
00136 /*  (deflating subspaces). */
00137 
00138 /*  A generalized eigenvalue for a pair of matrices (A,B) is a scalar w */
00139 /*  or a ratio alpha/beta = w, such that  A - w*B is singular.  It is */
00140 /*  usually represented as the pair (alpha,beta), as there is a */
00141 /*  reasonable interpretation for beta=0 or for both being zero. */
00142 
00143 /*  A pair of matrices (S,T) is in generalized complex Schur form if T is */
00144 /*  upper triangular with non-negative diagonal and S is upper */
00145 /*  triangular. */
00146 
00147 /*  Arguments */
00148 /*  ========= */
00149 
00150 /*  JOBVSL  (input) CHARACTER*1 */
00151 /*          = 'N':  do not compute the left Schur vectors; */
00152 /*          = 'V':  compute the left Schur vectors. */
00153 
00154 /*  JOBVSR  (input) CHARACTER*1 */
00155 /*          = 'N':  do not compute the right Schur vectors; */
00156 /*          = 'V':  compute the right Schur vectors. */
00157 
00158 /*  SORT    (input) CHARACTER*1 */
00159 /*          Specifies whether or not to order the eigenvalues on the */
00160 /*          diagonal of the generalized Schur form. */
00161 /*          = 'N':  Eigenvalues are not ordered; */
00162 /*          = 'S':  Eigenvalues are ordered (see SELCTG). */
00163 
00164 /*  SELCTG  (external procedure) LOGICAL FUNCTION of two COMPLEX*16 arguments */
00165 /*          SELCTG must be declared EXTERNAL in the calling subroutine. */
00166 /*          If SORT = 'N', SELCTG is not referenced. */
00167 /*          If SORT = 'S', SELCTG is used to select eigenvalues to sort */
00168 /*          to the top left of the Schur form. */
00169 /*          Note that a selected complex eigenvalue may no longer satisfy */
00170 /*          SELCTG(ALPHA(j),BETA(j)) = .TRUE. after ordering, since */
00171 /*          ordering may change the value of complex eigenvalues */
00172 /*          (especially if the eigenvalue is ill-conditioned), in this */
00173 /*          case INFO is set to N+3 see INFO below). */
00174 
00175 /*  SENSE   (input) CHARACTER*1 */
00176 /*          Determines which reciprocal condition numbers are computed. */
00177 /*          = 'N' : None are computed; */
00178 /*          = 'E' : Computed for average of selected eigenvalues only; */
00179 /*          = 'V' : Computed for selected deflating subspaces only; */
00180 /*          = 'B' : Computed for both. */
00181 /*          If SENSE = 'E', 'V', or 'B', SORT must equal 'S'. */
00182 
00183 /*  N       (input) INTEGER */
00184 /*          The order of the matrices A, B, VSL, and VSR.  N >= 0. */
00185 
00186 /*  A       (input/output) COMPLEX*16 array, dimension (LDA, N) */
00187 /*          On entry, the first of the pair of matrices. */
00188 /*          On exit, A has been overwritten by its generalized Schur */
00189 /*          form S. */
00190 
00191 /*  LDA     (input) INTEGER */
00192 /*          The leading dimension of A.  LDA >= max(1,N). */
00193 
00194 /*  B       (input/output) COMPLEX*16 array, dimension (LDB, N) */
00195 /*          On entry, the second of the pair of matrices. */
00196 /*          On exit, B has been overwritten by its generalized Schur */
00197 /*          form T. */
00198 
00199 /*  LDB     (input) INTEGER */
00200 /*          The leading dimension of B.  LDB >= max(1,N). */
00201 
00202 /*  SDIM    (output) INTEGER */
00203 /*          If SORT = 'N', SDIM = 0. */
00204 /*          If SORT = 'S', SDIM = number of eigenvalues (after sorting) */
00205 /*          for which SELCTG is true. */
00206 
00207 /*  ALPHA   (output) COMPLEX*16 array, dimension (N) */
00208 /*  BETA    (output) COMPLEX*16 array, dimension (N) */
00209 /*          On exit, ALPHA(j)/BETA(j), j=1,...,N, will be the */
00210 /*          generalized eigenvalues.  ALPHA(j) and BETA(j),j=1,...,N  are */
00211 /*          the diagonals of the complex Schur form (S,T).  BETA(j) will */
00212 /*          be non-negative real. */
00213 
00214 /*          Note: the quotients ALPHA(j)/BETA(j) may easily over- or */
00215 /*          underflow, and BETA(j) may even be zero.  Thus, the user */
00216 /*          should avoid naively computing the ratio alpha/beta. */
00217 /*          However, ALPHA will be always less than and usually */
00218 /*          comparable with norm(A) in magnitude, and BETA always less */
00219 /*          than and usually comparable with norm(B). */
00220 
00221 /*  VSL     (output) COMPLEX*16 array, dimension (LDVSL,N) */
00222 /*          If JOBVSL = 'V', VSL will contain the left Schur vectors. */
00223 /*          Not referenced if JOBVSL = 'N'. */
00224 
00225 /*  LDVSL   (input) INTEGER */
00226 /*          The leading dimension of the matrix VSL. LDVSL >=1, and */
00227 /*          if JOBVSL = 'V', LDVSL >= N. */
00228 
00229 /*  VSR     (output) COMPLEX*16 array, dimension (LDVSR,N) */
00230 /*          If JOBVSR = 'V', VSR will contain the right Schur vectors. */
00231 /*          Not referenced if JOBVSR = 'N'. */
00232 
00233 /*  LDVSR   (input) INTEGER */
00234 /*          The leading dimension of the matrix VSR. LDVSR >= 1, and */
00235 /*          if JOBVSR = 'V', LDVSR >= N. */
00236 
00237 /*  RCONDE  (output) DOUBLE PRECISION array, dimension ( 2 ) */
00238 /*          If SENSE = 'E' or 'B', RCONDE(1) and RCONDE(2) contain the */
00239 /*          reciprocal condition numbers for the average of the selected */
00240 /*          eigenvalues. */
00241 /*          Not referenced if SENSE = 'N' or 'V'. */
00242 
00243 /*  RCONDV  (output) DOUBLE PRECISION array, dimension ( 2 ) */
00244 /*          If SENSE = 'V' or 'B', RCONDV(1) and RCONDV(2) contain the */
00245 /*          reciprocal condition number for the selected deflating */
00246 /*          subspaces. */
00247 /*          Not referenced if SENSE = 'N' or 'E'. */
00248 
00249 /*  WORK    (workspace/output) COMPLEX*16 array, dimension (MAX(1,LWORK)) */
00250 /*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK. */
00251 
00252 /*  LWORK   (input) INTEGER */
00253 /*          The dimension of the array WORK. */
00254 /*          If N = 0, LWORK >= 1, else if SENSE = 'E', 'V', or 'B', */
00255 /*          LWORK >= MAX(1,2*N,2*SDIM*(N-SDIM)), else */
00256 /*          LWORK >= MAX(1,2*N).  Note that 2*SDIM*(N-SDIM) <= N*N/2. */
00257 /*          Note also that an error is only returned if */
00258 /*          LWORK < MAX(1,2*N), but if SENSE = 'E' or 'V' or 'B' this may */
00259 /*          not be large enough. */
00260 
00261 /*          If LWORK = -1, then a workspace query is assumed; the routine */
00262 /*          only calculates the bound on the optimal size of the WORK */
00263 /*          array and the minimum size of the IWORK array, returns these */
00264 /*          values as the first entries of the WORK and IWORK arrays, and */
00265 /*          no error message related to LWORK or LIWORK is issued by */
00266 /*          XERBLA. */
00267 
00268 /*  RWORK   (workspace) DOUBLE PRECISION array, dimension ( 8*N ) */
00269 /*          Real workspace. */
00270 
00271 /*  IWORK   (workspace/output) INTEGER array, dimension (MAX(1,LIWORK)) */
00272 /*          On exit, if INFO = 0, IWORK(1) returns the minimum LIWORK. */
00273 
00274 /*  LIWORK  (input) INTEGER */
00275 /*          The dimension of the array IWORK. */
00276 /*          If SENSE = 'N' or N = 0, LIWORK >= 1, otherwise */
00277 /*          LIWORK >= N+2. */
00278 
00279 /*          If LIWORK = -1, then a workspace query is assumed; the */
00280 /*          routine only calculates the bound on the optimal size of the */
00281 /*          WORK array and the minimum size of the IWORK array, returns */
00282 /*          these values as the first entries of the WORK and IWORK */
00283 /*          arrays, and no error message related to LWORK or LIWORK is */
00284 /*          issued by XERBLA. */
00285 
00286 /*  BWORK   (workspace) LOGICAL array, dimension (N) */
00287 /*          Not referenced if SORT = 'N'. */
00288 
00289 /*  INFO    (output) INTEGER */
00290 /*          = 0:  successful exit */
00291 /*          < 0:  if INFO = -i, the i-th argument had an illegal value. */
00292 /*          = 1,...,N: */
00293 /*                The QZ iteration failed.  (A,B) are not in Schur */
00294 /*                form, but ALPHA(j) and BETA(j) should be correct for */
00295 /*                j=INFO+1,...,N. */
00296 /*          > N:  =N+1: other than QZ iteration failed in ZHGEQZ */
00297 /*                =N+2: after reordering, roundoff changed values of */
00298 /*                      some complex eigenvalues so that leading */
00299 /*                      eigenvalues in the Generalized Schur form no */
00300 /*                      longer satisfy SELCTG=.TRUE.  This could also */
00301 /*                      be caused due to scaling. */
00302 /*                =N+3: reordering failed in ZTGSEN. */
00303 
00304 /*  ===================================================================== */
00305 
00306 /*     .. Parameters .. */
00307 /*     .. */
00308 /*     .. Local Scalars .. */
00309 /*     .. */
00310 /*     .. Local Arrays .. */
00311 /*     .. */
00312 /*     .. External Subroutines .. */
00313 /*     .. */
00314 /*     .. External Functions .. */
00315 /*     .. */
00316 /*     .. Intrinsic Functions .. */
00317 /*     .. */
00318 /*     .. Executable Statements .. */
00319 
00320 /*     Decode the input arguments */
00321 
00322     /* Parameter adjustments */
00323     a_dim1 = *lda;
00324     a_offset = 1 + a_dim1;
00325     a -= a_offset;
00326     b_dim1 = *ldb;
00327     b_offset = 1 + b_dim1;
00328     b -= b_offset;
00329     --alpha;
00330     --beta;
00331     vsl_dim1 = *ldvsl;
00332     vsl_offset = 1 + vsl_dim1;
00333     vsl -= vsl_offset;
00334     vsr_dim1 = *ldvsr;
00335     vsr_offset = 1 + vsr_dim1;
00336     vsr -= vsr_offset;
00337     --rconde;
00338     --rcondv;
00339     --work;
00340     --rwork;
00341     --iwork;
00342     --bwork;
00343 
00344     /* Function Body */
00345     if (lsame_(jobvsl, "N")) {
00346         ijobvl = 1;
00347         ilvsl = FALSE_;
00348     } else if (lsame_(jobvsl, "V")) {
00349         ijobvl = 2;
00350         ilvsl = TRUE_;
00351     } else {
00352         ijobvl = -1;
00353         ilvsl = FALSE_;
00354     }
00355 
00356     if (lsame_(jobvsr, "N")) {
00357         ijobvr = 1;
00358         ilvsr = FALSE_;
00359     } else if (lsame_(jobvsr, "V")) {
00360         ijobvr = 2;
00361         ilvsr = TRUE_;
00362     } else {
00363         ijobvr = -1;
00364         ilvsr = FALSE_;
00365     }
00366 
00367     wantst = lsame_(sort, "S");
00368     wantsn = lsame_(sense, "N");
00369     wantse = lsame_(sense, "E");
00370     wantsv = lsame_(sense, "V");
00371     wantsb = lsame_(sense, "B");
00372     lquery = *lwork == -1 || *liwork == -1;
00373     if (wantsn) {
00374         ijob = 0;
00375     } else if (wantse) {
00376         ijob = 1;
00377     } else if (wantsv) {
00378         ijob = 2;
00379     } else if (wantsb) {
00380         ijob = 4;
00381     }
00382 
00383 /*     Test the input arguments */
00384 
00385     *info = 0;
00386     if (ijobvl <= 0) {
00387         *info = -1;
00388     } else if (ijobvr <= 0) {
00389         *info = -2;
00390     } else if (! wantst && ! lsame_(sort, "N")) {
00391         *info = -3;
00392     } else if (! (wantsn || wantse || wantsv || wantsb) || ! wantst && ! 
00393             wantsn) {
00394         *info = -5;
00395     } else if (*n < 0) {
00396         *info = -6;
00397     } else if (*lda < max(1,*n)) {
00398         *info = -8;
00399     } else if (*ldb < max(1,*n)) {
00400         *info = -10;
00401     } else if (*ldvsl < 1 || ilvsl && *ldvsl < *n) {
00402         *info = -15;
00403     } else if (*ldvsr < 1 || ilvsr && *ldvsr < *n) {
00404         *info = -17;
00405     }
00406 
00407 /*     Compute workspace */
00408 /*      (Note: Comments in the code beginning "Workspace:" describe the */
00409 /*       minimal amount of workspace needed at that point in the code, */
00410 /*       as well as the preferred amount for good performance. */
00411 /*       NB refers to the optimal block size for the immediately */
00412 /*       following subroutine, as returned by ILAENV.) */
00413 
00414     if (*info == 0) {
00415         if (*n > 0) {
00416             minwrk = *n << 1;
00417             maxwrk = *n * (ilaenv_(&c__1, "ZGEQRF", " ", n, &c__1, n, &c__0) + 1);
00418 /* Computing MAX */
00419             i__1 = maxwrk, i__2 = *n * (ilaenv_(&c__1, "ZUNMQR", " ", n, &
00420                     c__1, n, &c_n1) + 1);
00421             maxwrk = max(i__1,i__2);
00422             if (ilvsl) {
00423 /* Computing MAX */
00424                 i__1 = maxwrk, i__2 = *n * (ilaenv_(&c__1, "ZUNGQR", " ", n, &
00425                         c__1, n, &c_n1) + 1);
00426                 maxwrk = max(i__1,i__2);
00427             }
00428             lwrk = maxwrk;
00429             if (ijob >= 1) {
00430 /* Computing MAX */
00431                 i__1 = lwrk, i__2 = *n * *n / 2;
00432                 lwrk = max(i__1,i__2);
00433             }
00434         } else {
00435             minwrk = 1;
00436             maxwrk = 1;
00437             lwrk = 1;
00438         }
00439         work[1].r = (doublereal) lwrk, work[1].i = 0.;
00440         if (wantsn || *n == 0) {
00441             liwmin = 1;
00442         } else {
00443             liwmin = *n + 2;
00444         }
00445         iwork[1] = liwmin;
00446 
00447         if (*lwork < minwrk && ! lquery) {
00448             *info = -21;
00449         } else if (*liwork < liwmin && ! lquery) {
00450             *info = -24;
00451         }
00452     }
00453 
00454     if (*info != 0) {
00455         i__1 = -(*info);
00456         xerbla_("ZGGESX", &i__1);
00457         return 0;
00458     } else if (lquery) {
00459         return 0;
00460     }
00461 
00462 /*     Quick return if possible */
00463 
00464     if (*n == 0) {
00465         *sdim = 0;
00466         return 0;
00467     }
00468 
00469 /*     Get machine constants */
00470 
00471     eps = dlamch_("P");
00472     smlnum = dlamch_("S");
00473     bignum = 1. / smlnum;
00474     dlabad_(&smlnum, &bignum);
00475     smlnum = sqrt(smlnum) / eps;
00476     bignum = 1. / smlnum;
00477 
00478 /*     Scale A if max element outside range [SMLNUM,BIGNUM] */
00479 
00480     anrm = zlange_("M", n, n, &a[a_offset], lda, &rwork[1]);
00481     ilascl = FALSE_;
00482     if (anrm > 0. && anrm < smlnum) {
00483         anrmto = smlnum;
00484         ilascl = TRUE_;
00485     } else if (anrm > bignum) {
00486         anrmto = bignum;
00487         ilascl = TRUE_;
00488     }
00489     if (ilascl) {
00490         zlascl_("G", &c__0, &c__0, &anrm, &anrmto, n, n, &a[a_offset], lda, &
00491                 ierr);
00492     }
00493 
00494 /*     Scale B if max element outside range [SMLNUM,BIGNUM] */
00495 
00496     bnrm = zlange_("M", n, n, &b[b_offset], ldb, &rwork[1]);
00497     ilbscl = FALSE_;
00498     if (bnrm > 0. && bnrm < smlnum) {
00499         bnrmto = smlnum;
00500         ilbscl = TRUE_;
00501     } else if (bnrm > bignum) {
00502         bnrmto = bignum;
00503         ilbscl = TRUE_;
00504     }
00505     if (ilbscl) {
00506         zlascl_("G", &c__0, &c__0, &bnrm, &bnrmto, n, n, &b[b_offset], ldb, &
00507                 ierr);
00508     }
00509 
00510 /*     Permute the matrix to make it more nearly triangular */
00511 /*     (Real Workspace: need 6*N) */
00512 
00513     ileft = 1;
00514     iright = *n + 1;
00515     irwrk = iright + *n;
00516     zggbal_("P", n, &a[a_offset], lda, &b[b_offset], ldb, &ilo, &ihi, &rwork[
00517             ileft], &rwork[iright], &rwork[irwrk], &ierr);
00518 
00519 /*     Reduce B to triangular form (QR decomposition of B) */
00520 /*     (Complex Workspace: need N, prefer N*NB) */
00521 
00522     irows = ihi + 1 - ilo;
00523     icols = *n + 1 - ilo;
00524     itau = 1;
00525     iwrk = itau + irows;
00526     i__1 = *lwork + 1 - iwrk;
00527     zgeqrf_(&irows, &icols, &b[ilo + ilo * b_dim1], ldb, &work[itau], &work[
00528             iwrk], &i__1, &ierr);
00529 
00530 /*     Apply the unitary transformation to matrix A */
00531 /*     (Complex Workspace: need N, prefer N*NB) */
00532 
00533     i__1 = *lwork + 1 - iwrk;
00534     zunmqr_("L", "C", &irows, &icols, &irows, &b[ilo + ilo * b_dim1], ldb, &
00535             work[itau], &a[ilo + ilo * a_dim1], lda, &work[iwrk], &i__1, &
00536             ierr);
00537 
00538 /*     Initialize VSL */
00539 /*     (Complex Workspace: need N, prefer N*NB) */
00540 
00541     if (ilvsl) {
00542         zlaset_("Full", n, n, &c_b1, &c_b2, &vsl[vsl_offset], ldvsl);
00543         if (irows > 1) {
00544             i__1 = irows - 1;
00545             i__2 = irows - 1;
00546             zlacpy_("L", &i__1, &i__2, &b[ilo + 1 + ilo * b_dim1], ldb, &vsl[
00547                     ilo + 1 + ilo * vsl_dim1], ldvsl);
00548         }
00549         i__1 = *lwork + 1 - iwrk;
00550         zungqr_(&irows, &irows, &irows, &vsl[ilo + ilo * vsl_dim1], ldvsl, &
00551                 work[itau], &work[iwrk], &i__1, &ierr);
00552     }
00553 
00554 /*     Initialize VSR */
00555 
00556     if (ilvsr) {
00557         zlaset_("Full", n, n, &c_b1, &c_b2, &vsr[vsr_offset], ldvsr);
00558     }
00559 
00560 /*     Reduce to generalized Hessenberg form */
00561 /*     (Workspace: none needed) */
00562 
00563     zgghrd_(jobvsl, jobvsr, n, &ilo, &ihi, &a[a_offset], lda, &b[b_offset], 
00564             ldb, &vsl[vsl_offset], ldvsl, &vsr[vsr_offset], ldvsr, &ierr);
00565 
00566     *sdim = 0;
00567 
00568 /*     Perform QZ algorithm, computing Schur vectors if desired */
00569 /*     (Complex Workspace: need N) */
00570 /*     (Real Workspace:    need N) */
00571 
00572     iwrk = itau;
00573     i__1 = *lwork + 1 - iwrk;
00574     zhgeqz_("S", jobvsl, jobvsr, n, &ilo, &ihi, &a[a_offset], lda, &b[
00575             b_offset], ldb, &alpha[1], &beta[1], &vsl[vsl_offset], ldvsl, &
00576             vsr[vsr_offset], ldvsr, &work[iwrk], &i__1, &rwork[irwrk], &ierr);
00577     if (ierr != 0) {
00578         if (ierr > 0 && ierr <= *n) {
00579             *info = ierr;
00580         } else if (ierr > *n && ierr <= *n << 1) {
00581             *info = ierr - *n;
00582         } else {
00583             *info = *n + 1;
00584         }
00585         goto L40;
00586     }
00587 
00588 /*     Sort eigenvalues ALPHA/BETA and compute the reciprocal of */
00589 /*     condition number(s) */
00590 
00591     if (wantst) {
00592 
00593 /*        Undo scaling on eigenvalues before SELCTGing */
00594 
00595         if (ilascl) {
00596             zlascl_("G", &c__0, &c__0, &anrmto, &anrm, n, &c__1, &alpha[1], n, 
00597                      &ierr);
00598         }
00599         if (ilbscl) {
00600             zlascl_("G", &c__0, &c__0, &bnrmto, &bnrm, n, &c__1, &beta[1], n, 
00601                     &ierr);
00602         }
00603 
00604 /*        Select eigenvalues */
00605 
00606         i__1 = *n;
00607         for (i__ = 1; i__ <= i__1; ++i__) {
00608             bwork[i__] = (*selctg)(&alpha[i__], &beta[i__]);
00609 /* L10: */
00610         }
00611 
00612 /*        Reorder eigenvalues, transform Generalized Schur vectors, and */
00613 /*        compute reciprocal condition numbers */
00614 /*        (Complex Workspace: If IJOB >= 1, need MAX(1, 2*SDIM*(N-SDIM)) */
00615 /*                            otherwise, need 1 ) */
00616 
00617         i__1 = *lwork - iwrk + 1;
00618         ztgsen_(&ijob, &ilvsl, &ilvsr, &bwork[1], n, &a[a_offset], lda, &b[
00619                 b_offset], ldb, &alpha[1], &beta[1], &vsl[vsl_offset], ldvsl, 
00620                 &vsr[vsr_offset], ldvsr, sdim, &pl, &pr, dif, &work[iwrk], &
00621                 i__1, &iwork[1], liwork, &ierr);
00622 
00623         if (ijob >= 1) {
00624 /* Computing MAX */
00625             i__1 = maxwrk, i__2 = (*sdim << 1) * (*n - *sdim);
00626             maxwrk = max(i__1,i__2);
00627         }
00628         if (ierr == -21) {
00629 
00630 /*            not enough complex workspace */
00631 
00632             *info = -21;
00633         } else {
00634             if (ijob == 1 || ijob == 4) {
00635                 rconde[1] = pl;
00636                 rconde[2] = pr;
00637             }
00638             if (ijob == 2 || ijob == 4) {
00639                 rcondv[1] = dif[0];
00640                 rcondv[2] = dif[1];
00641             }
00642             if (ierr == 1) {
00643                 *info = *n + 3;
00644             }
00645         }
00646 
00647     }
00648 
00649 /*     Apply permutation to VSL and VSR */
00650 /*     (Workspace: none needed) */
00651 
00652     if (ilvsl) {
00653         zggbak_("P", "L", n, &ilo, &ihi, &rwork[ileft], &rwork[iright], n, &
00654                 vsl[vsl_offset], ldvsl, &ierr);
00655     }
00656 
00657     if (ilvsr) {
00658         zggbak_("P", "R", n, &ilo, &ihi, &rwork[ileft], &rwork[iright], n, &
00659                 vsr[vsr_offset], ldvsr, &ierr);
00660     }
00661 
00662 /*     Undo scaling */
00663 
00664     if (ilascl) {
00665         zlascl_("U", &c__0, &c__0, &anrmto, &anrm, n, n, &a[a_offset], lda, &
00666                 ierr);
00667         zlascl_("G", &c__0, &c__0, &anrmto, &anrm, n, &c__1, &alpha[1], n, &
00668                 ierr);
00669     }
00670 
00671     if (ilbscl) {
00672         zlascl_("U", &c__0, &c__0, &bnrmto, &bnrm, n, n, &b[b_offset], ldb, &
00673                 ierr);
00674         zlascl_("G", &c__0, &c__0, &bnrmto, &bnrm, n, &c__1, &beta[1], n, &
00675                 ierr);
00676     }
00677 
00678     if (wantst) {
00679 
00680 /*        Check if reordering is correct */
00681 
00682         lastsl = TRUE_;
00683         *sdim = 0;
00684         i__1 = *n;
00685         for (i__ = 1; i__ <= i__1; ++i__) {
00686             cursl = (*selctg)(&alpha[i__], &beta[i__]);
00687             if (cursl) {
00688                 ++(*sdim);
00689             }
00690             if (cursl && ! lastsl) {
00691                 *info = *n + 2;
00692             }
00693             lastsl = cursl;
00694 /* L30: */
00695         }
00696 
00697     }
00698 
00699 L40:
00700 
00701     work[1].r = (doublereal) maxwrk, work[1].i = 0.;
00702     iwork[1] = liwmin;
00703 
00704     return 0;
00705 
00706 /*     End of ZGGESX */
00707 
00708 } /* zggesx_ */


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