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


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