zgeev.c
Go to the documentation of this file.
00001 /* zgeev.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 zgeev_(char *jobvl, char *jobvr, integer *n, 
00023         doublecomplex *a, integer *lda, doublecomplex *w, doublecomplex *vl, 
00024         integer *ldvl, doublecomplex *vr, integer *ldvr, doublecomplex *work, 
00025         integer *lwork, doublereal *rwork, integer *info)
00026 {
00027     /* System generated locals */
00028     integer a_dim1, a_offset, vl_dim1, vl_offset, vr_dim1, vr_offset, i__1, 
00029             i__2, i__3;
00030     doublereal d__1, d__2;
00031     doublecomplex z__1, z__2;
00032 
00033     /* Builtin functions */
00034     double sqrt(doublereal), d_imag(doublecomplex *);
00035     void d_cnjg(doublecomplex *, doublecomplex *);
00036 
00037     /* Local variables */
00038     integer i__, k, ihi;
00039     doublereal scl;
00040     integer ilo;
00041     doublereal dum[1], eps;
00042     doublecomplex tmp;
00043     integer ibal;
00044     char side[1];
00045     doublereal anrm;
00046     integer ierr, itau, iwrk, nout;
00047     extern logical lsame_(char *, char *);
00048     extern /* Subroutine */ int zscal_(integer *, doublecomplex *, 
00049             doublecomplex *, integer *), dlabad_(doublereal *, doublereal *);
00050     extern doublereal dznrm2_(integer *, doublecomplex *, integer *);
00051     logical scalea;
00052     extern doublereal dlamch_(char *);
00053     doublereal cscale;
00054     extern /* Subroutine */ int zgebak_(char *, char *, integer *, integer *, 
00055             integer *, doublereal *, integer *, doublecomplex *, integer *, 
00056             integer *), zgebal_(char *, integer *, 
00057             doublecomplex *, integer *, integer *, integer *, doublereal *, 
00058             integer *);
00059     extern integer idamax_(integer *, doublereal *, integer *);
00060     extern /* Subroutine */ int xerbla_(char *, integer *);
00061     extern integer ilaenv_(integer *, char *, char *, integer *, integer *, 
00062             integer *, integer *);
00063     logical select[1];
00064     extern /* Subroutine */ int zdscal_(integer *, doublereal *, 
00065             doublecomplex *, integer *);
00066     doublereal bignum;
00067     extern doublereal zlange_(char *, integer *, integer *, doublecomplex *, 
00068             integer *, doublereal *);
00069     extern /* Subroutine */ int zgehrd_(integer *, integer *, integer *, 
00070             doublecomplex *, integer *, doublecomplex *, doublecomplex *, 
00071             integer *, integer *), zlascl_(char *, integer *, integer *, 
00072             doublereal *, doublereal *, integer *, integer *, doublecomplex *, 
00073              integer *, integer *), zlacpy_(char *, integer *, 
00074             integer *, doublecomplex *, integer *, doublecomplex *, integer *);
00075     integer minwrk, maxwrk;
00076     logical wantvl;
00077     doublereal smlnum;
00078     integer hswork, irwork;
00079     extern /* Subroutine */ int zhseqr_(char *, char *, integer *, integer *, 
00080             integer *, doublecomplex *, integer *, doublecomplex *, 
00081             doublecomplex *, integer *, doublecomplex *, integer *, integer *), ztrevc_(char *, char *, logical *, integer *, 
00082             doublecomplex *, integer *, doublecomplex *, integer *, 
00083             doublecomplex *, integer *, integer *, integer *, doublecomplex *, 
00084              doublereal *, integer *);
00085     logical lquery, wantvr;
00086     extern /* Subroutine */ int zunghr_(integer *, integer *, integer *, 
00087             doublecomplex *, integer *, doublecomplex *, doublecomplex *, 
00088             integer *, integer *);
00089 
00090 
00091 /*  -- LAPACK driver routine (version 3.2) -- */
00092 /*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
00093 /*     November 2006 */
00094 
00095 /*     .. Scalar Arguments .. */
00096 /*     .. */
00097 /*     .. Array Arguments .. */
00098 /*     .. */
00099 
00100 /*  Purpose */
00101 /*  ======= */
00102 
00103 /*  ZGEEV computes for an N-by-N complex nonsymmetric matrix A, the */
00104 /*  eigenvalues and, optionally, the left and/or right eigenvectors. */
00105 
00106 /*  The right eigenvector v(j) of A satisfies */
00107 /*                   A * v(j) = lambda(j) * v(j) */
00108 /*  where lambda(j) is its eigenvalue. */
00109 /*  The left eigenvector u(j) of A satisfies */
00110 /*                u(j)**H * A = lambda(j) * u(j)**H */
00111 /*  where u(j)**H denotes the conjugate transpose of u(j). */
00112 
00113 /*  The computed eigenvectors are normalized to have Euclidean norm */
00114 /*  equal to 1 and largest component real. */
00115 
00116 /*  Arguments */
00117 /*  ========= */
00118 
00119 /*  JOBVL   (input) CHARACTER*1 */
00120 /*          = 'N': left eigenvectors of A are not computed; */
00121 /*          = 'V': left eigenvectors of are computed. */
00122 
00123 /*  JOBVR   (input) CHARACTER*1 */
00124 /*          = 'N': right eigenvectors of A are not computed; */
00125 /*          = 'V': right eigenvectors of A are computed. */
00126 
00127 /*  N       (input) INTEGER */
00128 /*          The order of the matrix A. N >= 0. */
00129 
00130 /*  A       (input/output) COMPLEX*16 array, dimension (LDA,N) */
00131 /*          On entry, the N-by-N matrix A. */
00132 /*          On exit, A has been overwritten. */
00133 
00134 /*  LDA     (input) INTEGER */
00135 /*          The leading dimension of the array A.  LDA >= max(1,N). */
00136 
00137 /*  W       (output) COMPLEX*16 array, dimension (N) */
00138 /*          W contains the computed eigenvalues. */
00139 
00140 /*  VL      (output) COMPLEX*16 array, dimension (LDVL,N) */
00141 /*          If JOBVL = 'V', the left eigenvectors u(j) are stored one */
00142 /*          after another in the columns of VL, in the same order */
00143 /*          as their eigenvalues. */
00144 /*          If JOBVL = 'N', VL is not referenced. */
00145 /*          u(j) = VL(:,j), the j-th column of VL. */
00146 
00147 /*  LDVL    (input) INTEGER */
00148 /*          The leading dimension of the array VL.  LDVL >= 1; if */
00149 /*          JOBVL = 'V', LDVL >= N. */
00150 
00151 /*  VR      (output) COMPLEX*16 array, dimension (LDVR,N) */
00152 /*          If JOBVR = 'V', the right eigenvectors v(j) are stored one */
00153 /*          after another in the columns of VR, in the same order */
00154 /*          as their eigenvalues. */
00155 /*          If JOBVR = 'N', VR is not referenced. */
00156 /*          v(j) = VR(:,j), the j-th column of VR. */
00157 
00158 /*  LDVR    (input) INTEGER */
00159 /*          The leading dimension of the array VR.  LDVR >= 1; if */
00160 /*          JOBVR = 'V', LDVR >= N. */
00161 
00162 /*  WORK    (workspace/output) COMPLEX*16 array, dimension (MAX(1,LWORK)) */
00163 /*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK. */
00164 
00165 /*  LWORK   (input) INTEGER */
00166 /*          The dimension of the array WORK.  LWORK >= max(1,2*N). */
00167 /*          For good performance, LWORK must generally be larger. */
00168 
00169 /*          If LWORK = -1, then a workspace query is assumed; the routine */
00170 /*          only calculates the optimal size of the WORK array, returns */
00171 /*          this value as the first entry of the WORK array, and no error */
00172 /*          message related to LWORK is issued by XERBLA. */
00173 
00174 /*  RWORK   (workspace) DOUBLE PRECISION array, dimension (2*N) */
00175 
00176 /*  INFO    (output) INTEGER */
00177 /*          = 0:  successful exit */
00178 /*          < 0:  if INFO = -i, the i-th argument had an illegal value. */
00179 /*          > 0:  if INFO = i, the QR algorithm failed to compute all the */
00180 /*                eigenvalues, and no eigenvectors have been computed; */
00181 /*                elements and i+1:N of W contain eigenvalues which have */
00182 /*                converged. */
00183 
00184 /*  ===================================================================== */
00185 
00186 /*     .. Parameters .. */
00187 /*     .. */
00188 /*     .. Local Scalars .. */
00189 /*     .. */
00190 /*     .. Local Arrays .. */
00191 /*     .. */
00192 /*     .. External Subroutines .. */
00193 /*     .. */
00194 /*     .. External Functions .. */
00195 /*     .. */
00196 /*     .. Intrinsic Functions .. */
00197 /*     .. */
00198 /*     .. Executable Statements .. */
00199 
00200 /*     Test the input arguments */
00201 
00202     /* Parameter adjustments */
00203     a_dim1 = *lda;
00204     a_offset = 1 + a_dim1;
00205     a -= a_offset;
00206     --w;
00207     vl_dim1 = *ldvl;
00208     vl_offset = 1 + vl_dim1;
00209     vl -= vl_offset;
00210     vr_dim1 = *ldvr;
00211     vr_offset = 1 + vr_dim1;
00212     vr -= vr_offset;
00213     --work;
00214     --rwork;
00215 
00216     /* Function Body */
00217     *info = 0;
00218     lquery = *lwork == -1;
00219     wantvl = lsame_(jobvl, "V");
00220     wantvr = lsame_(jobvr, "V");
00221     if (! wantvl && ! lsame_(jobvl, "N")) {
00222         *info = -1;
00223     } else if (! wantvr && ! lsame_(jobvr, "N")) {
00224         *info = -2;
00225     } else if (*n < 0) {
00226         *info = -3;
00227     } else if (*lda < max(1,*n)) {
00228         *info = -5;
00229     } else if (*ldvl < 1 || wantvl && *ldvl < *n) {
00230         *info = -8;
00231     } else if (*ldvr < 1 || wantvr && *ldvr < *n) {
00232         *info = -10;
00233     }
00234 
00235 /*     Compute workspace */
00236 /*      (Note: Comments in the code beginning "Workspace:" describe the */
00237 /*       minimal amount of workspace needed at that point in the code, */
00238 /*       as well as the preferred amount for good performance. */
00239 /*       CWorkspace refers to complex workspace, and RWorkspace to real */
00240 /*       workspace. NB refers to the optimal block size for the */
00241 /*       immediately following subroutine, as returned by ILAENV. */
00242 /*       HSWORK refers to the workspace preferred by ZHSEQR, as */
00243 /*       calculated below. HSWORK is computed assuming ILO=1 and IHI=N, */
00244 /*       the worst case.) */
00245 
00246     if (*info == 0) {
00247         if (*n == 0) {
00248             minwrk = 1;
00249             maxwrk = 1;
00250         } else {
00251             maxwrk = *n + *n * ilaenv_(&c__1, "ZGEHRD", " ", n, &c__1, n, &
00252                     c__0);
00253             minwrk = *n << 1;
00254             if (wantvl) {
00255 /* Computing MAX */
00256                 i__1 = maxwrk, i__2 = *n + (*n - 1) * ilaenv_(&c__1, "ZUNGHR", 
00257                          " ", n, &c__1, n, &c_n1);
00258                 maxwrk = max(i__1,i__2);
00259                 zhseqr_("S", "V", n, &c__1, n, &a[a_offset], lda, &w[1], &vl[
00260                         vl_offset], ldvl, &work[1], &c_n1, info);
00261             } else if (wantvr) {
00262 /* Computing MAX */
00263                 i__1 = maxwrk, i__2 = *n + (*n - 1) * ilaenv_(&c__1, "ZUNGHR", 
00264                          " ", n, &c__1, n, &c_n1);
00265                 maxwrk = max(i__1,i__2);
00266                 zhseqr_("S", "V", n, &c__1, n, &a[a_offset], lda, &w[1], &vr[
00267                         vr_offset], ldvr, &work[1], &c_n1, info);
00268             } else {
00269                 zhseqr_("E", "N", n, &c__1, n, &a[a_offset], lda, &w[1], &vr[
00270                         vr_offset], ldvr, &work[1], &c_n1, info);
00271             }
00272             hswork = (integer) work[1].r;
00273 /* Computing MAX */
00274             i__1 = max(maxwrk,hswork);
00275             maxwrk = max(i__1,minwrk);
00276         }
00277         work[1].r = (doublereal) maxwrk, work[1].i = 0.;
00278 
00279         if (*lwork < minwrk && ! lquery) {
00280             *info = -12;
00281         }
00282     }
00283 
00284     if (*info != 0) {
00285         i__1 = -(*info);
00286         xerbla_("ZGEEV ", &i__1);
00287         return 0;
00288     } else if (lquery) {
00289         return 0;
00290     }
00291 
00292 /*     Quick return if possible */
00293 
00294     if (*n == 0) {
00295         return 0;
00296     }
00297 
00298 /*     Get machine constants */
00299 
00300     eps = dlamch_("P");
00301     smlnum = dlamch_("S");
00302     bignum = 1. / smlnum;
00303     dlabad_(&smlnum, &bignum);
00304     smlnum = sqrt(smlnum) / eps;
00305     bignum = 1. / smlnum;
00306 
00307 /*     Scale A if max element outside range [SMLNUM,BIGNUM] */
00308 
00309     anrm = zlange_("M", n, n, &a[a_offset], lda, dum);
00310     scalea = FALSE_;
00311     if (anrm > 0. && anrm < smlnum) {
00312         scalea = TRUE_;
00313         cscale = smlnum;
00314     } else if (anrm > bignum) {
00315         scalea = TRUE_;
00316         cscale = bignum;
00317     }
00318     if (scalea) {
00319         zlascl_("G", &c__0, &c__0, &anrm, &cscale, n, n, &a[a_offset], lda, &
00320                 ierr);
00321     }
00322 
00323 /*     Balance the matrix */
00324 /*     (CWorkspace: none) */
00325 /*     (RWorkspace: need N) */
00326 
00327     ibal = 1;
00328     zgebal_("B", n, &a[a_offset], lda, &ilo, &ihi, &rwork[ibal], &ierr);
00329 
00330 /*     Reduce to upper Hessenberg form */
00331 /*     (CWorkspace: need 2*N, prefer N+N*NB) */
00332 /*     (RWorkspace: none) */
00333 
00334     itau = 1;
00335     iwrk = itau + *n;
00336     i__1 = *lwork - iwrk + 1;
00337     zgehrd_(n, &ilo, &ihi, &a[a_offset], lda, &work[itau], &work[iwrk], &i__1, 
00338              &ierr);
00339 
00340     if (wantvl) {
00341 
00342 /*        Want left eigenvectors */
00343 /*        Copy Householder vectors to VL */
00344 
00345         *(unsigned char *)side = 'L';
00346         zlacpy_("L", n, n, &a[a_offset], lda, &vl[vl_offset], ldvl)
00347                 ;
00348 
00349 /*        Generate unitary matrix in VL */
00350 /*        (CWorkspace: need 2*N-1, prefer N+(N-1)*NB) */
00351 /*        (RWorkspace: none) */
00352 
00353         i__1 = *lwork - iwrk + 1;
00354         zunghr_(n, &ilo, &ihi, &vl[vl_offset], ldvl, &work[itau], &work[iwrk], 
00355                  &i__1, &ierr);
00356 
00357 /*        Perform QR iteration, accumulating Schur vectors in VL */
00358 /*        (CWorkspace: need 1, prefer HSWORK (see comments) ) */
00359 /*        (RWorkspace: none) */
00360 
00361         iwrk = itau;
00362         i__1 = *lwork - iwrk + 1;
00363         zhseqr_("S", "V", n, &ilo, &ihi, &a[a_offset], lda, &w[1], &vl[
00364                 vl_offset], ldvl, &work[iwrk], &i__1, info);
00365 
00366         if (wantvr) {
00367 
00368 /*           Want left and right eigenvectors */
00369 /*           Copy Schur vectors to VR */
00370 
00371             *(unsigned char *)side = 'B';
00372             zlacpy_("F", n, n, &vl[vl_offset], ldvl, &vr[vr_offset], ldvr);
00373         }
00374 
00375     } else if (wantvr) {
00376 
00377 /*        Want right eigenvectors */
00378 /*        Copy Householder vectors to VR */
00379 
00380         *(unsigned char *)side = 'R';
00381         zlacpy_("L", n, n, &a[a_offset], lda, &vr[vr_offset], ldvr)
00382                 ;
00383 
00384 /*        Generate unitary matrix in VR */
00385 /*        (CWorkspace: need 2*N-1, prefer N+(N-1)*NB) */
00386 /*        (RWorkspace: none) */
00387 
00388         i__1 = *lwork - iwrk + 1;
00389         zunghr_(n, &ilo, &ihi, &vr[vr_offset], ldvr, &work[itau], &work[iwrk], 
00390                  &i__1, &ierr);
00391 
00392 /*        Perform QR iteration, accumulating Schur vectors in VR */
00393 /*        (CWorkspace: need 1, prefer HSWORK (see comments) ) */
00394 /*        (RWorkspace: none) */
00395 
00396         iwrk = itau;
00397         i__1 = *lwork - iwrk + 1;
00398         zhseqr_("S", "V", n, &ilo, &ihi, &a[a_offset], lda, &w[1], &vr[
00399                 vr_offset], ldvr, &work[iwrk], &i__1, info);
00400 
00401     } else {
00402 
00403 /*        Compute eigenvalues only */
00404 /*        (CWorkspace: need 1, prefer HSWORK (see comments) ) */
00405 /*        (RWorkspace: none) */
00406 
00407         iwrk = itau;
00408         i__1 = *lwork - iwrk + 1;
00409         zhseqr_("E", "N", n, &ilo, &ihi, &a[a_offset], lda, &w[1], &vr[
00410                 vr_offset], ldvr, &work[iwrk], &i__1, info);
00411     }
00412 
00413 /*     If INFO > 0 from ZHSEQR, then quit */
00414 
00415     if (*info > 0) {
00416         goto L50;
00417     }
00418 
00419     if (wantvl || wantvr) {
00420 
00421 /*        Compute left and/or right eigenvectors */
00422 /*        (CWorkspace: need 2*N) */
00423 /*        (RWorkspace: need 2*N) */
00424 
00425         irwork = ibal + *n;
00426         ztrevc_(side, "B", select, n, &a[a_offset], lda, &vl[vl_offset], ldvl, 
00427                  &vr[vr_offset], ldvr, n, &nout, &work[iwrk], &rwork[irwork], 
00428                 &ierr);
00429     }
00430 
00431     if (wantvl) {
00432 
00433 /*        Undo balancing of left eigenvectors */
00434 /*        (CWorkspace: none) */
00435 /*        (RWorkspace: need N) */
00436 
00437         zgebak_("B", "L", n, &ilo, &ihi, &rwork[ibal], n, &vl[vl_offset], 
00438                 ldvl, &ierr);
00439 
00440 /*        Normalize left eigenvectors and make largest component real */
00441 
00442         i__1 = *n;
00443         for (i__ = 1; i__ <= i__1; ++i__) {
00444             scl = 1. / dznrm2_(n, &vl[i__ * vl_dim1 + 1], &c__1);
00445             zdscal_(n, &scl, &vl[i__ * vl_dim1 + 1], &c__1);
00446             i__2 = *n;
00447             for (k = 1; k <= i__2; ++k) {
00448                 i__3 = k + i__ * vl_dim1;
00449 /* Computing 2nd power */
00450                 d__1 = vl[i__3].r;
00451 /* Computing 2nd power */
00452                 d__2 = d_imag(&vl[k + i__ * vl_dim1]);
00453                 rwork[irwork + k - 1] = d__1 * d__1 + d__2 * d__2;
00454 /* L10: */
00455             }
00456             k = idamax_(n, &rwork[irwork], &c__1);
00457             d_cnjg(&z__2, &vl[k + i__ * vl_dim1]);
00458             d__1 = sqrt(rwork[irwork + k - 1]);
00459             z__1.r = z__2.r / d__1, z__1.i = z__2.i / d__1;
00460             tmp.r = z__1.r, tmp.i = z__1.i;
00461             zscal_(n, &tmp, &vl[i__ * vl_dim1 + 1], &c__1);
00462             i__2 = k + i__ * vl_dim1;
00463             i__3 = k + i__ * vl_dim1;
00464             d__1 = vl[i__3].r;
00465             z__1.r = d__1, z__1.i = 0.;
00466             vl[i__2].r = z__1.r, vl[i__2].i = z__1.i;
00467 /* L20: */
00468         }
00469     }
00470 
00471     if (wantvr) {
00472 
00473 /*        Undo balancing of right eigenvectors */
00474 /*        (CWorkspace: none) */
00475 /*        (RWorkspace: need N) */
00476 
00477         zgebak_("B", "R", n, &ilo, &ihi, &rwork[ibal], n, &vr[vr_offset], 
00478                 ldvr, &ierr);
00479 
00480 /*        Normalize right eigenvectors and make largest component real */
00481 
00482         i__1 = *n;
00483         for (i__ = 1; i__ <= i__1; ++i__) {
00484             scl = 1. / dznrm2_(n, &vr[i__ * vr_dim1 + 1], &c__1);
00485             zdscal_(n, &scl, &vr[i__ * vr_dim1 + 1], &c__1);
00486             i__2 = *n;
00487             for (k = 1; k <= i__2; ++k) {
00488                 i__3 = k + i__ * vr_dim1;
00489 /* Computing 2nd power */
00490                 d__1 = vr[i__3].r;
00491 /* Computing 2nd power */
00492                 d__2 = d_imag(&vr[k + i__ * vr_dim1]);
00493                 rwork[irwork + k - 1] = d__1 * d__1 + d__2 * d__2;
00494 /* L30: */
00495             }
00496             k = idamax_(n, &rwork[irwork], &c__1);
00497             d_cnjg(&z__2, &vr[k + i__ * vr_dim1]);
00498             d__1 = sqrt(rwork[irwork + k - 1]);
00499             z__1.r = z__2.r / d__1, z__1.i = z__2.i / d__1;
00500             tmp.r = z__1.r, tmp.i = z__1.i;
00501             zscal_(n, &tmp, &vr[i__ * vr_dim1 + 1], &c__1);
00502             i__2 = k + i__ * vr_dim1;
00503             i__3 = k + i__ * vr_dim1;
00504             d__1 = vr[i__3].r;
00505             z__1.r = d__1, z__1.i = 0.;
00506             vr[i__2].r = z__1.r, vr[i__2].i = z__1.i;
00507 /* L40: */
00508         }
00509     }
00510 
00511 /*     Undo scaling if necessary */
00512 
00513 L50:
00514     if (scalea) {
00515         i__1 = *n - *info;
00516 /* Computing MAX */
00517         i__3 = *n - *info;
00518         i__2 = max(i__3,1);
00519         zlascl_("G", &c__0, &c__0, &cscale, &anrm, &i__1, &c__1, &w[*info + 1]
00520 , &i__2, &ierr);
00521         if (*info > 0) {
00522             i__1 = ilo - 1;
00523             zlascl_("G", &c__0, &c__0, &cscale, &anrm, &i__1, &c__1, &w[1], n, 
00524                      &ierr);
00525         }
00526     }
00527 
00528     work[1].r = (doublereal) maxwrk, work[1].i = 0.;
00529     return 0;
00530 
00531 /*     End of ZGEEV */
00532 
00533 } /* zgeev_ */


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