zgeesx.c
Go to the documentation of this file.
00001 /* zgeesx.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 integer c__1 = 1;
00019 static integer c__0 = 0;
00020 static integer c_n1 = -1;
00021 
00022 /* Subroutine */ int zgeesx_(char *jobvs, char *sort, L_fp select, char *
00023         sense, integer *n, doublecomplex *a, integer *lda, integer *sdim, 
00024         doublecomplex *w, doublecomplex *vs, integer *ldvs, doublereal *
00025         rconde, doublereal *rcondv, doublecomplex *work, integer *lwork, 
00026         doublereal *rwork, logical *bwork, integer *info)
00027 {
00028     /* System generated locals */
00029     integer a_dim1, a_offset, vs_dim1, vs_offset, i__1, i__2;
00030 
00031     /* Builtin functions */
00032     double sqrt(doublereal);
00033 
00034     /* Local variables */
00035     integer i__, ihi, ilo;
00036     doublereal dum[1], eps;
00037     integer ibal;
00038     doublereal anrm;
00039     integer ierr, itau, iwrk, lwrk, icond, ieval;
00040     extern logical lsame_(char *, char *);
00041     extern /* Subroutine */ int zcopy_(integer *, doublecomplex *, integer *, 
00042             doublecomplex *, integer *), dlabad_(doublereal *, doublereal *);
00043     logical scalea;
00044     extern doublereal dlamch_(char *);
00045     doublereal cscale;
00046     extern /* Subroutine */ int dlascl_(char *, integer *, integer *, 
00047             doublereal *, doublereal *, integer *, integer *, doublereal *, 
00048             integer *, integer *), zgebak_(char *, char *, integer *, 
00049             integer *, integer *, doublereal *, integer *, doublecomplex *, 
00050             integer *, integer *), zgebal_(char *, integer *, 
00051             doublecomplex *, integer *, integer *, integer *, doublereal *, 
00052             integer *), xerbla_(char *, integer *);
00053     extern integer ilaenv_(integer *, char *, char *, integer *, integer *, 
00054             integer *, integer *);
00055     extern doublereal zlange_(char *, integer *, integer *, doublecomplex *, 
00056             integer *, doublereal *);
00057     doublereal bignum;
00058     extern /* Subroutine */ int zgehrd_(integer *, integer *, integer *, 
00059             doublecomplex *, integer *, doublecomplex *, doublecomplex *, 
00060             integer *, integer *), zlascl_(char *, integer *, integer *, 
00061             doublereal *, doublereal *, integer *, integer *, doublecomplex *, 
00062              integer *, integer *);
00063     logical wantsb, wantse;
00064     extern /* Subroutine */ int zlacpy_(char *, integer *, integer *, 
00065             doublecomplex *, integer *, doublecomplex *, integer *);
00066     integer minwrk, maxwrk;
00067     logical wantsn;
00068     doublereal smlnum;
00069     extern /* Subroutine */ int zhseqr_(char *, char *, integer *, integer *, 
00070             integer *, doublecomplex *, integer *, doublecomplex *, 
00071             doublecomplex *, integer *, doublecomplex *, integer *, integer *);
00072     integer hswork;
00073     extern /* Subroutine */ int zunghr_(integer *, integer *, integer *, 
00074             doublecomplex *, integer *, doublecomplex *, doublecomplex *, 
00075             integer *, integer *);
00076     logical wantst, wantsv, wantvs;
00077     extern /* Subroutine */ int ztrsen_(char *, char *, logical *, integer *, 
00078             doublecomplex *, integer *, doublecomplex *, integer *, 
00079             doublecomplex *, integer *, doublereal *, doublereal *, 
00080             doublecomplex *, integer *, integer *);
00081 
00082 
00083 /*  -- LAPACK driver routine (version 3.2) -- */
00084 /*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
00085 /*     November 2006 */
00086 
00087 /*     .. Scalar Arguments .. */
00088 /*     .. */
00089 /*     .. Array Arguments .. */
00090 /*     .. */
00091 /*     .. Function Arguments .. */
00092 /*     .. */
00093 
00094 /*  Purpose */
00095 /*  ======= */
00096 
00097 /*  ZGEESX computes for an N-by-N complex nonsymmetric matrix A, the */
00098 /*  eigenvalues, the Schur form T, and, optionally, the matrix of Schur */
00099 /*  vectors Z.  This gives the Schur factorization A = Z*T*(Z**H). */
00100 
00101 /*  Optionally, it also orders the eigenvalues on the diagonal of the */
00102 /*  Schur form so that selected eigenvalues are at the top left; */
00103 /*  computes a reciprocal condition number for the average of the */
00104 /*  selected eigenvalues (RCONDE); and computes a reciprocal condition */
00105 /*  number for the right invariant subspace corresponding to the */
00106 /*  selected eigenvalues (RCONDV).  The leading columns of Z form an */
00107 /*  orthonormal basis for this invariant subspace. */
00108 
00109 /*  For further explanation of the reciprocal condition numbers RCONDE */
00110 /*  and RCONDV, see Section 4.10 of the LAPACK Users' Guide (where */
00111 /*  these quantities are called s and sep respectively). */
00112 
00113 /*  A complex matrix is in Schur form if it is upper triangular. */
00114 
00115 /*  Arguments */
00116 /*  ========= */
00117 
00118 /*  JOBVS   (input) CHARACTER*1 */
00119 /*          = 'N': Schur vectors are not computed; */
00120 /*          = 'V': Schur vectors are computed. */
00121 
00122 /*  SORT    (input) CHARACTER*1 */
00123 /*          Specifies whether or not to order the eigenvalues on the */
00124 /*          diagonal of the Schur form. */
00125 /*          = 'N': Eigenvalues are not ordered; */
00126 /*          = 'S': Eigenvalues are ordered (see SELECT). */
00127 
00128 /*  SELECT  (external procedure) LOGICAL FUNCTION of one COMPLEX*16 argument */
00129 /*          SELECT must be declared EXTERNAL in the calling subroutine. */
00130 /*          If SORT = 'S', SELECT is used to select eigenvalues to order */
00131 /*          to the top left of the Schur form. */
00132 /*          If SORT = 'N', SELECT is not referenced. */
00133 /*          An eigenvalue W(j) is selected if SELECT(W(j)) is true. */
00134 
00135 /*  SENSE   (input) CHARACTER*1 */
00136 /*          Determines which reciprocal condition numbers are computed. */
00137 /*          = 'N': None are computed; */
00138 /*          = 'E': Computed for average of selected eigenvalues only; */
00139 /*          = 'V': Computed for selected right invariant subspace only; */
00140 /*          = 'B': Computed for both. */
00141 /*          If SENSE = 'E', 'V' or 'B', SORT must equal 'S'. */
00142 
00143 /*  N       (input) INTEGER */
00144 /*          The order of the matrix A. N >= 0. */
00145 
00146 /*  A       (input/output) COMPLEX*16 array, dimension (LDA, N) */
00147 /*          On entry, the N-by-N matrix A. */
00148 /*          On exit, A is overwritten by its Schur form T. */
00149 
00150 /*  LDA     (input) INTEGER */
00151 /*          The leading dimension of the array A.  LDA >= max(1,N). */
00152 
00153 /*  SDIM    (output) INTEGER */
00154 /*          If SORT = 'N', SDIM = 0. */
00155 /*          If SORT = 'S', SDIM = number of eigenvalues for which */
00156 /*                         SELECT is true. */
00157 
00158 /*  W       (output) COMPLEX*16 array, dimension (N) */
00159 /*          W contains the computed eigenvalues, in the same order */
00160 /*          that they appear on the diagonal of the output Schur form T. */
00161 
00162 /*  VS      (output) COMPLEX*16 array, dimension (LDVS,N) */
00163 /*          If JOBVS = 'V', VS contains the unitary matrix Z of Schur */
00164 /*          vectors. */
00165 /*          If JOBVS = 'N', VS is not referenced. */
00166 
00167 /*  LDVS    (input) INTEGER */
00168 /*          The leading dimension of the array VS.  LDVS >= 1, and if */
00169 /*          JOBVS = 'V', LDVS >= N. */
00170 
00171 /*  RCONDE  (output) DOUBLE PRECISION */
00172 /*          If SENSE = 'E' or 'B', RCONDE contains the reciprocal */
00173 /*          condition number for the average of the selected eigenvalues. */
00174 /*          Not referenced if SENSE = 'N' or 'V'. */
00175 
00176 /*  RCONDV  (output) DOUBLE PRECISION */
00177 /*          If SENSE = 'V' or 'B', RCONDV contains the reciprocal */
00178 /*          condition number for the selected right invariant subspace. */
00179 /*          Not referenced if SENSE = 'N' or 'E'. */
00180 
00181 /*  WORK    (workspace/output) COMPLEX*16 array, dimension (MAX(1,LWORK)) */
00182 /*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK. */
00183 
00184 /*  LWORK   (input) INTEGER */
00185 /*          The dimension of the array WORK.  LWORK >= max(1,2*N). */
00186 /*          Also, if SENSE = 'E' or 'V' or 'B', LWORK >= 2*SDIM*(N-SDIM), */
00187 /*          where SDIM is the number of selected eigenvalues computed by */
00188 /*          this routine.  Note that 2*SDIM*(N-SDIM) <= N*N/2. Note also */
00189 /*          that an error is only returned if LWORK < max(1,2*N), but if */
00190 /*          SENSE = 'E' or 'V' or 'B' this may not be large enough. */
00191 /*          For good performance, LWORK must generally be larger. */
00192 
00193 /*          If LWORK = -1, then a workspace query is assumed; the routine */
00194 /*          only calculates upper bound on the optimal size of the */
00195 /*          array WORK, returns this value as the first entry of the WORK */
00196 /*          array, and no error message related to LWORK is issued by */
00197 /*          XERBLA. */
00198 
00199 /*  RWORK   (workspace) DOUBLE PRECISION array, dimension (N) */
00200 
00201 /*  BWORK   (workspace) LOGICAL array, dimension (N) */
00202 /*          Not referenced if SORT = 'N'. */
00203 
00204 /*  INFO    (output) INTEGER */
00205 /*          = 0: successful exit */
00206 /*          < 0: if INFO = -i, the i-th argument had an illegal value. */
00207 /*          > 0: if INFO = i, and i is */
00208 /*             <= N: the QR algorithm failed to compute all the */
00209 /*                   eigenvalues; elements 1:ILO-1 and i+1:N of W */
00210 /*                   contain those eigenvalues which have converged; if */
00211 /*                   JOBVS = 'V', VS contains the transformation which */
00212 /*                   reduces A to its partially converged Schur form. */
00213 /*             = N+1: the eigenvalues could not be reordered because some */
00214 /*                   eigenvalues were too close to separate (the problem */
00215 /*                   is very ill-conditioned); */
00216 /*             = N+2: after reordering, roundoff changed values of some */
00217 /*                   complex eigenvalues so that leading eigenvalues in */
00218 /*                   the Schur form no longer satisfy SELECT=.TRUE.  This */
00219 /*                   could also be caused by underflow due to scaling. */
00220 
00221 /*  ===================================================================== */
00222 
00223 /*     .. Parameters .. */
00224 /*     .. */
00225 /*     .. Local Scalars .. */
00226 /*     .. */
00227 /*     .. Local Arrays .. */
00228 /*     .. */
00229 /*     .. External Subroutines .. */
00230 /*     .. */
00231 /*     .. External Functions .. */
00232 /*     .. */
00233 /*     .. Intrinsic Functions .. */
00234 /*     .. */
00235 /*     .. Executable Statements .. */
00236 
00237 /*     Test the input arguments */
00238 
00239     /* Parameter adjustments */
00240     a_dim1 = *lda;
00241     a_offset = 1 + a_dim1;
00242     a -= a_offset;
00243     --w;
00244     vs_dim1 = *ldvs;
00245     vs_offset = 1 + vs_dim1;
00246     vs -= vs_offset;
00247     --work;
00248     --rwork;
00249     --bwork;
00250 
00251     /* Function Body */
00252     *info = 0;
00253     wantvs = lsame_(jobvs, "V");
00254     wantst = lsame_(sort, "S");
00255     wantsn = lsame_(sense, "N");
00256     wantse = lsame_(sense, "E");
00257     wantsv = lsame_(sense, "V");
00258     wantsb = lsame_(sense, "B");
00259     if (! wantvs && ! lsame_(jobvs, "N")) {
00260         *info = -1;
00261     } else if (! wantst && ! lsame_(sort, "N")) {
00262         *info = -2;
00263     } else if (! (wantsn || wantse || wantsv || wantsb) || ! wantst && ! 
00264             wantsn) {
00265         *info = -4;
00266     } else if (*n < 0) {
00267         *info = -5;
00268     } else if (*lda < max(1,*n)) {
00269         *info = -7;
00270     } else if (*ldvs < 1 || wantvs && *ldvs < *n) {
00271         *info = -11;
00272     }
00273 
00274 /*     Compute workspace */
00275 /*      (Note: Comments in the code beginning "Workspace:" describe the */
00276 /*       minimal amount of real workspace needed at that point in the */
00277 /*       code, as well as the preferred amount for good performance. */
00278 /*       CWorkspace refers to complex workspace, and RWorkspace to real */
00279 /*       workspace. NB refers to the optimal block size for the */
00280 /*       immediately following subroutine, as returned by ILAENV. */
00281 /*       HSWORK refers to the workspace preferred by ZHSEQR, as */
00282 /*       calculated below. HSWORK is computed assuming ILO=1 and IHI=N, */
00283 /*       the worst case. */
00284 /*       If SENSE = 'E', 'V' or 'B', then the amount of workspace needed */
00285 /*       depends on SDIM, which is computed by the routine ZTRSEN later */
00286 /*       in the code.) */
00287 
00288     if (*info == 0) {
00289         if (*n == 0) {
00290             minwrk = 1;
00291             lwrk = 1;
00292         } else {
00293             maxwrk = *n + *n * ilaenv_(&c__1, "ZGEHRD", " ", n, &c__1, n, &
00294                     c__0);
00295             minwrk = *n << 1;
00296 
00297             zhseqr_("S", jobvs, n, &c__1, n, &a[a_offset], lda, &w[1], &vs[
00298                     vs_offset], ldvs, &work[1], &c_n1, &ieval);
00299             hswork = (integer) work[1].r;
00300 
00301             if (! wantvs) {
00302                 maxwrk = max(maxwrk,hswork);
00303             } else {
00304 /* Computing MAX */
00305                 i__1 = maxwrk, i__2 = *n + (*n - 1) * ilaenv_(&c__1, "ZUNGHR", 
00306                          " ", n, &c__1, n, &c_n1);
00307                 maxwrk = max(i__1,i__2);
00308                 maxwrk = max(maxwrk,hswork);
00309             }
00310             lwrk = maxwrk;
00311             if (! wantsn) {
00312 /* Computing MAX */
00313                 i__1 = lwrk, i__2 = *n * *n / 2;
00314                 lwrk = max(i__1,i__2);
00315             }
00316         }
00317         work[1].r = (doublereal) lwrk, work[1].i = 0.;
00318 
00319         if (*lwork < minwrk) {
00320             *info = -15;
00321         }
00322     }
00323 
00324     if (*info != 0) {
00325         i__1 = -(*info);
00326         xerbla_("ZGEESX", &i__1);
00327         return 0;
00328     }
00329 
00330 /*     Quick return if possible */
00331 
00332     if (*n == 0) {
00333         *sdim = 0;
00334         return 0;
00335     }
00336 
00337 /*     Get machine constants */
00338 
00339     eps = dlamch_("P");
00340     smlnum = dlamch_("S");
00341     bignum = 1. / smlnum;
00342     dlabad_(&smlnum, &bignum);
00343     smlnum = sqrt(smlnum) / eps;
00344     bignum = 1. / smlnum;
00345 
00346 /*     Scale A if max element outside range [SMLNUM,BIGNUM] */
00347 
00348     anrm = zlange_("M", n, n, &a[a_offset], lda, dum);
00349     scalea = FALSE_;
00350     if (anrm > 0. && anrm < smlnum) {
00351         scalea = TRUE_;
00352         cscale = smlnum;
00353     } else if (anrm > bignum) {
00354         scalea = TRUE_;
00355         cscale = bignum;
00356     }
00357     if (scalea) {
00358         zlascl_("G", &c__0, &c__0, &anrm, &cscale, n, n, &a[a_offset], lda, &
00359                 ierr);
00360     }
00361 
00362 
00363 /*     Permute the matrix to make it more nearly triangular */
00364 /*     (CWorkspace: none) */
00365 /*     (RWorkspace: need N) */
00366 
00367     ibal = 1;
00368     zgebal_("P", n, &a[a_offset], lda, &ilo, &ihi, &rwork[ibal], &ierr);
00369 
00370 /*     Reduce to upper Hessenberg form */
00371 /*     (CWorkspace: need 2*N, prefer N+N*NB) */
00372 /*     (RWorkspace: none) */
00373 
00374     itau = 1;
00375     iwrk = *n + itau;
00376     i__1 = *lwork - iwrk + 1;
00377     zgehrd_(n, &ilo, &ihi, &a[a_offset], lda, &work[itau], &work[iwrk], &i__1, 
00378              &ierr);
00379 
00380     if (wantvs) {
00381 
00382 /*        Copy Householder vectors to VS */
00383 
00384         zlacpy_("L", n, n, &a[a_offset], lda, &vs[vs_offset], ldvs)
00385                 ;
00386 
00387 /*        Generate unitary matrix in VS */
00388 /*        (CWorkspace: need 2*N-1, prefer N+(N-1)*NB) */
00389 /*        (RWorkspace: none) */
00390 
00391         i__1 = *lwork - iwrk + 1;
00392         zunghr_(n, &ilo, &ihi, &vs[vs_offset], ldvs, &work[itau], &work[iwrk], 
00393                  &i__1, &ierr);
00394     }
00395 
00396     *sdim = 0;
00397 
00398 /*     Perform QR iteration, accumulating Schur vectors in VS if desired */
00399 /*     (CWorkspace: need 1, prefer HSWORK (see comments) ) */
00400 /*     (RWorkspace: none) */
00401 
00402     iwrk = itau;
00403     i__1 = *lwork - iwrk + 1;
00404     zhseqr_("S", jobvs, n, &ilo, &ihi, &a[a_offset], lda, &w[1], &vs[
00405             vs_offset], ldvs, &work[iwrk], &i__1, &ieval);
00406     if (ieval > 0) {
00407         *info = ieval;
00408     }
00409 
00410 /*     Sort eigenvalues if desired */
00411 
00412     if (wantst && *info == 0) {
00413         if (scalea) {
00414             zlascl_("G", &c__0, &c__0, &cscale, &anrm, n, &c__1, &w[1], n, &
00415                     ierr);
00416         }
00417         i__1 = *n;
00418         for (i__ = 1; i__ <= i__1; ++i__) {
00419             bwork[i__] = (*select)(&w[i__]);
00420 /* L10: */
00421         }
00422 
00423 /*        Reorder eigenvalues, transform Schur vectors, and compute */
00424 /*        reciprocal condition numbers */
00425 /*        (CWorkspace: if SENSE is not 'N', need 2*SDIM*(N-SDIM) */
00426 /*                     otherwise, need none ) */
00427 /*        (RWorkspace: none) */
00428 
00429         i__1 = *lwork - iwrk + 1;
00430         ztrsen_(sense, jobvs, &bwork[1], n, &a[a_offset], lda, &vs[vs_offset], 
00431                  ldvs, &w[1], sdim, rconde, rcondv, &work[iwrk], &i__1, &
00432                 icond);
00433         if (! wantsn) {
00434 /* Computing MAX */
00435             i__1 = maxwrk, i__2 = (*sdim << 1) * (*n - *sdim);
00436             maxwrk = max(i__1,i__2);
00437         }
00438         if (icond == -14) {
00439 
00440 /*           Not enough complex workspace */
00441 
00442             *info = -15;
00443         }
00444     }
00445 
00446     if (wantvs) {
00447 
00448 /*        Undo balancing */
00449 /*        (CWorkspace: none) */
00450 /*        (RWorkspace: need N) */
00451 
00452         zgebak_("P", "R", n, &ilo, &ihi, &rwork[ibal], n, &vs[vs_offset], 
00453                 ldvs, &ierr);
00454     }
00455 
00456     if (scalea) {
00457 
00458 /*        Undo scaling for the Schur form of A */
00459 
00460         zlascl_("U", &c__0, &c__0, &cscale, &anrm, n, n, &a[a_offset], lda, &
00461                 ierr);
00462         i__1 = *lda + 1;
00463         zcopy_(n, &a[a_offset], &i__1, &w[1], &c__1);
00464         if ((wantsv || wantsb) && *info == 0) {
00465             dum[0] = *rcondv;
00466             dlascl_("G", &c__0, &c__0, &cscale, &anrm, &c__1, &c__1, dum, &
00467                     c__1, &ierr);
00468             *rcondv = dum[0];
00469         }
00470     }
00471 
00472     work[1].r = (doublereal) maxwrk, work[1].i = 0.;
00473     return 0;
00474 
00475 /*     End of ZGEESX */
00476 
00477 } /* zgeesx_ */


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